Exemplo n.º 1
0
        public static bool IsFixable(
            SimpleMemberInvocationExpressionInfo invocationInfo,
            SemanticModel semanticModel,
            CancellationToken cancellationToken)
        {
            if (invocationInfo.Expression?.IsMissing != false)
            {
                return(false);
            }

            IMethodSymbol methodSymbol = semanticModel.GetReducedExtensionMethodInfo(invocationInfo.InvocationExpression, cancellationToken).Symbol;

            if (methodSymbol == null)
            {
                return(false);
            }

            if (!SymbolUtility.IsLinqExtensionOfIEnumerableOfTWithoutParameters(methodSymbol, "First", semanticModel, allowImmutableArrayExtension: true))
            {
                return(false);
            }

            ITypeSymbol typeSymbol = semanticModel.GetTypeSymbol(invocationInfo.Expression, cancellationToken);

            return(SymbolUtility.HasAccessibleIndexer(typeSymbol, semanticModel, invocationInfo.InvocationExpression.SpanStart));
        }
        public static void AnalyzeWhere(SyntaxNodeAnalysisContext context, SimpleMemberInvocationExpressionInfo invocationInfo)
        {
            SimpleMemberInvocationExpressionInfo invocationInfo2 = SyntaxInfo.SimpleMemberInvocationExpressionInfo(invocationInfo.Expression);

            if (!invocationInfo2.Success)
            {
                return;
            }

            if (invocationInfo2.Arguments.Count != 1)
            {
                return;
            }

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

            InvocationExpressionSyntax invocation = invocationInfo.InvocationExpression;

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

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

            if (methodSymbol == null)
            {
                return;
            }

            if (!SymbolUtility.IsLinqExtensionOfIEnumerableOfTWithoutParameters(methodSymbol, invocationInfo.NameText, semanticModel))
            {
                return;
            }

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

            if (methodSymbol2 == null)
            {
                return;
            }

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

            TextSpan span = TextSpan.FromBounds(invocationInfo2.Name.SpanStart, invocation.Span.End);

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

            context.ReportDiagnostic(
                DiagnosticDescriptors.SimplifyLinqMethodChain,
                Location.Create(invocation.SyntaxTree, span));
        }
        public static void Analyze(SyntaxNodeAnalysisContext context, SimpleMemberInvocationExpressionInfo invocationInfo)
        {
            InvocationExpressionSyntax invocationExpression = invocationInfo.InvocationExpression;

            if (invocationExpression.IsParentKind(SyntaxKind.SimpleMemberAccessExpression))
            {
                return;
            }

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

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

            if (methodSymbol == null)
            {
                return;
            }

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

            string propertyName = CSharpUtility.GetCountOrLengthPropertyName(invocationInfo.Expression, semanticModel, cancellationToken);

            if (propertyName == null)
            {
                return;
            }

            context.ReportDiagnostic(
                DiagnosticDescriptors.UseCountOrLengthPropertyInsteadOfAnyMethod,
                Location.Create(context.Node.SyntaxTree, TextSpan.FromBounds(invocationInfo.Name.SpanStart, invocationExpression.Span.End)),
                ImmutableDictionary.CreateRange(new KeyValuePair <string, string>[] { new KeyValuePair <string, string>("PropertyName", propertyName) }),
                propertyName);
        }
        public static void Analyze(SyntaxNodeAnalysisContext context, SimpleMemberInvocationExpressionInfo invocationInfo)
        {
            InvocationExpressionSyntax invocationExpression = invocationInfo.InvocationExpression;

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

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

            if (methodSymbol == null)
            {
                return;
            }

            if (!SymbolUtility.IsLinqExtensionOfIEnumerableOfTWithoutParameters(methodSymbol, "Count", semanticModel))
            {
                return;
            }

            string propertyName = CSharpUtility.GetCountOrLengthPropertyName(invocationInfo.Expression, semanticModel, cancellationToken);

            if (propertyName != null)
            {
                context.ReportDiagnostic(
                    DiagnosticDescriptors.UseCountOrLengthPropertyInsteadOfCountMethod,
                    Location.Create(context.Node.SyntaxTree, TextSpan.FromBounds(invocationInfo.Name.SpanStart, invocationExpression.Span.End)),
                    ImmutableDictionary.CreateRange(new KeyValuePair <string, string>[] { new KeyValuePair <string, string>("PropertyName", propertyName) }),
                    propertyName);
            }
            else
            {
                SyntaxNode parent = invocationExpression.Parent;

                switch (parent.Kind())
                {
                case SyntaxKind.EqualsExpression:
                case SyntaxKind.NotEqualsExpression:
                {
                    var equalsExpression = (BinaryExpressionSyntax)parent;

                    if (equalsExpression.Left == invocationExpression)
                    {
                        if (equalsExpression.Right.IsNumericLiteralExpression("0"))
                        {
                            context.ReportDiagnostic(DiagnosticDescriptors.CallAnyInsteadOfCount, parent);
                        }
                    }
                    else if (equalsExpression.Left.IsNumericLiteralExpression("0"))
                    {
                        context.ReportDiagnostic(DiagnosticDescriptors.CallAnyInsteadOfCount, parent);
                    }

                    break;
                }

                case SyntaxKind.GreaterThanExpression:
                {
                    var equalsExpression = (BinaryExpressionSyntax)parent;

                    if (equalsExpression.Left == invocationExpression)
                    {
                        if (equalsExpression.Right.IsNumericLiteralExpression("0"))
                        {
                            context.ReportDiagnostic(DiagnosticDescriptors.CallAnyInsteadOfCount, parent);
                        }
                        else
                        {
                            context.ReportDiagnostic(DiagnosticDescriptors.CallSkipAndAnyInsteadOfCount, parent);
                        }
                    }
                    else if (equalsExpression.Left.IsNumericLiteralExpression("1"))
                    {
                        context.ReportDiagnostic(DiagnosticDescriptors.CallAnyInsteadOfCount, parent);
                    }
                    else
                    {
                        context.ReportDiagnostic(DiagnosticDescriptors.CallSkipAndAnyInsteadOfCount, parent);
                    }

                    break;
                }

                case SyntaxKind.GreaterThanOrEqualExpression:
                {
                    var equalsExpression = (BinaryExpressionSyntax)parent;

                    if (equalsExpression.Left == invocationExpression)
                    {
                        if (equalsExpression.Right.IsNumericLiteralExpression("1"))
                        {
                            context.ReportDiagnostic(DiagnosticDescriptors.CallAnyInsteadOfCount, parent);
                        }
                        else
                        {
                            context.ReportDiagnostic(DiagnosticDescriptors.CallSkipAndAnyInsteadOfCount, parent);
                        }
                    }
                    else if (equalsExpression.Left.IsNumericLiteralExpression("0"))
                    {
                        context.ReportDiagnostic(DiagnosticDescriptors.CallAnyInsteadOfCount, parent);
                    }
                    else
                    {
                        context.ReportDiagnostic(DiagnosticDescriptors.CallSkipAndAnyInsteadOfCount, parent);
                    }

                    break;
                }

                case SyntaxKind.LessThanExpression:
                {
                    var equalsExpression = (BinaryExpressionSyntax)parent;

                    if (equalsExpression.Left == invocationExpression)
                    {
                        if (equalsExpression.Right.IsNumericLiteralExpression("1"))
                        {
                            context.ReportDiagnostic(DiagnosticDescriptors.CallAnyInsteadOfCount, parent);
                        }
                        else
                        {
                            context.ReportDiagnostic(DiagnosticDescriptors.CallSkipAndAnyInsteadOfCount, parent);
                        }
                    }
                    else if (equalsExpression.Left.IsNumericLiteralExpression("0"))
                    {
                        context.ReportDiagnostic(DiagnosticDescriptors.CallAnyInsteadOfCount, parent);
                    }
                    else
                    {
                        context.ReportDiagnostic(DiagnosticDescriptors.CallSkipAndAnyInsteadOfCount, parent);
                    }

                    break;
                }

                case SyntaxKind.LessThanOrEqualExpression:
                {
                    var equalsExpression = (BinaryExpressionSyntax)parent;

                    if (equalsExpression.Left == invocationExpression)
                    {
                        if (equalsExpression.Right.IsNumericLiteralExpression("0"))
                        {
                            context.ReportDiagnostic(DiagnosticDescriptors.CallAnyInsteadOfCount, parent);
                        }
                        else
                        {
                            context.ReportDiagnostic(DiagnosticDescriptors.CallSkipAndAnyInsteadOfCount, parent);
                        }
                    }
                    else if (equalsExpression.Left.IsNumericLiteralExpression("1"))
                    {
                        context.ReportDiagnostic(DiagnosticDescriptors.CallAnyInsteadOfCount, parent);
                    }
                    else
                    {
                        context.ReportDiagnostic(DiagnosticDescriptors.CallSkipAndAnyInsteadOfCount, parent);
                    }

                    break;
                }
                }
            }
        }
        private static void AnalyzeInvocationExpression(SyntaxNodeAnalysisContext context)
        {
            var invocationExpression = (InvocationExpressionSyntax)context.Node;

            if (invocationExpression.ContainsDiagnostics)
            {
                return;
            }

            SimpleMemberInvocationExpressionInfo invocationInfo = SyntaxInfo.SimpleMemberInvocationExpressionInfo(invocationExpression);

            if (!invocationInfo.Success)
            {
                return;
            }

            if (invocationInfo.Arguments.Count != 0)
            {
                return;
            }

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

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

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

            if (methodSymbol == null)
            {
                return;
            }

            if (!SymbolUtility.IsLinqExtensionOfIEnumerableOfTWithoutParameters(methodSymbol, "Count"))
            {
                return;
            }

            SyntaxNode parent = invocationExpression.Parent;

            switch (parent.Kind())
            {
            case SyntaxKind.GreaterThanExpression:
            case SyntaxKind.LessThanOrEqualExpression:
            {
                var binaryExpression = (BinaryExpressionSyntax)parent;

                if (binaryExpression.Left == invocationExpression)
                {
                    if (!binaryExpression.Right.IsNumericLiteralExpression("0"))
                    {
                        ReportDiagnostic(parent);
                    }
                }
                else if (!binaryExpression.Left.IsNumericLiteralExpression("1"))
                {
                    ReportDiagnostic(parent);
                }

                break;
            }

            case SyntaxKind.GreaterThanOrEqualExpression:
            case SyntaxKind.LessThanExpression:
            {
                var binaryExpression = (BinaryExpressionSyntax)parent;

                if (binaryExpression.Left == invocationExpression)
                {
                    if (!binaryExpression.Right.IsNumericLiteralExpression("1"))
                    {
                        ReportDiagnostic(parent);
                    }
                }
                else if (!binaryExpression.Left.IsNumericLiteralExpression("0"))
                {
                    ReportDiagnostic(parent);
                }

                break;
            }
            }

            void ReportDiagnostic(SyntaxNode node)
            {
                context.ReportDiagnostic(DiagnosticDescriptors.CallSkipAndAnyInsteadOfCount, node);
            }
        }