diff --git a/src/Workspaces/Remote/ServiceHub/Services/DiagnosticAnalyzer/IPerformanceTrackerService.cs b/src/Features/Core/Portable/Diagnostics/IPerformanceTrackerService.cs similarity index 93% rename from src/Workspaces/Remote/ServiceHub/Services/DiagnosticAnalyzer/IPerformanceTrackerService.cs rename to src/Features/Core/Portable/Diagnostics/IPerformanceTrackerService.cs index 5b4c5c34b3a81..c2357bba42106 100644 --- a/src/Workspaces/Remote/ServiceHub/Services/DiagnosticAnalyzer/IPerformanceTrackerService.cs +++ b/src/Features/Core/Portable/Diagnostics/IPerformanceTrackerService.cs @@ -4,10 +4,9 @@ using System; using System.Collections.Generic; -using Microsoft.CodeAnalysis.Diagnostics; using Microsoft.CodeAnalysis.Host; -namespace Microsoft.CodeAnalysis.Remote.Diagnostics; +namespace Microsoft.CodeAnalysis.Diagnostics; internal interface IPerformanceTrackerService : IWorkspaceService { diff --git a/src/Features/Core/Portable/Diagnostics/Service/EngineV2/InProcOrRemoteHostAnalyzerRunner.cs b/src/Features/Core/Portable/Diagnostics/Service/EngineV2/InProcOrRemoteHostAnalyzerRunner.cs index 92deddf7bee47..e3b03f96f3f29 100644 --- a/src/Features/Core/Portable/Diagnostics/Service/EngineV2/InProcOrRemoteHostAnalyzerRunner.cs +++ b/src/Features/Core/Portable/Diagnostics/Service/EngineV2/InProcOrRemoteHostAnalyzerRunner.cs @@ -12,26 +12,20 @@ using Microsoft.CodeAnalysis.Diagnostics.Telemetry; using Microsoft.CodeAnalysis.ErrorReporting; using Microsoft.CodeAnalysis.Host; -using Microsoft.CodeAnalysis.Remote; +using Microsoft.CodeAnalysis.Internal.Log; using Microsoft.CodeAnalysis.Shared.Extensions; using Microsoft.CodeAnalysis.Shared.TestHooks; using Microsoft.CodeAnalysis.Workspaces.Diagnostics; -using Roslyn.Utilities; +using RoslynLogger = Microsoft.CodeAnalysis.Internal.Log.Logger; namespace Microsoft.CodeAnalysis.Diagnostics; -internal sealed class InProcOrRemoteHostAnalyzerRunner +internal sealed class InProcOrRemoteHostAnalyzerRunner( + DiagnosticAnalyzerInfoCache analyzerInfoCache, + IAsynchronousOperationListener? operationListener = null) { - private readonly IAsynchronousOperationListener _asyncOperationListener; - public DiagnosticAnalyzerInfoCache AnalyzerInfoCache { get; } - - public InProcOrRemoteHostAnalyzerRunner( - DiagnosticAnalyzerInfoCache analyzerInfoCache, - IAsynchronousOperationListener? operationListener = null) - { - AnalyzerInfoCache = analyzerInfoCache; - _asyncOperationListener = operationListener ?? AsynchronousOperationListenerProvider.NullListener; - } + private readonly IAsynchronousOperationListener _asyncOperationListener = operationListener ?? AsynchronousOperationListenerProvider.NullListener; + public DiagnosticAnalyzerInfoCache AnalyzerInfoCache { get; } = analyzerInfoCache; public Task> AnalyzeDocumentAsync( DocumentAnalysisScope documentAnalysisScope, @@ -57,31 +51,17 @@ private async Task> AnalyzeCoreAsync() - { - Contract.ThrowIfFalse(compilationWithAnalyzers.HasAnalyzers); - - var remoteHostClient = await RemoteHostClient.TryGetClientAsync(project, cancellationToken).ConfigureAwait(false); - if (remoteHostClient != null) - { - return await AnalyzeOutOfProcAsync(documentAnalysisScope, project, compilationWithAnalyzers, remoteHostClient, - logPerformanceInfo, getTelemetryInfo, cancellationToken).ConfigureAwait(false); - } - - return await AnalyzeInProcAsync(documentAnalysisScope, project, compilationWithAnalyzers, - client: null, logPerformanceInfo, getTelemetryInfo, cancellationToken).ConfigureAwait(false); - } } private async Task> AnalyzeInProcAsync( DocumentAnalysisScope? documentAnalysisScope, Project project, CompilationWithAnalyzersPair compilationWithAnalyzers, - RemoteHostClient? client, bool logPerformanceInfo, bool getTelemetryInfo, CancellationToken cancellationToken) @@ -93,7 +73,9 @@ private async Task ReportAnalyzerPerformance(documentAnalysisScope, project, analysisResult, cancellationToken), + cancellationToken).CompletesAsyncOperation(asyncToken); } var projectAnalyzers = documentAnalysisScope?.ProjectAnalyzers ?? compilationWithAnalyzers.ProjectAnalyzers; @@ -120,18 +102,12 @@ private async Task( - (service, cancellationToken) => service.ReportAnalyzerPerformanceAsync(performanceInfo, count, forSpanAnalysis, cancellationToken), - cancellationToken).ConfigureAwait(false); + using (RoslynLogger.LogBlock(FunctionId.CodeAnalysisService_ReportAnalyzerPerformance, cancellationToken)) + { + var service = project.Solution.Services.GetService(); + service?.AddSnapshot(performanceInfo, count, forSpanAnalysis); + } } catch (Exception ex) when (FatalError.ReportAndCatchUnlessCanceled(ex, cancellationToken)) { // ignore all, this is fire and forget method } } - - private static async Task> AnalyzeOutOfProcAsync( - DocumentAnalysisScope? documentAnalysisScope, - Project project, - CompilationWithAnalyzersPair compilationWithAnalyzers, - RemoteHostClient client, - bool logPerformanceInfo, - bool getTelemetryInfo, - CancellationToken cancellationToken) - { - using var pooledObject1 = SharedPools.Default>().GetPooledObject(); - using var pooledObject2 = SharedPools.Default>().GetPooledObject(); - var projectAnalyzerMap = pooledObject1.Object; - var hostAnalyzerMap = pooledObject2.Object; - - var projectAnalyzers = documentAnalysisScope?.ProjectAnalyzers ?? compilationWithAnalyzers.ProjectAnalyzers; - var hostAnalyzers = documentAnalysisScope?.HostAnalyzers ?? compilationWithAnalyzers.HostAnalyzers; - - projectAnalyzerMap.AppendAnalyzerMap(projectAnalyzers); - hostAnalyzerMap.AppendAnalyzerMap(hostAnalyzers); - - if (projectAnalyzerMap.Count == 0 && hostAnalyzerMap.Count == 0) - { - return DiagnosticAnalysisResultMap.Empty; - } - - var argument = new DiagnosticArguments( - logPerformanceInfo, - getTelemetryInfo, - documentAnalysisScope?.TextDocument.Id, - documentAnalysisScope?.Span, - documentAnalysisScope?.Kind, - project.Id, - [.. projectAnalyzerMap.Keys], - [.. hostAnalyzerMap.Keys]); - - var result = await client.TryInvokeAsync( - project.Solution, - invocation: (service, solutionInfo, cancellationToken) => service.CalculateDiagnosticsAsync(solutionInfo, argument, cancellationToken), - cancellationToken).ConfigureAwait(false); - - if (!result.HasValue) - return DiagnosticAnalysisResultMap.Empty; - - return new DiagnosticAnalysisResultMap( - result.Value.Diagnostics.ToImmutableDictionary( - entry => IReadOnlyDictionaryExtensions.GetValueOrDefault(projectAnalyzerMap, entry.analyzerId) ?? hostAnalyzerMap[entry.analyzerId], - entry => DiagnosticAnalysisResult.Create( - project, - syntaxLocalMap: Hydrate(entry.diagnosticMap.Syntax, project), - semanticLocalMap: Hydrate(entry.diagnosticMap.Semantic, project), - nonLocalMap: Hydrate(entry.diagnosticMap.NonLocal, project), - others: entry.diagnosticMap.Other)), - result.Value.Telemetry.ToImmutableDictionary( - entry => IReadOnlyDictionaryExtensions.GetValueOrDefault(projectAnalyzerMap, entry.analyzerId) ?? hostAnalyzerMap[entry.analyzerId], - entry => entry.telemetry)); - } - - // TODO: filter in OOP https://github.com/dotnet/roslyn/issues/47859 - private static ImmutableDictionary> Hydrate(ImmutableArray<(DocumentId documentId, ImmutableArray diagnostics)> diagnosticByDocument, Project project) - => diagnosticByDocument - .Where( - entry => - { - // Source generated documents (for which GetTextDocument returns null) support diagnostics. Only - // filter out diagnostics where the document is non-null and SupportDiagnostics() is false. - return project.GetTextDocument(entry.documentId)?.SupportsDiagnostics() != false; - }) - .ToImmutableDictionary(entry => entry.documentId, entry => entry.diagnostics); } diff --git a/src/VisualStudio/Core/Test.Next/Services/VisualStudioDiagnosticAnalyzerExecutorTests.cs b/src/VisualStudio/Core/Test.Next/Services/VisualStudioDiagnosticAnalyzerExecutorTests.cs index 25b2c968db8ee..9addebfabffcb 100644 --- a/src/VisualStudio/Core/Test.Next/Services/VisualStudioDiagnosticAnalyzerExecutorTests.cs +++ b/src/VisualStudio/Core/Test.Next/Services/VisualStudioDiagnosticAnalyzerExecutorTests.cs @@ -61,7 +61,7 @@ void Method() diagnostics = analyzerResult.GetDocumentDiagnostics(project.DocumentIds.First(), AnalysisKind.Semantic); Assert.Equal(IDEDiagnosticIds.UseExplicitTypeDiagnosticId, diagnostics[0].Id); - Assert.Equal(isHostAnalyzer ? DiagnosticSeverity.Info : DiagnosticSeverity.Hidden, diagnostics[0].Severity); + Assert.Equal(DiagnosticSeverity.Hidden, diagnostics[0].Severity); } [Theory, CombinatorialData] @@ -84,17 +84,9 @@ End Class var project = workspace.CurrentSolution.Projects.First(); var analyzerResult = await AnalyzeAsync(workspace, project.Id, analyzerType, isHostAnalyzer); - ImmutableArray diagnostics; - if (isHostAnalyzer) - { - Assert.True(analyzerResult.GetAllDiagnostics().IsEmpty); - } - else - { - diagnostics = analyzerResult.GetDocumentDiagnostics(project.DocumentIds.First(), AnalysisKind.Semantic); - Assert.Equal(IDEDiagnosticIds.UseNullPropagationDiagnosticId, diagnostics[0].Id); - Assert.Equal(DiagnosticSeverity.Info, diagnostics[0].Severity); - } + var diagnostics = analyzerResult.GetDocumentDiagnostics(project.DocumentIds.First(), AnalysisKind.Semantic); + Assert.Equal(IDEDiagnosticIds.UseNullPropagationDiagnosticId, diagnostics[0].Id); + Assert.Equal(DiagnosticSeverity.Info, diagnostics[0].Severity); workspace.SetAnalyzerFallbackOptions(LanguageNames.VisualBasic, ("dotnet_style_null_propagation", "true:error")); @@ -102,7 +94,7 @@ End Class diagnostics = analyzerResult.GetDocumentDiagnostics(project.DocumentIds.First(), AnalysisKind.Semantic); Assert.Equal(IDEDiagnosticIds.UseNullPropagationDiagnosticId, diagnostics[0].Id); - Assert.Equal(isHostAnalyzer ? DiagnosticSeverity.Error : DiagnosticSeverity.Info, diagnostics[0].Severity); + Assert.Equal(DiagnosticSeverity.Info, diagnostics[0].Severity); } [Fact] diff --git a/src/Workspaces/Core/Portable/Diagnostics/DiagnosticArguments.cs b/src/Workspaces/Core/Portable/Diagnostics/DiagnosticArguments.cs deleted file mode 100644 index a90abd145ae43..0000000000000 --- a/src/Workspaces/Core/Portable/Diagnostics/DiagnosticArguments.cs +++ /dev/null @@ -1,97 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System.Collections.Immutable; -using System.Diagnostics; -using System.Runtime.Serialization; -using Microsoft.CodeAnalysis.Text; - -namespace Microsoft.CodeAnalysis.Diagnostics; - -/// -/// helper type to package diagnostic arguments to pass around between remote hosts -/// -[DataContract] -internal sealed class DiagnosticArguments -{ - /// - /// Flag indicating if analyzer performance info, such as analyzer execution times, - /// should be logged as performance telemetry. - /// - [DataMember(Order = 0)] - public bool LogPerformanceInfo; - - /// - /// Flag indicating if the analyzer telemety info, such as registered analyzer action counts - /// and analyzer execution times, should be included in the computed result. - /// - [DataMember(Order = 1)] - public bool GetTelemetryInfo; - - /// - /// Optional document ID, if computing diagnostics for a specific document. - /// For example, diagnostic computation for open file analysis. - /// - [DataMember(Order = 2)] - public DocumentId? DocumentId; - - /// - /// Optional document text span, if computing diagnostics for a specific span for a document. - /// For example, diagnostic computation for light bulb invocation for a specific line in active document. - /// - [DataMember(Order = 3)] - public TextSpan? DocumentSpan; - - /// - /// Optional , if computing specific kind of diagnostics for a document request, - /// i.e. must be non-null for a non-null analysis kind. - /// Only supported non-null values are and . - /// - [DataMember(Order = 4)] - public AnalysisKind? DocumentAnalysisKind; - - /// - /// Project ID for the document or project for which diagnostics need to be computed. - /// - [DataMember(Order = 5)] - public ProjectId ProjectId; - - /// - /// Array of analyzer IDs for analyzers that need to be executed for computing diagnostics. - /// - [DataMember(Order = 6)] - public ImmutableArray ProjectAnalyzerIds; - - /// - /// Array of analyzer IDs for analyzers that need to be executed for computing diagnostics. - /// - [DataMember(Order = 7)] - public ImmutableArray HostAnalyzerIds; - - public DiagnosticArguments( - bool logPerformanceInfo, - bool getTelemetryInfo, - DocumentId? documentId, - TextSpan? documentSpan, - AnalysisKind? documentAnalysisKind, - ProjectId projectId, - ImmutableArray projectAnalyzerIds, - ImmutableArray hostAnalyzerIds) - { - Debug.Assert(documentId != null || documentSpan == null); - Debug.Assert(documentId != null || documentAnalysisKind == null); - Debug.Assert(documentAnalysisKind is null or - (AnalysisKind?)AnalysisKind.Syntax or (AnalysisKind?)AnalysisKind.Semantic); - Debug.Assert(projectAnalyzerIds.Length > 0 || hostAnalyzerIds.Length > 0); - - LogPerformanceInfo = logPerformanceInfo; - GetTelemetryInfo = getTelemetryInfo; - DocumentId = documentId; - DocumentSpan = documentSpan; - DocumentAnalysisKind = documentAnalysisKind; - ProjectId = projectId; - ProjectAnalyzerIds = projectAnalyzerIds; - HostAnalyzerIds = hostAnalyzerIds; - } -} diff --git a/src/Workspaces/Core/Portable/Diagnostics/IRemoteDiagnosticAnalyzerService.cs b/src/Workspaces/Core/Portable/Diagnostics/IRemoteDiagnosticAnalyzerService.cs index ea009d943211a..81a6fb5e06c83 100644 --- a/src/Workspaces/Core/Portable/Diagnostics/IRemoteDiagnosticAnalyzerService.cs +++ b/src/Workspaces/Core/Portable/Diagnostics/IRemoteDiagnosticAnalyzerService.cs @@ -30,8 +30,6 @@ internal interface IRemoteDiagnosticAnalyzerService ValueTask> GetDeprioritizationCandidatesAsync( Checksum solutionChecksum, ProjectId projectId, ImmutableHashSet analyzerIds, CancellationToken cancellationToken); - ValueTask CalculateDiagnosticsAsync(Checksum solutionChecksum, DiagnosticArguments arguments, CancellationToken cancellationToken); - ValueTask> ComputeDiagnosticsAsync( Checksum solutionChecksum, DocumentId documentId, TextSpan? range, ImmutableHashSet allAnalyzerIds, @@ -53,7 +51,6 @@ ValueTask> ProduceProjectDiagnosticsAsync( CancellationToken cancellationToken); ValueTask> GetSourceGeneratorDiagnosticsAsync(Checksum solutionChecksum, ProjectId projectId, CancellationToken cancellationToken); - ValueTask ReportAnalyzerPerformanceAsync(ImmutableArray snapshot, int unitCount, bool forSpanAnalysis, CancellationToken cancellationToken); ValueTask> GetDiagnosticDescriptorsAsync( Checksum solutionChecksum, ProjectId projectId, string analyzerReferenceFullPath, string language, CancellationToken cancellationToken); diff --git a/src/Workspaces/Remote/ServiceHub/Services/DiagnosticAnalyzer/DiagnosticComputer.cs b/src/Workspaces/Remote/ServiceHub/Services/DiagnosticAnalyzer/DiagnosticComputer.cs index 5e8cb4987adcb..a8fbc902f216e 100644 --- a/src/Workspaces/Remote/ServiceHub/Services/DiagnosticAnalyzer/DiagnosticComputer.cs +++ b/src/Workspaces/Remote/ServiceHub/Services/DiagnosticAnalyzer/DiagnosticComputer.cs @@ -79,7 +79,7 @@ private DiagnosticComputer( _performanceTracker = project.Solution.Services.GetService(); } - public static Task GetDiagnosticsAsync( + public static Task GetDiagnosticsAsync( TextDocument? document, Project project, Checksum solutionChecksum, @@ -120,7 +120,7 @@ public static Task GetDiagnosticsAsync( projectAnalyzerIds, hostAnalyzerIds, logPerformanceInfo, getTelemetryInfo, cancellationToken); } - private async Task GetDiagnosticsAsync( + private async Task GetDiagnosticsAsync( ImmutableArray projectAnalyzerIds, ImmutableArray hostAnalyzerIds, bool logPerformanceInfo, @@ -129,15 +129,11 @@ private async Task GetDiagnosticsAsync( { var (compilationWithAnalyzers, projectAnalyzerToIdMap, hostAnalyzerToIdMap) = await GetOrCreateCompilationWithAnalyzersAsync(cancellationToken).ConfigureAwait(false); if (compilationWithAnalyzers == null) - { - return SerializableDiagnosticAnalysisResults.Empty; - } + return DiagnosticAnalysisResults.Empty; var (projectAnalyzers, hostAnalyzers) = GetAnalyzers(projectAnalyzerToIdMap, hostAnalyzerToIdMap, projectAnalyzerIds, hostAnalyzerIds); if (projectAnalyzers.IsEmpty && hostAnalyzers.IsEmpty) - { - return SerializableDiagnosticAnalysisResults.Empty; - } + return DiagnosticAnalysisResults.Empty; if (_document == null) { @@ -169,7 +165,7 @@ private async Task GetDiagnosticsAsync( logPerformanceInfo, getTelemetryInfo, cancellationToken).ConfigureAwait(false); } - private async Task AnalyzeAsync( + private async Task AnalyzeAsync( CompilationWithAnalyzersPair compilationWithAnalyzers, BidirectionalMap projectAnalyzerToIdMap, BidirectionalMap hostAnalyzerToIdMap, @@ -216,22 +212,22 @@ private async Task AnalyzeAsync( ? GetTelemetryInfo(analysisResult, projectAnalyzers, hostAnalyzers, projectAnalyzerToIdMap, hostAnalyzerToIdMap) : []; - return new SerializableDiagnosticAnalysisResults(Dehydrate(builderMap, projectAnalyzerToIdMap, hostAnalyzerToIdMap), telemetry); + return new DiagnosticAnalysisResults(Dehydrate(builderMap, projectAnalyzerToIdMap, hostAnalyzerToIdMap), telemetry); } - private static ImmutableArray<(string analyzerId, SerializableDiagnosticMap diagnosticMap)> Dehydrate( + private static ImmutableArray<(string analyzerId, DiagnosticMap diagnosticMap)> Dehydrate( ImmutableDictionary builderMap, BidirectionalMap projectAnalyzerToIdMap, BidirectionalMap hostAnalyzerToIdMap) { - var diagnostics = new FixedSizeArrayBuilder<(string analyzerId, SerializableDiagnosticMap diagnosticMap)>(builderMap.Count); + var diagnostics = new FixedSizeArrayBuilder<(string analyzerId, DiagnosticMap diagnosticMap)>(builderMap.Count); foreach (var (analyzer, analyzerResults) in builderMap) { var analyzerId = GetAnalyzerId(projectAnalyzerToIdMap, hostAnalyzerToIdMap, analyzer); diagnostics.Add((analyzerId, - new SerializableDiagnosticMap( + new DiagnosticMap( analyzerResults.SyntaxLocals.SelectAsArray(entry => (entry.Key, entry.Value)), analyzerResults.SemanticLocals.SelectAsArray(entry => (entry.Key, entry.Value)), analyzerResults.NonLocals.SelectAsArray(entry => (entry.Key, entry.Value)), diff --git a/src/Workspaces/Remote/ServiceHub/Services/DiagnosticAnalyzer/RemoteDiagnosticAnalyzerService.cs b/src/Workspaces/Remote/ServiceHub/Services/DiagnosticAnalyzer/RemoteDiagnosticAnalyzerService.cs index f714c306c32d0..66ceee5fb3fba 100644 --- a/src/Workspaces/Remote/ServiceHub/Services/DiagnosticAnalyzer/RemoteDiagnosticAnalyzerService.cs +++ b/src/Workspaces/Remote/ServiceHub/Services/DiagnosticAnalyzer/RemoteDiagnosticAnalyzerService.cs @@ -3,16 +3,13 @@ // See the LICENSE file in the project root for more information. using System.Collections.Immutable; -using System.Diagnostics; using System.Linq; using System.Threading; using System.Threading.Tasks; using Microsoft.CodeAnalysis.Collections; using Microsoft.CodeAnalysis.Diagnostics; using Microsoft.CodeAnalysis.Internal.Log; -using Microsoft.CodeAnalysis.Remote.Diagnostics; using Microsoft.CodeAnalysis.Shared.Extensions; -using Microsoft.CodeAnalysis.Telemetry; using Microsoft.CodeAnalysis.Text; using RoslynLogger = Microsoft.CodeAnalysis.Internal.Log.Logger; @@ -27,55 +24,6 @@ protected override IRemoteDiagnosticAnalyzerService CreateService(in ServiceCons => new RemoteDiagnosticAnalyzerService(arguments); } - private readonly DiagnosticAnalyzerInfoCache _analyzerInfoCache = new(); - - /// - /// Calculate diagnostics. 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 - /// - public async ValueTask CalculateDiagnosticsAsync(Checksum solutionChecksum, DiagnosticArguments arguments, CancellationToken cancellationToken) - { - // Complete RPC right away so the client can start reading from the stream. - // The fire-and forget task starts writing to the output stream and the client will read it until it reads all expected data. - - using (TelemetryLogging.LogBlockTimeAggregatedHistogram(FunctionId.PerformAnalysis_Summary, $"Total")) - using (RoslynLogger.LogBlock(FunctionId.CodeAnalysisService_CalculateDiagnosticsAsync, arguments.ProjectId.DebugName, cancellationToken)) - { - return await RunWithSolutionAsync( - solutionChecksum, - async solution => - { - var documentId = arguments.DocumentId; - var projectId = arguments.ProjectId; - var project = solution.GetRequiredProject(projectId); - var document = arguments.DocumentId != null - ? solution.GetTextDocument(arguments.DocumentId) ?? await solution.GetSourceGeneratedDocumentAsync(arguments.DocumentId, cancellationToken).ConfigureAwait(false) - : null; - var documentSpan = arguments.DocumentSpan; - var documentAnalysisKind = arguments.DocumentAnalysisKind; - var hostWorkspaceServices = this.GetWorkspace().Services; - - var result = await DiagnosticComputer.GetDiagnosticsAsync( - document, project, solutionChecksum, - documentSpan, - arguments.ProjectAnalyzerIds, arguments.HostAnalyzerIds, documentAnalysisKind, - _analyzerInfoCache, hostWorkspaceServices, - logPerformanceInfo: arguments.LogPerformanceInfo, - getTelemetryInfo: arguments.GetTelemetryInfo, - cancellationToken).ConfigureAwait(false); - - // save log for debugging - var diagnosticCount = result.Diagnostics.Sum( - entry => entry.diagnosticMap.Syntax.Length + entry.diagnosticMap.Semantic.Length + entry.diagnosticMap.NonLocal.Length + entry.diagnosticMap.Other.Length); - - Log(TraceEventType.Information, $"diagnostics: {diagnosticCount}, telemetry: {result.Telemetry.Length}"); - - return result; - }, cancellationToken).ConfigureAwait(false); - } - } - public ValueTask> ProduceProjectDiagnosticsAsync( Checksum solutionChecksum, ProjectId projectId, ImmutableHashSet analyzerIds, diff --git a/src/Workspaces/Core/Portable/Diagnostics/SerializableDiagnosticAnalysisResultMap.cs b/src/Workspaces/Remote/ServiceHub/Services/DiagnosticAnalyzer/SerializableDiagnosticAnalysisResultMap.cs similarity index 60% rename from src/Workspaces/Core/Portable/Diagnostics/SerializableDiagnosticAnalysisResultMap.cs rename to src/Workspaces/Remote/ServiceHub/Services/DiagnosticAnalyzer/SerializableDiagnosticAnalysisResultMap.cs index 2a9b210b2c906..9a6de6fa56e6d 100644 --- a/src/Workspaces/Core/Portable/Diagnostics/SerializableDiagnosticAnalysisResultMap.cs +++ b/src/Workspaces/Remote/ServiceHub/Services/DiagnosticAnalyzer/SerializableDiagnosticAnalysisResultMap.cs @@ -3,43 +3,28 @@ // See the LICENSE file in the project root for more information. using System.Collections.Immutable; -using System.Runtime.Serialization; using Microsoft.CodeAnalysis.Diagnostics.Telemetry; namespace Microsoft.CodeAnalysis.Diagnostics; -[DataContract] -internal readonly struct SerializableDiagnosticAnalysisResults( - ImmutableArray<(string analyzerId, SerializableDiagnosticMap diagnosticMap)> diagnostics, +internal readonly struct DiagnosticAnalysisResults( + ImmutableArray<(string analyzerId, DiagnosticMap diagnosticMap)> diagnostics, ImmutableArray<(string analyzerId, AnalyzerTelemetryInfo)> telemetry) { - public static readonly SerializableDiagnosticAnalysisResults Empty = new( - [], - []); + public static readonly DiagnosticAnalysisResults Empty = default; - [DataMember(Order = 0)] - internal readonly ImmutableArray<(string analyzerId, SerializableDiagnosticMap diagnosticMap)> Diagnostics = diagnostics; - - [DataMember(Order = 1)] - internal readonly ImmutableArray<(string analyzerId, AnalyzerTelemetryInfo telemetry)> Telemetry = telemetry; + internal readonly ImmutableArray<(string analyzerId, DiagnosticMap diagnosticMap)> Diagnostics => diagnostics.NullToEmpty(); + internal readonly ImmutableArray<(string analyzerId, AnalyzerTelemetryInfo telemetry)> Telemetry => telemetry.NullToEmpty(); } -[DataContract] -internal readonly struct SerializableDiagnosticMap( +internal readonly struct DiagnosticMap( ImmutableArray<(DocumentId, ImmutableArray)> syntax, ImmutableArray<(DocumentId, ImmutableArray)> semantic, ImmutableArray<(DocumentId, ImmutableArray)> nonLocal, ImmutableArray other) { - [DataMember(Order = 0)] public readonly ImmutableArray<(DocumentId, ImmutableArray)> Syntax = syntax; - - [DataMember(Order = 1)] public readonly ImmutableArray<(DocumentId, ImmutableArray)> Semantic = semantic; - - [DataMember(Order = 2)] public readonly ImmutableArray<(DocumentId, ImmutableArray)> NonLocal = nonLocal; - - [DataMember(Order = 3)] public readonly ImmutableArray Other = other; } diff --git a/src/Workspaces/Remote/ServiceHub/Services/ProcessTelemetry/RemoteProcessTelemetryService.PerformanceReporter.cs b/src/Workspaces/Remote/ServiceHub/Services/ProcessTelemetry/RemoteProcessTelemetryService.PerformanceReporter.cs index aa5db4e22ec1e..3f4230e85e358 100644 --- a/src/Workspaces/Remote/ServiceHub/Services/ProcessTelemetry/RemoteProcessTelemetryService.PerformanceReporter.cs +++ b/src/Workspaces/Remote/ServiceHub/Services/ProcessTelemetry/RemoteProcessTelemetryService.PerformanceReporter.cs @@ -6,12 +6,11 @@ using System.Collections.Generic; using System.Threading; using System.Threading.Tasks; +using Microsoft.CodeAnalysis.Diagnostics; using Microsoft.CodeAnalysis.Internal.Log; -using Microsoft.CodeAnalysis.Remote.Diagnostics; using Microsoft.CodeAnalysis.Shared.TestHooks; using Microsoft.CodeAnalysis.Threading; using Microsoft.VisualStudio.Telemetry; -using Roslyn.Utilities; using RoslynLogger = Microsoft.CodeAnalysis.Internal.Log.Logger; namespace Microsoft.CodeAnalysis.Remote; diff --git a/src/Workspaces/Remote/ServiceHub/Services/ProcessTelemetry/RemoteProcessTelemetryService.cs b/src/Workspaces/Remote/ServiceHub/Services/ProcessTelemetry/RemoteProcessTelemetryService.cs index c43060e2e1e2f..bb9112646ca6e 100644 --- a/src/Workspaces/Remote/ServiceHub/Services/ProcessTelemetry/RemoteProcessTelemetryService.cs +++ b/src/Workspaces/Remote/ServiceHub/Services/ProcessTelemetry/RemoteProcessTelemetryService.cs @@ -8,13 +8,12 @@ using System.Runtime.InteropServices; using System.Threading; using System.Threading.Tasks; +using Microsoft.CodeAnalysis.Diagnostics; using Microsoft.CodeAnalysis.ErrorReporting; using Microsoft.CodeAnalysis.Internal.Log; -using Microsoft.CodeAnalysis.Remote.Diagnostics; using Microsoft.CodeAnalysis.Telemetry; using Microsoft.VisualStudio.LanguageServices.Telemetry; using Microsoft.VisualStudio.Telemetry; -using Roslyn.Utilities; using RoslynLogger = Microsoft.CodeAnalysis.Internal.Log.Logger; namespace Microsoft.CodeAnalysis.Remote;