static bool HasPredicateVersion(IMethodSymbol member)
 {
     if (!ReplaceWithSingleCallToAnyAnalyzer.IsQueryExtensionClass(member.ContainingType))
     {
         return(false);
     }
     return(member.Name == "Last");
 }
        static bool TryGetDiagnostic(SyntaxNodeAnalysisContext nodeContext, out Diagnostic diagnostic)
        {
            diagnostic = default(Diagnostic);
            if (nodeContext.IsFromGeneratedCode())
            {
                return(false);
            }
            var anyInvoke = nodeContext.Node as InvocationExpressionSyntax;
            var info      = nodeContext.SemanticModel.GetSymbolInfo(anyInvoke);

            IMethodSymbol anyResolve = info.Symbol as IMethodSymbol;

            if (anyResolve == null)
            {
                anyResolve = info.CandidateSymbols.OfType <IMethodSymbol>().FirstOrDefault(candidate => HasPredicateVersion(candidate));
            }

            if (anyResolve == null || !HasPredicateVersion(anyResolve))
            {
                return(false);
            }

            ExpressionSyntax           target;
            InvocationExpressionSyntax whereInvoke;

            if (!ReplaceWithSingleCallToAnyAnalyzer.MatchWhere(anyInvoke, out target, out whereInvoke))
            {
                return(false);
            }
            info = nodeContext.SemanticModel.GetSymbolInfo(whereInvoke);
            IMethodSymbol whereResolve = info.Symbol as IMethodSymbol;

            if (whereResolve == null)
            {
                whereResolve = info.CandidateSymbols.OfType <IMethodSymbol>().FirstOrDefault(candidate => candidate.Name == "Where" && ReplaceWithSingleCallToAnyAnalyzer.IsQueryExtensionClass(candidate.ContainingType));
            }

            if (whereResolve == null || whereResolve.Name != "Where" || !ReplaceWithSingleCallToAnyAnalyzer.IsQueryExtensionClass(whereResolve.ContainingType))
            {
                return(false);
            }
            if (whereResolve.Parameters.Length != 1)
            {
                return(false);
            }
            var predResolve = whereResolve.Parameters[0];

            if (predResolve.Type.GetTypeParameters().Length != 2)
            {
                return(false);
            }
            diagnostic = Diagnostic.Create(
                descriptor,
                anyInvoke.GetLocation()
                );
            return(true);
        }
예제 #3
0
        public async override Task RegisterCodeFixesAsync(CodeFixContext context)
        {
            var document          = context.Document;
            var cancellationToken = context.CancellationToken;
            var span        = context.Span;
            var diagnostics = context.Diagnostics;
            var root        = await document.GetSyntaxRootAsync(cancellationToken);

            var diagnostic = diagnostics.First();
            var node       = root.FindNode(context.Span, getInnermostNodeForTie: true) as InvocationExpressionSyntax;
            var newRoot    = root.ReplaceNode(node, ReplaceWithSingleCallToAnyAnalyzer.MakeSingleCall(node));

            context.RegisterCodeFix(CodeActionFactory.Create(node.Span, diagnostic.Severity, "Replace with single call to 'Count'", document.WithSyntaxRoot(newRoot)), diagnostic);
        }
        public async override Task RegisterCodeFixesAsync(CodeFixContext context)
        {
            var document          = context.Document;
            var cancellationToken = context.CancellationToken;
            var span        = context.Span;
            var diagnostics = context.Diagnostics;
            var root        = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false);

            var diagnostic = diagnostics.First();
            var node       = root.FindNode(context.Span, getInnermostNodeForTie: true) as InvocationExpressionSyntax;
            var newRoot    = root.ReplaceNode(node, ReplaceWithSingleCallToAnyAnalyzer.MakeSingleCall(node));
            var member     = ((MemberAccessExpressionSyntax)node.Expression).Name;

            context.RegisterCodeFix(CodeActionFactory.Create(node.Span, diagnostic.Severity, string.Format("Replace with single call to '{0}'", member.Identifier.ValueText), document.WithSyntaxRoot(newRoot)), diagnostic);
        }