Esempio n. 1
0
        public Expression ConvertMethodParameters(OverloadResolutionData <MethodInfo> resolvedMethod, Expression target, DynamicMetaObject[] args)//, Type[] argTypeArray)
        {
            if (resolvedMethod == null)
            {
                throw new ArgumentNullException(nameof(resolvedMethod));
            }

            if (args == null)
            {
                throw new ArgumentNullException(nameof(args));
            }

            var argExpressions = _overloadResolver.CreateParameterExpressions(resolvedMethod, args);
            var method         = resolvedMethod.FunctionMember;

            Expression result = Expression.Call(
                VelocityExpressions.ConvertIfNeeded(target, method.DeclaringType),
                method,
                argExpressions
                );

            if (method.ReturnType == typeof(void))
            {
                result = Expression.Block(
                    result,
                    Constants.VoidReturnValue
                    );
            }

            return(result);
        }
        public IImmutableList<Expression> CreateParameterExpressions<T>(OverloadResolutionData<T> overload, DynamicMetaObject[] args)
            where T : MemberInfo
        {
            if (overload == null)
                throw new ArgumentNullException(nameof(overload));

            if (args == null)
                throw new ArgumentNullException(nameof(args));

            var parameters = overload.Parameters;

            bool isInExpandedForm = overload.ApplicableForm == ApplicableForm.Expanded;

            int fixedParams = isInExpandedForm
                ? parameters.Length - 1
                : parameters.Length;

            var argExpressionBuilder = ImmutableArray.CreateBuilder<Expression>(parameters.Length);

            for (int i = 0; i < fixedParams; i++)
            {
                var parameter = parameters[i];
                argExpressionBuilder.Add(VelocityExpressions.ConvertIfNeeded(args[i], parameter));
            }
            if (isInExpandedForm)
            {
                var lastParameter = overload.Parameters.Last();

                var elementType = lastParameter.GetElementType();
                argExpressionBuilder.Add(Expression.NewArrayInit(
                    elementType,
                    args.Skip(fixedParams)
                        .Select(x => VelocityExpressions.ConvertIfNeeded(x, elementType))
                    ));
            }

            return argExpressionBuilder.ToImmutable();
        }
        public BetterResult IsBetterFunctionMember<T>(IImmutableList<Type> arguments, OverloadResolutionData<T> left, OverloadResolutionData<T> right)
            where T : MemberInfo
        {
            if (left == null)
                throw new ArgumentNullException(nameof(left));
            if (right == null)
                throw new ArgumentNullException(nameof(right));

            // - for each argument, the implicit conversion from EX to QX is not better than the implicit conversion from EX to PX, and
            // - for at least one argument, the conversion from EX to PX is better than the conversion from EX to QX.
            bool leftIsBetter = false;
            bool rightIsBetter = false;

            for (int i = 0; i < arguments.Count; i++)
            {
                var expressionType = arguments[i];
                var leftParamType = left.GetExpandedParameterType(i);
                var rightParamType = right.GetExpandedParameterType(i);

                leftIsBetter |= IsBetterConversionFromExpression(expressionType, leftParamType, rightParamType);
                rightIsBetter |= IsBetterConversionFromExpression(expressionType, rightParamType, leftParamType);
            }

            if (leftIsBetter != rightIsBetter)
            {
                return leftIsBetter
                    ? BetterResult.Better
                    : BetterResult.Worse;
            }

            // Otherwise, if MP is applicable in its normal form and MQ has a params array and is applicable
            // only in its expanded form, then MP is better than MQ.
            if (left.ApplicableForm != right.ApplicableForm)
            {
                return left.ApplicableForm == ApplicableForm.Normal
                    ? BetterResult.Better
                    : BetterResult.Worse;
            }

            // Otherwise, if MP has more declared parameters than MQ, then MP is better than MQ. This can
            // occur if both methods have params arrays and are applicable only in their expanded forms.
            var leftParamCount = left.Parameters.Length;
            var rightParamCount = right.Parameters.Length;
            if (leftParamCount != rightParamCount)
            {
                return leftParamCount > rightParamCount
                    ? BetterResult.Better
                    : BetterResult.Worse;
            }

            return BetterResult.Incomparable;
        }