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

                    foreach (var analyzer in ideAnalyzers)
                    {
                        var builder = new DiagnosticAnalysisResultBuilder(project, version);

                        if (analyzer is DocumentDiagnosticAnalyzer documentAnalyzer)
                        {
                            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));
                                }
                            }
                        }

                        if (analyzer is ProjectDiagnosticAnalyzer projectAnalyzer)
                        {
                            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, DiagnosticAnalysisResult.CreateFromBuilder(builder));
                    }

                    return(result);
                }
                catch (Exception e) when(FatalError.ReportUnlessCanceled(e))
                {
                    throw ExceptionUtilities.Unreachable;
                }
            }
        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;
            }
        }
예제 #3
0
            private async Task <DiagnosticAnalysisResultMap <DiagnosticAnalyzer, DiagnosticAnalysisResult> > AnalyzeInProcAsync(
                CompilationWithAnalyzers compilation, Project project, RemoteHostClient?client, CancellationToken cancellationToken)
            {
                Debug.Assert(compilation.Analyzers.Length != 0);

                var version = await GetDiagnosticVersionAsync(project, cancellationToken).ConfigureAwait(false);

                // PERF: Run all analyzers at once using the new GetAnalysisResultAsync API.
                var analysisResult = await compilation.GetAnalysisResultAsync(cancellationToken).ConfigureAwait(false);

                // if remote host is there, report performance data
                var asyncToken = _asyncOperationListener.BeginAsyncOperation(nameof(AnalyzeInProcAsync));
                var _          = FireAndForgetReportAnalyzerPerformanceAsync(project, client, analysisResult, cancellationToken).CompletesAsyncOperation(asyncToken);

                // get compiler result builder map
                var builderMap = analysisResult.ToResultBuilderMap(project, version, compilation.Compilation, compilation.Analyzers, cancellationToken);

                return(DiagnosticAnalysisResultMap.Create(
                           builderMap.ToImmutableDictionary(kv => kv.Key, kv => DiagnosticAnalysisResult.CreateFromBuilder(kv.Value)),
                           analysisResult.AnalyzerTelemetryInfo));
            }
예제 #4
0
        private async Task <DiagnosticAnalysisResultMap <DiagnosticAnalyzer, DiagnosticAnalysisResult> > AnalyzeInProcAsync(
            DocumentAnalysisScope?documentAnalysisScope,
            Project project,
            CompilationWithAnalyzers compilationWithAnalyzers,
            RemoteHostClient?client,
            bool logPerformanceInfo,
            bool getTelemetryInfo,
            CancellationToken cancellationToken)
        {
            var version = await DiagnosticIncrementalAnalyzer.GetDiagnosticVersionAsync(project, cancellationToken).ConfigureAwait(false);

            var(analysisResult, additionalPragmaSuppressionDiagnostics) = await compilationWithAnalyzers.GetAnalysisResultAsync(
                documentAnalysisScope, project, AnalyzerInfoCache, cancellationToken).ConfigureAwait(false);

            if (logPerformanceInfo)
            {
                // if remote host is there, report performance data
                var asyncToken = _asyncOperationListener.BeginAsyncOperation(nameof(AnalyzeInProcAsync));
                var _          = FireAndForgetReportAnalyzerPerformanceAsync(documentAnalysisScope, project, client, analysisResult, cancellationToken).CompletesAsyncOperation(asyncToken);
            }

            var analyzers            = documentAnalysisScope?.Analyzers ?? compilationWithAnalyzers.Analyzers;
            var skippedAnalyzersInfo = project.GetSkippedAnalyzersInfo(AnalyzerInfoCache);

            // get compiler result builder map
            var builderMap = await analysisResult.ToResultBuilderMapAsync(
                additionalPragmaSuppressionDiagnostics, documentAnalysisScope, project, version,
                compilationWithAnalyzers.Compilation, analyzers, skippedAnalyzersInfo,
                compilationWithAnalyzers.AnalysisOptions.ReportSuppressedDiagnostics, cancellationToken).ConfigureAwait(false);

            var result    = builderMap.ToImmutableDictionary(kv => kv.Key, kv => DiagnosticAnalysisResult.CreateFromBuilder(kv.Value));
            var telemetry = getTelemetryInfo
                ? analysisResult.AnalyzerTelemetryInfo
                : ImmutableDictionary <DiagnosticAnalyzer, AnalyzerTelemetryInfo> .Empty;

            return(DiagnosticAnalysisResultMap.Create(result, telemetry));
        }
예제 #5
0
        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;
            }
        }
            private async Task <DiagnosticAnalysisResultMap <DiagnosticAnalyzer, DiagnosticAnalysisResult> > AnalyzeInProcAsync(
                CompilationWithAnalyzers analyzerDriver, Project project, RemoteHostClient client, CancellationToken cancellationToken)
            {
                if (analyzerDriver == null ||
                    analyzerDriver.Analyzers.Length == 0)
                {
                    // quick bail out
                    return(DiagnosticAnalysisResultMap.Create(ImmutableDictionary <DiagnosticAnalyzer, DiagnosticAnalysisResult> .Empty, ImmutableDictionary <DiagnosticAnalyzer, AnalyzerTelemetryInfo> .Empty));
                }

                var version = await DiagnosticIncrementalAnalyzer.GetDiagnosticVersionAsync(project, cancellationToken).ConfigureAwait(false);

                // PERF: Run all analyzers at once using the new GetAnalysisResultAsync API.
                var analysisResult = await analyzerDriver.GetAnalysisResultAsync(cancellationToken).ConfigureAwait(false);

                // if remote host is there, report performance data
                var asyncToken = _owner?.Listener.BeginAsyncOperation(nameof(AnalyzeInProcAsync));
                var _          = FireAndForgetReportAnalyzerPerformanceAsync(project, client, analysisResult, cancellationToken).CompletesAsyncOperation(asyncToken);

                // get compiler result builder map
                var builderMap = analysisResult.ToResultBuilderMap(project, version, analyzerDriver.Compilation, analyzerDriver.Analyzers, cancellationToken);

                return(DiagnosticAnalysisResultMap.Create(builderMap.ToImmutableDictionary(kv => kv.Key, kv => DiagnosticAnalysisResult.CreateFromBuilder(kv.Value)), analysisResult.AnalyzerTelemetryInfo));
            }