예제 #1
0
        private async Task <DiagnosticAnalysisResultMap <DiagnosticAnalyzer, DiagnosticAnalysisResult> > AnalyzeOutOfProcAsync(
            DocumentAnalysisScope?documentAnalysisScope,
            Project project,
            CompilationWithAnalyzers compilationWithAnalyzers,
            RemoteHostClient client,
            bool forceExecuteAllAnalyzers,
            bool logPerformanceInfo,
            bool getTelemetryInfo,
            CancellationToken cancellationToken)
        {
            var solution = project.Solution;

            using var pooledObject = SharedPools.Default <Dictionary <string, DiagnosticAnalyzer> >().GetPooledObject();
            var analyzerMap = pooledObject.Object;

            var analyzers = documentAnalysisScope?.Analyzers ??
                            compilationWithAnalyzers.Analyzers.Where(a => forceExecuteAllAnalyzers || !a.IsOpenFileOnly(solution.Options));

            analyzerMap.AppendAnalyzerMap(analyzers);

            if (analyzerMap.Count == 0)
            {
                return(DiagnosticAnalysisResultMap <DiagnosticAnalyzer, DiagnosticAnalysisResult> .Empty);
            }

            // Use high priority if we are force executing all analyzers for user action OR serving an active document request.
            var isHighPriority = forceExecuteAllAnalyzers ||
                                 documentAnalysisScope != null && _documentTrackingService?.TryGetActiveDocument() == documentAnalysisScope.TextDocument.Id;

            var argument = new DiagnosticArguments(
                isHighPriority,
                compilationWithAnalyzers.AnalysisOptions.ReportSuppressedDiagnostics,
                logPerformanceInfo,
                getTelemetryInfo,
                documentAnalysisScope?.TextDocument.Id,
                documentAnalysisScope?.Span,
                documentAnalysisScope?.Kind,
                project.Id,
                analyzerMap.Keys.ToArray());

            return(await client.RunRemoteAsync(
                       WellKnownServiceHubService.CodeAnalysis,
                       nameof(IRemoteDiagnosticAnalyzerService.CalculateDiagnosticsAsync),
                       solution,
                       new object[] { argument },
                       callbackTarget : null,
                       (s, c) => ReadCompilerAnalysisResultAsync(s, analyzerMap, documentAnalysisScope, project, c),
                       cancellationToken).ConfigureAwait(false));
        }
            > AnalyzeOutOfProcAsync(
            DocumentAnalysisScope?documentAnalysisScope,
            Project project,
            CompilationWithAnalyzers compilationWithAnalyzers,
            RemoteHostClient client,
            bool forceExecuteAllAnalyzers,
            bool logPerformanceInfo,
            bool getTelemetryInfo,
            CancellationToken cancellationToken
            )
        {
            var solution = project.Solution;

            using var pooledObject = SharedPools
                                     .Default <Dictionary <string, DiagnosticAnalyzer> >()
                                     .GetPooledObject();
            var analyzerMap = pooledObject.Object;

            var analyzers =
                documentAnalysisScope?.Analyzers
                ?? compilationWithAnalyzers.Analyzers.Where(
                    a => forceExecuteAllAnalyzers || !a.IsOpenFileOnly(solution.Options)
                    );

            analyzerMap.AppendAnalyzerMap(analyzers);

            if (analyzerMap.Count == 0)
            {
                return(DiagnosticAnalysisResultMap <
                           DiagnosticAnalyzer,
                           DiagnosticAnalysisResult
                           > .Empty);
            }

            var argument = new DiagnosticArguments(
                compilationWithAnalyzers.AnalysisOptions.ReportSuppressedDiagnostics,
                logPerformanceInfo,
                getTelemetryInfo,
                documentAnalysisScope?.TextDocument.Id,
                documentAnalysisScope?.Span,
                documentAnalysisScope?.Kind,
                project.Id,
                analyzerMap.Keys.ToArray()
                );

            var result = await client
                         .TryInvokeAsync <
                IRemoteDiagnosticAnalyzerService,
                SerializableDiagnosticAnalysisResults
                >(
                solution,
                invocation : (service, solutionInfo, cancellationToken) =>
                service.CalculateDiagnosticsAsync(
                    solutionInfo,
                    argument,
                    cancellationToken
                    ),
                cancellationToken
                )
                         .ConfigureAwait(false);

            if (!result.HasValue)
            {
                return(DiagnosticAnalysisResultMap <
                           DiagnosticAnalyzer,
                           DiagnosticAnalysisResult
                           > .Empty);
            }

            // handling of cancellation and exception
            var version = await DiagnosticIncrementalAnalyzer
                          .GetDiagnosticVersionAsync(project, cancellationToken)
                          .ConfigureAwait(false);

            var documentIds =
                (documentAnalysisScope != null)
                    ? ImmutableHashSet.Create(documentAnalysisScope.TextDocument.Id)
                    : null;

            return(new DiagnosticAnalysisResultMap <DiagnosticAnalyzer, DiagnosticAnalysisResult>(
                       result.Value.Diagnostics.ToImmutableDictionary(
                           entry => analyzerMap[entry.analyzerId],
                           entry =>
                           DiagnosticAnalysisResult.Create(
                               project,
                               version,
                               syntaxLocalMap: Hydrate(entry.diagnosticMap.Syntax, project),
                               semanticLocalMap: Hydrate(entry.diagnosticMap.Semantic, project),
                               nonLocalMap: Hydrate(entry.diagnosticMap.NonLocal, project),
                               others: entry.diagnosticMap.Other,
                               documentIds
                               )
                           ),
                       result.Value.Telemetry.ToImmutableDictionary(
                           entry => analyzerMap[entry.analyzerId],
                           entry => entry.telemetry
                           )
                       ));
        }