private void StartAnalyzeCompilation([NotNull] CompilationStartAnalysisContext context) { Guard.NotNull(context, nameof(context)); AnalyzerSettings settings = SettingsProvider.LoadSettings(context.Options, context.CancellationToken); NullabilityAttributeSymbols nullSymbols = NullabilityAttributeProvider.GetCached() .GetSymbols(context.Compilation, context.CancellationToken); if (nullSymbols == null) { // Nullability attributes not found; keep silent. return; } IExternalAnnotationsResolver resolver = ExternalAnnotationsResolver.GetCached(); resolver.EnsureScanned(); var generatedCodeCache = new GeneratedCodeDocumentCache(); var typeCache = new FrameworkTypeCache(context.Compilation); var nullabilityContext = new AnalysisScope(resolver, generatedCodeCache, typeCache, settings, disableReportOnNullableValueTypesRule, appliesToItem); var factory = new SymbolAnalyzerFactory(nullabilityContext); ImmutableDictionary <string, string> properties = nullSymbols.GetMetadataNamesAsProperties(); context.RegisterSymbolAction(c => AnalyzeField(c, factory, properties), SymbolKind.Field); context.RegisterSymbolAction(c => AnalyzeProperty(c, factory, properties), SymbolKind.Property); context.RegisterSymbolAction(c => AnalyzeMethod(c, factory, properties), SymbolKind.Method); context.RegisterSyntaxNodeAction(c => AnalyzeParameter(SyntaxToSymbolContext(c), factory, properties), SyntaxKind.Parameter); }
private void RegisterFixForNotNull(CodeFixContext context, [NotNull] SyntaxNode syntaxNode, [NotNull] Diagnostic diagnostic, [NotNull] NullabilityAttributeSymbols nullSymbols) { INamedTypeSymbol notNullAttribute = appliesToItem ? nullSymbols.ItemNotNull : nullSymbols.NotNull; Func <CancellationToken, Task <Document> > fixForNotNull = cancellationToken => WithAttributeAsync(notNullAttribute, context.Document, syntaxNode, cancellationToken); string notNullText = "Decorate with " + GetDisplayNameFor(notNullAttribute); RegisterCodeFixFor(fixForNotNull, notNullText, context, diagnostic); }
private static async Task <NullabilityAttributeSymbols> GetNullabilityAttributesFromDiagnostic(CodeFixContext context, [NotNull] Diagnostic diagnostic) { NullabilityAttributeMetadataNames names = NullabilityAttributeMetadataNames.FromImmutableDictionary(diagnostic.Properties); Compilation compilation = await context.Document.Project.GetCompilationAsync(context.CancellationToken) .ConfigureAwait(false); var attributeProvider = new CachingNullabilityAttributeProvider(names); NullabilityAttributeSymbols nullSymbols = attributeProvider.GetSymbols(compilation, context.CancellationToken); if (nullSymbols == null) { throw new InvalidOperationException("Internal error - failed to resolve attributes."); } return(nullSymbols); }
public override sealed async Task RegisterCodeFixesAsync(CodeFixContext context) { foreach (Diagnostic diagnostic in context.Diagnostics) { NullabilityAttributeSymbols nullSymbols = await GetNullabilityAttributesFromDiagnostic(context, diagnostic); SyntaxNode syntaxRoot = await context.Document.GetSyntaxRootAsync(context.CancellationToken).ConfigureAwait(false); SyntaxNode targetSyntax = syntaxRoot.FindNode(context.Span); FieldDeclarationSyntax fieldSyntax = targetSyntax is VariableDeclaratorSyntax ? targetSyntax.GetAncestorOrThis <FieldDeclarationSyntax>() : null; if (targetSyntax is MethodDeclarationSyntax || targetSyntax is IndexerDeclarationSyntax || targetSyntax is PropertyDeclarationSyntax || targetSyntax is ParameterSyntax || fieldSyntax != null) { RegisterFixesForSyntaxNode(context, fieldSyntax ?? targetSyntax, diagnostic, nullSymbols); } } }
private void RegisterFixesForSyntaxNode(CodeFixContext context, [NotNull] SyntaxNode syntaxNode, [NotNull] Diagnostic diagnostic, [NotNull] NullabilityAttributeSymbols nullSymbols) { RegisterFixForNotNull(context, syntaxNode, diagnostic, nullSymbols); RegisterFixForCanBeNull(context, syntaxNode, diagnostic, nullSymbols); }