/// <summary> /// This is top level entry point for diagnostic calculation from client (VS). /// /// This will be called by ServiceHub/JsonRpc framework /// </summary> public async Task CalculateDiagnosticsAsync(DiagnosticArguments arguments, byte[] solutionChecksum, string streamName) { using (RoslynLogger.LogBlock(FunctionId.CodeAnalysisService_CalculateDiagnosticsAsync, arguments.ProjectIdDebugName, CancellationToken)) { try { var optionSet = await RoslynServices.AssetService.GetAssetAsync<OptionSet>(arguments.GetOptionSetChecksum(), CancellationToken).ConfigureAwait(false); // entry point for diagnostic service var solution = await RoslynServices.SolutionService.GetSolutionAsync(new Checksum(solutionChecksum), optionSet, CancellationToken).ConfigureAwait(false); var projectId = arguments.GetProjectId(); var analyzers = await GetHostAnalyzerReferences(arguments.GetHostAnalyzerChecksums()).ConfigureAwait(false); var result = await (new DiagnosticComputer(solution.GetProject(projectId))).GetDiagnosticsAsync( analyzers, arguments.AnalyzerIds, arguments.ReportSuppressedDiagnostics, arguments.LogAnalyzerExecutionTime, CancellationToken).ConfigureAwait(false); await SerializeDiagnosticResultAsync(streamName, result).ConfigureAwait(false); } catch (IOException) { // stream to send over result has closed before we // had chance to check cancellation } catch (OperationCanceledException) { // rpc connection has closed. // this can happen if client side cancelled the // operation } } }
private async Task<DiagnosticAnalysisResultMap<DiagnosticAnalyzer, DiagnosticAnalysisResult>> AnalyzeOutOfProcAsync( RemoteHostClient client, CompilationWithAnalyzers analyzerDriver, Project project, CancellationToken cancellationToken) { var solution = project.Solution; var snapshotService = solution.Workspace.Services.GetService<ISolutionSynchronizationService>(); // TODO: this should be moved out var analyzerMap = CreateAnalyzerMap(analyzerDriver.Analyzers); if (analyzerMap.Count == 0) { return DiagnosticAnalysisResultMap.Create(ImmutableDictionary<DiagnosticAnalyzer, DiagnosticAnalysisResult>.Empty, ImmutableDictionary<DiagnosticAnalyzer, AnalyzerTelemetryInfo>.Empty); } var optionAsset = GetOptionsAsset(solution, project.Language, cancellationToken); var hostChecksums = GetHostAnalyzerReferences(snapshotService, project.Language, _analyzerService.GetHostAnalyzerReferences(), cancellationToken); var argument = new DiagnosticArguments( analyzerDriver.AnalysisOptions.ReportSuppressedDiagnostics, analyzerDriver.AnalysisOptions.LogAnalyzerExecutionTime, project.Id, optionAsset.Checksum.ToArray(), hostChecksums, analyzerMap.Keys.ToArray()); // TODO: send telemetry on session using (var session = await client.CreateCodeAnalysisServiceSessionAsync(solution, cancellationToken).ConfigureAwait(false)) { session.AddAdditionalAssets(optionAsset); var result = await session.InvokeAsync( WellKnownServiceHubServices.CodeAnalysisService_CalculateDiagnosticsAsync, new object[] { argument }, (s, c) => GetCompilerAnalysisResultAsync(s, analyzerMap, project, c)).ConfigureAwait(false); ReportAnalyzerExceptions(project, result.Exceptions); return result; } }