static bool TryGetDiagnostic(SyntaxNodeAnalysisContext nodeContext, out Diagnostic diagnostic) { diagnostic = default(Diagnostic); 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, followUp; TypeSyntax type; ParameterSyntax param; if (ReplaceWithOfTypeAnyAnalyzer.MatchSelect(anyInvoke, out target, out type, out param, out followUp)) { // if (member == "Where" && followUp == null) return; diagnostic = Diagnostic.Create( descriptor, anyInvoke.GetLocation() ); return(true); } return(false); }
static bool HasPredicateVersion(IMethodSymbol member) { if (!ReplaceWithOfTypeAnyAnalyzer.IsQueryExtensionClass(member.ContainingType)) { return(false); } return(member.Name == "LastOrDefault"); }
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, ReplaceWithOfTypeAnyAnalyzer.MakeOfTypeCall(node)); context.RegisterCodeFix(CodeActionFactory.Create(node.Span, diagnostic.Severity, "Replace with call to OfType<T>().LongCount()", document.WithSyntaxRoot(newRoot)), diagnostic); }