예제 #1
0
        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);
 }