예제 #1
0
        public SkippedHostAnalyzersInfo GetSkippedAnalyzersInfo(
            Project project,
            DiagnosticAnalyzerInfoCache infoCache
            )
        {
            var box = _skippedHostAnalyzers.GetOrCreateValue(project.AnalyzerReferences);

            if (box.Value != null && box.Value.TryGetValue(project.Language, out var info))
            {
                return(info);
            }
            lock (box)
            {
                box.Value ??= ImmutableDictionary <string, SkippedHostAnalyzersInfo> .Empty;

                if (!box.Value.TryGetValue(project.Language, out info))
                {
                    info = SkippedHostAnalyzersInfo.Create(
                        this,
                        project.AnalyzerReferences,
                        project.Language,
                        infoCache
                        );
                    box.Value = box.Value.Add(project.Language, info);
                }

                return(info);
            }
        }
예제 #2
0
        public static ImmutableDictionary <DiagnosticAnalyzer, DiagnosticAnalysisResultBuilder> ToResultBuilderMap(
            this AnalysisResult analysisResult,
            Project project, VersionStamp version, Compilation compilation, IEnumerable <DiagnosticAnalyzer> analyzers,
            SkippedHostAnalyzersInfo skippedAnalyzersInfo,
            CancellationToken cancellationToken)
        {
            var builder = ImmutableDictionary.CreateBuilder <DiagnosticAnalyzer, DiagnosticAnalysisResultBuilder>();

            ImmutableArray <Diagnostic> diagnostics;

            foreach (var analyzer in analyzers)
            {
                cancellationToken.ThrowIfCancellationRequested();

                if (skippedAnalyzersInfo.SkippedAnalyzers.Contains(analyzer))
                {
                    continue;
                }

                var result = new DiagnosticAnalysisResultBuilder(project, version);
                var diagnosticIdsToFilter = skippedAnalyzersInfo.FilteredDiagnosticIdsForAnalyzers.GetValueOrDefault(
                    analyzer,
                    ImmutableArray <string> .Empty);

                foreach (var(tree, diagnosticsByAnalyzerMap) in analysisResult.SyntaxDiagnostics)
                {
                    if (diagnosticsByAnalyzerMap.TryGetValue(analyzer, out diagnostics))
                    {
                        diagnostics = diagnostics.Filter(diagnosticIdsToFilter);
                        Debug.Assert(diagnostics.Length == CompilationWithAnalyzers.GetEffectiveDiagnostics(diagnostics, compilation).Count());
                        result.AddSyntaxDiagnostics(tree, diagnostics);
                    }
                }

                foreach (var(tree, diagnosticsByAnalyzerMap) in analysisResult.SemanticDiagnostics)
                {
                    if (diagnosticsByAnalyzerMap.TryGetValue(analyzer, out diagnostics))
                    {
                        diagnostics = diagnostics.Filter(diagnosticIdsToFilter);
                        Debug.Assert(diagnostics.Length == CompilationWithAnalyzers.GetEffectiveDiagnostics(diagnostics, compilation).Count());
                        result.AddSemanticDiagnostics(tree, diagnostics);
                    }
                }

                if (analysisResult.CompilationDiagnostics.TryGetValue(analyzer, out diagnostics))
                {
                    diagnostics = diagnostics.Filter(diagnosticIdsToFilter);
                    Debug.Assert(diagnostics.Length == CompilationWithAnalyzers.GetEffectiveDiagnostics(diagnostics, compilation).Count());
                    result.AddCompilationDiagnostics(diagnostics);
                }

                builder.Add(analyzer, result);
            }

            return(builder.ToImmutable());
        }
예제 #3
0
        public ISkippedAnalyzersInfo GetOrCreateSkippedAnalyzersInfo(Project project, IEnumerable <AnalyzerReference> hostAnalyzers)
        {
            if (_skippedAnalyzersInfo.TryGetValue(project.AnalyzerReferences, out var skippedAnalyzersInfo))
            {
                return(skippedAnalyzersInfo);
            }

            var createValueCallback = new ConditionalWeakTable <IReadOnlyList <AnalyzerReference>, ISkippedAnalyzersInfo> .CreateValueCallback(
                _ => SkippedHostAnalyzersInfo.Create(project, hostAnalyzers, this));

            return(_skippedAnalyzersInfo.GetValue(project.AnalyzerReferences, createValueCallback));
        }
예제 #4
0
        public static async Task <ImmutableDictionary <DiagnosticAnalyzer, DiagnosticAnalysisResultBuilder> > ToResultBuilderMapAsync(
            this AnalysisResult analysisResult,
            ImmutableArray <Diagnostic> additionalPragmaSuppressionDiagnostics,
            DocumentAnalysisScope?documentAnalysisScope,
            Project project,
            VersionStamp version,
            Compilation compilation,
            IEnumerable <DiagnosticAnalyzer> analyzers,
            SkippedHostAnalyzersInfo skippedAnalyzersInfo,
            bool includeSuppressedDiagnostics,
            CancellationToken cancellationToken)
        {
            SyntaxTree?    treeToAnalyze           = null;
            AdditionalText?additionalFileToAnalyze = null;

            if (documentAnalysisScope != null)
            {
                if (documentAnalysisScope.TextDocument is Document document)
                {
                    treeToAnalyze = await document.GetSyntaxTreeAsync(cancellationToken).ConfigureAwait(false);
                }
                else
                {
                    additionalFileToAnalyze = documentAnalysisScope.AdditionalFile;
                }
            }

            var builder = ImmutableDictionary.CreateBuilder <DiagnosticAnalyzer, DiagnosticAnalysisResultBuilder>();

            foreach (var analyzer in analyzers)
            {
                cancellationToken.ThrowIfCancellationRequested();

                if (skippedAnalyzersInfo.SkippedAnalyzers.Contains(analyzer))
                {
                    continue;
                }

                var result = new DiagnosticAnalysisResultBuilder(project, version);
                var diagnosticIdsToFilter = skippedAnalyzersInfo.FilteredDiagnosticIdsForAnalyzers.GetValueOrDefault(
                    analyzer,
                    ImmutableArray <string> .Empty);

                if (documentAnalysisScope != null)
                {
                    RoslynDebug.Assert(treeToAnalyze != null || additionalFileToAnalyze != null);
                    var spanToAnalyze = documentAnalysisScope.Span;
                    var kind          = documentAnalysisScope.Kind;

                    ImmutableDictionary <DiagnosticAnalyzer, ImmutableArray <Diagnostic> >?diagnosticsByAnalyzerMap;
                    switch (kind)
                    {
                    case AnalysisKind.Syntax:
                        if (treeToAnalyze != null)
                        {
                            if (analysisResult.SyntaxDiagnostics.TryGetValue(treeToAnalyze, out diagnosticsByAnalyzerMap))
                            {
                                AddAnalyzerDiagnosticsToResult(analyzer, diagnosticsByAnalyzerMap, ref result, compilation,
                                                               treeToAnalyze, additionalDocumentId: null, spanToAnalyze, AnalysisKind.Syntax, diagnosticIdsToFilter, includeSuppressedDiagnostics);
                            }
                        }
                        else if (analysisResult.AdditionalFileDiagnostics.TryGetValue(additionalFileToAnalyze !, out diagnosticsByAnalyzerMap))
                        {
                            AddAnalyzerDiagnosticsToResult(analyzer, diagnosticsByAnalyzerMap, ref result, compilation,
                                                           tree: null, documentAnalysisScope.TextDocument.Id, spanToAnalyze, AnalysisKind.Syntax, diagnosticIdsToFilter, includeSuppressedDiagnostics);
                        }

                        break;

                    case AnalysisKind.Semantic:
                        if (analysisResult.SemanticDiagnostics.TryGetValue(treeToAnalyze !, out diagnosticsByAnalyzerMap))
                        {
                            AddAnalyzerDiagnosticsToResult(analyzer, diagnosticsByAnalyzerMap, ref result, compilation,
                                                           treeToAnalyze, additionalDocumentId: null, spanToAnalyze, AnalysisKind.Semantic, diagnosticIdsToFilter, includeSuppressedDiagnostics);
                        }

                        break;

                    default:
                        throw ExceptionUtilities.UnexpectedValue(kind);
                    }
                }
                else
                {
                    foreach (var(tree, diagnosticsByAnalyzerMap) in analysisResult.SyntaxDiagnostics)
                    {
                        AddAnalyzerDiagnosticsToResult(analyzer, diagnosticsByAnalyzerMap, ref result, compilation,
                                                       tree, additionalDocumentId: null, span: null, AnalysisKind.Syntax, diagnosticIdsToFilter, includeSuppressedDiagnostics);
                    }

                    foreach (var(tree, diagnosticsByAnalyzerMap) in analysisResult.SemanticDiagnostics)
                    {
                        AddAnalyzerDiagnosticsToResult(analyzer, diagnosticsByAnalyzerMap, ref result, compilation,
                                                       tree, additionalDocumentId: null, span: null, AnalysisKind.Semantic, diagnosticIdsToFilter, includeSuppressedDiagnostics);
                    }

                    foreach (var(file, diagnosticsByAnalyzerMap) in analysisResult.AdditionalFileDiagnostics)
                    {
                        var additionalDocumentId = project.GetDocumentForFile(file);
                        var kind = additionalDocumentId != null ? AnalysisKind.Syntax : AnalysisKind.NonLocal;
                        AddAnalyzerDiagnosticsToResult(analyzer, diagnosticsByAnalyzerMap, ref result, compilation,
                                                       tree: null, additionalDocumentId, span: null, kind, diagnosticIdsToFilter, includeSuppressedDiagnostics);
                    }

                    AddAnalyzerDiagnosticsToResult(analyzer, analysisResult.CompilationDiagnostics, ref result, compilation,
                                                   tree: null, additionalDocumentId: null, span: null, AnalysisKind.NonLocal, diagnosticIdsToFilter, includeSuppressedDiagnostics);
                }

                // Special handling for pragma suppression diagnostics.
                if (!additionalPragmaSuppressionDiagnostics.IsEmpty &&
                    analyzer is IPragmaSuppressionsAnalyzer)
                {
                    if (documentAnalysisScope != null)
                    {
                        if (treeToAnalyze != null)
                        {
                            var diagnostics = additionalPragmaSuppressionDiagnostics.WhereAsArray(d => d.Location.SourceTree == treeToAnalyze);
                            AddDiagnosticsToResult(diagnostics, ref result, compilation, treeToAnalyze, additionalDocumentId: null,
                                                   documentAnalysisScope !.Span, AnalysisKind.Semantic, diagnosticIdsToFilter, includeSuppressedDiagnostics);
                        }
                    }
                    else
                    {
                        foreach (var group in additionalPragmaSuppressionDiagnostics.GroupBy(d => d.Location.SourceTree !))
                        {
                            AddDiagnosticsToResult(group.AsImmutable(), ref result, compilation, group.Key, additionalDocumentId: null,
                                                   span: null, AnalysisKind.Semantic, diagnosticIdsToFilter, includeSuppressedDiagnostics);
                        }
                    }

                    additionalPragmaSuppressionDiagnostics = ImmutableArray <Diagnostic> .Empty;
                }

                builder.Add(analyzer, result);
            }

            return(builder.ToImmutable());
예제 #5
0
        public static ImmutableDictionary <DiagnosticAnalyzer, DiagnosticAnalysisResultBuilder> ToResultBuilderMap(
            this AnalysisResult analysisResult,
            ImmutableArray <Diagnostic> additionalPragmaSuppressionDiagnostics,
            Project project, VersionStamp version, Compilation compilation, IEnumerable <DiagnosticAnalyzer> analyzers,
            SkippedHostAnalyzersInfo skippedAnalyzersInfo,
            CancellationToken cancellationToken)
        {
            var builder = ImmutableDictionary.CreateBuilder <DiagnosticAnalyzer, DiagnosticAnalysisResultBuilder>();

            ImmutableArray <Diagnostic> diagnostics;

            foreach (var analyzer in analyzers)
            {
                cancellationToken.ThrowIfCancellationRequested();

                if (skippedAnalyzersInfo.SkippedAnalyzers.Contains(analyzer))
                {
                    continue;
                }

                var result = new DiagnosticAnalysisResultBuilder(project, version);
                var diagnosticIdsToFilter = skippedAnalyzersInfo.FilteredDiagnosticIdsForAnalyzers.GetValueOrDefault(
                    analyzer,
                    ImmutableArray <string> .Empty);

                foreach (var(tree, diagnosticsByAnalyzerMap) in analysisResult.SyntaxDiagnostics)
                {
                    if (diagnosticsByAnalyzerMap.TryGetValue(analyzer, out diagnostics))
                    {
                        diagnostics = diagnostics.Filter(diagnosticIdsToFilter);
                        Debug.Assert(diagnostics.Length == CompilationWithAnalyzers.GetEffectiveDiagnostics(diagnostics, compilation).Count());
                        result.AddSyntaxDiagnostics(tree, diagnostics);
                    }
                }

                foreach (var(tree, diagnosticsByAnalyzerMap) in analysisResult.SemanticDiagnostics)
                {
                    if (diagnosticsByAnalyzerMap.TryGetValue(analyzer, out diagnostics))
                    {
                        diagnostics = diagnostics.Filter(diagnosticIdsToFilter);
                        Debug.Assert(diagnostics.Length == CompilationWithAnalyzers.GetEffectiveDiagnostics(diagnostics, compilation).Count());
                        result.AddSemanticDiagnostics(tree, diagnostics);
                    }
                }

                foreach (var(file, diagnosticsByAnalyzerMap) in analysisResult.AdditionalFileDiagnostics)
                {
                    if (diagnosticsByAnalyzerMap.TryGetValue(analyzer, out diagnostics))
                    {
                        diagnostics = diagnostics.Filter(diagnosticIdsToFilter);
                        Debug.Assert(diagnostics.Length == CompilationWithAnalyzers.GetEffectiveDiagnostics(diagnostics, compilation).Count());

                        if (project.GetDocumentForFile(file) is DocumentId documentId)
                        {
                            result.AddExternalSyntaxDiagnostics(documentId, diagnostics);
                        }
                        else
                        {
                            result.AddCompilationDiagnostics(diagnostics);
                        }
                    }
                }

                if (analysisResult.CompilationDiagnostics.TryGetValue(analyzer, out diagnostics))
                {
                    diagnostics = diagnostics.Filter(diagnosticIdsToFilter);
                    Debug.Assert(diagnostics.Length == CompilationWithAnalyzers.GetEffectiveDiagnostics(diagnostics, compilation).Count());
                    result.AddCompilationDiagnostics(diagnostics);
                }

                // Special handling for pragma suppression diagnostics.
                if (analyzer is IPragmaSuppressionsAnalyzer)
                {
                    foreach (var group in additionalPragmaSuppressionDiagnostics.GroupBy(d => d.Location.SourceTree !))
                    {
                        diagnostics = group.AsImmutable().Filter(diagnosticIdsToFilter);
                        Debug.Assert(diagnostics.Length == CompilationWithAnalyzers.GetEffectiveDiagnostics(diagnostics, compilation).Count());
                        result.AddSemanticDiagnostics(group.Key, diagnostics);
                    }

                    additionalPragmaSuppressionDiagnostics = ImmutableArray <Diagnostic> .Empty;
                }

                builder.Add(analyzer, result);
            }

            return(builder.ToImmutable());
        }