public InvocationShape(LambdaExpression expression, MethodInfo method, IReadOnlyList <Expression> arguments = null, bool exactGenericTypeArguments = false, bool skipMatcherInitialization = false, bool allowNonOverridable = false) { Debug.Assert(expression != null); Debug.Assert(method != null); if (!allowNonOverridable) // the sole currently known legitimate case where this evaluates to `false` is when setting non-overridable properties via LINQ to Mocks { Guard.IsOverridable(method, expression); Guard.IsVisibleToProxyFactory(method); } this.Expression = expression; this.Method = method; if (arguments != null && !skipMatcherInitialization) { (this.argumentMatchers, this.Arguments) = MatcherFactory.CreateMatchers(arguments, method.GetParameters()); } else { this.argumentMatchers = noArgumentMatchers; this.Arguments = arguments ?? noArguments; } this.exactGenericTypeArguments = exactGenericTypeArguments; }
public static IMatcher CreateMatcher(Expression argument, ParameterInfo parameter) { if (parameter.ParameterType.IsByRef) { if ((parameter.Attributes & (ParameterAttributes.In | ParameterAttributes.Out)) == ParameterAttributes.Out) { // `out` parameter return(AnyMatcher.Instance); } else { // `ref` parameter // Test for special case: `It.Ref<TValue>.IsAny` if (argument is MemberExpression memberExpression) { var member = memberExpression.Member; if (member.Name == nameof(It.Ref <object> .IsAny)) { var memberDeclaringType = member.DeclaringType; if (memberDeclaringType.IsGenericType) { var memberDeclaringTypeDefinition = memberDeclaringType.GetGenericTypeDefinition(); if (memberDeclaringTypeDefinition == typeof(It.Ref <>)) { return(AnyMatcher.Instance); } } } } var constant = argument.PartialEval() as ConstantExpression; if (constant == null) { throw new NotSupportedException(Resources.RefExpressionMustBeConstantValue); } return(new RefMatcher(constant.Value)); } } else if (parameter.IsDefined(typeof(ParamArrayAttribute), true) && (argument.NodeType == ExpressionType.NewArrayInit || !argument.Type.IsArray)) { return(new ParamArrayMatcher((NewArrayExpression)argument)); } else { return(MatcherFactory.CreateMatcher(argument)); } }
private static IMatcher[] GetArgumentMatchers(IReadOnlyList <Expression> arguments, ParameterInfo[] parameters) { Debug.Assert(arguments != null); Debug.Assert(parameters != null); Debug.Assert(arguments.Count == parameters.Length); var n = parameters.Length; var argumentMatchers = new IMatcher[n]; for (int i = 0; i < n; ++i) { argumentMatchers[i] = MatcherFactory.CreateMatcher(arguments[i], parameters[i]); } return(argumentMatchers); }
public InvocationShape(LambdaExpression expression, MethodInfo method, IReadOnlyList <Expression> arguments = null) { Debug.Assert(expression != null); Debug.Assert(method != null); Guard.IsOverridable(method, expression); Guard.IsVisibleToProxyFactory(method); this.Expression = expression; this.Method = method; this.Arguments = arguments ?? noArguments; this.argumentMatchers = arguments != null?MatcherFactory.CreateMatchers(arguments, method.GetParameters()) : noArgumentMatchers; }
public static Pair <IMatcher[], Expression[]> CreateMatchers(IReadOnlyList <Expression> arguments, ParameterInfo[] parameters) { Debug.Assert(arguments != null); Debug.Assert(parameters != null); Debug.Assert(arguments.Count == parameters.Length); var n = parameters.Length; var evaluatedArguments = new Expression[n]; var argumentMatchers = new IMatcher[n]; for (int i = 0; i < n; ++i) { (argumentMatchers[i], evaluatedArguments[i]) = MatcherFactory.CreateMatcher(arguments[i], parameters[i]); } return(new Pair <IMatcher[], Expression[]>(argumentMatchers, evaluatedArguments)); }
public InvocationShape(LambdaExpression expression, MethodInfo method, IReadOnlyList <Expression> arguments = null, bool exactGenericTypeArguments = false) { Debug.Assert(expression != null); Debug.Assert(method != null); Guard.IsOverridable(method, expression); Guard.IsVisibleToProxyFactory(method); this.Expression = expression; this.Method = method; if (arguments != null) { (this.argumentMatchers, this.Arguments) = MatcherFactory.CreateMatchers(arguments, method.GetParameters()); } else { this.argumentMatchers = noArgumentMatchers; this.Arguments = noArguments; } this.exactGenericTypeArguments = exactGenericTypeArguments; }
public static Pair <IMatcher, Expression> CreateMatcher(Expression argument, ParameterInfo parameter) { if (parameter.ParameterType.IsByRef) { if ((parameter.Attributes & (ParameterAttributes.In | ParameterAttributes.Out)) == ParameterAttributes.Out) { // `out` parameter return(new Pair <IMatcher, Expression>(AnyMatcher.Instance, argument)); } else { // `ref` parameter // Test for special case: `It.Ref<TValue>.IsAny` if (argument is MemberExpression memberExpression) { var member = memberExpression.Member; if (member.Name == nameof(It.Ref <object> .IsAny)) { var memberDeclaringType = member.DeclaringType; if (memberDeclaringType.IsGenericType) { var memberDeclaringTypeDefinition = memberDeclaringType.GetGenericTypeDefinition(); if (memberDeclaringTypeDefinition == typeof(It.Ref <>)) { return(new Pair <IMatcher, Expression>(AnyMatcher.Instance, argument)); } } } } if (argument.PartialEval() is ConstantExpression constant) { return(new Pair <IMatcher, Expression>(new RefMatcher(constant.Value), constant)); } throw new NotSupportedException(Resources.RefExpressionMustBeConstantValue); } } else if (parameter.IsDefined(typeof(ParamArrayAttribute), true) && argument.NodeType == ExpressionType.NewArrayInit) { var newArrayExpression = (NewArrayExpression)argument; Debug.Assert(newArrayExpression.Type.IsArray); var elementType = newArrayExpression.Type.GetElementType(); var n = newArrayExpression.Expressions.Count; var matchers = new IMatcher[n]; var initializers = new Expression[n]; for (int i = 0; i < n; ++i) { (matchers[i], initializers[i]) = MatcherFactory.CreateMatcher(newArrayExpression.Expressions[i]); initializers[i] = initializers[i].ConvertIfNeeded(elementType); } return(new Pair <IMatcher, Expression>(new ParamArrayMatcher(matchers), Expression.NewArrayInit(elementType, initializers))); } else if (argument.NodeType == ExpressionType.Convert) { var convertExpression = (UnaryExpression)argument; if (convertExpression.Method?.Name == "op_Implicit") { if (!parameter.ParameterType.IsAssignableFrom(convertExpression.Operand.Type) && convertExpression.Operand.IsMatch(out _)) { throw new ArgumentException( string.Format( Resources.ArgumentMatcherWillNeverMatch, convertExpression.Operand.ToStringFixed(), convertExpression.Operand.Type.GetFormattedName(), parameter.ParameterType.GetFormattedName())); } } } return(MatcherFactory.CreateMatcher(argument)); }