private async Task <ImmutableDictionary <DiagnosticAnalyzer, DiagnosticAnalysisResult> > MergeProjectDiagnosticAnalyzerDiagnosticsAsync( Project project, IEnumerable <StateSet> stateSets, Compilation compilationOpt, ImmutableDictionary <DiagnosticAnalyzer, DiagnosticAnalysisResult> result, CancellationToken cancellationToken) { try { // check whether there is IDE specific project diagnostic analyzer var ideAnalyzers = stateSets.Select(s => s.Analyzer).Where(a => a is ProjectDiagnosticAnalyzer || a is DocumentDiagnosticAnalyzer).ToImmutableArrayOrEmpty(); if (ideAnalyzers.Length <= 0) { return(result); } // create result map var version = await GetDiagnosticVersionAsync(project, cancellationToken).ConfigureAwait(false); var builder = new DiagnosticAnalysisResultBuilder(project, version); foreach (var analyzer in ideAnalyzers) { var documentAnalyzer = analyzer as DocumentDiagnosticAnalyzer; if (documentAnalyzer != null) { foreach (var document in project.Documents) { if (document.SupportsSyntaxTree) { var tree = await document.GetSyntaxTreeAsync(cancellationToken).ConfigureAwait(false); builder.AddSyntaxDiagnostics(tree, await ComputeDocumentDiagnosticAnalyzerDiagnosticsAsync(document, documentAnalyzer, AnalysisKind.Syntax, compilationOpt, cancellationToken).ConfigureAwait(false)); builder.AddSemanticDiagnostics(tree, await ComputeDocumentDiagnosticAnalyzerDiagnosticsAsync(document, documentAnalyzer, AnalysisKind.Semantic, compilationOpt, cancellationToken).ConfigureAwait(false)); } else { builder.AddExternalSyntaxDiagnostics(document.Id, await ComputeDocumentDiagnosticAnalyzerDiagnosticsAsync(document, documentAnalyzer, AnalysisKind.Syntax, compilationOpt, cancellationToken).ConfigureAwait(false)); builder.AddExternalSemanticDiagnostics(document.Id, await ComputeDocumentDiagnosticAnalyzerDiagnosticsAsync(document, documentAnalyzer, AnalysisKind.Semantic, compilationOpt, cancellationToken).ConfigureAwait(false)); } } } var projectAnalyzer = analyzer as ProjectDiagnosticAnalyzer; if (projectAnalyzer != null) { builder.AddCompilationDiagnostics(await ComputeProjectDiagnosticAnalyzerDiagnosticsAsync(project, projectAnalyzer, compilationOpt, cancellationToken).ConfigureAwait(false)); } // merge the result to existing one. // there can be existing one from compiler driver with empty set. overwrite it with // ide one. result = result.SetItem(analyzer, new DiagnosticAnalysisResult(builder)); } return(result); } catch (Exception e) when(FatalError.ReportUnlessCanceled(e)) { throw ExceptionUtilities.Unreachable; } }
public static ImmutableDictionary <DiagnosticAnalyzer, DiagnosticAnalysisResultBuilder> ToResultBuilderMap( this AnalysisResult analysisResult, Project project, VersionStamp version, Compilation compilation, IEnumerable <DiagnosticAnalyzer> analyzers, ISkippedAnalyzersInfo 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()); }
private async Task <ImmutableDictionary <DiagnosticAnalyzer, DiagnosticAnalysisResult> > MergeProjectDiagnosticAnalyzerDiagnosticsAsync( Project project, ImmutableArray <DiagnosticAnalyzer> ideAnalyzers, Compilation?compilation, ImmutableDictionary <DiagnosticAnalyzer, DiagnosticAnalysisResult> result, CancellationToken cancellationToken) { try { // create result map var version = await GetDiagnosticVersionAsync(project, cancellationToken).ConfigureAwait(false); foreach (var analyzer in ideAnalyzers) { var builder = new DiagnosticAnalysisResultBuilder(project, version); if (analyzer is DocumentDiagnosticAnalyzer documentAnalyzer) { foreach (var document in project.Documents) { var tree = await document.GetSyntaxTreeAsync(cancellationToken).ConfigureAwait(false); if (tree != null) { builder.AddSyntaxDiagnostics(tree, await ComputeDocumentDiagnosticAnalyzerDiagnosticsAsync(document, documentAnalyzer, AnalysisKind.Syntax, compilation, cancellationToken).ConfigureAwait(false)); builder.AddSemanticDiagnostics(tree, await ComputeDocumentDiagnosticAnalyzerDiagnosticsAsync(document, documentAnalyzer, AnalysisKind.Semantic, compilation, cancellationToken).ConfigureAwait(false)); } else { builder.AddExternalSyntaxDiagnostics(document.Id, await ComputeDocumentDiagnosticAnalyzerDiagnosticsAsync(document, documentAnalyzer, AnalysisKind.Syntax, compilation, cancellationToken).ConfigureAwait(false)); builder.AddExternalSemanticDiagnostics(document.Id, await ComputeDocumentDiagnosticAnalyzerDiagnosticsAsync(document, documentAnalyzer, AnalysisKind.Semantic, compilation, cancellationToken).ConfigureAwait(false)); } } } if (analyzer is ProjectDiagnosticAnalyzer projectAnalyzer) { builder.AddCompilationDiagnostics(await ComputeProjectDiagnosticAnalyzerDiagnosticsAsync(project, projectAnalyzer, compilation, cancellationToken).ConfigureAwait(false)); } // merge the result to existing one. // there can be existing one from compiler driver with empty set. overwrite it with // ide one. result = result.SetItem(analyzer, DiagnosticAnalysisResult.CreateFromBuilder(builder)); } return(result); } catch (Exception e) when(FatalError.ReportUnlessCanceled(e)) { throw ExceptionUtilities.Unreachable; } }
public static ImmutableDictionary <DiagnosticAnalyzer, DiagnosticAnalysisResultBuilder> ToResultBuilderMap( this AnalysisResult analysisResult, Project project, VersionStamp version, Compilation compilation, IEnumerable <DiagnosticAnalyzer> analyzers, CancellationToken cancellationToken) { var builder = ImmutableDictionary.CreateBuilder <DiagnosticAnalyzer, DiagnosticAnalysisResultBuilder>(); ImmutableArray <Diagnostic> diagnostics; ImmutableDictionary <DiagnosticAnalyzer, ImmutableArray <Diagnostic> > diagnosticsByAnalyzerMap; foreach (var analyzer in analyzers) { cancellationToken.ThrowIfCancellationRequested(); var result = new DiagnosticAnalysisResultBuilder(project, version); foreach (var tree in analysisResult.SyntaxDiagnostics.Keys) { if (analysisResult.SyntaxDiagnostics.TryGetValue(tree, out diagnosticsByAnalyzerMap) && diagnosticsByAnalyzerMap.TryGetValue(analyzer, out diagnostics)) { Contract.Requires(diagnostics.Length == CompilationWithAnalyzers.GetEffectiveDiagnostics(diagnostics, compilation).Count()); result.AddSyntaxDiagnostics(tree, diagnostics); } } foreach (var tree in analysisResult.SemanticDiagnostics.Keys) { if (analysisResult.SemanticDiagnostics.TryGetValue(tree, out diagnosticsByAnalyzerMap) && diagnosticsByAnalyzerMap.TryGetValue(analyzer, out diagnostics)) { Contract.Requires(diagnostics.Length == CompilationWithAnalyzers.GetEffectiveDiagnostics(diagnostics, compilation).Count()); result.AddSemanticDiagnostics(tree, diagnostics); } } if (analysisResult.CompilationDiagnostics.TryGetValue(analyzer, out diagnostics)) { Contract.Requires(diagnostics.Length == CompilationWithAnalyzers.GetEffectiveDiagnostics(diagnostics, compilation).Count()); result.AddCompilationDiagnostics(diagnostics); } builder.Add(analyzer, result); } return(builder.ToImmutable()); }
static void AddDiagnosticsToResult( ImmutableArray <Diagnostic> diagnostics, ref DiagnosticAnalysisResultBuilder result, Compilation compilation, SyntaxTree?tree, DocumentId?additionalDocumentId, TextSpan?span, AnalysisKind kind, ImmutableArray <string> diagnosticIdsToFilter, bool includeSuppressedDiagnostics) { if (diagnostics.IsEmpty) { return; } diagnostics = diagnostics.Filter(diagnosticIdsToFilter, includeSuppressedDiagnostics, span); Debug.Assert(diagnostics.Length == CompilationWithAnalyzers.GetEffectiveDiagnostics(diagnostics, compilation).Count()); switch (kind) { case AnalysisKind.Syntax: if (tree != null) { Debug.Assert(diagnostics.All(d => d.Location.SourceTree == tree)); result.AddSyntaxDiagnostics(tree !, diagnostics); } else { RoslynDebug.Assert(additionalDocumentId != null); result.AddExternalSyntaxDiagnostics(additionalDocumentId, diagnostics); } break; case AnalysisKind.Semantic: Debug.Assert(diagnostics.All(d => d.Location.SourceTree == tree)); result.AddSemanticDiagnostics(tree !, diagnostics); break; default: result.AddCompilationDiagnostics(diagnostics); break; } }
static void AddAnalyzerDiagnosticsToResult( DiagnosticAnalyzer analyzer, ImmutableDictionary <DiagnosticAnalyzer, ImmutableArray <Diagnostic> > diagnosticsByAnalyzer, ref DiagnosticAnalysisResultBuilder result, Compilation compilation, SyntaxTree?tree, DocumentId?additionalDocumentId, TextSpan?span, AnalysisKind kind, ImmutableArray <string> diagnosticIdsToFilter, bool includeSuppressedDiagnostics) { if (diagnosticsByAnalyzer.TryGetValue(analyzer, out var diagnostics)) { AddDiagnosticsToResult(diagnostics, ref result, compilation, tree, additionalDocumentId, span, kind, diagnosticIdsToFilter, includeSuppressedDiagnostics); } }
private static async Task <ImmutableDictionary <DiagnosticAnalyzer, DiagnosticAnalysisResult> > MergeProjectDiagnosticAnalyzerDiagnosticsAsync( Project project, ImmutableArray <DiagnosticAnalyzer> ideAnalyzers, Compilation?compilation, ImmutableDictionary <DiagnosticAnalyzer, DiagnosticAnalysisResult> result, CancellationToken cancellationToken) { try { var version = await GetDiagnosticVersionAsync(project, cancellationToken).ConfigureAwait(false); var(fileLoadAnalysisResult, failedDocuments) = await GetDocumentLoadFailuresAsync(project, version, cancellationToken).ConfigureAwait(false); result = result.SetItem(FileContentLoadAnalyzer.Instance, fileLoadAnalysisResult); foreach (var analyzer in ideAnalyzers) { var builder = new DiagnosticAnalysisResultBuilder(project, version); switch (analyzer) { case DocumentDiagnosticAnalyzer documentAnalyzer: foreach (var document in project.Documents) { // don't analyze documents whose content failed to load if (failedDocuments == null || !failedDocuments.Contains(document)) { var tree = await document.GetSyntaxTreeAsync(cancellationToken).ConfigureAwait(false); if (tree != null) { builder.AddSyntaxDiagnostics(tree, await AnalyzerHelper.ComputeDocumentDiagnosticAnalyzerDiagnosticsAsync(documentAnalyzer, document, AnalysisKind.Syntax, compilation, cancellationToken).ConfigureAwait(false)); builder.AddSemanticDiagnostics(tree, await AnalyzerHelper.ComputeDocumentDiagnosticAnalyzerDiagnosticsAsync(documentAnalyzer, document, AnalysisKind.Semantic, compilation, cancellationToken).ConfigureAwait(false)); } else { builder.AddExternalSyntaxDiagnostics(document.Id, await AnalyzerHelper.ComputeDocumentDiagnosticAnalyzerDiagnosticsAsync(documentAnalyzer, document, AnalysisKind.Syntax, compilation, cancellationToken).ConfigureAwait(false)); builder.AddExternalSemanticDiagnostics(document.Id, await AnalyzerHelper.ComputeDocumentDiagnosticAnalyzerDiagnosticsAsync(documentAnalyzer, document, AnalysisKind.Semantic, compilation, cancellationToken).ConfigureAwait(false)); } } } break; case ProjectDiagnosticAnalyzer projectAnalyzer: builder.AddCompilationDiagnostics(await AnalyzerHelper.ComputeProjectDiagnosticAnalyzerDiagnosticsAsync(projectAnalyzer, project, compilation, cancellationToken).ConfigureAwait(false)); break; } // merge the result to existing one. // there can be existing one from compiler driver with empty set. overwrite it with // ide one. result = result.SetItem(analyzer, DiagnosticAnalysisResult.CreateFromBuilder(builder)); } return(result); } catch (Exception e) when(FatalError.ReportUnlessCanceled(e)) { throw ExceptionUtilities.Unreachable; } }
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());
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()); }