예제 #1
0
        private static InvocationExpressionSyntax SplitLinqWhereInvocation(
            InvocationExpressionSyntax invocation,
            SimpleLambdaExpressionSyntax filter)
        {
            var filterParameter  = filter.Parameter;
            var filterExpression = (ExpressionSyntax)filter.Body;

            var factors = FactorizeExpression(filterExpression);

            var newInvocation = ExtendedSyntaxFactory.MakeInvocationWithLambdaArgument(
                invocation.Expression,
                filterParameter,
                factors[0]);

            for (int i = 1; i < factors.Count; ++i)
            {
                var memberAccess = SyntaxFactory.MemberAccessExpression(
                    SyntaxKind.SimpleMemberAccessExpression,
                    newInvocation,
                    SyntaxFactory.IdentifierName(LinqHelper.WhereMethodName));

                newInvocation = ExtendedSyntaxFactory.MakeInvocationWithLambdaArgument(
                    memberAccess,
                    filterParameter,
                    factors[i]);
            }

            return(newInvocation.WithTriviaFrom(invocation));
        }
예제 #2
0
        private static ExpressionSyntax Invert(
            bool isAllToAny,
            bool isNegationRequired,
            InvocationExpressionSyntax invocation,
            SimpleLambdaExpressionSyntax lambda)
        {
            SimpleLambdaExpressionSyntax invertedLambda;

            if (lambda.Body.IsKind(SyntaxKind.LogicalNotExpression))
            {
                var negation = (PrefixUnaryExpressionSyntax)lambda.Body;

                invertedLambda = SyntaxFactory.SimpleLambdaExpression(
                    lambda.Parameter,
                    negation.Operand);
            }
            else if (lambda.Body.IsKind(SyntaxKind.IdentifierName) ||
                     lambda.Body.IsKind(SyntaxKind.SimpleMemberAccessExpression) ||
                     lambda.Body.IsKind(SyntaxKind.InvocationExpression))
            {
                var negation = SyntaxFactory.PrefixUnaryExpression(
                    SyntaxKind.LogicalNotExpression,
                    (ExpressionSyntax)lambda.Body);

                invertedLambda = SyntaxFactory.SimpleLambdaExpression(
                    lambda.Parameter,
                    negation);
            }
            else
            {
                var operation = (BinaryExpressionSyntax)lambda.Body;

                var invertedOperator = InvertOperator(operation.OperatorToken.CSharpKind());

                var invertedOperationToken = SyntaxFactory.Token(invertedOperator);

                var invertedOperation = operation.WithOperatorToken(invertedOperationToken);

                invertedLambda = SyntaxFactory.SimpleLambdaExpression(
                    lambda.Parameter,
                    invertedOperation);
            }

            var memberAccess = (MemberAccessExpressionSyntax)invocation.Expression;

            var newName = isAllToAny ? LinqHelper.AnyMethodName : LinqHelper.AllMethodName;

            var newNameIdentifier = SyntaxFactory.IdentifierName(newName);

            var newMemberAccess = memberAccess.WithName(newNameIdentifier);

            var newInvocation = ExtendedSyntaxFactory.MakeInvocation(
                newMemberAccess,
                invertedLambda);

            return(newInvocation);
        }
예제 #3
0
        private static InvocationExpressionSyntax SplitFunctionComposition(
            InvocationExpressionSyntax selectInvocation,
            SimpleLambdaExpressionSyntax projection,
            InvocationExpressionSyntax[] invocationStack,
            SemanticModel semanticModel)
        {
            var lambdaParameter = projection.Parameter;
            var parameterName   = lambdaParameter.Identifier.Text;
            var parameterSymbol = semanticModel.GetDeclaredSymbol(lambdaParameter);

            Func <InvocationExpressionSyntax, bool> isNeedToReplaceInvocation = i =>
                                                                                DataFlowAnalysisHelper.IsIdentifierReferencedIn(
                parameterName,
                parameterSymbol,
                semanticModel,
                i);

            var newSelectInvocation = ExtendedSyntaxFactory.MakeInvocationWithLambdaArgument(
                selectInvocation.Expression,
                lambdaParameter,
                invocationStack[0]);

            var invocationReplacer = new InvocationReplacer(
                isNeedToReplaceInvocation,
                SyntaxFactory.IdentifierName(parameterName));

            for (int i = 1; i < invocationStack.Length; ++i)
            {
                var innerInvocation = invocationStack[i];

                var processedInnerInvocation = ReplaceInvocationsInArguments(
                    innerInvocation,
                    invocationReplacer);

                var memberAccess = SyntaxFactory.MemberAccessExpression(
                    SyntaxKind.SimpleMemberAccessExpression,
                    newSelectInvocation,
                    SyntaxFactory.IdentifierName(LinqHelper.SelectMethodName));

                newSelectInvocation = ExtendedSyntaxFactory.MakeInvocationWithLambdaArgument(
                    memberAccess,
                    lambdaParameter,
                    processedInnerInvocation);
            }

            return(newSelectInvocation.WithTriviaFrom(selectInvocation));
        }
예제 #4
0
        private static InvocationExpressionSyntax Merge(
            InvocationExpressionSyntax outerMostInvocation,
            MemberAccessExpressionSyntax innerMostWhereAccess,
            List <ExpressionSyntax> selectArguments,
            SemanticModel semanticModel)
        {
            var firstArgument = selectArguments[0];

            string                     parameterName;
            ParameterSyntax            firstParameter;
            IdentifierNameSyntax       firstParameterIdentifier;
            InvocationExpressionSyntax resultInvocation;

            if (firstArgument.IsKind(SyntaxKind.SimpleLambdaExpression))
            {
                var lambda = (SimpleLambdaExpressionSyntax)firstArgument;
                firstParameter           = lambda.Parameter;
                parameterName            = firstParameter.Identifier.Text;
                firstParameterIdentifier = SyntaxFactory.IdentifierName(firstParameter.Identifier);
                resultInvocation         = (InvocationExpressionSyntax)lambda.Body;
            }
            else
            {
                parameterName = NameHelper.GetLambdaParameterName(
                    outerMostInvocation.SpanStart,
                    semanticModel);

                var parameterIdentifier = SyntaxFactory
                                          .Identifier(parameterName)
                                          .WithAdditionalAnnotations(RenameAnnotation.Create());

                firstParameter = SyntaxFactory.Parameter(parameterIdentifier);

                firstParameterIdentifier = SyntaxFactory.IdentifierName(parameterIdentifier);

                resultInvocation = ExtendedSyntaxFactory.MakeInvocation(
                    firstArgument,
                    firstParameterIdentifier);
            }

            for (int i = 1; i < selectArguments.Count; ++i)
            {
                if (selectArguments[i].IsKind(SyntaxKind.SimpleLambdaExpression))
                {
                    var currentLambda        = (SimpleLambdaExpressionSyntax)selectArguments[i];
                    var currentParameter     = currentLambda.Parameter;
                    var currentParameterName = currentParameter.Identifier.Text;

                    var parameterSymbol = semanticModel.GetDeclaredSymbol(currentParameter);

                    var substituteRewriter = new SubstituteRewriter(
                        currentParameterName,
                        parameterSymbol,
                        semanticModel,
                        resultInvocation);

                    resultInvocation = (InvocationExpressionSyntax)currentLambda
                                       .Body
                                       .Accept(substituteRewriter);
                }
                else
                {
                    resultInvocation = ExtendedSyntaxFactory.MakeInvocation(
                        selectArguments[i],
                        resultInvocation);
                }
            }

            var newLambda = SyntaxFactory.SimpleLambdaExpression(
                firstParameter,
                resultInvocation);

            var newInvocation = ExtendedSyntaxFactory.MakeInvocation(
                innerMostWhereAccess,
                newLambda);

            return(newInvocation);
        }
예제 #5
0
        private static InvocationExpressionSyntax Merge(
            InvocationExpressionSyntax outerMostInvocation,
            MemberAccessExpressionSyntax innerMostWhereAccess,
            List <ExpressionSyntax> whereArguments,
            SemanticModel semanticModel)
        {
            var firstArgument = whereArguments[0];

            string               parameterName;
            ParameterSyntax      firstParameter;
            IdentifierNameSyntax firstParameterIdentifier;
            ExpressionSyntax     filterExpression;

            if (firstArgument.IsKind(SyntaxKind.SimpleLambdaExpression))
            {
                var lambda = (SimpleLambdaExpressionSyntax)firstArgument;
                firstParameter           = lambda.Parameter;
                parameterName            = firstParameter.Identifier.Text;
                firstParameterIdentifier = SyntaxFactory.IdentifierName(firstParameter.Identifier);
                filterExpression         = MakeExpressionFromLambdaBody(lambda.Body);
            }
            else
            {
                parameterName = NameHelper.GetLambdaParameterName(
                    outerMostInvocation.SpanStart,
                    semanticModel);

                var parameterIdentifier = SyntaxFactory
                                          .Identifier(parameterName)
                                          .WithAdditionalAnnotations(RenameAnnotation.Create());

                firstParameter = SyntaxFactory.Parameter(parameterIdentifier);

                firstParameterIdentifier = SyntaxFactory.IdentifierName(parameterIdentifier);

                filterExpression = ExtendedSyntaxFactory.MakeInvocation(
                    firstArgument,
                    firstParameterIdentifier);
            }


            for (int i = 1; i < whereArguments.Count; ++i)
            {
                ExpressionSyntax andOperand;

                if (whereArguments[i].IsKind(SyntaxKind.SimpleLambdaExpression))
                {
                    var currentLambda        = (SimpleLambdaExpressionSyntax)whereArguments[i];
                    var currentParameter     = currentLambda.Parameter;
                    var currentParameterName = currentParameter.Identifier.Text;

                    if (currentParameterName != parameterName)
                    {
                        var parameterSymbol = semanticModel.GetDeclaredSymbol(currentParameter);

                        var substituteRewriter = new SubstituteRewriter(
                            currentParameterName,
                            parameterSymbol,
                            semanticModel,
                            firstParameterIdentifier);

                        var newBody = (CSharpSyntaxNode)currentLambda.Body.Accept(substituteRewriter);

                        andOperand = MakeExpressionFromLambdaBody(newBody);
                    }
                    else
                    {
                        andOperand = MakeExpressionFromLambdaBody(currentLambda.Body);
                    }
                }
                else
                {
                    andOperand = ExtendedSyntaxFactory.MakeInvocation(
                        whereArguments[i],
                        firstParameterIdentifier);
                }

                filterExpression = SyntaxFactory.BinaryExpression(
                    SyntaxKind.LogicalAndExpression,
                    filterExpression,
                    andOperand);
            }

            var newLambda = SyntaxFactory.SimpleLambdaExpression(
                firstParameter,
                filterExpression);

            var newInvocation = ExtendedSyntaxFactory.MakeInvocation(
                innerMostWhereAccess,
                newLambda);

            return(newInvocation);
        }