protected override void InitializeWorker(AnalysisContext context) { context.RegisterCompilationStartAction(compilationContext => { // We're going to be checking every invocation in the compilation. Cache information // we compute in this object so we don't have to continually recompute it. if (!InfoCache.TryCreate(compilationContext.Compilation, out var infoCache)) { return; } compilationContext.RegisterOperationAction( c => AnalyzeInvocation(c, infoCache), OperationKind.Invocation); }); }
protected override void InitializeWorker(AnalysisContext context) { context.RegisterCompilationStartAction(context => { var compilation = (CSharpCompilation)context.Compilation; // Only supported on C# 8 and above. if (compilation.LanguageVersion < LanguageVersion.CSharp8) { return; } // We're going to be checking every property-reference and invocation in the // compilation. Cache information we compute in this object so we don't have to // continually recompute it. if (!InfoCache.TryCreate(compilation, out var infoCache)) { return; } // Register to hear property references, so we can hear about calls to indexers // like: s[s.Length - n] context.RegisterOperationAction( c => AnalyzePropertyReference(c, infoCache), OperationKind.PropertyReference); // Register to hear about methods for: s.Get(s.Length - n) context.RegisterOperationAction( c => AnalyzeInvocation(c, infoCache), OperationKind.Invocation); var arrayType = compilation.GetSpecialType(SpecialType.System_Array); var arrayLengthProperty = TryGetNoArgInt32Property(arrayType, nameof(Array.Length)); if (arrayLengthProperty != null) { // Array indexing is represented with a different operation kind. Register // specifically for that. context.RegisterOperationAction( c => AnalyzeArrayElementReference(c, infoCache, arrayLengthProperty), OperationKind.ArrayElementReference); } }); }
private static SyntaxNode UpdateInvocation( SemanticModel semanticModel, SyntaxNode currentRoot, InvocationExpressionSyntax currentInvocation, SyntaxGenerator generator, CancellationToken cancellationToken) { if (semanticModel.GetOperation(currentInvocation, cancellationToken) is IInvocationOperation invocation && InfoCache.TryCreate(semanticModel.Compilation, out var infoCache) && AnalyzeInvocation(invocation, infoCache) is { } result) { var updatedNode = FixOne(result, generator); if (updatedNode != null) { return(currentRoot.ReplaceNode(result.Invocation, updatedNode)); } } return(currentRoot); }