public void TestDiagnosticArguments() { var arguments = new DiagnosticArguments( forcedAnalysis: false, reportSuppressedDiagnostics: true, logAnalyzerExecutionTime: false, projectId: ProjectId.CreateNewId("project"), optionSetChecksum: Checksum.Null, analyzerIds: new[] { "analyzer1", "analyzer2" }); VerifyJsonSerialization(arguments, (x, y) => { if (x.ForcedAnalysis == y.ForcedAnalysis && x.ReportSuppressedDiagnostics == y.ReportSuppressedDiagnostics && x.LogAnalyzerExecutionTime == y.LogAnalyzerExecutionTime && x.ProjectId == y.ProjectId && x.OptionSetChecksum == y.OptionSetChecksum && x.AnalyzerIds.Length == y.AnalyzerIds.Length && x.AnalyzerIds.Except(y.AnalyzerIds).Count() == 0) { return(0); } return(1); }); }
private async Task <DiagnosticAnalysisResultMap <DiagnosticAnalyzer, DiagnosticAnalysisResult> > AnalyzeOutOfProcAsync( RemoteHostClient client, CompilationWithAnalyzers analyzerDriver, Project project, bool forcedAnalysis, CancellationToken cancellationToken) { var solution = project.Solution; using var pooledObject = SharedPools.Default <Dictionary <string, DiagnosticAnalyzer> >().GetPooledObject(); var analyzerMap = pooledObject.Object; analyzerMap.AppendAnalyzerMap(analyzerDriver.Analyzers.Where(a => forcedAnalysis || !a.IsOpenFileOnly(solution.Options))); if (analyzerMap.Count == 0) { return(DiagnosticAnalysisResultMap <DiagnosticAnalyzer, DiagnosticAnalysisResult> .Empty); } var argument = new DiagnosticArguments( forcedAnalysis, analyzerDriver.AnalysisOptions.ReportSuppressedDiagnostics, analyzerDriver.AnalysisOptions.LogAnalyzerExecutionTime, project.Id, analyzerMap.Keys.ToArray()); var result = await client.TryRunRemoteAsync( WellKnownServiceHubServices.CodeAnalysisService, nameof(IRemoteDiagnosticAnalyzerService.CalculateDiagnosticsAsync), solution, new object[] { argument }, callbackTarget : null, (s, c) => ReadCompilerAnalysisResultAsync(s, analyzerMap, project, c), cancellationToken).ConfigureAwait(false); return(result.HasValue ? result.Value : DiagnosticAnalysisResultMap <DiagnosticAnalyzer, DiagnosticAnalysisResult> .Empty); }
public void TestDiagnosticArguments() { var projectId = ProjectId.CreateNewId("project"); var arguments = new DiagnosticArguments( reportSuppressedDiagnostics: true, logPerformanceInfo: true, getTelemetryInfo: true, documentId: DocumentId.CreateNewId(projectId), documentSpan: new TextSpan(0, 1), documentAnalysisKind: AnalysisKind.Syntax, projectId: projectId, analyzerIds: new[] { "analyzer1", "analyzer2" }); VerifyJsonSerialization(arguments, (x, y) => { if (x.ReportSuppressedDiagnostics == y.ReportSuppressedDiagnostics && x.LogPerformanceInfo == y.LogPerformanceInfo && x.GetTelemetryInfo == y.GetTelemetryInfo && x.DocumentId == y.DocumentId && x.DocumentSpan == y.DocumentSpan && x.DocumentAnalysisKind == y.DocumentAnalysisKind && x.ProjectId == y.ProjectId && x.AnalyzerIds.Length == y.AnalyzerIds.Length && x.AnalyzerIds.Except(y.AnalyzerIds).Count() == 0) { return(0); } return(1); }); }
/// <summary> /// This is top level entry point for diagnostic calculation from client (VS). /// /// This will be called by ServiceHub/JsonRpc framework /// </summary> public Task CalculateDiagnosticsAsync(DiagnosticArguments arguments, string streamName, CancellationToken cancellationToken) { return(RunServiceAsync(async() => { // if this analysis is explicitly asked by user, boost priority of this request using (RoslynLogger.LogBlock(FunctionId.CodeAnalysisService_CalculateDiagnosticsAsync, arguments.ProjectId.DebugName, cancellationToken)) using (arguments.ForcedAnalysis ? UserOperationBooster.Boost() : default) { try { // entry point for diagnostic service var solution = await GetSolutionAsync(cancellationToken).ConfigureAwait(false); var optionSet = await RoslynServices.AssetService.GetAssetAsync <OptionSet>(arguments.OptionSetChecksum, cancellationToken).ConfigureAwait(false); var projectId = arguments.ProjectId; var analyzers = RoslynServices.AssetService.GetGlobalAssetsOfType <AnalyzerReference>(cancellationToken); var result = await(new DiagnosticComputer(solution.GetProject(projectId))).GetDiagnosticsAsync( analyzers, optionSet, arguments.AnalyzerIds, arguments.ReportSuppressedDiagnostics, arguments.LogAnalyzerExecutionTime, cancellationToken).ConfigureAwait(false); await SerializeDiagnosticResultAsync(streamName, result, cancellationToken).ConfigureAwait(false); } catch (IOException) { // direct stream to send over result has closed before we // had chance to check cancellation } } }, cancellationToken)); }
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 <ISolutionChecksumService>(); // TODO: this should be moved out var hostChecksums = GetHostAnalyzerReferences(snapshotService, _analyzerService.GetHostAnalyzerReferences(), cancellationToken); var analyzerMap = CreateAnalyzerMap(analyzerDriver.Analyzers.Where(a => !a.MustRunInProcess())); if (analyzerMap.Count == 0) { return(DiagnosticAnalysisResultMap.Create(ImmutableDictionary <DiagnosticAnalyzer, DiagnosticAnalysisResult> .Empty, ImmutableDictionary <DiagnosticAnalyzer, AnalyzerTelemetryInfo> .Empty)); } // TODO: send telemetry on session using (var session = await client.CreateCodeAnalysisServiceSessionAsync(solution, cancellationToken).ConfigureAwait(false)) { var argument = new DiagnosticArguments( analyzerDriver.AnalysisOptions.ReportSuppressedDiagnostics, analyzerDriver.AnalysisOptions.LogAnalyzerExecutionTime, project.Id, hostChecksums, analyzerMap.Keys.ToArray()); 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); } }
/// <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, 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 GetSolutionWithSpecificOptionsAsync(optionSet).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 } } }
/// <summary> /// Calculate dignostics. this works differently than other ones such as todo comments or designer attribute scanner /// since in proc and out of proc runs quite differently due to concurrency and due to possible amount of data /// that needs to pass through between processes /// </summary> public Task CalculateDiagnosticsAsync(DiagnosticArguments arguments, string pipeName, CancellationToken cancellationToken) { return(RunServiceAsync(async() => { // if this analysis is explicitly asked by user, boost priority of this request using (RoslynLogger.LogBlock(FunctionId.CodeAnalysisService_CalculateDiagnosticsAsync, arguments.ProjectId.DebugName, cancellationToken)) using (arguments.ForcedAnalysis ? UserOperationBooster.Boost() : default) { // entry point for diagnostic service var solution = await GetSolutionAsync(cancellationToken).ConfigureAwait(false); var projectId = arguments.ProjectId; var analyzers = RoslynServices.AssetService.GetGlobalAssetsOfType <AnalyzerReference>(cancellationToken); var result = await new DiagnosticComputer(solution.GetProject(projectId)).GetDiagnosticsAsync( analyzers, arguments.AnalyzerIds, arguments.ReportSuppressedDiagnostics, arguments.LogAnalyzerExecutionTime, cancellationToken).ConfigureAwait(false); await RemoteEndPoint.WriteDataToNamedPipeAsync(pipeName, result, (writer, data, cancellationToken) => { var(diagnostics, telemetry, exceptions) = DiagnosticResultSerializer.WriteDiagnosticAnalysisResults(writer, data, cancellationToken); // save log for debugging Log(TraceEventType.Information, $"diagnostics: {diagnostics}, telemetry: {telemetry}, exceptions: {exceptions}"); return Task.CompletedTask; }, cancellationToken).ConfigureAwait(false); } }, cancellationToken)); }
public void TestDiagnosticArguments() { var arguments = new DiagnosticArguments( reportSuppressedDiagnostics: true, logAnalyzerExecutionTime: false, projectId: ProjectId.CreateNewId("project"), optionSetChecksum: Checksum.Null, hostAnalyzerChecksums: ImmutableArray.CreateRange(new[] { new Checksum(Guid.NewGuid().ToByteArray()), new Checksum(Guid.NewGuid().ToByteArray()) }), analyzerIds: new[] { "analyzer1", "analyzer2" }); VerifyJsonSerialization(arguments, (x, y) => { if (x.ReportSuppressedDiagnostics == y.ReportSuppressedDiagnostics && x.LogAnalyzerExecutionTime == y.LogAnalyzerExecutionTime && x.ProjectId == y.ProjectId && x.OptionSetChecksum == y.OptionSetChecksum && x.HostAnalyzerChecksums.Length == y.HostAnalyzerChecksums.Length && x.HostAnalyzerChecksums.Except(y.HostAnalyzerChecksums).Count() == 0 && x.AnalyzerIds.Length == y.AnalyzerIds.Length && x.AnalyzerIds.Except(y.AnalyzerIds).Count() == 0) { return(0); } return(1); }); }
/// <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) { try { // entry point for diagnostic service var solution = await RoslynServices.SolutionService.GetSolutionAsync(new Checksum(solutionChecksum), 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 } }
/// <summary> /// Calculate dignostics. this works differently than other ones such as todo comments or designer attribute scanner /// since in proc and out of proc runs quite differently due to concurrency and due to possible amount of data /// that needs to pass through between processes /// </summary> public Task CalculateDiagnosticsAsync(PinnedSolutionInfo solutionInfo, DiagnosticArguments arguments, string pipeName, CancellationToken cancellationToken) { return(RunServiceAsync(async() => { using (RoslynLogger.LogBlock(FunctionId.CodeAnalysisService_CalculateDiagnosticsAsync, arguments.ProjectId.DebugName, cancellationToken)) using (arguments.IsHighPriority ? UserOperationBooster.Boost() : default) { var solution = await GetSolutionAsync(solutionInfo, cancellationToken).ConfigureAwait(false); var documentId = arguments.DocumentId; var projectId = arguments.ProjectId; var project = solution.GetProject(projectId); var documentSpan = arguments.DocumentSpan; var documentAnalysisKind = arguments.DocumentAnalysisKind; var diagnosticComputer = new DiagnosticComputer(documentId, project, documentSpan, documentAnalysisKind, _analyzerInfoCache); var result = await diagnosticComputer.GetDiagnosticsAsync( arguments.AnalyzerIds, reportSuppressedDiagnostics: arguments.ReportSuppressedDiagnostics, logPerformanceInfo: arguments.LogPerformanceInfo, getTelemetryInfo: arguments.GetTelemetryInfo, cancellationToken).ConfigureAwait(false); await RemoteEndPoint.WriteDataToNamedPipeAsync(pipeName, (result, documentAnalysisKind), (writer, data, cancellationToken) => { var(diagnostics, telemetry) = DiagnosticResultSerializer.WriteDiagnosticAnalysisResults(writer, data.documentAnalysisKind, data.result, cancellationToken); // save log for debugging Log(TraceEventType.Information, $"diagnostics: {diagnostics}, telemetry: {telemetry}"); return Task.CompletedTask; }, cancellationToken).ConfigureAwait(false); } }, cancellationToken)); }
private async Task <DiagnosticAnalysisResultMap <DiagnosticAnalyzer, DiagnosticAnalysisResult> > AnalyzeOutOfProcAsync( RemoteHostClient client, CompilationWithAnalyzers analyzerDriver, Project project, bool forcedAnalysis, CancellationToken cancellationToken) { var solution = project.Solution; var snapshotService = solution.Workspace.Services.GetService <IRemotableDataService>(); using var pooledObject = SharedPools.Default <Dictionary <string, DiagnosticAnalyzer> >().GetPooledObject(); var analyzerMap = pooledObject.Object; analyzerMap.AppendAnalyzerMap(analyzerDriver.Analyzers.Where(a => forcedAnalysis || !a.IsOpenFileOnly(solution.Options))); if (analyzerMap.Count == 0) { return(DiagnosticAnalysisResultMap <DiagnosticAnalyzer, DiagnosticAnalysisResult> .Empty); } var argument = new DiagnosticArguments( forcedAnalysis, analyzerDriver.AnalysisOptions.ReportSuppressedDiagnostics, analyzerDriver.AnalysisOptions.LogAnalyzerExecutionTime, project.Id, analyzerMap.Keys.ToArray()); using var session = await client.TryCreateSessionAsync(WellKnownServiceHubServices.CodeAnalysisService, solution, callbackTarget : null, cancellationToken).ConfigureAwait(false); if (session == null) { // session is not available return(DiagnosticAnalysisResultMap <DiagnosticAnalyzer, DiagnosticAnalysisResult> .Empty); } return(await session.Connection.InvokeAsync( nameof(IRemoteDiagnosticAnalyzerService.CalculateDiagnosticsAsync), new object[] { argument }, (stream, cancellationToken) => ReadCompilerAnalysisResultAsync(stream, analyzerMap, project, cancellationToken), cancellationToken).ConfigureAwait(false)); }
private async Task <DiagnosticAnalysisResultMap <DiagnosticAnalyzer, DiagnosticAnalysisResult> > AnalyzeOutOfProcAsync( RemoteHostClient client, CompilationWithAnalyzers analyzerDriver, Project project, bool forcedAnalysis, CancellationToken cancellationToken) { var solution = project.Solution; var snapshotService = solution.Workspace.Services.GetService <IRemotableDataService>(); using (var pooledObject = SharedPools.Default <Dictionary <string, DiagnosticAnalyzer> >().GetPooledObject()) { var analyzerMap = pooledObject.Object; analyzerMap.AppendAnalyzerMap(analyzerDriver.Analyzers.Where(a => !a.IsInProcessOnly() && (forcedAnalysis || !a.IsOpenFileOnly(solution.Workspace)))); if (analyzerMap.Count == 0) { return(DiagnosticAnalysisResultMap.Create(ImmutableDictionary <DiagnosticAnalyzer, DiagnosticAnalysisResult> .Empty, ImmutableDictionary <DiagnosticAnalyzer, AnalyzerTelemetryInfo> .Empty)); } var optionAsset = GetOptionsAsset(solution, project.Language, cancellationToken); var argument = new DiagnosticArguments( forcedAnalysis, analyzerDriver.AnalysisOptions.ReportSuppressedDiagnostics, analyzerDriver.AnalysisOptions.LogAnalyzerExecutionTime, project.Id, optionAsset.Checksum, analyzerMap.Keys.ToArray()); using (var session = await client.TryCreateCodeAnalysisSessionAsync(solution, cancellationToken).ConfigureAwait(false)) { if (session == null) { // session is not available return(DiagnosticAnalysisResultMap.Create(ImmutableDictionary <DiagnosticAnalyzer, DiagnosticAnalysisResult> .Empty, ImmutableDictionary <DiagnosticAnalyzer, AnalyzerTelemetryInfo> .Empty)); } session.AddAdditionalAssets(optionAsset); var result = await session.InvokeAsync( nameof(IRemoteDiagnosticAnalyzerService.CalculateDiagnosticsAsync), new object[] { argument }, (s, c) => GetCompilerAnalysisResultAsync(s, analyzerMap, project, c), cancellationToken).ConfigureAwait(false); ReportAnalyzerExceptions(project, result.Exceptions); return(result); } } }
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 argument = new DiagnosticArguments( analyzerDriver.AnalysisOptions.ReportSuppressedDiagnostics, analyzerDriver.AnalysisOptions.LogAnalyzerExecutionTime, project.Id, optionAsset.Checksum, analyzerMap.Keys.ToArray()); using (var session = await client.TryCreateCodeAnalysisServiceSessionAsync(solution, cancellationToken).ConfigureAwait(false)) { if (session == null) { // session is not available return(DiagnosticAnalysisResultMap.Create(ImmutableDictionary <DiagnosticAnalyzer, DiagnosticAnalysisResult> .Empty, ImmutableDictionary <DiagnosticAnalyzer, AnalyzerTelemetryInfo> .Empty)); } 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); } }