Пример #1
0
        public static void Analyze(SyntaxNodeAnalysisContext context, MemberInvocationExpressionInfo invocationInfo)
        {
            SyntaxNode parent = invocationInfo.InvocationExpression.WalkUpParentheses().Parent;

            if (parent.Kind() != SyntaxKind.LogicalNotExpression)
            {
                return;
            }

            SingleParameterLambdaExpressionInfo lambdaInfo = SyntaxInfo.SingleParameterLambdaExpressionInfo(invocationInfo.Arguments.First().Expression.WalkDownParentheses());

            if (!lambdaInfo.Success)
            {
                return;
            }

            ExpressionSyntax expression = GetReturnExpression(lambdaInfo.Body)?.WalkDownParentheses();

            if (expression?.IsKind(SyntaxKind.LogicalNotExpression) != true)
            {
                return;
            }

            if (!context.SemanticModel.TryGetExtensionMethodInfo(invocationInfo.InvocationExpression, out MethodInfo methodInfo, ExtensionMethodKind.Reduced, context.CancellationToken))
            {
                return;
            }

            if (!methodInfo.IsLinqExtensionOfIEnumerableOfTWithPredicate())
            {
                return;
            }

            context.ReportDiagnostic(DiagnosticDescriptors.SimplifyLogicalNegation, parent);
        }
        private static ExpressionSyntax GetNewNode(PrefixUnaryExpressionSyntax logicalNot)
        {
            ExpressionSyntax operand    = logicalNot.Operand;
            ExpressionSyntax expression = operand.WalkDownParentheses();

            switch (expression.Kind())
            {
            case SyntaxKind.TrueLiteralExpression:
            case SyntaxKind.FalseLiteralExpression:
            {
                LiteralExpressionSyntax newNode = BooleanLiteralExpression(expression.Kind() == SyntaxKind.FalseLiteralExpression);

                newNode = newNode.WithTriviaFrom(expression);

                return(operand.ReplaceNode(expression, newNode));
            }

            case SyntaxKind.LogicalNotExpression:
            {
                return(((PrefixUnaryExpressionSyntax)expression).Operand);
            }

            case SyntaxKind.EqualsExpression:
            {
                var equalsExpression = (BinaryExpressionSyntax)expression;

                BinaryExpressionSyntax notEqualsExpression = NotEqualsExpression(
                    equalsExpression.Left,
                    SyntaxFactory.Token(SyntaxKind.ExclamationEqualsToken).WithTriviaFrom(equalsExpression.OperatorToken),
                    equalsExpression.Right);

                return(operand.ReplaceNode(equalsExpression, notEqualsExpression));
            }

            case SyntaxKind.InvocationExpression:
            {
                var invocationExpression = (InvocationExpressionSyntax)expression;

                var memberAccessExpression = (MemberAccessExpressionSyntax)invocationExpression.Expression;

                ExpressionSyntax lambdaExpression = invocationExpression.ArgumentList.Arguments.First().Expression.WalkDownParentheses();

                SingleParameterLambdaExpressionInfo lambdaInfo = SyntaxInfo.SingleParameterLambdaExpressionInfo(lambdaExpression);

                var logicalNot2 = (PrefixUnaryExpressionSyntax)SimplifyLogicalNegationAnalyzer.GetReturnExpression(lambdaInfo.Body).WalkDownParentheses();

                InvocationExpressionSyntax newNode = invocationExpression.ReplaceNode(logicalNot2, logicalNot2.Operand.WithTriviaFrom(logicalNot2));

                return(SyntaxRefactorings.ChangeInvokedMethodName(newNode, (memberAccessExpression.Name.Identifier.ValueText == "All") ? "Any" : "All"));
            }
            }

            return(null);
        }
Пример #3
0
        internal static void AnalyzeInvocationExpression(SyntaxNodeAnalysisContext context)
        {
            var invocationExpression = (InvocationExpressionSyntax)context.Node;

            if (!invocationExpression.ContainsDiagnostics &&
                !invocationExpression.SpanContainsDirectives())
            {
                MemberInvocationExpressionInfo invocationInfo = SyntaxInfo.MemberInvocationExpressionInfo(invocationExpression);
                if (invocationInfo.Success &&
                    invocationInfo.NameText == "Any")
                {
                    ArgumentSyntax argument1 = invocationInfo.Arguments.SingleOrDefault(shouldthrow: false);

                    if (argument1 != null)
                    {
                        MemberInvocationExpressionInfo invocationInfo2 = SyntaxInfo.MemberInvocationExpressionInfo(invocationInfo.Expression);
                        if (invocationInfo2.Success &&
                            invocationInfo2.NameText == "Where")
                        {
                            ArgumentSyntax argument2 = invocationInfo2.Arguments.SingleOrDefault(shouldthrow: false);

                            if (argument2 != null)
                            {
                                SemanticModel     semanticModel     = context.SemanticModel;
                                CancellationToken cancellationToken = context.CancellationToken;

                                if (semanticModel.TryGetExtensionMethodInfo(invocationExpression, out MethodInfo methodInfo, ExtensionMethodKind.None, cancellationToken) &&
                                    methodInfo.IsLinqExtensionOfIEnumerableOfTWithPredicate("Any") &&
                                    semanticModel.TryGetExtensionMethodInfo(invocationInfo2.InvocationExpression, out MethodInfo methodInfo2, ExtensionMethodKind.None, cancellationToken) &&
                                    methodInfo2.IsLinqWhere(allowImmutableArrayExtension: true))
                                {
                                    SingleParameterLambdaExpressionInfo lambda = SyntaxInfo.SingleParameterLambdaExpressionInfo(argument1.Expression);
                                    if (lambda.Success &&
                                        lambda.Body is ExpressionSyntax)
                                    {
                                        SingleParameterLambdaExpressionInfo lambda2 = SyntaxInfo.SingleParameterLambdaExpressionInfo(argument2.Expression);
                                        if (lambda2.Success &&
                                            lambda2.Body is ExpressionSyntax &&
                                            lambda.ParameterName.Equals(lambda2.ParameterName, StringComparison.Ordinal))
                                        {
                                            context.ReportDiagnostic(
                                                DiagnosticDescriptors.SimplifyLinqMethodChain,
                                                Location.Create(context.SyntaxTree(), TextSpan.FromBounds(invocationInfo2.Name.SpanStart, invocationExpression.Span.End)));
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
Пример #4
0
        public static Task <Document> RefactorAsync(
            Document document,
            InvocationExpressionSyntax invocationExpression,
            CancellationToken cancellationToken)
        {
            MemberInvocationExpressionInfo invocationInfo  = SyntaxInfo.MemberInvocationExpressionInfo(invocationExpression);
            MemberInvocationExpressionInfo invocationInfo2 = SyntaxInfo.MemberInvocationExpressionInfo(invocationInfo.Expression);

            SingleParameterLambdaExpressionInfo lambda  = SyntaxInfo.SingleParameterLambdaExpressionInfo((LambdaExpressionSyntax)invocationInfo.Arguments.First().Expression);
            SingleParameterLambdaExpressionInfo lambda2 = SyntaxInfo.SingleParameterLambdaExpressionInfo((LambdaExpressionSyntax)invocationInfo2.Arguments.First().Expression);

            BinaryExpressionSyntax logicalAnd = CSharpFactory.LogicalAndExpression(
                ((ExpressionSyntax)lambda2.Body).Parenthesize(),
                ((ExpressionSyntax)lambda.Body).Parenthesize());

            InvocationExpressionSyntax newNode = invocationInfo2.InvocationExpression
                                                 .ReplaceNode(invocationInfo2.Name, invocationInfo.Name.WithTriviaFrom(invocationInfo2.Name))
                                                 .WithArgumentList(invocationInfo2.ArgumentList.ReplaceNode((ExpressionSyntax)lambda2.Body, logicalAnd));

            return(document.ReplaceNodeAsync(invocationExpression, newNode, cancellationToken));
        }
Пример #5
0
        private static Task <Document> CombineEnumerableWhereAndAnyAsync(
            Document document,
            InvocationExpressionSyntax invocationExpression,
            CancellationToken cancellationToken)
        {
            SimpleMemberInvocationExpressionInfo invocationInfo  = SimpleMemberInvocationExpressionInfo(invocationExpression);
            SimpleMemberInvocationExpressionInfo invocationInfo2 = SimpleMemberInvocationExpressionInfo(invocationInfo.Expression);

            SingleParameterLambdaExpressionInfo lambda  = SingleParameterLambdaExpressionInfo((LambdaExpressionSyntax)invocationInfo.Arguments.First().Expression);
            SingleParameterLambdaExpressionInfo lambda2 = SingleParameterLambdaExpressionInfo((LambdaExpressionSyntax)invocationInfo2.Arguments.First().Expression);

            BinaryExpressionSyntax logicalAnd = LogicalAndExpression(
                ((ExpressionSyntax)lambda2.Body).Parenthesize(),
                ((ExpressionSyntax)lambda.Body).Parenthesize());

            InvocationExpressionSyntax newNode = invocationInfo2.InvocationExpression
                                                 .ReplaceNode(invocationInfo2.Name, invocationInfo.Name.WithTriviaFrom(invocationInfo2.Name))
                                                 .WithArgumentList(invocationInfo2.ArgumentList.ReplaceNode((ExpressionSyntax)lambda2.Body, logicalAnd));

            return(document.ReplaceNodeAsync(invocationExpression, newNode, cancellationToken));
        }
        public static void AnalyzeWhereAndAny(SyntaxNodeAnalysisContext context)
        {
            var invocationExpression = (InvocationExpressionSyntax)context.Node;

            if (invocationExpression.ContainsDiagnostics)
            {
                return;
            }

            if (invocationExpression.SpanContainsDirectives())
            {
                return;
            }

            SimpleMemberInvocationExpressionInfo invocationInfo = SyntaxInfo.SimpleMemberInvocationExpressionInfo(invocationExpression);

            if (!invocationInfo.Success)
            {
                return;
            }

            if (invocationInfo.NameText != "Any")
            {
                return;
            }

            ArgumentSyntax argument1 = invocationInfo.Arguments.SingleOrDefault(shouldThrow: false);

            if (argument1 == null)
            {
                return;
            }

            SimpleMemberInvocationExpressionInfo invocationInfo2 = SyntaxInfo.SimpleMemberInvocationExpressionInfo(invocationInfo.Expression);

            if (!invocationInfo2.Success)
            {
                return;
            }

            if (invocationInfo2.NameText != "Where")
            {
                return;
            }

            ArgumentSyntax argument2 = invocationInfo2.Arguments.SingleOrDefault(shouldThrow: false);

            if (argument2 == null)
            {
                return;
            }

            SemanticModel     semanticModel     = context.SemanticModel;
            CancellationToken cancellationToken = context.CancellationToken;

            IMethodSymbol methodSymbol = semanticModel.GetExtensionMethodInfo(invocationExpression, cancellationToken).Symbol;

            if (methodSymbol == null)
            {
                return;
            }

            if (!SymbolUtility.IsLinqExtensionOfIEnumerableOfTWithPredicate(methodSymbol, semanticModel, "Any"))
            {
                return;
            }

            IMethodSymbol methodSymbol2 = semanticModel.GetExtensionMethodInfo(invocationInfo2.InvocationExpression, cancellationToken).Symbol;

            if (methodSymbol2 == null)
            {
                return;
            }

            if (!SymbolUtility.IsLinqWhere(methodSymbol2, semanticModel, allowImmutableArrayExtension: true))
            {
                return;
            }

            SingleParameterLambdaExpressionInfo lambda = SyntaxInfo.SingleParameterLambdaExpressionInfo(argument1.Expression);

            if (!lambda.Success)
            {
                return;
            }

            if (!(lambda.Body is ExpressionSyntax))
            {
                return;
            }

            SingleParameterLambdaExpressionInfo lambda2 = SyntaxInfo.SingleParameterLambdaExpressionInfo(argument2.Expression);

            if (!lambda2.Success)
            {
                return;
            }

            if (!(lambda2.Body is ExpressionSyntax))
            {
                return;
            }

            if (!lambda.Parameter.Identifier.ValueText.Equals(lambda2.Parameter.Identifier.ValueText, StringComparison.Ordinal))
            {
                return;
            }

            context.ReportDiagnostic(
                DiagnosticDescriptors.SimplifyLinqMethodChain,
                Location.Create(invocationExpression.SyntaxTree, TextSpan.FromBounds(invocationInfo2.Name.SpanStart, invocationExpression.Span.End)));
        }
Пример #7
0
        private static ExpressionSyntax GetNewNode(PrefixUnaryExpressionSyntax logicalNot, Document document)
        {
            ExpressionSyntax operand    = logicalNot.Operand;
            ExpressionSyntax expression = operand.WalkDownParentheses();

            switch (expression.Kind())
            {
            case SyntaxKind.TrueLiteralExpression:
            case SyntaxKind.FalseLiteralExpression:
            {
                LiteralExpressionSyntax newNode = BooleanLiteralExpression(expression.Kind() == SyntaxKind.FalseLiteralExpression);

                newNode = newNode.WithTriviaFrom(expression);

                return(operand.ReplaceNode(expression, newNode));
            }

            case SyntaxKind.LogicalNotExpression:
            {
                return(((PrefixUnaryExpressionSyntax)expression).Operand);
            }

            case SyntaxKind.EqualsExpression:
            case SyntaxKind.NotEqualsExpression:
            case SyntaxKind.LessThanExpression:
            case SyntaxKind.LessThanOrEqualExpression:
            case SyntaxKind.GreaterThanExpression:
            case SyntaxKind.GreaterThanOrEqualExpression:
            {
                BinaryExpressionSyntax newExpression = SyntaxLogicalInverter.GetInstance(document).InvertBinaryExpression((BinaryExpressionSyntax)expression);

                return(operand.ReplaceNode(expression, newExpression));
            }

            case SyntaxKind.InvocationExpression:
            {
                var invocationExpression = (InvocationExpressionSyntax)expression;

                var memberAccessExpression = (MemberAccessExpressionSyntax)invocationExpression.Expression;

                ExpressionSyntax lambdaExpression = invocationExpression.ArgumentList.Arguments[0].Expression.WalkDownParentheses();

                SingleParameterLambdaExpressionInfo lambdaInfo = SyntaxInfo.SingleParameterLambdaExpressionInfo(lambdaExpression);

                var logicalNot2 = (PrefixUnaryExpressionSyntax)SimplifyLogicalNegationAnalyzer.GetReturnExpression(lambdaInfo.Body).WalkDownParentheses();

                InvocationExpressionSyntax newNode = invocationExpression.ReplaceNode(logicalNot2, logicalNot2.Operand.WithTriviaFrom(logicalNot2));

                return(SyntaxRefactorings.ChangeInvokedMethodName(newNode, (memberAccessExpression.Name.Identifier.ValueText == "All") ? "Any" : "All"));
            }

            case SyntaxKind.IsPatternExpression:
            {
                var isPatternExpression = (IsPatternExpressionSyntax)expression;

                var pattern = (ConstantPatternSyntax)isPatternExpression.Pattern;

                UnaryPatternSyntax newPattern = NotPattern(pattern.WithoutTrivia()).WithTriviaFrom(pattern);

                return(isPatternExpression.WithPattern(newPattern)
                       .PrependToLeadingTrivia(logicalNot.GetLeadingTrivia())
                       .AppendToTrailingTrivia(logicalNot.GetTrailingTrivia()));
            }
            }

            return(null);
        }
Пример #8
0
        public static void Analyze(
            SyntaxNodeAnalysisContext context,
            MemberInvocationExpressionInfo invocationInfo)
        {
            InvocationExpressionSyntax invocationExpression = invocationInfo.InvocationExpression;

            TextSpan span = TextSpan.FromBounds(invocationInfo.Name.Span.Start, invocationExpression.Span.End);

            if (invocationExpression.ContainsDirectives(span))
            {
                return;
            }

            SemanticModel     semanticModel     = context.SemanticModel;
            CancellationToken cancellationToken = context.CancellationToken;

            var methodSymbol = semanticModel.GetSymbol(invocationExpression, cancellationToken) as IMethodSymbol;

            if (methodSymbol == null)
            {
                return;
            }

            if (!ExtensionMethodInfo.TryCreate(methodSymbol, semanticModel, out ExtensionMethodInfo extensionMethodInfo))
            {
                return;
            }

            if (!extensionMethodInfo.MethodInfo.IsLinqSelect(allowImmutableArrayExtension: true))
            {
                return;
            }

            ITypeSymbol typeArgument = extensionMethodInfo.ReducedSymbolOrSymbol.TypeArguments[0];

            if (!typeArgument.IsReferenceType)
            {
                return;
            }

            if (typeArgument.SpecialType == SpecialType.System_Object)
            {
                return;
            }

            ExpressionSyntax expression = invocationExpression.ArgumentList?.Arguments.Last().Expression;

            SingleParameterLambdaExpressionInfo lambdaInfo = SyntaxInfo.SingleParameterLambdaExpressionInfo(expression);

            if (!lambdaInfo.Success)
            {
                return;
            }

            CastExpressionSyntax castExpression = GetCastExpression(lambdaInfo.Body);

            if (castExpression == null)
            {
                return;
            }

            if (!(castExpression.Expression is IdentifierNameSyntax identifierName))
            {
                return;
            }

            if (!string.Equals(lambdaInfo.Parameter.Identifier.ValueText, identifierName.Identifier.ValueText, StringComparison.Ordinal))
            {
                return;
            }

            var castSymbol = semanticModel.GetSymbol(castExpression, cancellationToken) as IMethodSymbol;

            if (castSymbol?.MethodKind == MethodKind.Conversion)
            {
                return;
            }

            context.ReportDiagnostic(
                DiagnosticDescriptors.CallCastInsteadOfSelect,
                Location.Create(invocationExpression.SyntaxTree, span));
        }