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; }