Beispiel #1
0
        internal static ConversionRank GetArgumentConversionRank(
            object argument,
            Type parameterType)
        {
            ConversionRank conversionRank = LanguagePrimitives.GetConversionRank(Adapter.GetArgumentType(argument), parameterType);

            if (conversionRank == ConversionRank.None)
            {
                conversionRank = LanguagePrimitives.GetConversionRank(Adapter.GetArgumentType(PSObject.Base(argument)), parameterType);
            }
            return(conversionRank);
        }
Beispiel #2
0
        internal static MethodInformation FindBestMethod(
            string methodName,
            MethodInformation[] methods,
            object[] arguments,
            out bool expandParamsOnBest)
        {
            if (methods.Length == 1 && !methods[0].hasVarArgs && methods[0].parameters.Length == arguments.Length)
            {
                expandParamsOnBest = false;
                return(methods[0]);
            }
            List <Adapter.OverloadCandidate> candidates = new List <Adapter.OverloadCandidate>();

            for (int index1 = 0; index1 < methods.Length; ++index1)
            {
                MethodInformation method = methods[index1];
                if (!method.isGeneric)
                {
                    ParameterInformation[] parameters = method.parameters;
                    if (arguments.Length != parameters.Length)
                    {
                        if (arguments.Length > parameters.Length)
                        {
                            if (!method.hasVarArgs)
                            {
                                continue;
                            }
                        }
                        else if (method.hasOptional || method.hasVarArgs && arguments.Length + 1 == parameters.Length)
                        {
                            if (method.hasOptional)
                            {
                                int num = 0;
                                for (int index2 = 0; index2 < parameters.Length; ++index2)
                                {
                                    if (parameters[index2].isOptional)
                                    {
                                        ++num;
                                    }
                                }
                                if (arguments.Length + num < parameters.Length)
                                {
                                    continue;
                                }
                            }
                        }
                        else
                        {
                            continue;
                        }
                    }
                    Adapter.OverloadCandidate overloadCandidate = new Adapter.OverloadCandidate(method, arguments.Length);
                    for (int index2 = 0; overloadCandidate != null && index2 < parameters.Length; ++index2)
                    {
                        ParameterInformation parameterInformation = parameters[index2];
                        if (!parameterInformation.isOptional || arguments.Length > index2)
                        {
                            if (parameterInformation.isParamArray)
                            {
                                Type elementType = parameterInformation.parameterType.GetElementType();
                                if (parameters.Length == arguments.Length)
                                {
                                    ConversionRank argumentConversionRank1 = Adapter.GetArgumentConversionRank(arguments[index2], parameterInformation.parameterType);
                                    ConversionRank argumentConversionRank2 = Adapter.GetArgumentConversionRank(arguments[index2], elementType);
                                    if (argumentConversionRank2 > argumentConversionRank1)
                                    {
                                        overloadCandidate.expandedParameters      = Adapter.ExpandParameters(arguments.Length, parameters, elementType);
                                        overloadCandidate.conversionRanks[index2] = argumentConversionRank2;
                                    }
                                    else
                                    {
                                        overloadCandidate.conversionRanks[index2] = argumentConversionRank1;
                                    }
                                    if (overloadCandidate.conversionRanks[index2] == ConversionRank.None)
                                    {
                                        overloadCandidate = (Adapter.OverloadCandidate)null;
                                    }
                                }
                                else
                                {
                                    for (int index3 = index2; index3 < arguments.Length; ++index3)
                                    {
                                        overloadCandidate.conversionRanks[index3] = Adapter.GetArgumentConversionRank(arguments[index3], elementType);
                                        if (overloadCandidate.conversionRanks[index3] == ConversionRank.None)
                                        {
                                            overloadCandidate = (Adapter.OverloadCandidate)null;
                                            break;
                                        }
                                    }
                                    if (overloadCandidate != null)
                                    {
                                        overloadCandidate.expandedParameters = Adapter.ExpandParameters(arguments.Length, parameters, elementType);
                                    }
                                }
                            }
                            else
                            {
                                overloadCandidate.conversionRanks[index2] = Adapter.GetArgumentConversionRank(arguments[index2], parameterInformation.parameterType);
                                if (overloadCandidate.conversionRanks[index2] == ConversionRank.None)
                                {
                                    overloadCandidate = (Adapter.OverloadCandidate)null;
                                }
                            }
                        }
                        else
                        {
                            break;
                        }
                    }
                    if (overloadCandidate != null)
                    {
                        candidates.Add(overloadCandidate);
                    }
                }
            }
            if (candidates.Count == 0)
            {
                throw new MethodException("MethodCountCouldNotFindBest", (Exception)null, "ExtendedTypeSystem", "MethodArgumentCountException", new object[2]
                {
                    (object)methodName,
                    (object)arguments.Length
                });
            }
            Adapter.OverloadCandidate overloadCandidate1 = candidates.Count != 1 ? Adapter.FindBestCandidate(candidates, arguments) : candidates[0];
            if (overloadCandidate1 != null)
            {
                expandParamsOnBest = overloadCandidate1.expandedParameters != null;
                return(overloadCandidate1.method);
            }
            throw new MethodException("MethodCountCouldNotFindBest", (Exception)null, "ExtendedTypeSystem", "MethodAmbiguousException", new object[2]
            {
                (object)methodName,
                (object)arguments.Length
            });
        }
Beispiel #3
0
        private static int CompareMethods(
            Adapter.OverloadCandidate candidate1,
            Adapter.OverloadCandidate candidate2,
            object[] arguments)
        {
            ParameterInformation[] parameterInformationArray1 = candidate1.expandedParameters != null ? candidate1.expandedParameters : candidate1.parameters;
            ParameterInformation[] parameterInformationArray2 = candidate2.expandedParameters != null ? candidate2.expandedParameters : candidate2.parameters;
            int num1   = 0;
            int length = parameterInformationArray1.Length;
            int index1 = 0;

            while (index1 < parameterInformationArray1.Length)
            {
                if (candidate1.conversionRanks[index1] < candidate2.conversionRanks[index1])
                {
                    num1 -= length;
                }
                else if (candidate1.conversionRanks[index1] > candidate2.conversionRanks[index1])
                {
                    num1 += length;
                }
                else if (candidate1.conversionRanks[index1] == ConversionRank.UnrelatedArrays)
                {
                    Type           elementType     = Adapter.EffectiveArgumentType(arguments[index1]).GetElementType();
                    ConversionRank conversionRank1 = LanguagePrimitives.GetConversionRank(elementType, parameterInformationArray1[index1].parameterType.GetElementType());
                    ConversionRank conversionRank2 = LanguagePrimitives.GetConversionRank(elementType, parameterInformationArray2[index1].parameterType.GetElementType());
                    if (conversionRank1 < conversionRank2)
                    {
                        num1 -= length;
                    }
                    else if (conversionRank1 > conversionRank2)
                    {
                        num1 += length;
                    }
                }
                ++index1;
                --length;
            }
            if (num1 == 0)
            {
                int num2   = parameterInformationArray1.Length;
                int index2 = 0;
                while (index2 < parameterInformationArray1.Length)
                {
                    ConversionRank conversionRank1 = candidate1.conversionRanks[index2];
                    ConversionRank conversionRank2 = candidate2.conversionRanks[index2];
                    if (conversionRank1 >= ConversionRank.NullToValue && conversionRank2 >= ConversionRank.NullToValue && conversionRank1 >= ConversionRank.NumericImplicit == conversionRank2 >= ConversionRank.NumericImplicit)
                    {
                        if (conversionRank1 >= ConversionRank.NumericImplicit)
                        {
                            num2 = -num2;
                        }
                        ConversionRank conversionRank3 = LanguagePrimitives.GetConversionRank(parameterInformationArray1[index2].parameterType, parameterInformationArray2[index2].parameterType);
                        ConversionRank conversionRank4 = LanguagePrimitives.GetConversionRank(parameterInformationArray2[index2].parameterType, parameterInformationArray1[index2].parameterType);
                        if (conversionRank3 < conversionRank4)
                        {
                            num1 += num2;
                        }
                        else if (conversionRank3 > conversionRank4)
                        {
                            num1 -= num2;
                        }
                    }
                    ++index2;
                    num2 = Math.Abs(num2) - 1;
                }
            }
            if (num1 != 0)
            {
                return(num1);
            }
            for (int index2 = 0; index2 < parameterInformationArray1.Length; ++index2)
            {
                if (!parameterInformationArray1[index2].parameterType.Equals(parameterInformationArray2[index2].parameterType))
                {
                    return(0);
                }
            }
            if (candidate1.expandedParameters != null && candidate2.expandedParameters != null)
            {
                return(candidate1.parameters.Length <= candidate2.parameters.Length ? -1 : 1);
            }
            if (candidate1.expandedParameters != null)
            {
                return(-1);
            }
            return(candidate2.expandedParameters == null ? 0 : 1);
        }
Beispiel #4
0
        private object CoerceTypeAsNeeded(CommandParameterInternal argument, string parameterName, Type toType, ParameterCollectionTypeInformation collectionTypeInfo, object currentValue)
        {
            if (argument == null)
            {
                throw PSTraceSource.NewArgumentNullException("argument");
            }
            if (toType == null)
            {
                throw PSTraceSource.NewArgumentNullException("toType");
            }
            if (collectionTypeInfo == null)
            {
                collectionTypeInfo = new ParameterCollectionTypeInformation(toType);
            }
            object result = currentValue;

            using (bindingTracer.TraceScope("COERCE arg to [{0}]", new object[] { toType }))
            {
                Type c = null;
                try
                {
                    if (IsNullParameterValue(currentValue))
                    {
                        return(this.HandleNullParameterForSpecialTypes(argument, parameterName, toType, currentValue));
                    }
                    c = currentValue.GetType();
                    if (toType.IsAssignableFrom(c))
                    {
                        bindingTracer.WriteLine("Parameter and arg types the same, no coercion is needed.", new object[0]);
                        return(currentValue);
                    }
                    bindingTracer.WriteLine("Trying to convert argument value from {0} to {1}", new object[] { c, toType });
                    if (toType == typeof(PSObject))
                    {
                        if ((this.command != null) && (currentValue == this.command.CurrentPipelineObject.BaseObject))
                        {
                            currentValue = this.command.CurrentPipelineObject;
                        }
                        bindingTracer.WriteLine("The parameter is of type [{0}] and the argument is an PSObject, so the parameter value is the argument value wrapped into an PSObject.", new object[] { toType });
                        return(LanguagePrimitives.AsPSObjectOrNull(currentValue));
                    }
                    if ((toType == typeof(string)) && (c == typeof(PSObject)))
                    {
                        PSObject obj3 = (PSObject)currentValue;
                        if (obj3 == AutomationNull.Value)
                        {
                            bindingTracer.WriteLine("CONVERT a null PSObject to a null string.", new object[0]);
                            return(null);
                        }
                    }
                    if (((toType == typeof(bool)) || (toType == typeof(SwitchParameter))) || (toType == typeof(bool?)))
                    {
                        Type type = null;
                        if (c == typeof(PSObject))
                        {
                            PSObject obj4 = (PSObject)currentValue;
                            currentValue = obj4.BaseObject;
                            if (currentValue is SwitchParameter)
                            {
                                SwitchParameter parameter = (SwitchParameter)currentValue;
                                currentValue = parameter.IsPresent;
                            }
                            type = currentValue.GetType();
                        }
                        else
                        {
                            type = c;
                        }
                        if (type == typeof(bool))
                        {
                            if (LanguagePrimitives.IsBooleanType(toType))
                            {
                                return(ParserOps.BoolToObject((bool)currentValue));
                            }
                            return(new SwitchParameter((bool)currentValue));
                        }
                        if (type == typeof(int))
                        {
                            if (((int)LanguagePrimitives.ConvertTo(currentValue, typeof(int), CultureInfo.InvariantCulture)) != 0)
                            {
                                if (LanguagePrimitives.IsBooleanType(toType))
                                {
                                    return(ParserOps.BoolToObject(true));
                                }
                                return(new SwitchParameter(true));
                            }
                            if (LanguagePrimitives.IsBooleanType(toType))
                            {
                                return(ParserOps.BoolToObject(false));
                            }
                            return(new SwitchParameter(false));
                        }
                        if (LanguagePrimitives.IsNumeric(Type.GetTypeCode(type)))
                        {
                            double num = (double)LanguagePrimitives.ConvertTo(currentValue, typeof(double), CultureInfo.InvariantCulture);
                            if (num == 0.0)
                            {
                                if (LanguagePrimitives.IsBooleanType(toType))
                                {
                                    return(ParserOps.BoolToObject(false));
                                }
                                return(new SwitchParameter(false));
                            }
                            if (LanguagePrimitives.IsBooleanType(toType))
                            {
                                return(ParserOps.BoolToObject(true));
                            }
                            return(new SwitchParameter(true));
                        }
                        ParameterBindingException exception = new ParameterBindingException(ErrorCategory.InvalidArgument, this.InvocationInfo, this.GetErrorExtent(argument), parameterName, toType, c, "ParameterBinderStrings", "CannotConvertArgument", new object[] { type, "" });
                        throw exception;
                    }
                    if ((collectionTypeInfo.ParameterCollectionType == ParameterCollectionType.ICollectionGeneric) || (collectionTypeInfo.ParameterCollectionType == ParameterCollectionType.IList))
                    {
                        object obj5 = PSObject.Base(currentValue);
                        if (obj5 != null)
                        {
                            ConversionRank conversionRank = LanguagePrimitives.GetConversionRank(obj5.GetType(), toType);
                            if ((((conversionRank == ConversionRank.Constructor) || (conversionRank == ConversionRank.ImplicitCast)) || (conversionRank == ConversionRank.ExplicitCast)) && LanguagePrimitives.TryConvertTo(currentValue, toType, Thread.CurrentThread.CurrentCulture, out result))
                            {
                                return(result);
                            }
                        }
                    }
                    if (collectionTypeInfo.ParameterCollectionType != ParameterCollectionType.NotCollection)
                    {
                        bindingTracer.WriteLine("ENCODING arg into collection", new object[0]);
                        bool coercionRequired = false;
                        return(this.EncodeCollection(argument, parameterName, collectionTypeInfo, toType, currentValue, collectionTypeInfo.ElementType != null, out coercionRequired));
                    }
                    if (((((GetIList(currentValue) != null) && (toType != typeof(object))) && ((toType != typeof(PSObject)) && (toType != typeof(PSListModifier)))) && ((!toType.IsGenericType || (toType.GetGenericTypeDefinition() != typeof(PSListModifier <>))) && (!toType.IsGenericType || (toType.GetGenericTypeDefinition() != typeof(FlagsExpression <>))))) && !toType.IsEnum)
                    {
                        throw new NotSupportedException();
                    }
                    bindingTracer.WriteLine("CONVERT arg type to param type using LanguagePrimitives.ConvertTo", new object[0]);
                    bool flag2 = false;
                    if (this.context.LanguageMode == PSLanguageMode.ConstrainedLanguage)
                    {
                        object obj6  = PSObject.Base(currentValue);
                        bool   flag3 = obj6 is PSObject;
                        bool   flag4 = (obj6 != null) && typeof(IDictionary).IsAssignableFrom(obj6.GetType());
                        flag2 = ((((PSLanguageMode)this.Command.CommandInfo.DefiningLanguageMode) == PSLanguageMode.FullLanguage) && !flag3) && !flag4;
                    }
                    try
                    {
                        if (flag2)
                        {
                            this.context.LanguageMode = PSLanguageMode.FullLanguage;
                        }
                        result = LanguagePrimitives.ConvertTo(currentValue, toType, Thread.CurrentThread.CurrentCulture);
                    }
                    finally
                    {
                        if (flag2)
                        {
                            this.context.LanguageMode = PSLanguageMode.ConstrainedLanguage;
                        }
                    }
                    bindingTracer.WriteLine("CONVERT SUCCESSFUL using LanguagePrimitives.ConvertTo: [{0}]", new object[] { (result == null) ? "null" : result.ToString() });
                    return(result);
                }
                catch (NotSupportedException exception2)
                {
                    bindingTracer.TraceError("ERROR: COERCE FAILED: arg [{0}] could not be converted to the parameter type [{1}]", new object[] { (result == null) ? "null" : result, toType });
                    ParameterBindingException exception3 = new ParameterBindingException(exception2, ErrorCategory.InvalidArgument, this.InvocationInfo, this.GetErrorExtent(argument), parameterName, toType, c, "ParameterBinderStrings", "CannotConvertArgument", new object[] { (result == null) ? "null" : result, exception2.Message });
                    throw exception3;
                }
                catch (PSInvalidCastException exception4)
                {
                    object[] args = new object[] { result ?? "null", toType };
                    bindingTracer.TraceError("ERROR: COERCE FAILED: arg [{0}] could not be converted to the parameter type [{1}]", args);
                    ParameterBindingException exception5 = new ParameterBindingException(exception4, ErrorCategory.InvalidArgument, this.InvocationInfo, this.GetErrorExtent(argument), parameterName, toType, c, "ParameterBinderStrings", "CannotConvertArgumentNoMessage", new object[] { exception4.Message });
                    throw exception5;
                }
            }
            return(result);
        }