public static ParsedCallExpression BuildSetterFromGetter <TValue>(
            ParsedCallExpression parsedCallExpression)
        {
            var propertyName = GetPropertyName(parsedCallExpression);

            if (propertyName is null)
            {
                var expressionDescription = GetExpressionDescription(parsedCallExpression);
                throw new ArgumentException("Expression '" + expressionDescription +
                                            "' must refer to a property or indexer getter, but doesn't.");
            }

            var parameterTypes = new Type[parsedCallExpression.ArgumentsExpressions.Length + 1];

            for (int i = 0; i < parsedCallExpression.ArgumentsExpressions.Length; ++i)
            {
                parameterTypes[i] = parsedCallExpression.ArgumentsExpressions[i].ArgumentInformation.ParameterType;
            }

            parameterTypes[parsedCallExpression.ArgumentsExpressions.Length] = parsedCallExpression.CalledMethod.ReturnType;

            // The DeclaringType may be null, so fall back to the faked object type.
            // (It's unlikely to happen, though, and would require the client code to have passed a specially
            // constructed expression to ACallToSet; perhaps a dynamically generated method created
            // via lightweight code generation.)
            var callTargetType = parsedCallExpression.CalledMethod.DeclaringType
                                 ?? Fake.GetFakeManager(parsedCallExpression.CallTarget).FakeObjectType;
            var setPropertyName   = "set_" + propertyName;
            var indexerSetterInfo = callTargetType.GetMethod(setPropertyName, parameterTypes);

            if (indexerSetterInfo is null)
            {
                if (parsedCallExpression.ArgumentsExpressions.Any())
                {
                    var expressionDescription = GetExpressionDescription(parsedCallExpression);
                    throw new ArgumentException("Expression '" + expressionDescription +
                                                "' refers to an indexed property that does not have a setter.");
                }

                throw new ArgumentException($"The property {propertyName} does not have a setter.");
            }

            var originalParameterInfos = indexerSetterInfo.GetParameters();

            var newParsedSetterValueExpression = new ParsedArgumentExpression(
                BuildArgumentThatMatchesAnything <TValue>(),
                originalParameterInfos.Last());

            var arguments = new ParsedArgumentExpression[originalParameterInfos.Length];

            Array.Copy(parsedCallExpression.ArgumentsExpressions, arguments, originalParameterInfos.Length - 1);
            arguments[originalParameterInfos.Length - 1] = newParsedSetterValueExpression;

            return(new ParsedCallExpression(indexerSetterInfo, parsedCallExpression.CallTarget, arguments));
        }
Example #2
0
        private ParsedCallExpression CreateSetterExpressionWithNewValue(Expression <Func <TValue> > valueExpression)
        {
            var originalParameterInfos = this.parsedSetterExpression.CalledMethod.GetParameters();
            var parsedValueExpression  = new ParsedArgumentExpression(
                valueExpression.Body,
                originalParameterInfos.Last());

            var arguments = this.parsedSetterExpression.ArgumentsExpressions
                            .Take(originalParameterInfos.Length - 1)
                            .Concat(new[] { parsedValueExpression });

            return(new ParsedCallExpression(
                       this.parsedSetterExpression.CalledMethod,
                       this.parsedSetterExpression.CallTarget,
                       arguments));
        }
        private ParsedCallExpression CreateSetterExpressionWithNewValue(Expression <Func <TValue> > valueExpression)
        {
            var originalParameterInfos = this.parsedSetterExpression.CalledMethod.GetParameters();
            var parsedValueExpression  = new ParsedArgumentExpression(
                valueExpression.Body,
                originalParameterInfos.Last());

            var arguments = new ParsedArgumentExpression[originalParameterInfos.Length];

            Array.Copy(this.parsedSetterExpression.ArgumentsExpressions, arguments, originalParameterInfos.Length - 1);
            arguments[originalParameterInfos.Length - 1] = parsedValueExpression;

            return(new ParsedCallExpression(
                       this.parsedSetterExpression.CalledMethod,
                       this.parsedSetterExpression.CallTarget,
                       arguments));
        }
        private static ParsedCallExpression BuildSetterFromGetter <TValue>(
            ParsedCallExpression parsedCallExpression)
        {
            var propertyName = GetPropertyName(parsedCallExpression);

            if (propertyName == null)
            {
                var expressionDescription = GetExpressionDescription(parsedCallExpression);
                throw new ArgumentException("Expression '" + expressionDescription +
                                            "' must refer to a property or indexer getter, but doesn't.");
            }

            var parsedArgumentExpressions = parsedCallExpression.ArgumentsExpressions ?? new ParsedArgumentExpression[0];
            var parameterTypes            = parsedArgumentExpressions
                                            .Select(p => p.ArgumentInformation.ParameterType)
                                            .Concat(new[] { parsedCallExpression.CalledMethod.ReturnType })
                                            .ToArray();

            var indexerSetterInfo = parsedCallExpression.CallTarget.GetType()
                                    .GetMethod("set_" + propertyName, parameterTypes);

            if (indexerSetterInfo == null)
            {
                if (parsedArgumentExpressions.Any())
                {
                    var expressionDescription = GetExpressionDescription(parsedCallExpression);
                    throw new ArgumentException("Expression '" + expressionDescription +
                                                "' refers to an indexed property that does not have a setter.");
                }

                throw new ArgumentException(
                          "The property '" + propertyName + "' does not have a setter.");
            }

            var originalParameterInfos = indexerSetterInfo.GetParameters();

            var newParsedSetterValueExpression = new ParsedArgumentExpression(
                BuildArgumentThatMatchesAnything <TValue>(),
                originalParameterInfos.Last());

            var arguments = parsedArgumentExpressions
                            .Take(originalParameterInfos.Length - 1)
                            .Concat(new[] { newParsedSetterValueExpression });

            return(new ParsedCallExpression(indexerSetterInfo, parsedCallExpression.CallTarget, arguments));
        }