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;
        }
Exemple #2
0
        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));
            }
        }
Exemple #3
0
        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);
        }
Exemple #4
0
        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;
        }
Exemple #5
0
        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));
        }
Exemple #6
0
        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;
        }
Exemple #7
0
        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));
        }