From a105ce769d7c56127270c9f3950d2171f80592cd Mon Sep 17 00:00:00 2001 From: Heejae Chang Date: Tue, 6 Mar 2018 14:15:16 -0800 Subject: [PATCH] Blame (#24043) * enable logAnalyzerExecutionTime on IDE so that we can start track analyzer perf * removed unnecessary ICodeAnalysisDiagnosticAnalyzerExecutor interface. it was added when OOP is first introduced to make sure VS.Next dll won't get loaded to VS process if OOP is not enabled. when it is enabled by default, rather than removing the interface, implementation just moved down to feature layer to reduce code churn. now, I am properly removing unnecessary abstraction. * take Executor out of test MEF composition * added IRemoteDiagnosticAnalyzerService interface * made initial version working. * added tests * add tracking for inproc only analyzers * pass in diagnostic analyzer service * added open file performance tracking as well. * added PII test * dont hash analyzerId when it is reported by internal user * added link to LOF wiki * made blame to track open files as well. * forgot to add return in if statement * reduce threshold to 100ms decide to start from lower threshold and then iterate rather than start from higher threshold * added a way to log real time perf data in local machine with explicit option which can be used to train formula later * addressed ivan's feedbacks * renamed to ExpensiveAnalyzerInfo * addressed PR feedbacks * more renames * addressed PR feedbacks. renamed as much as I can find. * listener can be null in unit test * addressed PR feedbacks --- .../ServiceTestExportProvider.cs | 3 +- .../Portable/Diagnostics/AnalyzerHelper.cs | 13 + ...cIncrementalAnalyzer.CompilationManager.cs | 2 +- .../DiagnosticIncrementalAnalyzer.Executor.cs | 6 +- ...lyzer.InProcOrRemoteHostAnalyzerRunner.cs} | 70 ++- ...IncrementalAnalyzer_IncrementalAnalyzer.cs | 58 +++ ...ICodeAnalysisDiagnosticAnalyzerExecutor.cs | 20 - .../IRemoteDiagnosticAnalyzerService.cs | 29 ++ .../Log/DiagnosticAnalyzerLogger.cs | 16 +- .../Log/DiagnosticLogAggregator.cs | 2 +- .../Test.Next/Remote/JsonConverterTests.cs | 8 + .../PerformanceTrackerServiceTests.cs | 191 ++++++++ ...alStudioDiagnosticAnalyzerExecutorTests.cs | 6 +- .../Test.Next/TestFiles/analyzer_input.csv | 54 +++ .../Test.Next/VisualStudioTest.Next.csproj | 5 +- .../Core/Portable/Log/FunctionId.cs | 5 +- .../Remote/RemoteHostClientExtensions.cs | 8 + .../Remote/WellKnownServiceHubServices.cs | 2 - .../Core/Diagnostics/DiagnosticComputer.cs | 12 + .../Diagnostics/IPerformanceTrackerService.cs | 39 ++ .../Core/Diagnostics/PerformanceQueue.cs | 227 +++++++++ .../Diagnostics/PerformanceTrackerService.cs | 447 ++++++++++++++++++ .../CodeAnalysisService_Diagnostics.cs | 28 +- .../RemoteHostService.PerformanceReporter.cs | 109 +++++ .../ServiceHub/Services/RemoteHostService.cs | 15 +- .../Shared/RoslynJsonConverter.RoslynOnly.cs | 52 +- ...oslynJsonConverter.SolutionIdConverters.cs | 2 +- .../ServiceHub/Shared/RoslynJsonConverter.cs | 4 +- .../ServiceHub/Telemetry/WatsonReporter.cs | 5 + 29 files changed, 1358 insertions(+), 80 deletions(-) rename src/Features/Core/Portable/Diagnostics/EngineV2/{DiagnosticAnalyzerExecutor.cs => DiagnosticIncrementalAnalyzer.InProcOrRemoteHostAnalyzerRunner.cs} (81%) delete mode 100644 src/Features/Core/Portable/Diagnostics/EngineV2/ICodeAnalysisDiagnosticAnalyzerExecutor.cs create mode 100644 src/Features/Core/Portable/Diagnostics/IRemoteDiagnosticAnalyzerService.cs create mode 100644 src/VisualStudio/Core/Test.Next/Services/PerformanceTrackerServiceTests.cs create mode 100644 src/VisualStudio/Core/Test.Next/TestFiles/analyzer_input.csv create mode 100644 src/Workspaces/Remote/Core/Diagnostics/IPerformanceTrackerService.cs create mode 100644 src/Workspaces/Remote/Core/Diagnostics/PerformanceQueue.cs create mode 100644 src/Workspaces/Remote/Core/Diagnostics/PerformanceTrackerService.cs create mode 100644 src/Workspaces/Remote/ServiceHub/Services/RemoteHostService.PerformanceReporter.cs diff --git a/src/EditorFeatures/TestUtilities/ServiceTestExportProvider.cs b/src/EditorFeatures/TestUtilities/ServiceTestExportProvider.cs index a02cef76bf0..6d26ac6ef2f 100644 --- a/src/EditorFeatures/TestUtilities/ServiceTestExportProvider.cs +++ b/src/EditorFeatures/TestUtilities/ServiceTestExportProvider.cs @@ -34,8 +34,7 @@ public static Type[] GetLanguageNeutralTypes() typeof(Microsoft.CodeAnalysis.Editor.Implementation.SmartIndent.SmartIndentProvider), typeof(Microsoft.CodeAnalysis.Editor.Implementation.ForegroundNotification.ForegroundNotificationService), typeof(Implementation.InlineRename.InlineRenameService), // Ensure that EditorFeatures.Wpf is included in the composition - typeof(IncrementalCaches.SymbolTreeInfoIncrementalAnalyzerProvider), - typeof(CodeAnalysis.Diagnostics.EngineV2.DiagnosticAnalyzerExecutor) + typeof(IncrementalCaches.SymbolTreeInfoIncrementalAnalyzerProvider) }; return MinimalTestExportProvider.GetLanguageNeutralTypes().Concat(types).Distinct().ToArray(); diff --git a/src/Features/Core/Portable/Diagnostics/AnalyzerHelper.cs b/src/Features/Core/Portable/Diagnostics/AnalyzerHelper.cs index 68e757c5d19..de4d8eca38e 100644 --- a/src/Features/Core/Portable/Diagnostics/AnalyzerHelper.cs +++ b/src/Features/Core/Portable/Diagnostics/AnalyzerHelper.cs @@ -10,6 +10,9 @@ using System.Threading; using System.Threading.Tasks; using System.Collections.Generic; +using Microsoft.CodeAnalysis.Diagnostics.Log; +using Microsoft.CodeAnalysis.Diagnostics.Telemetry; +using System.Collections.Immutable; namespace Microsoft.CodeAnalysis.Diagnostics { @@ -294,5 +297,15 @@ public static void AppendAnalyzerMap(this Dictionary analyzerMap[analyzer.GetAnalyzerId()] = analyzer; } } + + public static IEnumerable ToAnalyzerPerformanceInfo(this IDictionary analysisResult, IDiagnosticAnalyzerService serviceOpt = null) + { + return Convert(analysisResult.Select(kv => (kv.Key, kv.Value.ExecutionTime)), serviceOpt); + } + + private static IEnumerable Convert(IEnumerable<(DiagnosticAnalyzer analyzer, TimeSpan timeSpan)> analyzerPerf, IDiagnosticAnalyzerService serviceOpt = null) + { + return analyzerPerf.Select(kv => new AnalyzerPerformanceInfo(kv.analyzer.GetAnalyzerId(), DiagnosticAnalyzerLogger.AllowsTelemetry(kv.analyzer, serviceOpt), kv.timeSpan)); + } } } diff --git a/src/Features/Core/Portable/Diagnostics/EngineV2/DiagnosticIncrementalAnalyzer.CompilationManager.cs b/src/Features/Core/Portable/Diagnostics/EngineV2/DiagnosticIncrementalAnalyzer.CompilationManager.cs index a446155b3d4..4faeb20f9c9 100644 --- a/src/Features/Core/Portable/Diagnostics/EngineV2/DiagnosticIncrementalAnalyzer.CompilationManager.cs +++ b/src/Features/Core/Portable/Diagnostics/EngineV2/DiagnosticIncrementalAnalyzer.CompilationManager.cs @@ -82,7 +82,7 @@ public Task CreateAnalyzerDriverAsync(Project project, // Create driver that holds onto compilation and associated analyzers return CreateAnalyzerDriver( - project, compilation, analyzers, logAnalyzerExecutionTime: false, reportSuppressedDiagnostics: includeSuppressedDiagnostics); + project, compilation, analyzers, logAnalyzerExecutionTime: true, reportSuppressedDiagnostics: includeSuppressedDiagnostics); } private CompilationWithAnalyzers CreateAnalyzerDriver( diff --git a/src/Features/Core/Portable/Diagnostics/EngineV2/DiagnosticIncrementalAnalyzer.Executor.cs b/src/Features/Core/Portable/Diagnostics/EngineV2/DiagnosticIncrementalAnalyzer.Executor.cs index 2ecff8e2d99..266062d577c 100644 --- a/src/Features/Core/Portable/Diagnostics/EngineV2/DiagnosticIncrementalAnalyzer.Executor.cs +++ b/src/Features/Core/Portable/Diagnostics/EngineV2/DiagnosticIncrementalAnalyzer.Executor.cs @@ -9,7 +9,6 @@ using Microsoft.CodeAnalysis.Diagnostics.Log; using Microsoft.CodeAnalysis.Diagnostics.Telemetry; using Microsoft.CodeAnalysis.ErrorReporting; -using Microsoft.CodeAnalysis.Execution; using Microsoft.CodeAnalysis.Internal.Log; using Microsoft.CodeAnalysis.Shared.Options; using Microsoft.CodeAnalysis.Text; @@ -27,10 +26,12 @@ internal partial class DiagnosticIncrementalAnalyzer private class Executor { private readonly DiagnosticIncrementalAnalyzer _owner; + private readonly InProcOrRemoteHostAnalyzerRunner _diagnosticAnalyzerRunner; public Executor(DiagnosticIncrementalAnalyzer owner) { _owner = owner; + _diagnosticAnalyzerRunner = new InProcOrRemoteHostAnalyzerRunner(_owner.Owner, _owner.HostDiagnosticUpdateSource); } public IEnumerable ConvertToLocalDiagnostics(Document targetDocument, IEnumerable diagnostics, TextSpan? span = null) @@ -578,8 +579,7 @@ private IEnumerable ConvertToLocalDiagnosticsWithoutCompilation( ImmutableDictionary.Empty); } - var executor = project.Solution.Workspace.Services.GetService(); - return await executor.AnalyzeAsync(analyzerDriver, project, forcedAnalysis, cancellationToken).ConfigureAwait(false); + return await _diagnosticAnalyzerRunner.AnalyzeAsync(analyzerDriver, project, forcedAnalysis, cancellationToken).ConfigureAwait(false); } private IEnumerable ConvertToLocalDiagnosticsWithCompilation(Document targetDocument, IEnumerable diagnostics, TextSpan? span = null) diff --git a/src/Features/Core/Portable/Diagnostics/EngineV2/DiagnosticAnalyzerExecutor.cs b/src/Features/Core/Portable/Diagnostics/EngineV2/DiagnosticIncrementalAnalyzer.InProcOrRemoteHostAnalyzerRunner.cs similarity index 81% rename from src/Features/Core/Portable/Diagnostics/EngineV2/DiagnosticAnalyzerExecutor.cs rename to src/Features/Core/Portable/Diagnostics/EngineV2/DiagnosticIncrementalAnalyzer.InProcOrRemoteHostAnalyzerRunner.cs index 47b9cd9eaae..c98775addb9 100644 --- a/src/Features/Core/Portable/Diagnostics/EngineV2/DiagnosticAnalyzerExecutor.cs +++ b/src/Features/Core/Portable/Diagnostics/EngineV2/DiagnosticIncrementalAnalyzer.InProcOrRemoteHostAnalyzerRunner.cs @@ -4,49 +4,36 @@ using System.Collections.Concurrent; using System.Collections.Generic; using System.Collections.Immutable; -using System.Composition; using System.Diagnostics; using System.IO; using System.Linq; using System.Threading; using System.Threading.Tasks; using Microsoft.CodeAnalysis.Diagnostics.Telemetry; +using Microsoft.CodeAnalysis.ErrorReporting; using Microsoft.CodeAnalysis.Execution; -using Microsoft.CodeAnalysis.Host; -using Microsoft.CodeAnalysis.Host.Mef; using Microsoft.CodeAnalysis.Options; using Microsoft.CodeAnalysis.Remote; +using Microsoft.CodeAnalysis.Shared.TestHooks; using Microsoft.CodeAnalysis.Workspaces.Diagnostics; using Roslyn.Utilities; namespace Microsoft.CodeAnalysis.Diagnostics.EngineV2 { - [ExportWorkspaceServiceFactory(typeof(ICodeAnalysisDiagnosticAnalyzerExecutor)), Shared] - internal class DiagnosticAnalyzerExecutor : IWorkspaceServiceFactory + internal partial class DiagnosticIncrementalAnalyzer { - private readonly AbstractHostDiagnosticUpdateSource _hostDiagnosticUpdateSourceOpt; - - [ImportingConstructor] - public DiagnosticAnalyzerExecutor([Import(AllowDefault = true)]AbstractHostDiagnosticUpdateSource hostDiagnosticUpdateSource) - { - // hostDiagnosticUpdateSource can be null in unit test - _hostDiagnosticUpdateSourceOpt = hostDiagnosticUpdateSource; - } - - public IWorkspaceService CreateService(HostWorkspaceServices workspaceServices) - { - return new AnalyzerExecutor(_hostDiagnosticUpdateSourceOpt); - } - - private class AnalyzerExecutor : ICodeAnalysisDiagnosticAnalyzerExecutor + // internal for testing + internal class InProcOrRemoteHostAnalyzerRunner { + private readonly DiagnosticAnalyzerService _owner; private readonly AbstractHostDiagnosticUpdateSource _hostDiagnosticUpdateSourceOpt; // TODO: this should be removed once we move options down to compiler layer private readonly ConcurrentDictionary> _lastOptionSetPerLanguage; - public AnalyzerExecutor(AbstractHostDiagnosticUpdateSource hostDiagnosticUpdateSource) + public InProcOrRemoteHostAnalyzerRunner(DiagnosticAnalyzerService owner, AbstractHostDiagnosticUpdateSource hostDiagnosticUpdateSource) { + _owner = owner; _hostDiagnosticUpdateSourceOpt = hostDiagnosticUpdateSource; // currently option is a bit wierd since it is not part of snapshot and @@ -80,7 +67,7 @@ public AnalyzerExecutor(AbstractHostDiagnosticUpdateSource hostDiagnosticUpdateS } // due to OpenFileOnly analyzer, we need to run inproc as well for such analyzers - var inProcResultTask = AnalyzeInProcAsync(CreateAnalyzerDriver(analyzerDriver, a => a.IsOpenFileOnly(project.Solution.Workspace)), project, cancellationToken); + var inProcResultTask = AnalyzeInProcAsync(CreateAnalyzerDriver(analyzerDriver, a => a.IsOpenFileOnly(project.Solution.Workspace)), project, remoteHostClient, cancellationToken); var outOfProcResultTask = AnalyzeOutOfProcAsync(remoteHostClient, analyzerDriver, project, forcedAnalysis, cancellationToken); // run them concurrently in vs and remote host @@ -95,8 +82,14 @@ public AnalyzerExecutor(AbstractHostDiagnosticUpdateSource hostDiagnosticUpdateS inProcResultTask.Result.TelemetryInfo.AddRange(outOfProcResultTask.Result.TelemetryInfo)); } - private async Task> AnalyzeInProcAsync( + private Task> AnalyzeInProcAsync( CompilationWithAnalyzers analyzerDriver, Project project, CancellationToken cancellationToken) + { + return AnalyzeInProcAsync(analyzerDriver, project, client: null, cancellationToken); + } + + private async Task> AnalyzeInProcAsync( + CompilationWithAnalyzers analyzerDriver, Project project, RemoteHostClient client, CancellationToken cancellationToken) { if (analyzerDriver == null || analyzerDriver.Analyzers.Length == 0) @@ -110,12 +103,41 @@ public AnalyzerExecutor(AbstractHostDiagnosticUpdateSource hostDiagnosticUpdateS // 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 => new DiagnosticAnalysisResult(kv.Value)), analysisResult.AnalyzerTelemetryInfo); } + private async Task FireAndForgetReportAnalyzerPerformanceAsync(Project project, RemoteHostClient client, AnalysisResult analysisResult, CancellationToken cancellationToken) + { + if (client == null) + { + return; + } + + try + { + await client.TryRunCodeAnalysisRemoteAsync( + nameof(IRemoteDiagnosticAnalyzerService.ReportAnalyzerPerformance), + new object[] + { + analysisResult.AnalyzerTelemetryInfo.ToAnalyzerPerformanceInfo(_owner), + // +1 for project itself + project.DocumentIds.Count + 1 + }, + cancellationToken).ConfigureAwait(false); + } + catch (Exception ex) when (FatalError.ReportWithoutCrashUnlessCanceled(ex)) + { + // ignore all, this is fire and forget method + } + } + private async Task> AnalyzeOutOfProcAsync( RemoteHostClient client, CompilationWithAnalyzers analyzerDriver, Project project, bool forcedAnalysis, CancellationToken cancellationToken) { @@ -149,7 +171,7 @@ public AnalyzerExecutor(AbstractHostDiagnosticUpdateSource hostDiagnosticUpdateS session.AddAdditionalAssets(optionAsset); var result = await session.InvokeAsync( - WellKnownServiceHubServices.CodeAnalysisService_CalculateDiagnosticsAsync, + nameof(IRemoteDiagnosticAnalyzerService.CalculateDiagnosticsAsync), new object[] { argument }, (s, c) => GetCompilerAnalysisResultAsync(s, analyzerMap, project, c), cancellationToken).ConfigureAwait(false); diff --git a/src/Features/Core/Portable/Diagnostics/EngineV2/DiagnosticIncrementalAnalyzer_IncrementalAnalyzer.cs b/src/Features/Core/Portable/Diagnostics/EngineV2/DiagnosticIncrementalAnalyzer_IncrementalAnalyzer.cs index b6d1fb8dfb9..93eab43d0b0 100644 --- a/src/Features/Core/Portable/Diagnostics/EngineV2/DiagnosticIncrementalAnalyzer_IncrementalAnalyzer.cs +++ b/src/Features/Core/Portable/Diagnostics/EngineV2/DiagnosticIncrementalAnalyzer_IncrementalAnalyzer.cs @@ -6,10 +6,13 @@ using System.Linq; using System.Threading; using System.Threading.Tasks; +using Microsoft.CodeAnalysis.Diagnostics.Telemetry; using Microsoft.CodeAnalysis.ErrorReporting; using Microsoft.CodeAnalysis.Internal.Log; +using Microsoft.CodeAnalysis.Remote; using Microsoft.CodeAnalysis.Shared.Extensions; using Microsoft.CodeAnalysis.Shared.Options; +using Microsoft.CodeAnalysis.Shared.TestHooks; using Microsoft.CodeAnalysis.SolutionCrawler; using Microsoft.CodeAnalysis.Workspaces.Diagnostics; using Roslyn.Utilities; @@ -59,6 +62,9 @@ private async Task AnalyzeDocumentForKindAsync(Document document, AnalysisKind k RaiseDocumentDiagnosticsIfNeeded(document, stateSet, kind, result.OldItems, result.Items); } + + var asyncToken = Owner.Listener.BeginAsyncOperation(nameof(AnalyzeDocumentForKindAsync)); + var _ = ReportAnalyzerPerformanceAsync(document, analyzerDriverOpt, cancellationToken).CompletesAsyncOperation(asyncToken); } catch (Exception e) when (FatalError.ReportUnlessCanceled(e)) { @@ -429,5 +435,57 @@ private void RaiseProjectDiagnosticsRemoved(StateSet stateSet, ProjectId project RaiseDiagnosticsRemoved(projectId, nullSolution, stateSet, raiseEvents); } + + private async Task ReportAnalyzerPerformanceAsync(Document document, CompilationWithAnalyzers analyzerDriverOpt, CancellationToken cancellationToken) + { + try + { + if (analyzerDriverOpt == null) + { + return; + } + + var client = await document.Project.Solution.Workspace.TryGetRemoteHostClientAsync(cancellationToken).ConfigureAwait(false); + if (client == null) + { + // no remote support + return; + } + + cancellationToken.ThrowIfCancellationRequested(); + + using (var pooledObject = SharedPools.Default>().GetPooledObject()) + { + var containsData = false; + foreach (var analyzer in analyzerDriverOpt.Analyzers) + { + var telemetryInfo = await analyzerDriverOpt.GetAnalyzerTelemetryInfoAsync(analyzer, cancellationToken).ConfigureAwait(false); + if (!containsData && telemetryInfo.ExecutionTime.Ticks > 0) + { + // this is unfortunate tweak due to how GetAnalyzerTelemetryInfoAsync works when analyzers are asked + // one by one rather than in bulk. + containsData = true; + } + + pooledObject.Object.Add(analyzer, telemetryInfo); + } + + if (!containsData) + { + // looks like there is no new data from driver. skip reporting. + return; + } + + await client.TryRunCodeAnalysisRemoteAsync( + nameof(IRemoteDiagnosticAnalyzerService.ReportAnalyzerPerformance), + new object[] { pooledObject.Object.ToAnalyzerPerformanceInfo(Owner), /* unit count */ 1 }, + cancellationToken).ConfigureAwait(false); + } + } + catch (Exception ex) when (FatalError.ReportWithoutCrashUnlessCanceled(ex)) + { + // this is fire and forget method + } + } } } diff --git a/src/Features/Core/Portable/Diagnostics/EngineV2/ICodeAnalysisDiagnosticAnalyzerExecutor.cs b/src/Features/Core/Portable/Diagnostics/EngineV2/ICodeAnalysisDiagnosticAnalyzerExecutor.cs deleted file mode 100644 index 78960f8ebf7..00000000000 --- a/src/Features/Core/Portable/Diagnostics/EngineV2/ICodeAnalysisDiagnosticAnalyzerExecutor.cs +++ /dev/null @@ -1,20 +0,0 @@ -// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System.Threading; -using System.Threading.Tasks; -using Microsoft.CodeAnalysis.Host; -using Microsoft.CodeAnalysis.Workspaces.Diagnostics; - -namespace Microsoft.CodeAnalysis.Diagnostics.EngineV2 -{ - /// - /// Interface to run DiagnosticAnalyzers. Implementation of this interface should be - /// able to run analyzers that can run in command line (Host agnostic DiagnosticAnalyzers) - /// - /// How and where analyzers run depends on the implementation of this interface - /// - internal interface ICodeAnalysisDiagnosticAnalyzerExecutor : IWorkspaceService - { - Task> AnalyzeAsync(CompilationWithAnalyzers analyzerDriver, Project project, bool forcedAnalysis, CancellationToken cancellationToken); - } -} diff --git a/src/Features/Core/Portable/Diagnostics/IRemoteDiagnosticAnalyzerService.cs b/src/Features/Core/Portable/Diagnostics/IRemoteDiagnosticAnalyzerService.cs new file mode 100644 index 00000000000..a0984aa3dd5 --- /dev/null +++ b/src/Features/Core/Portable/Diagnostics/IRemoteDiagnosticAnalyzerService.cs @@ -0,0 +1,29 @@ +// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; +using System.Collections.Generic; +using System.Threading; +using System.Threading.Tasks; + +namespace Microsoft.CodeAnalysis.Diagnostics +{ + interface IRemoteDiagnosticAnalyzerService + { + Task CalculateDiagnosticsAsync(DiagnosticArguments arguments, string streamName, CancellationToken cancellationToken); + void ReportAnalyzerPerformance(List snapshot, int unitCount, CancellationToken cancellationToken); + } + + internal struct AnalyzerPerformanceInfo + { + public readonly string AnalyzerId; + public readonly bool BuiltIn; + public readonly TimeSpan TimeSpan; + + public AnalyzerPerformanceInfo(string analyzerid, bool builtIn, TimeSpan timeSpan) + { + AnalyzerId = analyzerid; + BuiltIn = builtIn; + TimeSpan = timeSpan; + } + } +} diff --git a/src/Features/Core/Portable/Diagnostics/Log/DiagnosticAnalyzerLogger.cs b/src/Features/Core/Portable/Diagnostics/Log/DiagnosticAnalyzerLogger.cs index df9a19ca8d9..63e47274a74 100644 --- a/src/Features/Core/Portable/Diagnostics/Log/DiagnosticAnalyzerLogger.cs +++ b/src/Features/Core/Portable/Diagnostics/Log/DiagnosticAnalyzerLogger.cs @@ -52,7 +52,7 @@ public static void LogAnalyzerCrashCount(DiagnosticAnalyzer analyzer, Exception } // TODO: once we create description manager, pass that into here. - bool telemetry = DiagnosticAnalyzerLogger.AllowsTelemetry(null, analyzer, projectId); + bool telemetry = DiagnosticAnalyzerLogger.AllowsTelemetry(analyzer, null); var tuple = ValueTuple.Create(telemetry, analyzer.GetType(), ex.GetType()); logAggregator.IncreaseCount(tuple); } @@ -137,28 +137,34 @@ public static void LogAnalyzerTypeCountSummary(int correlationId, DiagnosticLogA } } - public static bool AllowsTelemetry(DiagnosticAnalyzerService service, DiagnosticAnalyzer analyzer, ProjectId projectIdOpt) + public static bool AllowsTelemetry(DiagnosticAnalyzer analyzer, IDiagnosticAnalyzerService serviceOpt = null) { if (s_telemetryCache.TryGetValue(analyzer, out var value)) { return value.Value; } - return s_telemetryCache.GetValue(analyzer, a => new StrongBox(CheckTelemetry(service, a))).Value; + return s_telemetryCache.GetValue(analyzer, a => new StrongBox(CheckTelemetry(a, serviceOpt))).Value; } - private static bool CheckTelemetry(DiagnosticAnalyzerService service, DiagnosticAnalyzer analyzer) + private static bool CheckTelemetry(DiagnosticAnalyzer analyzer, IDiagnosticAnalyzerService serviceOpt) { if (analyzer.IsCompilerAnalyzer()) { return true; } + if (analyzer is IBuiltInAnalyzer) + { + // if it is builtin analyzer, telemetry is always allowed + return true; + } + ImmutableArray diagDescriptors; try { // SupportedDiagnostics is potentially user code and can throw an exception. - diagDescriptors = service != null ? service.GetDiagnosticDescriptors(analyzer) : analyzer.SupportedDiagnostics; + diagDescriptors = serviceOpt != null ? serviceOpt.GetDiagnosticDescriptors(analyzer) : analyzer.SupportedDiagnostics; } catch (Exception) { diff --git a/src/Features/Core/Portable/Diagnostics/Log/DiagnosticLogAggregator.cs b/src/Features/Core/Portable/Diagnostics/Log/DiagnosticLogAggregator.cs index 42fc962882a..097de53cf96 100644 --- a/src/Features/Core/Portable/Diagnostics/Log/DiagnosticLogAggregator.cs +++ b/src/Features/Core/Portable/Diagnostics/Log/DiagnosticLogAggregator.cs @@ -41,7 +41,7 @@ public DiagnosticLogAggregator(DiagnosticAnalyzerService owner) public void UpdateAnalyzerTypeCount(DiagnosticAnalyzer analyzer, AnalyzerTelemetryInfo analyzerTelemetryInfo, Project projectOpt) { - var telemetry = DiagnosticAnalyzerLogger.AllowsTelemetry(_owner, analyzer, projectOpt?.Id); + var telemetry = DiagnosticAnalyzerLogger.AllowsTelemetry(analyzer, _owner); ImmutableInterlocked.AddOrUpdate( ref _analyzerInfoMap, diff --git a/src/VisualStudio/Core/Test.Next/Remote/JsonConverterTests.cs b/src/VisualStudio/Core/Test.Next/Remote/JsonConverterTests.cs index faab8e3a48a..0d19753f4f2 100644 --- a/src/VisualStudio/Core/Test.Next/Remote/JsonConverterTests.cs +++ b/src/VisualStudio/Core/Test.Next/Remote/JsonConverterTests.cs @@ -139,6 +139,14 @@ public void TestPinnedSolutionInfo() }); } + [Fact, Trait(Traits.Feature, Traits.Features.RemoteHost)] + public void TestAnalyzerPerformanceInfo() + { + VerifyJsonSerialization( + new AnalyzerPerformanceInfo("testAnalyzer", builtIn: false, timeSpan: TimeSpan.FromMilliseconds(12345)), + (x, y) => (x.AnalyzerId == y.AnalyzerId && x.BuiltIn == y.BuiltIn && x.TimeSpan == y.TimeSpan) ? 0 : 1); + } + private static void VerifyJsonSerialization(T value, Comparison equality = null) { var serializer = new JsonSerializer(); diff --git a/src/VisualStudio/Core/Test.Next/Services/PerformanceTrackerServiceTests.cs b/src/VisualStudio/Core/Test.Next/Services/PerformanceTrackerServiceTests.cs new file mode 100644 index 00000000000..9f470229bf0 --- /dev/null +++ b/src/VisualStudio/Core/Test.Next/Services/PerformanceTrackerServiceTests.cs @@ -0,0 +1,191 @@ +// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Reflection; +using Microsoft.CodeAnalysis.Diagnostics; +using Microsoft.CodeAnalysis.Remote.Diagnostics; +using Xunit; + +namespace Roslyn.VisualStudio.Next.UnitTests.Services +{ + public class PerformanceTrackerServiceTests + { + [Fact] + public void TestTooFewSamples() + { + // minimum sample is 100 + var badAnalyzers = GetBadAnalyzers(@"TestFiles\analyzer_input.csv", to: 80); + + Assert.Empty(badAnalyzers); + } + + [Fact] + public void TestTracking() + { + var badAnalyzers = GetBadAnalyzers(@"TestFiles\analyzer_input.csv", to: 200); + + VerifyBadAnalyzer(badAnalyzers[0], "CSharpRemoveUnnecessaryCastDiagnosticAnalyzer", 101.244432561581, 54.48, 21.8163001442628); + VerifyBadAnalyzer(badAnalyzers[1], "CSharpInlineDeclarationDiagnosticAnalyzer", 49.9389715502954, 26.6686092715232, 9.2987133054884); + VerifyBadAnalyzer(badAnalyzers[2], "VisualBasicRemoveUnnecessaryCastDiagnosticAnalyzer", 42.0967360557792, 23.277619047619, 7.25464266261805); + } + + [Fact] + public void TestTrackingMaxSample() + { + var badAnalyzers = GetBadAnalyzers(@"TestFiles\analyzer_input.csv", to: 300); + + VerifyBadAnalyzer(badAnalyzers[0], "CSharpRemoveUnnecessaryCastDiagnosticAnalyzer", 85.6039521236341, 58.4542358078603, 18.4245217226717); + VerifyBadAnalyzer(badAnalyzers[1], "VisualBasic.UseAutoProperty.UseAutoPropertyAnalyzer", 45.0918385052674, 29.0622535211268, 9.13728667060397); + VerifyBadAnalyzer(badAnalyzers[2], "CSharpInlineDeclarationDiagnosticAnalyzer", 42.2014208750466, 28.7935371179039, 7.99261581900397); + } + + [Fact] + public void TestTrackingRolling() + { + // data starting to rolling at 300 data points + var badAnalyzers = GetBadAnalyzers(@"TestFiles\analyzer_input.csv", to: 400); + + VerifyBadAnalyzer(badAnalyzers[0], "CSharpRemoveUnnecessaryCastDiagnosticAnalyzer", 76.2748443491852, 51.1698695652174, 17.3819563479479); + VerifyBadAnalyzer(badAnalyzers[1], "VisualBasic.UseAutoProperty.UseAutoPropertyAnalyzer", 43.5700167914005, 29.2597857142857, 9.21213873850298); + VerifyBadAnalyzer(badAnalyzers[2], "InlineDeclaration.CSharpInlineDeclarationDiagnosticAnalyzer", 36.4336594793033, 23.9764782608696, 7.43956680199015); + } + + [Fact] + public void TestBadAnalyzerInfoPII() + { + var badAnalyzer1 = new ExpensiveAnalyzerInfo(true, "test", 0.1, 0.1, 0.1); + Assert.True(badAnalyzer1.PIISafeAnalyzerId == badAnalyzer1.AnalyzerId); + Assert.True(badAnalyzer1.PIISafeAnalyzerId == "test"); + + var badAnalyzer2 = new ExpensiveAnalyzerInfo(false, "test", 0.1, 0.1, 0.1); + Assert.True(badAnalyzer2.PIISafeAnalyzerId == badAnalyzer2.AnalyzerIdHash); + Assert.True(badAnalyzer2.PIISafeAnalyzerId == "test".GetHashCode().ToString()); + } + + private void VerifyBadAnalyzer(ExpensiveAnalyzerInfo analyzer, string analyzerId, double lof, double mean, double stddev) + { + Assert.True(analyzer.PIISafeAnalyzerId.IndexOf(analyzerId, StringComparison.OrdinalIgnoreCase) >= 0); + Assert.Equal(analyzer.LocalOutlierFactor, lof, precision: 4); + Assert.Equal(analyzer.Average, mean, precision: 4); + Assert.Equal(analyzer.AdjustedStandardDeviation, stddev, precision: 4); + } + + private List GetBadAnalyzers(string testFileName, int to) + { + var testFile = ReadTestFile(testFileName); + + var (matrix, dataCount) = CreateMatrix(testFile); + + to = Math.Min(to, dataCount); + + var service = new PerformanceTrackerService(minLOFValue: 0, averageThreshold: 0, stddevThreshold: 0); + + for (var i = 0; i < to; i++) + { + service.AddSnapshot(CreateSnapshots(matrix, i), unitCount: 100); + } + + var badAnalyzerInfo = new List(); + service.GenerateReport(badAnalyzerInfo); + + return badAnalyzerInfo; + } + + private IEnumerable CreateSnapshots(Dictionary matrix, int index) + { + foreach (var kv in matrix) + { + var timeSpan = kv.Value[index]; + if (double.IsNaN(timeSpan)) + { + continue; + } + + yield return new AnalyzerPerformanceInfo(kv.Key, true, TimeSpan.FromMilliseconds(timeSpan)); + } + } + + private (Dictionary matrix, int dataCount) CreateMatrix(string testFile) + { + var matrix = new Dictionary(); + + var lines = testFile.Split('\n'); + var expectedDataCount = GetExpectedDataCount(lines[0]); + + for (var i = 1; i < lines.Length; i++) + { + if (lines[i].Trim().Length == 0) + { + continue; + } + + var data = SkipAnalyzerId(lines[i]).Split(','); + Assert.Equal(data.Length, expectedDataCount); + + var analyzerId = GetAnalyzerId(lines[i]); + + var timeSpans = new double[expectedDataCount]; + for (var j = 0; j < data.Length; j++) + { + double result; + if (!double.TryParse(data[j], out result)) + { + // no data for this analyzer for this particular run + result = double.NaN; + } + + timeSpans[j] = result; + } + + matrix[analyzerId] = timeSpans; + } + + return (matrix, expectedDataCount); + } + + private string GetAnalyzerId(string line) + { + return line.Substring(1, line.LastIndexOf('"') - 1); + } + + private int GetExpectedDataCount(string header) + { + var data = header.Split(','); + return data.Length - 1; + } + + private string SkipAnalyzerId(string line) + { + return line.Substring(line.LastIndexOf('"') + 2); + } + + private string ReadTestFile(string name) + { + var assembly = typeof(PerformanceTrackerServiceTests).Assembly; + var resourceName = GetResourceName(assembly, name); + + using (var stream = assembly.GetManifestResourceStream(resourceName)) + { + if (stream == null) + { + throw new InvalidOperationException($"Resource '{resourceName}' not found in {assembly.FullName}."); + } + + using (var reader = new StreamReader(stream)) + { + return reader.ReadToEnd(); + } + } + } + + private static string GetResourceName(Assembly assembly, string name) + { + var convert = name.Replace(@"\", "."); + + return assembly.GetManifestResourceNames().Where(n => n.EndsWith(convert, StringComparison.OrdinalIgnoreCase)).First(); + } + } +} diff --git a/src/VisualStudio/Core/Test.Next/Services/VisualStudioDiagnosticAnalyzerExecutorTests.cs b/src/VisualStudio/Core/Test.Next/Services/VisualStudioDiagnosticAnalyzerExecutorTests.cs index d420ce38498..7dc0d4d103d 100644 --- a/src/VisualStudio/Core/Test.Next/Services/VisualStudioDiagnosticAnalyzerExecutorTests.cs +++ b/src/VisualStudio/Core/Test.Next/Services/VisualStudioDiagnosticAnalyzerExecutorTests.cs @@ -156,7 +156,7 @@ void Method() // run analysis var project = workspace.CurrentSolution.Projects.First(); - var executor = (ICodeAnalysisDiagnosticAnalyzerExecutor)new DiagnosticAnalyzerExecutor(new MyUpdateSource(workspace)).CreateService(workspace.Services); + var executor = new DiagnosticIncrementalAnalyzer.InProcOrRemoteHostAnalyzerRunner(owner: null, hostDiagnosticUpdateSource: new MyUpdateSource(workspace)); var analyzerDriver = (await project.GetCompilationAsync()).WithAnalyzers( analyzerReference.GetAnalyzers(project.Language).Where(a => a.GetType() == analyzerType).ToImmutableArray(), new WorkspaceAnalyzerOptions(project.AnalyzerOptions, project.Solution.Options, project.Solution)); @@ -202,7 +202,7 @@ void Method() // run analysis var project = workspace.CurrentSolution.Projects.First().AddAnalyzerReference(analyzerReference); - var executor = (ICodeAnalysisDiagnosticAnalyzerExecutor)new DiagnosticAnalyzerExecutor(new MyUpdateSource(workspace)).CreateService(workspace.Services); + var executor = new DiagnosticIncrementalAnalyzer.InProcOrRemoteHostAnalyzerRunner(owner: null, hostDiagnosticUpdateSource: new MyUpdateSource(workspace)); var analyzerDriver = (await project.GetCompilationAsync()).WithAnalyzers( analyzerReference.GetAnalyzers(project.Language).Where(a => a.GetType() == analyzerType).ToImmutableArray(), new WorkspaceAnalyzerOptions(project.AnalyzerOptions, project.Solution.Options, project.Solution)); @@ -219,7 +219,7 @@ void Method() private static async Task AnalyzeAsync(TestWorkspace workspace, ProjectId projectId, Type analyzerType, CancellationToken cancellationToken = default(CancellationToken)) { - var executor = (ICodeAnalysisDiagnosticAnalyzerExecutor)new DiagnosticAnalyzerExecutor(new MyUpdateSource(workspace)).CreateService(workspace.Services); + var executor = new DiagnosticIncrementalAnalyzer.InProcOrRemoteHostAnalyzerRunner(owner: null, hostDiagnosticUpdateSource: new MyUpdateSource(workspace)); var analyzerReference = new AnalyzerFileReference(analyzerType.Assembly.Location, new TestAnalyzerAssemblyLoader()); var project = workspace.CurrentSolution.GetProject(projectId).AddAnalyzerReference(analyzerReference); diff --git a/src/VisualStudio/Core/Test.Next/TestFiles/analyzer_input.csv b/src/VisualStudio/Core/Test.Next/TestFiles/analyzer_input.csv new file mode 100644 index 00000000000..4cf5b114ea6 --- /dev/null +++ b/src/VisualStudio/Core/Test.Next/TestFiles/analyzer_input.csv @@ -0,0 +1,54 @@ +Analyzer,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,163,164,165,166,167,173,174,175,176,177,178,179,180,181,182,183,184,185,191,192,227,228,229,230,231,232,233,234,235,236,237,238,239,240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,302,303,304,305,306,307,321,322,323,324,325,326,327,328,329,330,331,332,333,334,335,336,337,338,339,340,341,342,343,344,345,346,347,348,349,350,351,352,353,354,355,356,357,358,359,360,361,362,363,364,365,366,367,368,369,370,371,372,373,374,375,376,377,378,379,380,381,382,383,384,385,386,387,388,389,390,391,392,393,394,395,396,397,398,399,400 +"Microsoft.ApiDesignGuidelines.Analyzers.CancellationTokenParametersMustComeLastAnalyzer,Microsoft.CodeQuality.Analyzers,Version=2.0.0.0,Culture=neutral,PublicKeyToken=31bf3856ad364e35",,,,,,,,7.0,3.0,0.0,0.0,0.0,3.0,,0.0,22.0,53.0,26.0,115.0,2.0,24.0,62.0,20.0,48.0,,7.0,,,0.0,6.0,0.0,0.0,0.0,0.0,,119.0,,5.0,,44.0,,0.0,4.0,0.0,,2.0,,0.0,0.0,1.0,7.0,66.0,196.0,20.0,8.0,80.0,46.0,52.0,0.0,8.0,0.0,0.0,0.0,2.0,10.0,0.0,256.0,0.0,1.0,2.0,9.0,0.0,0.0,0.0,3.0,3.0,,,,,,,,0.0,0.0,16.0,1.0,3.0,7.0,0.0,1.0,,0.0,0.0,,0.0,0.0,20.0,,,,,,,,,,,,,,,0.0,0.0,2.0,0.0,3.0,0.0,0.0,1.0,0.0,2.0,0.0,1.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,,,,,,,,,,,,,,,,,0.0,,,,,,,,,,,,,,,,,,,,,,,12.0,0.0,124.0,9.0,2.0,,86.0,1.0,,25.0,0.0,74.0,0.0,,,8.0,,,0.0,,3.0,,1.0,69.0,32.0,80.0,,59.0,,,,9.0,0.0,469.0,0.0,0.0,0.0,,,3.0,,1.0,,,86.0,,0.0,40.0,62.0,0.0,33.0,2.0,24.0,3.0,92.0,0.0,7.0,4.0,21.0,5.0,13.0,0.0,8.0,3.0,89.0,30.0,39.0,25.0,125.0,98.0,1.0,14.0,6.0,1.0,0.0,0.0,0.0,85.0,3.0,10.0,0.0,,3.0,4.0,2.0,0.0,2.0,40.0,,,,0.0,,,,,,,,,,,,8.0,3.0,25.0,4.0,46.0,0.0,48.0,0.0,29.0,128.0,0.0,0.0,1.0,0.0,0.0,19.0,154.0,0.0,,,2.0,,,,,,,83.0,,,0.0,,,,,,,,,,,,,,,,,,,1.0,,,,,,,, +"Microsoft.ApiDesignGuidelines.Analyzers.DoNotDirectlyAwaitATaskAnalyzer,Microsoft.CodeQuality.Analyzers,Version=2.0.0.0,Culture=neutral,PublicKeyToken=31bf3856ad364e35",,,,,,,,,,3.0,0.0,0.0,,,,,,,,,,,,,,0.0,,,,,,,,0.0,,0.0,,0.0,,0.0,,0.0,0.0,0.0,,0.0,,0.0,0.0,0.0,,,,,,0.0,0.0,0.0,,,,0.0,0.0,0.0,0.0,0.0,0.0,0.0,,,,0.0,0.0,0.0,0.0,0.0,,,,,,,,0.0,,,,,,,,,,,,,,0.0,,,,,,,,,,,,,,,,,,,,,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,,0.0,0.0,,0.0,,,,,,,,,,,,,,,,,0.0,,,,,,,,,,,,,,,,,,,,,,,,0.0,,0.0,,,,,,,0.0,,,,,,,,0.0,,,,,,,,,,,,,0.0,0.0,,0.0,0.0,,,,,,,,,,,0.0,0.0,,0.0,0.0,,,0.0,0.0,,,,0.0,0.0,,0.0,0.0,0.0,0.0,,0.0,,,0.0,,,,0.0,0.0,0.0,0.0,,0.0,,0.0,,,0.0,0.0,0.0,0.0,0.0,,,,0.0,,,,,,,,,,,,,,,,,,,,,,,0.0,0.0,0.0,0.0,,,0.0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +"Microsoft.ApiDesignGuidelines.Analyzers.EquatableAnalyzer,Microsoft.CodeQuality.Analyzers,Version=2.0.0.0,Culture=neutral,PublicKeyToken=31bf3856ad364e35",,,,,,,,10.0,1.0,0.0,0.0,0.0,0.0,,0.0,0.0,0.0,0.0,1.0,0.0,1.0,33.0,0.0,0.0,,0.0,,,0.0,0.0,0.0,0.0,0.0,0.0,,9.0,,0.0,,0.0,,0.0,0.0,0.0,,0.0,,0.0,0.0,0.0,1.0,3.0,2.0,0.0,0.0,4.0,1.0,0.0,0.0,28.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,3.0,0.0,0.0,0.0,0.0,0.0,,,,,,,,0.0,0.0,0.0,1.0,0.0,0.0,0.0,0.0,,0.0,0.0,,0.0,0.0,0.0,,,,,,,,,,,,,,,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,,,,,,,,,,,,,,,,,0.0,,,,,,,,,,,,,,,,,,,,,,,0.0,0.0,1.0,0.0,0.0,,0.0,0.0,,0.0,0.0,1.0,0.0,,,0.0,,,0.0,,1.0,,0.0,0.0,1.0,0.0,,0.0,,,,1.0,0.0,1.0,0.0,0.0,0.0,,,0.0,,0.0,,,0.0,,0.0,0.0,4.0,0.0,4.0,0.0,1.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,1.0,0.0,0.0,0.0,1.0,1.0,4.0,0.0,2.0,0.0,6.0,1.0,1.0,0.0,0.0,0.0,0.0,1.0,0.0,0.0,0.0,,0.0,0.0,0.0,0.0,0.0,0.0,,,,24.0,,,,,,,,,,,,0.0,1.0,1.0,0.0,0.0,0.0,0.0,0.0,0.0,1.0,0.0,0.0,27.0,0.0,0.0,0.0,0.0,0.0,,,0.0,,,,,,,0.0,,,0.0,,,,,,,,,,,,,,,,,,,0.0,,,,,,,, +"Microsoft.ApiDesignGuidelines.Analyzers.OperatorsShouldHaveSymmetricalOverloadsAnalyzer,Microsoft.CodeQuality.Analyzers,Version=2.0.0.0,Culture=neutral,PublicKeyToken=31bf3856ad364e35",,,,,,,,4.0,0.0,0.0,0.0,0.0,0.0,,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,,0.0,,,0.0,0.0,0.0,0.0,0.0,0.0,,3.0,,0.0,,29.0,,0.0,0.0,0.0,,0.0,,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,,,,,,,,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,,0.0,0.0,,0.0,0.0,0.0,,,,,,,,,,,,,,,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,,,,,,,,,,,,,,,,,0.0,,,,,,,,,,,,,,,,,,,,,,,0.0,0.0,0.0,0.0,0.0,,0.0,0.0,,0.0,0.0,0.0,0.0,,,0.0,,,0.0,,0.0,,0.0,0.0,0.0,0.0,,0.0,,,,2.0,0.0,0.0,0.0,0.0,0.0,,,0.0,,0.0,,,0.0,,0.0,0.0,0.0,0.0,1.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,,0.0,0.0,0.0,0.0,0.0,0.0,,,,0.0,,,,,,,,,,,,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,,,0.0,,,,,,,0.0,,,0.0,,,,,,,,,,,,,,,,,,,0.0,,,,,,,, +"Microsoft.ApiDesignGuidelines.Analyzers.PropertiesShouldNotBeWriteOnlyAnalyzer,Microsoft.CodeQuality.Analyzers,Version=2.0.0.0,Culture=neutral,PublicKeyToken=31bf3856ad364e35",,,,,,,,15.0,0.0,0.0,0.0,0.0,0.0,,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,,11.0,,,0.0,2.0,0.0,0.0,0.0,0.0,,10.0,,0.0,,0.0,,0.0,0.0,0.0,,0.0,,0.0,0.0,0.0,9.0,0.0,0.0,0.0,0.0,12.0,20.0,0.0,0.0,0.0,0.0,0.0,0.0,3.0,0.0,0.0,3.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,1.0,,,,,,,,0.0,0.0,0.0,0.0,0.0,0.0,0.0,3.0,,0.0,0.0,,0.0,0.0,0.0,,,,,,,,,,,,,,,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,3.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,,,,,,,,,,,,,,,,,0.0,,,,,,,,,,,,,,,,,,,,,,,0.0,0.0,0.0,14.0,4.0,,0.0,0.0,,0.0,0.0,0.0,0.0,,,0.0,,,0.0,,0.0,,0.0,0.0,0.0,0.0,,1.0,,,,9.0,0.0,0.0,0.0,0.0,0.0,,,0.0,,0.0,,,0.0,,0.0,0.0,0.0,0.0,10.0,0.0,0.0,0.0,45.0,0.0,0.0,7.0,0.0,0.0,0.0,0.0,0.0,0.0,70.0,0.0,11.0,0.0,0.0,0.0,0.0,0.0,1.0,0.0,0.0,0.0,0.0,14.0,1.0,0.0,0.0,,0.0,3.0,2.0,0.0,0.0,0.0,,,,0.0,,,,,,,,,,,,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,1.0,0.0,0.0,,,4.0,,,,,,,0.0,,,0.0,,,,,,,,,,,,,,,,,,,0.0,,,,,,,, +"Microsoft.CodeAnalysis.CSharp.Analyzers.CSharpImmutableObjectMethodAnalyzer,Microsoft.CodeAnalysis.CSharp.Analyzers,Version=2.0.0.0,Culture=neutral,PublicKeyToken=31bf3856ad364e35",,,,,,,,2.0,0.0,0.0,0.0,0.0,0.0,,0.0,0.0,0.0,0.0,,,,,,,,12.0,,,0.0,13.0,4.0,,0.0,0.0,,74.0,,,,1.0,,2.0,0.0,0.0,,0.0,,,0.0,1.0,70.0,,67.0,24.0,58.0,59.0,11.0,,,,3.0,0.0,,1.0,0.0,,12.0,0.0,,11.0,,0.0,0.0,0.0,0.0,0.0,,,,,,,,0.0,0.0,0.0,0.0,0.0,,,0.0,,0.0,0.0,,0.0,,0.0,,,,,,,,,,,,,,,0.0,0.0,2.0,0.0,8.0,0.0,0.0,0.0,0.0,42.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,1.0,0.0,0.0,0.0,0.0,,,,,,,,,,,,,,,,,0.0,,,,,,,,,,,,,,,,,,,,,,,,0.0,,7.0,0.0,,,0.0,,,0.0,,0.0,,,,,,0.0,,0.0,,0.0,,0.0,,,,,,,60.0,0.0,,0.0,0.0,0.0,,,,,0.0,,,,,0.0,1.0,,0.0,32.0,1.0,23.0,0.0,42.0,,42.0,43.0,,0.0,,0.0,0.0,,11.0,,66.0,8.0,110.0,2.0,,333.0,4.0,0.0,0.0,,1.0,5.0,2.0,0.0,0.0,,3.0,1.0,1.0,0.0,0.0,1.0,,,,,,,,,,,,,,,,0.0,0.0,0.0,,,0.0,,0.0,0.0,,0.0,0.0,0.0,0.0,0.0,,,0.0,,,0.0,,,,,,,0.0,,,0.0,,,,,,,,,,,,,,,,,,,0.0,,,,,,,, +"Microsoft.CodeAnalysis.CSharp.Diagnostics.AddBraces.CSharpAddBracesDiagnosticAnalyzer,Microsoft.CodeAnalysis.CSharp.Features,Version=42.42.42.42,Culture=neutral,PublicKeyToken=31bf3856ad364e35",281.0,52.0,0.0,,286.0,0.0,3.0,1.0,1.0,0.0,0.0,0.0,25.0,0.0,0.0,0.0,73.0,49.0,,,,,,,20.0,2.0,10.0,,0.0,1.0,0.0,,0.0,0.0,74.0,27.0,,,8.0,1.0,2.0,0.0,0.0,0.0,0.0,0.0,,,0.0,0.0,2.0,,2.0,0.0,1.0,42.0,2.0,,,,0.0,0.0,,0.0,0.0,,3.0,0.0,,0.0,,0.0,0.0,0.0,0.0,0.0,1.0,0.0,,0.0,1.0,0.0,,0.0,0.0,0.0,33.0,19.0,,,0.0,5.0,0.0,0.0,0.0,0.0,,0.0,2.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,,,,,0.0,0.0,0.0,0.0,1.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,30.0,0.0,0.0,0.0,0.0,1.0,0.0,1.0,,,1.0,,0.0,0.0,0.0,0.0,,0.0,0.0,0.0,0.0,0.0,11.0,27.0,,832.0,,164.0,0.0,113.0,37.0,0.0,1.0,0.0,1.0,,0.0,3.0,,446.0,78.0,0.0,0.0,0.0,,0.0,,3.0,0.0,10.0,,1.0,,,0.0,,0.0,4.0,,,358.0,89.0,0.0,53.0,1.0,0.0,0.0,,1.0,,,,46.0,0.0,0.0,2.0,0.0,,0.0,0.0,0.0,43.0,,,625.0,1.0,74.0,165.0,,0.0,0.0,0.0,,0.0,8.0,0.0,0.0,0.0,3.0,,0.0,0.0,,0.0,,0.0,0.0,,2.0,,37.0,0.0,1.0,44.0,,1.0,2.0,0.0,0.0,,0.0,2.0,0.0,0.0,0.0,25.0,1.0,0.0,0.0,0.0,0.0,0.0,4.0,,590.0,,0.0,0.0,0.0,0.0,0.0,0.0,0.0,23.0,1.0,272.0,26.0,0.0,1.0,21.0,,,0.0,,0.0,0.0,,0.0,0.0,0.0,0.0,0.0,,,0.0,,0.0,0.0,0.0,0.0,47.0,0.0,,51.0,68.0,,,0.0,0.0,0.0,0.0,0.0,,0.0,1.0,0.0,,0.0,1.0,0.0,47.0,0.0,0.0,0.0,0.0,,25.0,,1.0,0.0,16.0,,0.0,1.0,0.0 +"Microsoft.CodeAnalysis.CSharp.Diagnostics.CSharpUnboundIdentifiersDiagnosticAnalyzer,Microsoft.CodeAnalysis.CSharp.Features,Version=42.42.42.42,Culture=neutral,PublicKeyToken=31bf3856ad364e35",11.0,52.0,0.0,,34.0,0.0,0.0,0.0,1.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,3.0,3.0,,,,,,,4.0,0.0,1.0,,0.0,1.0,0.0,,0.0,0.0,3.0,2.0,,,1.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,,,0.0,0.0,0.0,,2.0,0.0,1.0,2.0,0.0,,,,0.0,0.0,,0.0,0.0,,0.0,0.0,,0.0,,0.0,0.0,0.0,0.0,0.0,0.0,0.0,,0.0,0.0,0.0,,0.0,0.0,2.0,0.0,0.0,,,0.0,0.0,0.0,0.0,0.0,0.0,,0.0,19.0,1.0,0.0,0.0,0.0,0.0,0.0,0.0,,,,,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,,,0.0,,0.0,0.0,0.0,0.0,,0.0,0.0,0.0,0.0,0.0,3.0,0.0,,4.0,,25.0,0.0,1.0,3.0,0.0,0.0,0.0,0.0,,0.0,0.0,,4.0,1.0,0.0,0.0,0.0,,0.0,,0.0,0.0,1.0,,0.0,,,0.0,,0.0,1.0,,,3.0,4.0,0.0,1.0,1.0,0.0,0.0,,1.0,,,,1.0,0.0,0.0,0.0,0.0,,0.0,0.0,0.0,0.0,,,107.0,0.0,4.0,1.0,,0.0,0.0,0.0,,0.0,1.0,0.0,0.0,0.0,0.0,,0.0,0.0,,0.0,,0.0,30.0,,0.0,,2.0,0.0,1.0,0.0,,1.0,0.0,0.0,0.0,,0.0,0.0,0.0,0.0,0.0,1.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,,94.0,,0.0,0.0,0.0,0.0,0.0,0.0,0.0,3.0,1.0,3.0,1.0,0.0,1.0,3.0,,,0.0,,0.0,0.0,,0.0,0.0,0.0,0.0,0.0,,,0.0,,0.0,30.0,0.0,0.0,36.0,0.0,,1.0,2.0,,,0.0,0.0,0.0,0.0,0.0,,0.0,0.0,0.0,,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,,0.0,,0.0,0.0,0.0,,0.0,0.0,0.0 +"Microsoft.CodeAnalysis.CSharp.Diagnostics.RemoveUnnecessaryCast.CSharpRemoveUnnecessaryCastDiagnosticAnalyzer,Microsoft.CodeAnalysis.CSharp.Features,Version=42.42.42.42,Culture=neutral,PublicKeyToken=31bf3856ad364e35",681.0,140706.0,0.0,,11888.0,87.0,320.0,9.0,367.0,7.0,13.0,4.0,7.0,28.0,0.0,57.0,7264.0,2631.0,,,,,,,513.0,18.0,691.0,,2.0,144.0,52.0,,1.0,0.0,116.0,38.0,,,439.0,17.0,78.0,5.0,0.0,0.0,0.0,0.0,,,0.0,31.0,101.0,,111.0,1.0,78.0,463.0,66.0,,,,0.0,0.0,,15.0,34.0,,205.0,0.0,,59.0,,0.0,0.0,0.0,1.0,2.0,19.0,23.0,,7.0,111.0,7.0,,0.0,7.0,269.0,72.0,114.0,,,85.0,16.0,0.0,2.0,0.0,1.0,,0.0,2775.0,900.0,0.0,0.0,0.0,0.0,18.0,6.0,,,,,0.0,0.0,0.0,0.0,107.0,3.0,0.0,0.0,0.0,0.0,2.0,8.0,0.0,5.0,0.0,0.0,0.0,6.0,0.0,8.0,0.0,0.0,3.0,0.0,1.0,0.0,24.0,,,18.0,,7.0,4.0,4.0,0.0,,3.0,1.0,0.0,0.0,0.0,173.0,322.0,,12223.0,,148948.0,0.0,155591.0,131.0,0.0,111.0,0.0,41.0,,0.0,577.0,,13569.0,149424.0,0.0,5.0,5.0,,4.0,,27.0,3.0,1187.0,,10.0,,,25.0,,0.0,625.0,,,12459.0,469.0,4.0,154214.0,209.0,0.0,3.0,,310.0,,,,967.0,4.0,3.0,21.0,4.0,,4.0,6.0,0.0,417.0,,,11013.0,41.0,493.0,153061.0,,0.0,0.0,4.0,,0.0,110.0,47.0,3.0,0.0,317.0,,0.0,17.0,,0.0,,0.0,0.0,,121.0,,412.0,0.0,74.0,125.0,,260.0,98.0,0.0,8.0,,2.0,64.0,4.0,45.0,0.0,160069.0,46.0,3.0,15.0,0.0,1.0,6.0,300.0,,14423.0,,0.0,0.0,0.0,0.0,0.0,0.0,0.0,1832.0,992.0,10450.0,152650.0,86.0,179.0,6510.0,,,1.0,,0.0,3.0,,0.0,0.0,6.0,17.0,4.0,,,0.0,,0.0,174.0,0.0,0.0,442.0,0.0,,697.0,2532.0,,,0.0,0.0,0.0,0.0,0.0,,0.0,21.0,37.0,,9.0,19.0,0.0,359.0,0.0,33.0,5.0,3.0,,9.0,,2.0,0.0,1.0,,40.0,21.0,0.0 +"Microsoft.CodeAnalysis.CSharp.InlineDeclaration.CSharpInlineDeclarationDiagnosticAnalyzer,Microsoft.CodeAnalysis.CSharp.Features,Version=42.42.42.42,Culture=neutral,PublicKeyToken=31bf3856ad364e35",32480.0,12870.0,2.0,,59782.0,411.0,335.0,161.0,588.0,121.0,71.0,59.0,279.0,66.0,0.0,173.0,1831.0,969.0,,,,,,,476.0,23.0,96.0,,4.0,44.0,18.0,,24.0,0.0,513.0,140.0,,,288.0,4.0,287.0,50.0,124.0,0.0,29.0,29.0,,,63.0,2.0,158.0,,1334.0,109.0,72.0,250.0,14.0,,,,1.0,0.0,,1.0,127.0,,12.0,0.0,,77.0,,0.0,0.0,0.0,6.0,5.0,346.0,640.0,,71.0,264.0,24.0,,0.0,229.0,6668.0,430.0,508.0,,,11.0,63.0,1.0,0.0,92.0,7.0,,5.0,949.0,2010.0,0.0,0.0,0.0,0.0,10.0,127.0,,,,,0.0,0.0,0.0,9.0,84.0,0.0,38.0,0.0,0.0,0.0,0.0,2.0,0.0,73.0,0.0,0.0,0.0,92.0,0.0,107.0,40.0,0.0,42.0,0.0,5.0,0.0,9.0,,,428.0,,20.0,64.0,48.0,0.0,,22.0,5.0,0.0,0.0,74.0,396.0,514.0,,71588.0,,14201.0,2.0,12114.0,410.0,50.0,374.0,8.0,409.0,,8.0,424.0,,66528.0,15468.0,3.0,97.0,41.0,,40.0,,138.0,135.0,168.0,,338.0,,,198.0,,1.0,435.0,,,74871.0,359.0,33.0,13777.0,629.0,27.0,106.0,,618.0,,,,281.0,30.0,60.0,246.0,56.0,,86.0,186.0,1.0,562.0,,,69029.0,232.0,463.0,14138.0,,2.0,0.0,17.0,,0.0,236.0,60.0,165.0,8.0,47.0,,42.0,73.0,,97.0,,0.0,85.0,,40.0,,171.0,104.0,523.0,6.0,,69.0,176.0,0.0,136.0,,0.0,131.0,4.0,222.0,0.0,14611.0,59.0,6.0,1.0,0.0,37.0,2.0,451.0,,67037.0,,2.0,0.0,0.0,0.0,0.0,0.0,0.0,1032.0,1473.0,69111.0,12423.0,181.0,588.0,1269.0,,,26.0,,1.0,92.0,,0.0,0.0,106.0,70.0,83.0,,,0.0,,0.0,34.0,0.0,0.0,197.0,0.0,,124.0,901.0,,,0.0,0.0,0.0,5.0,19.0,,39.0,341.0,11.0,,21.0,63.0,0.0,327.0,0.0,124.0,20.0,21.0,,214.0,,31.0,0.0,5.0,,618.0,77.0,2.0 +"Microsoft.CodeAnalysis.CSharp.InvokeDelegateWithConditionalAccess.InvokeDelegateWithConditionalAccessAnalyzer,Microsoft.CodeAnalysis.CSharp.Features,Version=42.42.42.42,Culture=neutral,PublicKeyToken=31bf3856ad364e35",128.0,111.0,0.0,,225.0,0.0,18.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,,,,,,,34.0,1.0,153.0,,0.0,0.0,0.0,,0.0,0.0,10.0,5.0,,,36.0,1.0,47.0,0.0,0.0,0.0,0.0,0.0,,,0.0,0.0,1.0,,0.0,0.0,0.0,8.0,2.0,,,,0.0,0.0,,0.0,0.0,,2.0,0.0,,0.0,,0.0,0.0,0.0,0.0,0.0,1.0,0.0,,0.0,0.0,0.0,,0.0,0.0,0.0,22.0,0.0,,,0.0,0.0,0.0,0.0,0.0,0.0,,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,,,,,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,19.0,,,1.0,,0.0,0.0,0.0,0.0,,0.0,0.0,0.0,0.0,0.0,9.0,2.0,,145.0,,74.0,0.0,51.0,9.0,0.0,1.0,0.0,35.0,,0.0,2.0,,192.0,127.0,0.0,0.0,0.0,,0.0,,1.0,0.0,55.0,,0.0,,,0.0,,0.0,2.0,,,208.0,62.0,0.0,54.0,0.0,0.0,0.0,,0.0,,,,8.0,0.0,0.0,1.0,0.0,,0.0,0.0,0.0,64.0,,,308.0,0.0,78.0,79.0,,0.0,0.0,0.0,,0.0,5.0,0.0,0.0,0.0,35.0,,0.0,0.0,,0.0,,0.0,0.0,,2.0,,36.0,0.0,0.0,1.0,,0.0,1.0,0.0,0.0,,0.0,1.0,0.0,0.0,0.0,53.0,0.0,0.0,0.0,0.0,0.0,0.0,2.0,,174.0,,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,263.0,74.0,0.0,0.0,0.0,,,0.0,,0.0,0.0,,0.0,0.0,1.0,0.0,0.0,,,0.0,,0.0,0.0,0.0,0.0,42.0,0.0,,11.0,0.0,,,0.0,0.0,0.0,0.0,0.0,,0.0,1.0,0.0,,0.0,0.0,0.0,30.0,0.0,0.0,0.0,0.0,,0.0,,0.0,0.0,0.0,,0.0,0.0,0.0 +"Microsoft.CodeAnalysis.CSharp.QualifyMemberAccess.CSharpQualifyMemberAccessDiagnosticAnalyzer,Microsoft.CodeAnalysis.CSharp.Features,Version=42.42.42.42,Culture=neutral,PublicKeyToken=31bf3856ad364e35",628.0,195.0,0.0,,649.0,1.0,62.0,25.0,55.0,1.0,0.0,0.0,2.0,0.0,0.0,5.0,243.0,301.0,,,,,,,140.0,23.0,21.0,,0.0,63.0,7.0,,0.0,0.0,243.0,94.0,,,39.0,25.0,66.0,0.0,0.0,0.0,0.0,0.0,,,1.0,1.0,156.0,,119.0,11.0,20.0,77.0,10.0,,,,0.0,0.0,,2.0,0.0,,24.0,0.0,,1.0,,0.0,0.0,0.0,0.0,0.0,1.0,0.0,,1.0,2.0,0.0,,0.0,0.0,1.0,3.0,0.0,,,0.0,4.0,0.0,0.0,0.0,0.0,,0.0,74.0,331.0,0.0,0.0,0.0,0.0,0.0,71.0,,,,,0.0,0.0,0.0,0.0,3.0,0.0,37.0,0.0,0.0,0.0,0.0,2.0,0.0,4.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,,,1.0,,0.0,0.0,0.0,0.0,,0.0,0.0,0.0,0.0,1.0,89.0,4.0,,766.0,,150.0,0.0,170.0,106.0,0.0,25.0,0.0,27.0,,0.0,27.0,,703.0,234.0,0.0,0.0,0.0,,0.0,,67.0,1.0,155.0,,1.0,,,1.0,,0.0,25.0,,,886.0,203.0,0.0,355.0,2.0,0.0,32.0,,2.0,,,,82.0,52.0,0.0,70.0,34.0,,50.0,1.0,0.0,47.0,,,521.0,1.0,170.0,324.0,,0.0,0.0,2.0,,0.0,57.0,0.0,0.0,0.0,41.0,,0.0,1.0,,1.0,,0.0,0.0,,105.0,,83.0,10.0,94.0,1.0,,3.0,61.0,25.0,0.0,,0.0,6.0,3.0,5.0,0.0,153.0,3.0,0.0,1.0,0.0,0.0,1.0,29.0,,768.0,,0.0,0.0,0.0,0.0,0.0,0.0,0.0,121.0,13.0,610.0,166.0,59.0,44.0,71.0,,,0.0,,0.0,23.0,,0.0,0.0,29.0,0.0,0.0,,,0.0,,0.0,0.0,0.0,0.0,226.0,0.0,,27.0,149.0,,,0.0,0.0,0.0,0.0,0.0,,0.0,2.0,0.0,,0.0,4.0,0.0,29.0,0.0,0.0,0.0,31.0,,1.0,,0.0,0.0,0.0,,45.0,0.0,0.0 +"Microsoft.CodeAnalysis.CSharp.UseCoalesceExpression.CSharpUseCoalesceExpressionDiagnosticAnalyzer,Microsoft.CodeAnalysis.CSharp.Features,Version=42.42.42.42,Culture=neutral,PublicKeyToken=31bf3856ad364e35",51.0,7.0,0.0,,33.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,26.0,0.0,,,,,,,2.0,0.0,1.0,,0.0,0.0,0.0,,0.0,0.0,165.0,0.0,,,85.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,,,0.0,0.0,0.0,,0.0,0.0,0.0,0.0,0.0,,,,0.0,0.0,,0.0,0.0,,0.0,0.0,,0.0,,0.0,0.0,0.0,0.0,0.0,0.0,0.0,,0.0,0.0,0.0,,0.0,0.0,0.0,0.0,0.0,,,0.0,0.0,0.0,0.0,0.0,0.0,,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,,,,,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,,,0.0,,0.0,0.0,0.0,0.0,,0.0,0.0,0.0,0.0,0.0,2.0,0.0,,48.0,,3.0,0.0,3.0,2.0,0.0,0.0,0.0,0.0,,0.0,0.0,,131.0,2.0,0.0,0.0,0.0,,0.0,,0.0,0.0,1.0,,0.0,,,0.0,,0.0,0.0,,,81.0,2.0,0.0,35.0,0.0,0.0,0.0,,0.0,,,,1.0,0.0,0.0,0.0,0.0,,0.0,0.0,0.0,0.0,,,69.0,0.0,2.0,2.0,,0.0,0.0,0.0,,0.0,0.0,0.0,0.0,0.0,0.0,,0.0,0.0,,0.0,,0.0,0.0,,0.0,,0.0,0.0,0.0,0.0,,0.0,0.0,0.0,0.0,,0.0,0.0,0.0,0.0,0.0,35.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,,45.0,,0.0,0.0,0.0,0.0,0.0,0.0,0.0,27.0,0.0,77.0,2.0,0.0,0.0,0.0,,,31.0,,0.0,0.0,,0.0,0.0,0.0,0.0,0.0,,,0.0,,0.0,0.0,0.0,0.0,2.0,0.0,,1.0,0.0,,,0.0,0.0,0.0,0.0,0.0,,0.0,0.0,0.0,,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,,0.0,,0.0,0.0,0.0,,0.0,0.0,0.0 +"Microsoft.CodeAnalysis.CSharp.UseCoalesceExpression.CSharpUseCoalesceExpressionForNullableDiagnosticAnalyzer,Microsoft.CodeAnalysis.CSharp.Features,Version=42.42.42.42,Culture=neutral,PublicKeyToken=31bf3856ad364e35",28.0,23.0,0.0,,7.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,,,,,,,3.0,3.0,18.0,,0.0,0.0,0.0,,0.0,0.0,28.0,1.0,,,1.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,,,0.0,0.0,0.0,,0.0,0.0,0.0,0.0,0.0,,,,0.0,0.0,,0.0,0.0,,0.0,0.0,,0.0,,0.0,0.0,0.0,0.0,0.0,0.0,0.0,,0.0,0.0,0.0,,0.0,0.0,0.0,1.0,0.0,,,0.0,0.0,0.0,0.0,0.0,0.0,,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,,,,,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,,,0.0,,0.0,0.0,0.0,0.0,,0.0,0.0,0.0,0.0,0.0,3.0,0.0,,83.0,,2.0,0.0,2.0,2.0,0.0,0.0,0.0,0.0,,0.0,0.0,,36.0,2.0,0.0,0.0,0.0,,0.0,,0.0,0.0,37.0,,0.0,,,0.0,,0.0,0.0,,,8.0,3.0,0.0,2.0,0.0,0.0,0.0,,0.0,,,,1.0,0.0,0.0,0.0,0.0,,0.0,0.0,0.0,0.0,,,38.0,0.0,3.0,2.0,,0.0,0.0,0.0,,0.0,1.0,0.0,0.0,0.0,0.0,,0.0,0.0,,0.0,,0.0,0.0,,0.0,,1.0,0.0,0.0,0.0,,0.0,0.0,0.0,0.0,,0.0,0.0,0.0,0.0,0.0,2.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,,7.0,,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,31.0,2.0,0.0,0.0,0.0,,,0.0,,0.0,0.0,,0.0,0.0,0.0,0.0,0.0,,,0.0,,0.0,0.0,0.0,0.0,3.0,0.0,,1.0,0.0,,,0.0,0.0,0.0,0.0,0.0,,0.0,0.0,0.0,,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,,0.0,,0.0,0.0,0.0,,0.0,0.0,0.0 +"Microsoft.CodeAnalysis.CSharp.UseCollectionInitializer.CSharpUseCollectionInitializerDiagnosticAnalyzer,Microsoft.CodeAnalysis.CSharp.Features,Version=42.42.42.42,Culture=neutral,PublicKeyToken=31bf3856ad364e35",2.0,732.0,0.0,,364.0,35.0,26.0,45.0,20.0,4.0,2.0,19.0,71.0,3.0,0.0,6.0,26.0,58.0,,,,,,,513.0,49.0,127.0,,0.0,18.0,10.0,,4.0,23.0,320.0,178.0,,,88.0,6.0,36.0,3.0,2.0,0.0,0.0,0.0,,,50.0,2.0,59.0,,483.0,1.0,25.0,517.0,36.0,,,,1.0,0.0,,1.0,0.0,,58.0,0.0,,6.0,,0.0,0.0,0.0,26.0,2.0,3.0,37.0,,0.0,38.0,0.0,,0.0,2.0,5.0,32.0,6.0,,,0.0,4.0,1.0,0.0,1.0,3.0,,0.0,44.0,62.0,0.0,0.0,0.0,0.0,0.0,6.0,,,,,0.0,0.0,0.0,0.0,5.0,1.0,2.0,0.0,0.0,1.0,0.0,28.0,0.0,2.0,0.0,0.0,0.0,3.0,0.0,2.0,6.0,0.0,4.0,0.0,1.0,0.0,0.0,,,4.0,,0.0,2.0,2.0,0.0,,3.0,8.0,0.0,0.0,4.0,2150.0,233.0,,315.0,,1690.0,0.0,1101.0,214.0,6.0,6.0,0.0,25.0,,0.0,254.0,,301.0,806.0,0.0,3.0,3.0,,2.0,,36.0,54.0,203.0,,15.0,,,4.0,,1.0,58.0,,,375.0,357.0,2.0,779.0,23.0,0.0,6.0,,20.0,,,,373.0,3.0,2.0,70.0,3.0,,30.0,42.0,1.0,71.0,,,274.0,19.0,1016.0,786.0,,0.0,1.0,8.0,,52.0,2700.0,3.0,6.0,1.0,26.0,,1.0,6.0,,2.0,,0.0,0.0,,115.0,,3215.0,2.0,140.0,6.0,,31.0,55.0,1.0,0.0,,0.0,60.0,7.0,6.0,0.0,658.0,34.0,4.0,2.0,0.0,3.0,4.0,97.0,,446.0,,0.0,0.0,0.0,0.0,0.0,0.0,0.0,83.0,27.0,340.0,1450.0,6.0,26.0,25.0,,,4.0,,1.0,6.0,,0.0,0.0,4.0,3.0,25.0,,,0.0,,0.0,0.0,0.0,0.0,3460.0,0.0,,151.0,181.0,,,0.0,0.0,0.0,1.0,1.0,,1.0,8.0,0.0,,5.0,183.0,0.0,745.0,0.0,3.0,2.0,2.0,,45.0,,0.0,0.0,0.0,,3.0,8.0,0.0 +"Microsoft.CodeAnalysis.CSharp.UseDefaultLiteral.CSharpUseDefaultLiteralDiagnosticAnalyzer,Microsoft.CodeAnalysis.CSharp.Features,Version=42.42.42.42,Culture=neutral,PublicKeyToken=31bf3856ad364e35",26.0,16.0,0.0,,3.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,,,,,,,1.0,0.0,0.0,,0.0,0.0,0.0,,0.0,0.0,0.0,0.0,,,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,,,0.0,0.0,0.0,,0.0,0.0,0.0,0.0,0.0,,,,0.0,0.0,,0.0,0.0,,0.0,0.0,,0.0,,0.0,0.0,0.0,0.0,0.0,0.0,0.0,,0.0,0.0,0.0,,0.0,0.0,0.0,0.0,0.0,,,0.0,0.0,0.0,0.0,0.0,0.0,,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,,,,,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,,,0.0,,0.0,0.0,0.0,0.0,,0.0,0.0,0.0,0.0,0.0,0.0,0.0,,3.0,,1.0,0.0,1.0,1.0,0.0,0.0,0.0,0.0,,0.0,0.0,,36.0,55.0,0.0,0.0,0.0,,0.0,,0.0,0.0,0.0,,0.0,,,0.0,,0.0,0.0,,,92.0,2.0,0.0,1.0,0.0,0.0,0.0,,0.0,,,,0.0,0.0,0.0,0.0,0.0,,0.0,0.0,0.0,0.0,,,39.0,0.0,3.0,1.0,,0.0,0.0,0.0,,0.0,0.0,0.0,0.0,0.0,0.0,,0.0,0.0,,0.0,,0.0,0.0,,0.0,,28.0,0.0,0.0,0.0,,0.0,0.0,0.0,0.0,,0.0,0.0,0.0,0.0,0.0,1.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,,3.0,,0.0,0.0,0.0,0.0,0.0,0.0,0.0,52.0,45.0,1591.0,191.0,0.0,68.0,187.0,,,0.0,,0.0,4.0,,0.0,0.0,4.0,0.0,0.0,,,0.0,,0.0,0.0,0.0,0.0,243.0,0.0,,115.0,29.0,,,0.0,0.0,0.0,0.0,0.0,,0.0,7.0,6.0,,0.0,0.0,0.0,8.0,0.0,1.0,0.0,0.0,,1.0,,0.0,0.0,0.0,,1.0,1.0,0.0 +"Microsoft.CodeAnalysis.CSharp.UseExpressionBody.UseExpressionBodyDiagnosticAnalyzer,Microsoft.CodeAnalysis.CSharp.Features,Version=42.42.42.42,Culture=neutral,PublicKeyToken=31bf3856ad364e35",1467.0,5767.0,1.0,,4787.0,5.0,462.0,5.0,15.0,4.0,1.0,1.0,104.0,52.0,0.0,28.0,185.0,213.0,,,,,,,4423.0,64.0,222.0,,0.0,127.0,6.0,,27.0,2.0,1053.0,3824.0,,,684.0,5.0,374.0,1.0,2.0,0.0,0.0,0.0,,,42.0,4.0,93.0,,1557.0,155.0,109.0,2287.0,1247.0,,,,0.0,0.0,,159.0,1.0,,77.0,0.0,,13.0,,0.0,0.0,0.0,0.0,1.0,5.0,3.0,,23.0,123.0,1.0,,0.0,2.0,22.0,86.0,5.0,,,48.0,38.0,0.0,0.0,2.0,0.0,,0.0,253.0,871.0,0.0,0.0,0.0,0.0,0.0,4.0,,,,,0.0,0.0,0.0,0.0,17.0,0.0,7.0,0.0,0.0,1.0,0.0,89.0,0.0,31.0,0.0,1.0,0.0,3.0,0.0,30.0,5.0,0.0,22.0,0.0,0.0,0.0,1.0,,,5.0,,1.0,1.0,0.0,0.0,,2.0,0.0,0.0,0.0,1.0,4971.0,160.0,,2457.0,,1072.0,1.0,1412.0,1781.0,0.0,41.0,0.0,73.0,,0.0,138.0,,3848.0,740.0,1.0,1.0,0.0,,1.0,,232.0,14.0,244.0,,8.0,,,3.0,,0.0,188.0,,,8414.0,530.0,1.0,2413.0,16.0,1.0,2.0,,68.0,,,,246.0,54.0,0.0,110.0,11.0,,1.0,29.0,0.0,129.0,,,3416.0,48.0,861.0,3662.0,,1.0,2.0,8.0,,4.0,5038.0,1.0,116.0,0.0,341.0,,0.0,50.0,,4.0,,0.0,11.0,,630.0,,5788.0,9.0,2504.0,9.0,,28.0,51.0,40.0,44.0,,0.0,29.0,9.0,7.0,0.0,12252.0,51.0,84.0,302.0,26.0,1.0,6.0,640.0,,8751.0,,18.0,0.0,0.0,0.0,0.0,0.0,0.0,1865.0,5231.0,40612.0,10337.0,35.0,637.0,3600.0,,,184.0,,0.0,2.0,,0.0,0.0,3.0,2.0,1.0,,,0.0,,0.0,1.0,0.0,0.0,6852.0,0.0,,105.0,158.0,,,0.0,0.0,0.0,1.0,3.0,,1.0,453.0,0.0,,4.0,191.0,0.0,131.0,0.0,2.0,1.0,2.0,,68.0,,10.0,0.0,0.0,,3.0,3.0,1.0 +"Microsoft.CodeAnalysis.CSharp.UseNullPropagation.CSharpUseNullPropagationDiagnosticAnalyzer,Microsoft.CodeAnalysis.CSharp.Features,Version=42.42.42.42,Culture=neutral,PublicKeyToken=31bf3856ad364e35",8.0,68.0,0.0,,75.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,,,,,,,41.0,0.0,1.0,,0.0,0.0,0.0,,0.0,0.0,21.0,1.0,,,1.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,,,0.0,0.0,0.0,,0.0,0.0,0.0,1.0,0.0,,,,0.0,0.0,,0.0,0.0,,0.0,0.0,,0.0,,0.0,0.0,0.0,0.0,0.0,0.0,0.0,,0.0,0.0,0.0,,0.0,0.0,0.0,0.0,0.0,,,0.0,0.0,0.0,0.0,0.0,0.0,,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,,,,,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,,,0.0,,0.0,0.0,0.0,0.0,,23.0,0.0,0.0,0.0,0.0,1.0,0.0,,141.0,,2.0,0.0,1.0,1.0,0.0,0.0,0.0,0.0,,0.0,0.0,,108.0,1.0,0.0,0.0,0.0,,0.0,,0.0,0.0,1.0,,0.0,,,0.0,,0.0,0.0,,,39.0,2.0,0.0,2.0,0.0,0.0,0.0,,0.0,,,,1.0,0.0,0.0,0.0,0.0,,0.0,0.0,0.0,40.0,,,72.0,0.0,2.0,1.0,,0.0,0.0,0.0,,0.0,1.0,0.0,0.0,0.0,0.0,,0.0,0.0,,0.0,,0.0,0.0,,0.0,,1.0,0.0,0.0,0.0,,0.0,0.0,0.0,0.0,,0.0,0.0,0.0,0.0,0.0,2.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,,46.0,,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,67.0,1.0,0.0,0.0,0.0,,,0.0,,0.0,0.0,,0.0,0.0,0.0,0.0,0.0,,,0.0,,0.0,0.0,0.0,0.0,2.0,0.0,,1.0,17.0,,,0.0,0.0,0.0,0.0,0.0,,0.0,0.0,0.0,,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,,0.0,,0.0,0.0,0.0,,0.0,0.0,0.0 +"Microsoft.CodeAnalysis.CSharp.UseObjectInitializer.CSharpUseObjectInitializerDiagnosticAnalyzer,Microsoft.CodeAnalysis.CSharp.Features,Version=42.42.42.42,Culture=neutral,PublicKeyToken=31bf3856ad364e35",537.0,85.0,0.0,,272.0,1.0,40.0,3.0,68.0,4.0,1.0,26.0,9.0,2.0,0.0,57.0,248.0,15.0,,,,,,,82.0,5.0,11.0,,0.0,48.0,1.0,,6.0,1.0,46.0,60.0,,,11.0,3.0,3.0,2.0,1.0,0.0,0.0,0.0,,,1.0,0.0,161.0,,62.0,0.0,75.0,28.0,32.0,,,,0.0,0.0,,0.0,0.0,,7.0,0.0,,4.0,,0.0,0.0,0.0,0.0,0.0,2.0,1.0,,1.0,176.0,0.0,,0.0,0.0,15.0,6.0,23.0,,,0.0,2.0,13.0,0.0,0.0,0.0,,0.0,188.0,40.0,0.0,0.0,0.0,0.0,0.0,5.0,,,,,0.0,0.0,0.0,0.0,3.0,0.0,69.0,0.0,0.0,1.0,0.0,3.0,0.0,0.0,0.0,0.0,0.0,2.0,0.0,6.0,1.0,0.0,8.0,0.0,0.0,0.0,0.0,,,2.0,,0.0,1.0,0.0,0.0,,1.0,0.0,0.0,0.0,1.0,42.0,87.0,,441.0,,74.0,0.0,70.0,70.0,0.0,3.0,0.0,3.0,,0.0,35.0,,173.0,153.0,0.0,2.0,0.0,,1.0,,5.0,65.0,10.0,,3.0,,,4.0,,122.0,8.0,,,302.0,84.0,1.0,73.0,58.0,0.0,8.0,,36.0,,,,57.0,2.0,0.0,7.0,1.0,,1.0,3.0,57.0,8.0,,,189.0,5.0,71.0,154.0,,0.0,2.0,4.0,,1.0,71.0,6.0,0.0,0.0,7.0,,0.0,6.0,,1.0,,0.0,0.0,,8.0,,84.0,7.0,110.0,3.0,,173.0,19.0,0.0,0.0,,0.0,18.0,2.0,55.0,0.0,68.0,28.0,1.0,1.0,0.0,0.0,0.0,42.0,,294.0,,0.0,0.0,0.0,0.0,0.0,0.0,0.0,79.0,17.0,270.0,97.0,36.0,94.0,116.0,,,6.0,,38.0,8.0,,0.0,0.0,4.0,1.0,1.0,,,0.0,,0.0,0.0,0.0,0.0,70.0,0.0,,51.0,16.0,,,0.0,0.0,0.0,25.0,0.0,,0.0,3.0,0.0,,5.0,2.0,0.0,748.0,0.0,1.0,0.0,0.0,,2.0,,0.0,0.0,0.0,,2.0,1.0,0.0 +"Microsoft.CodeAnalysis.CSharp.UsePatternMatching.CSharpAsAndNullCheckDiagnosticAnalyzer,Microsoft.CodeAnalysis.CSharp.Features,Version=42.42.42.42,Culture=neutral,PublicKeyToken=31bf3856ad364e35",242.0,146.0,0.0,,316.0,0.0,5.0,0.0,0.0,0.0,0.0,0.0,0.0,1.0,0.0,0.0,346.0,6.0,,,,,,,73.0,20.0,117.0,,0.0,1.0,0.0,,0.0,0.0,38.0,33.0,,,40.0,9.0,6.0,0.0,2.0,0.0,0.0,0.0,,,1.0,0.0,2.0,,6.0,0.0,0.0,34.0,54.0,,,,0.0,0.0,,0.0,0.0,,18.0,0.0,,0.0,,0.0,0.0,0.0,0.0,0.0,33.0,1.0,,0.0,1.0,0.0,,0.0,0.0,0.0,2.0,0.0,,,0.0,60.0,0.0,0.0,0.0,0.0,,0.0,2.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,,,,,0.0,0.0,0.0,0.0,1.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,2.0,,,1.0,,0.0,0.0,0.0,0.0,,0.0,0.0,0.0,0.0,1.0,23.0,27.0,,775.0,,157.0,0.0,111.0,51.0,0.0,27.0,0.0,5.0,,0.0,5.0,,463.0,162.0,0.0,0.0,0.0,,0.0,,42.0,0.0,229.0,,0.0,,,0.0,,0.0,5.0,,,479.0,89.0,0.0,154.0,0.0,0.0,0.0,,0.0,,,,254.0,0.0,0.0,2.0,0.0,,0.0,0.0,0.0,45.0,,,425.0,1.0,66.0,85.0,,0.0,0.0,0.0,,0.0,48.0,0.0,0.0,0.0,63.0,,0.0,0.0,,4.0,,0.0,0.0,,8.0,,73.0,0.0,6.0,67.0,,0.0,2.0,0.0,0.0,,0.0,2.0,0.0,0.0,0.0,122.0,2.0,0.0,1.0,0.0,0.0,0.0,49.0,,533.0,,0.0,0.0,0.0,0.0,0.0,0.0,0.0,2.0,0.0,311.0,158.0,0.0,0.0,29.0,,,0.0,,0.0,0.0,,0.0,0.0,0.0,0.0,0.0,,,0.0,,0.0,0.0,0.0,0.0,153.0,0.0,,248.0,6.0,,,0.0,0.0,0.0,0.0,0.0,,0.0,6.0,0.0,,0.0,15.0,0.0,42.0,0.0,0.0,0.0,0.0,,0.0,,2.0,0.0,0.0,,0.0,1.0,0.0 +"Microsoft.CodeAnalysis.CSharp.UsePatternMatching.CSharpIsAndCastCheckDiagnosticAnalyzer,Microsoft.CodeAnalysis.CSharp.Features,Version=42.42.42.42,Culture=neutral,PublicKeyToken=31bf3856ad364e35",4.0,15.0,0.0,,3.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,,,,,,,2.0,0.0,2.0,,0.0,0.0,0.0,,0.0,0.0,0.0,0.0,,,24.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,,,0.0,0.0,0.0,,0.0,0.0,0.0,0.0,0.0,,,,0.0,0.0,,0.0,0.0,,1.0,0.0,,0.0,,0.0,0.0,0.0,0.0,0.0,0.0,0.0,,0.0,0.0,0.0,,0.0,0.0,0.0,0.0,0.0,,,0.0,1.0,0.0,0.0,0.0,0.0,,0.0,4.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,,,,,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,1.0,,,0.0,,0.0,0.0,0.0,0.0,,0.0,0.0,0.0,0.0,0.0,0.0,0.0,,6.0,,1.0,0.0,2.0,0.0,0.0,0.0,0.0,0.0,,0.0,0.0,,3.0,1.0,0.0,0.0,0.0,,0.0,,0.0,0.0,2.0,,0.0,,,0.0,,0.0,0.0,,,3.0,1.0,0.0,1.0,0.0,0.0,0.0,,0.0,,,,2.0,0.0,0.0,0.0,0.0,,0.0,0.0,0.0,0.0,,,28.0,0.0,1.0,1.0,,0.0,0.0,0.0,,0.0,0.0,0.0,0.0,0.0,1.0,,0.0,0.0,,0.0,,0.0,0.0,,0.0,,0.0,0.0,0.0,0.0,,0.0,0.0,0.0,0.0,,0.0,0.0,0.0,0.0,0.0,1.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,,3.0,,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,1.0,3.0,1.0,0.0,0.0,0.0,,,0.0,,0.0,0.0,,0.0,0.0,0.0,0.0,0.0,,,0.0,,0.0,0.0,0.0,0.0,30.0,0.0,,2.0,0.0,,,0.0,0.0,0.0,0.0,0.0,,0.0,0.0,0.0,,0.0,1.0,0.0,0.0,0.0,0.0,0.0,0.0,,0.0,,1.0,0.0,0.0,,0.0,1.0,0.0 +"Microsoft.CodeAnalysis.CSharp.UseThrowExpression.CSharpUseThrowExpressionDiagnosticAnalyzer,Microsoft.CodeAnalysis.CSharp.Features,Version=42.42.42.42,Culture=neutral,PublicKeyToken=31bf3856ad364e35",1549.0,701.0,0.0,,847.0,27.0,118.0,33.0,7.0,4.0,2.0,2.0,6.0,3.0,0.0,7.0,137.0,44.0,,,,,,,770.0,62.0,46.0,,20.0,11.0,0.0,,3.0,2.0,151.0,70.0,,,35.0,0.0,64.0,5.0,3.0,0.0,1.0,0.0,,,1.0,1.0,28.0,,1.0,0.0,2.0,164.0,109.0,,,,0.0,0.0,,1.0,0.0,,406.0,0.0,,1.0,,0.0,0.0,0.0,2.0,0.0,5.0,12.0,,56.0,10.0,2.0,,0.0,4.0,48.0,72.0,2.0,,,1.0,6.0,0.0,0.0,0.0,0.0,,0.0,9.0,5.0,0.0,0.0,0.0,0.0,0.0,0.0,,,,,0.0,0.0,0.0,0.0,99.0,0.0,0.0,0.0,0.0,0.0,0.0,3.0,0.0,0.0,0.0,1.0,0.0,0.0,0.0,0.0,0.0,0.0,3.0,0.0,28.0,0.0,2.0,,,5.0,,1.0,2.0,2.0,0.0,,2.0,1.0,0.0,0.0,1.0,170.0,107.0,,916.0,,854.0,0.0,791.0,193.0,2.0,64.0,2.0,26.0,,1.0,163.0,,780.0,874.0,0.0,3.0,4.0,,2.0,,227.0,7.0,84.0,,18.0,,,4.0,,0.0,132.0,,,802.0,531.0,2.0,982.0,8.0,0.0,7.0,,9.0,,,,88.0,2.0,2.0,123.0,2.0,,2.0,4.0,0.0,220.0,,,963.0,52.0,587.0,897.0,,0.0,2.0,3.0,,2.0,77.0,0.0,0.0,0.0,484.0,,0.0,1.0,,4.0,,0.0,0.0,,136.0,,129.0,0.0,1.0,1.0,,2.0,28.0,0.0,0.0,,0.0,57.0,3.0,7.0,0.0,790.0,142.0,0.0,1.0,0.0,3.0,1.0,128.0,,953.0,,0.0,1.0,0.0,0.0,1.0,0.0,0.0,9.0,5.0,1136.0,742.0,7.0,7.0,109.0,,,1.0,,0.0,6.0,,0.0,0.0,27.0,2.0,2.0,,,0.0,,0.0,1.0,0.0,0.0,424.0,0.0,,113.0,33.0,,,0.0,0.0,0.0,1.0,1.0,,1.0,44.0,0.0,,0.0,6.0,0.0,65.0,0.0,2.0,2.0,2.0,,15.0,,1.0,0.0,27.0,,66.0,4.0,0.0 +"Microsoft.CodeAnalysis.Diagnostics.CSharp.CSharpCompilerDiagnosticAnalyzer,Microsoft.CodeAnalysis.CSharp,Version=42.42.42.42,Culture=neutral,PublicKeyToken=31bf3856ad364e35",18209.0,1446.0,2.0,,2085.0,7.0,69.0,15.0,49.0,9.0,6.0,4.0,4.0,6.0,0.0,3.0,54.0,42.0,,,,,,,1285.0,57.0,148.0,,1.0,23.0,3.0,,4.0,4.0,862.0,841.0,,,450.0,49.0,25.0,3.0,8.0,0.0,4.0,2.0,,,4.0,5.0,100.0,,359.0,60.0,56.0,702.0,90.0,,,,1.0,0.0,,9.0,2.0,,162.0,17.0,,30.0,,0.0,0.0,0.0,25.0,5.0,45.0,17.0,,9.0,31.0,4.0,,0.0,2.0,13.0,54.0,6.0,,,4.0,13.0,1.0,0.0,6.0,2.0,,0.0,79.0,55.0,0.0,0.0,0.0,0.0,0.0,6.0,,,,,0.0,0.0,0.0,1.0,48.0,1.0,42.0,0.0,0.0,3.0,1.0,14.0,0.0,23.0,0.0,2.0,0.0,4.0,0.0,3.0,19.0,0.0,2.0,0.0,1.0,0.0,3.0,,,45.0,,18.0,4.0,3.0,0.0,,23.0,1.0,0.0,0.0,4.0,896.0,66.0,,1789.0,,1650.0,2.0,1599.0,1174.0,4.0,41.0,5.0,49.0,,4.0,62.0,,1946.0,1556.0,2.0,7.0,3.0,,5.0,,77.0,6.0,173.0,,10.0,,,10.0,,1.0,57.0,,,1726.0,1500.0,5.0,1560.0,50.0,2.0,4.0,,31.0,,,,182.0,7.0,4.0,59.0,5.0,,6.0,49.0,3.0,114.0,,,1737.0,10.0,1482.0,1573.0,,2.0,33.0,10.0,,4.0,952.0,2.0,63.0,2.0,81.0,,1.0,43.0,,8.0,,0.0,32.0,,90.0,,635.0,18.0,409.0,63.0,,46.0,79.0,4.0,1.0,,1.0,80.0,10.0,5.0,0.0,1725.0,17.0,5.0,9.0,0.0,37.0,5.0,70.0,,1748.0,,28.0,65.0,0.0,0.0,0.0,1.0,0.0,83.0,65.0,1559.0,1445.0,5.0,57.0,69.0,,,4.0,,1.0,4.0,,0.0,0.0,16.0,4.0,4.0,,,0.0,,0.0,30.0,0.0,0.0,1473.0,0.0,,181.0,86.0,,,1.0,0.0,0.0,1.0,3.0,,32.0,23.0,0.0,,19.0,14.0,0.0,41.0,0.0,7.0,4.0,3.0,,10.0,,3.0,0.0,1.0,,3.0,5.0,2.0 +"Microsoft.CodeAnalysis.Diagnostics.VisualBasic.VisualBasicCompilerDiagnosticAnalyzer,Microsoft.CodeAnalysis.VisualBasic,Version=42.42.42.42,Culture=neutral,PublicKeyToken=31bf3856ad364e35",,,,51762.0,,,,,,,,,,,,,,,19.0,7.0,152.0,165.0,76.0,89.0,,,,413.0,,,,20.0,,,,,1420.0,135.0,,,,,,,,,40.0,3.0,,,,993.0,,,,,,173.0,6.0,186.0,,,0.0,,,2.0,,,9.0,,893.0,,,,,,,,51.0,,,,32.0,,,,,,47.0,25.0,,,,,,,2.0,,,,,,,,,,37.0,0.0,0.0,0.0,,,,,,,,,,,,,,,,,,,,,,,,,,,,6.0,0.0,,45.0,,,,,0.0,,,,,,,,51669.0,,1551.0,,,,,,,,,1875.0,,,54464.0,,,,,,133.0,,103.0,,,,11.0,,459.0,176.0,,276.0,,,53219.0,10.0,,,,,,,,11.0,,125.0,476.0,163.0,,,,,,234.0,,,,,53417.0,35.0,,,,,137.0,,,,1120.0,,,,,,,6.0,,,183.0,,589.0,,,134.0,,187.0,,,,,10.0,,,,,31.0,,,,,,,,,,,,,,54364.0,,2.0,,,,,,,,,,,,,,,6.0,127.0,,119.0,,,135.0,,,,,,105.0,33.0,,0.0,,,,,,,0.0,,,383.0,0.0,,,,,,7.0,,,,2.0,,,,,,,,,0.0,,23.0,,,,49946.0,,, +"Microsoft.CodeAnalysis.Editor.CSharp.UseAutoProperty.UseAutoPropertyAnalyzer,Microsoft.CodeAnalysis.CSharp.EditorFeatures,Version=42.42.42.42,Culture=neutral,PublicKeyToken=31bf3856ad364e35",1004.0,311.0,23.0,,613.0,2.0,76.0,1.0,6.0,0.0,0.0,0.0,0.0,0.0,0.0,5.0,232.0,602.0,,,,,,,363.0,6.0,398.0,,0.0,19.0,50.0,,52.0,0.0,172.0,51.0,,,24.0,0.0,2.0,0.0,0.0,0.0,0.0,0.0,,,0.0,0.0,33.0,,74.0,21.0,58.0,121.0,10.0,,,,0.0,0.0,,2.0,0.0,,4.0,0.0,,13.0,,0.0,0.0,0.0,0.0,0.0,1.0,0.0,,0.0,21.0,0.0,,0.0,0.0,138.0,3.0,153.0,,,0.0,20.0,0.0,0.0,0.0,0.0,,0.0,231.0,305.0,0.0,0.0,0.0,0.0,0.0,37.0,,,,,0.0,0.0,0.0,0.0,2.0,0.0,2.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,40.0,0.0,0.0,0.0,0.0,16.0,0.0,0.0,,,1.0,,0.0,0.0,0.0,0.0,,0.0,0.0,0.0,0.0,0.0,119.0,6.0,,1001.0,,267.0,2.0,208.0,54.0,0.0,40.0,0.0,3.0,,0.0,71.0,,892.0,306.0,2.0,0.0,28.0,,38.0,,41.0,0.0,97.0,,53.0,,,73.0,,0.0,7.0,,,2028.0,136.0,0.0,188.0,89.0,27.0,0.0,,25.0,,,,99.0,0.0,0.0,55.0,0.0,,0.0,50.0,0.0,228.0,,,976.0,1.0,281.0,270.0,,2.0,0.0,0.0,,0.0,104.0,0.0,32.0,0.0,48.0,,0.0,2.0,,0.0,,0.0,0.0,,43.0,,143.0,2.0,137.0,174.0,,5.0,6.0,0.0,0.0,,0.0,26.0,0.0,2.0,0.0,176.0,2.0,0.0,2.0,0.0,0.0,0.0,76.0,,1048.0,,2.0,0.0,0.0,0.0,0.0,0.0,0.0,167.0,97.0,854.0,131.0,25.0,6.0,136.0,,,1.0,,0.0,1.0,,0.0,0.0,0.0,0.0,0.0,,,0.0,,0.0,0.0,0.0,0.0,122.0,0.0,,101.0,238.0,,,0.0,0.0,0.0,0.0,0.0,,29.0,2.0,0.0,,0.0,2.0,0.0,146.0,0.0,0.0,0.0,0.0,,24.0,,0.0,0.0,0.0,,1.0,0.0,2.0 +"Microsoft.CodeAnalysis.Editor.VisualBasic.UseAutoProperty.UseAutoPropertyAnalyzer,Microsoft.CodeAnalysis.VisualBasic.EditorFeatures,Version=42.42.42.42,Culture=neutral,PublicKeyToken=31bf3856ad364e35",,,,12685.0,,,,,,,,,,,,,,,0.0,0.0,0.0,0.0,0.0,0.0,,,,35.0,,,,0.0,,,,,0.0,6.0,,,,,,,,,0.0,0.0,,,,0.0,,,,,,47.0,2.0,10.0,,,0.0,,,0.0,,,23.0,,9.0,,,,,,,,14.0,,,,0.0,,,,,,0.0,0.0,,,,,,,0.0,,,,,,,,,,0.0,0.0,0.0,0.0,,,,,,,,,,,,,,,,,,,,,,,,,,,,0.0,0.0,,0.0,,,,,0.0,,,,,,,,13561.0,,0.0,,,,,,,,,0.0,,,12758.0,,,,,,0.0,,0.0,,,,0.0,,36.0,0.0,,0.0,,,15289.0,0.0,,,,,,,,0.0,,0.0,38.0,0.0,,,,,,0.0,,,,,12805.0,57.0,,,,,0.0,,,,0.0,,,,,,,2.0,,,3.0,,10.0,,,6.0,,11.0,,,,,25.0,,,,,0.0,,,,,,,,,,,,,,12819.0,,0.0,,,,,,,,,,,,,,,0.0,0.0,,0.0,,,0.0,,,,,,0.0,0.0,,0.0,,,,,,,0.0,,,38.0,0.0,,,,,,0.0,,,,0.0,,,,,,,,,0.0,,0.0,,,,11983.0,,, +"Microsoft.CodeAnalysis.PopulateSwitch.PopulateSwitchDiagnosticAnalyzer,Microsoft.CodeAnalysis.Features,Version=42.42.42.42,Culture=neutral,PublicKeyToken=31bf3856ad364e35",15.0,42.0,0.0,414.0,374.0,0.0,4.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,10.0,86.0,0.0,0.0,15.0,15.0,3.0,1.0,4.0,0.0,25.0,204.0,0.0,0.0,0.0,0.0,0.0,0.0,2.0,2.0,1882.0,2.0,67.0,2.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,38.0,2.0,22.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,27.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,1.0,0.0,52.0,23.0,37.0,28.0,2.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,2.0,52.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,2.0,18.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,2.0,25.0,447.0,570.0,270.0,15.0,0.0,53.0,3.0,0.0,0.0,0.0,0.0,72.0,0.0,0.0,2288.0,3767.0,152.0,0.0,0.0,0.0,3.0,0.0,3.0,0.0,0.0,29.0,0.0,0.0,280.0,3.0,0.0,42.0,0.0,0.0,878.0,0.0,858.0,3.0,0.0,36.0,0.0,0.0,0.0,0.0,0.0,860.0,292.0,110.0,393.0,0.0,0.0,0.0,0.0,3.0,0.0,0.0,0.0,0.0,1706.0,0.0,1679.0,0.0,30.0,33.0,9.0,0.0,0.0,0.0,1.0,0.0,5.0,0.0,0.0,0.0,84.0,0.0,0.0,0.0,435.0,0.0,0.0,0.0,0.0,3.0,5.0,1.0,12.0,0.0,30.0,13.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,57.0,0.0,0.0,0.0,0.0,0.0,0.0,9.0,839.0,1609.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,5.0,9.0,1215.0,137.0,0.0,0.0,76.0,0.0,6.0,0.0,9.0,0.0,0.0,6.0,0.0,0.0,1.0,0.0,0.0,34.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,10.0,0.0,0.0,159.0,101.0,275.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,1.0,0.0,7.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,1339.0,0.0,0.0,0.0 +"Microsoft.CodeAnalysis.UseExplicitTupleName.UseExplicitTupleNameDiagnosticAnalyzer,Microsoft.CodeAnalysis.Features,Version=42.42.42.42,Culture=neutral,PublicKeyToken=31bf3856ad364e35",207.0,453.0,22.0,1075.0,748.0,2.0,8.0,2.0,7.0,1.0,0.0,0.0,1.0,1.0,0.0,7.0,276.0,171.0,2.0,7.0,73.0,267.0,52.0,230.0,39.0,5.0,19.0,183.0,0.0,6.0,7.0,8.0,0.0,0.0,73.0,79.0,128.0,228.0,21.0,2.0,2.0,0.0,1.0,0.0,0.0,0.0,0.0,0.0,0.0,1.0,6.0,87.0,74.0,6.0,7.0,31.0,28.0,26.0,1.0,47.0,0.0,0.0,0.0,1.0,0.0,0.0,42.0,0.0,2.0,3.0,53.0,0.0,0.0,0.0,0.0,0.0,3.0,1.0,4.0,20.0,78.0,2.0,4.0,0.0,1.0,118.0,5.0,43.0,8.0,2.0,1.0,2.0,0.0,0.0,0.0,0.0,0.0,0.0,269.0,60.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,3.0,0.0,8.0,0.0,0.0,0.0,0.0,1.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,1.0,0.0,1.0,7.0,0.0,9.0,4.0,2.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,1.0,30.0,8.0,1022.0,365.0,352.0,211.0,1.0,102.0,30.0,40.0,2.0,0.0,23.0,181.0,0.0,8.0,636.0,752.0,275.0,1.0,0.0,0.0,103.0,0.0,111.0,85.0,1.0,61.0,3.0,2.0,30.0,191.0,1.0,114.0,0.0,11.0,640.0,21.0,436.0,68.0,0.0,165.0,28.0,1.0,1.0,2.0,51.0,67.0,59.0,48.0,94.0,0.0,0.0,5.0,0.0,221.0,0.0,1.0,0.0,8.0,692.0,45.0,622.0,3.0,93.0,155.0,63.0,1.0,0.0,1.0,31.0,0.0,20.0,0.0,7.0,1.0,9.0,1.0,0.0,4.0,70.0,1.0,98.0,0.0,0.0,5.0,5.0,42.0,82.0,8.0,60.0,2.0,1.0,8.0,6.0,0.0,0.0,0.0,0.0,7.0,1.0,7.0,0.0,74.0,3.0,0.0,1.0,0.0,0.0,1.0,9.0,455.0,714.0,0.0,1.0,0.0,0.0,0.0,0.0,0.0,0.0,157.0,81.0,2437.0,130.0,19.0,7.0,82.0,7.0,137.0,32.0,70.0,0.0,1.0,265.0,0.0,0.0,34.0,0.0,0.0,39.0,2.0,0.0,0.0,0.0,1.0,0.0,0.0,251.0,0.0,0.0,72.0,309.0,844.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,2.0,0.0,0.0,1.0,2.0,0.0,8.0,0.0,0.0,17.0,0.0,0.0,2.0,43.0,2.0,0.0,1.0,19879.0,1.0,1.0,1.0 +"Microsoft.CodeAnalysis.VisualBasic.Diagnostics.RemoveUnnecessaryCast.VisualBasicRemoveUnnecessaryCastDiagnosticAnalyzer,Microsoft.CodeAnalysis.VisualBasic.Features,Version=42.42.42.42,Culture=neutral,PublicKeyToken=31bf3856ad364e35",,,,5117.0,,,,,,,,,,,,,,,234.0,49.0,5188.0,3095.0,3684.0,661.0,,,,2095.0,,,,9.0,,,,,1041.0,94.0,,,,,,,,,0.0,0.0,,,,127.0,,,,,,800.0,6.0,250.0,,,0.0,,,0.0,,,7.0,,751.0,,,,,,,,92.0,,,,10.0,,,,,,375.0,38.0,,,,,,,0.0,,,,,,,,,,0.0,0.0,0.0,0.0,,,,,,,,,,,,,,,,,,,,,,,,,,,,18.0,0.0,,30.0,,,,,0.0,,,,,,,,5580.0,,1421.0,,,,,,,,,1417.0,,,4633.0,,,,,,1115.0,,4437.0,,,,193.0,,1643.0,6604.0,,2602.0,,,4728.0,121.0,,,,,,,,154.0,,5478.0,2480.0,8453.0,,,,,,3373.0,,,,,4521.0,18.0,,,,,772.0,,,,127.0,,,,,,,7.0,,,776.0,,745.0,,,73.0,,144.0,,,,,7.0,,,,,0.0,,,,,,,,,,,,,,4672.0,,0.0,,,,,,,,,,,,,,,44.0,5649.0,,685.0,,,2965.0,,,,,,4316.0,152.0,,0.0,,,,,,,0.0,,,1616.0,0.0,,,,,,4.0,,,,0.0,,,,,,,,,0.0,,21.0,,,,4247.0,,, +"Microsoft.CodeAnalysis.VisualBasic.Diagnostics.VisualBasicUnboundIdentifiersDiagnosticAnalyzer,Microsoft.CodeAnalysis.VisualBasic.Features,Version=42.42.42.42,Culture=neutral,PublicKeyToken=31bf3856ad364e35",,,,7.0,,,,,,,,,,,,,,,0.0,0.0,2.0,3.0,2.0,0.0,,,,1.0,,,,0.0,,,,,1.0,0.0,,,,,,,,,0.0,0.0,,,,1.0,,,,,,1.0,0.0,25.0,,,0.0,,,0.0,,,0.0,,1.0,,,,,,,,0.0,,,,0.0,,,,,,1.0,0.0,,,,,,,0.0,,,,,,,,,,0.0,0.0,0.0,0.0,,,,,,,,,,,,,,,,,,,,,,,,,,,,0.0,0.0,,0.0,,,,,0.0,,,,,,,,5.0,,1.0,,,,,,,,,15.0,,,5.0,,,,,,0.0,,4.0,,,,0.0,,2.0,2.0,,37.0,,,5.0,0.0,,,,,,,,0.0,,30.0,3.0,3.0,,,,,,2.0,,,,,5.0,0.0,,,,,2.0,,,,1.0,,,,,,,0.0,,,0.0,,2.0,,,0.0,,25.0,,,,,0.0,,,,,0.0,,,,,,,,,,,,,,5.0,,0.0,,,,,,,,,,,,,,,0.0,2.0,,0.0,,,2.0,,,,,,2.0,0.0,,0.0,,,,,,,0.0,,,2.0,0.0,,,,,,0.0,,,,0.0,,,,,,,,,0.0,,0.0,,,,51.0,,, +"Microsoft.CodeAnalysis.VisualBasic.UseCoalesceExpression.VisualBasicUseCoalesceExpressionDiagnosticAnalyzer,Microsoft.CodeAnalysis.VisualBasic.Features,Version=42.42.42.42,Culture=neutral,PublicKeyToken=31bf3856ad364e35",,,,115.0,,,,,,,,,,,,,,,0.0,0.0,0.0,0.0,0.0,0.0,,,,2.0,,,,0.0,,,,,2.0,57.0,,,,,,,,,0.0,0.0,,,,0.0,,,,,,0.0,0.0,0.0,,,0.0,,,0.0,,,0.0,,0.0,,,,,,,,0.0,,,,0.0,,,,,,0.0,0.0,,,,,,,0.0,,,,,,,,,,0.0,0.0,0.0,0.0,,,,,,,,,,,,,,,,,,,,,,,,,,,,0.0,0.0,,0.0,,,,,0.0,,,,,,,,84.0,,4.0,,,,,,,,,3.0,,,64.0,,,,,,0.0,,0.0,,,,0.0,,2.0,0.0,,0.0,,,15.0,0.0,,,,,,,,0.0,,0.0,2.0,0.0,,,,,,0.0,,,,,12.0,0.0,,,,,0.0,,,,0.0,,,,,,,0.0,,,1.0,,0.0,,,0.0,,0.0,,,,,0.0,,,,,0.0,,,,,,,,,,,,,,26.0,,0.0,,,,,,,,,,,,,,,0.0,0.0,,0.0,,,0.0,,,,,,0.0,30.0,,0.0,,,,,,,0.0,,,1189.0,0.0,,,,,,0.0,,,,0.0,,,,,,,,,0.0,,0.0,,,,12.0,,, +"Microsoft.CodeAnalysis.VisualBasic.UseCoalesceExpression.VisualBasicUseCoalesceExpressionForNullableDiagnosticAnalyzer,Microsoft.CodeAnalysis.VisualBasic.Features,Version=42.42.42.42,Culture=neutral,PublicKeyToken=31bf3856ad364e35",,,,131.0,,,,,,,,,,,,,,,0.0,0.0,0.0,0.0,0.0,0.0,,,,1.0,,,,0.0,,,,,1.0,0.0,,,,,,,,,0.0,0.0,,,,0.0,,,,,,0.0,0.0,0.0,,,0.0,,,0.0,,,0.0,,0.0,,,,,,,,0.0,,,,0.0,,,,,,0.0,0.0,,,,,,,0.0,,,,,,,,,,0.0,0.0,0.0,0.0,,,,,,,,,,,,,,,,,,,,,,,,,,,,0.0,0.0,,0.0,,,,,0.0,,,,,,,,116.0,,1.0,,,,,,,,,1.0,,,10.0,,,,,,0.0,,0.0,,,,0.0,,1.0,0.0,,0.0,,,9.0,0.0,,,,,,,,0.0,,0.0,1.0,0.0,,,,,,0.0,,,,,34.0,0.0,,,,,0.0,,,,0.0,,,,,,,0.0,,,0.0,,0.0,,,0.0,,0.0,,,,,0.0,,,,,0.0,,,,,,,,,,,,,,47.0,,0.0,,,,,,,,,,,,,,,0.0,0.0,,0.0,,,0.0,,,,,,0.0,0.0,,0.0,,,,,,,0.0,,,1.0,0.0,,,,,,0.0,,,,0.0,,,,,,,,,0.0,,0.0,,,,10.0,,, +"Microsoft.CodeAnalysis.VisualBasic.UseCollectionInitializer.VisualBasicUseCollectionInitializerDiagnosticAnalyzer,Microsoft.CodeAnalysis.VisualBasic.Features,Version=42.42.42.42,Culture=neutral,PublicKeyToken=31bf3856ad364e35",,,,1598.0,,,,,,,,,,,,,,,485.0,54.0,870.0,674.0,458.0,311.0,,,,250.0,,,,44.0,,,,,404.0,77.0,,,,,,,,,1.0,1.0,,,,3132.0,,,,,,111.0,4.0,278.0,,,1.0,,,1.0,,,34.0,,569.0,,,,,,,,234.0,,,,2.0,,,,,,216.0,10.0,,,,,,,1.0,,,,,,,,,,4.0,0.0,0.0,0.0,,,,,,,,,,,,,,,,,,,,,,,,,,,,49.0,0.0,,3.0,,,,,1.0,,,,,,,,1413.0,,844.0,,,,,,,,,1378.0,,,1406.0,,,,,,325.0,,7149.0,,,,32.0,,162.0,1354.0,,464.0,,,1836.0,153.0,,,,,,,,42.0,,400.0,1434.0,1152.0,,,,,,1206.0,,,,,1236.0,140.0,,,,,407.0,,,,545.0,,,,,,,4.0,,,89.0,,566.0,,,48.0,,538.0,,,,,13.0,,,,,2.0,,,,,,,,,,,,,,2007.0,,32.0,,,,,,,,,,,,,,,57.0,873.0,,235.0,,,512.0,,,,,,316.0,287.0,,0.0,,,,,,,0.0,,,279.0,0.0,,,,,,3.0,,,,32.0,,,,,,,,,0.0,,30.0,,,,1096.0,,, +"Microsoft.CodeAnalysis.VisualBasic.UseNullPropagation.VisualBasicUseNullPropagationDiagnosticAnalyzer,Microsoft.CodeAnalysis.VisualBasic.Features,Version=42.42.42.42,Culture=neutral,PublicKeyToken=31bf3856ad364e35",,,,454.0,,,,,,,,,,,,,,,24.0,0.0,417.0,0.0,0.0,0.0,,,,28.0,,,,0.0,,,,,0.0,0.0,,,,,,,,,0.0,0.0,,,,0.0,,,,,,1.0,0.0,0.0,,,0.0,,,0.0,,,0.0,,0.0,,,,,,,,0.0,,,,0.0,,,,,,0.0,0.0,,,,,,,0.0,,,,,,,,,,0.0,0.0,0.0,0.0,,,,,,,,,,,,,,,,,,,,,,,,,,,,0.0,0.0,,0.0,,,,,0.0,,,,,,,,150.0,,0.0,,,,,,,,,1.0,,,110.0,,,,,,0.0,,0.0,,,,2.0,,53.0,26.0,,433.0,,,738.0,0.0,,,,,,,,2.0,,0.0,3.0,2.0,,,,,,0.0,,,,,16.0,0.0,,,,,0.0,,,,0.0,,,,,,,0.0,,,220.0,,0.0,,,0.0,,0.0,,,,,0.0,,,,,0.0,,,,,,,,,,,,,,77.0,,0.0,,,,,,,,,,,,,,,0.0,2.0,,0.0,,,0.0,,,,,,0.0,1.0,,0.0,,,,,,,0.0,,,33.0,0.0,,,,,,0.0,,,,0.0,,,,,,,,,0.0,,0.0,,,,20.0,,, +"Microsoft.CodeAnalysis.VisualBasic.UseObjectInitializer.VisualBasicUseObjectInitializerDiagnosticAnalyzer,Microsoft.CodeAnalysis.VisualBasic.Features,Version=42.42.42.42,Culture=neutral,PublicKeyToken=31bf3856ad364e35",,,,747.0,,,,,,,,,,,,,,,2.0,37.0,21.0,90.0,26.0,43.0,,,,66.0,,,,0.0,,,,,137.0,4.0,,,,,,,,,0.0,0.0,,,,18.0,,,,,,138.0,1.0,11.0,,,0.0,,,0.0,,,75.0,,91.0,,,,,,,,9.0,,,,0.0,,,,,,149.0,4.0,,,,,,,0.0,,,,,,,,,,3.0,0.0,0.0,0.0,,,,,,,,,,,,,,,,,,,,,,,,,,,,1.0,0.0,,0.0,,,,,0.0,,,,,,,,828.0,,117.0,,,,,,,,,128.0,,,602.0,,,,,,56.0,,167.0,,,,55.0,,120.0,24.0,,88.0,,,767.0,23.0,,,,,,,,2.0,,60.0,58.0,101.0,,,,,,157.0,,,,,997.0,61.0,,,,,15.0,,,,17.0,,,,,,,1.0,,,5.0,,19.0,,,5.0,,11.0,,,,,3.0,,,,,0.0,,,,,,,,,,,,,,560.0,,0.0,,,,,,,,,,,,,,,45.0,23.0,,3602.0,,,40.0,,,,,,26.0,2.0,,0.0,,,,,,,0.0,,,82.0,0.0,,,,,,0.0,,,,3.0,,,,,,,,,0.0,,2.0,,,,11812.0,,, +"Microsoft.Composition.Analyzers.DoNotMixAttributesFromDifferentVersionsOfMEFAnalyzer,Microsoft.NetCore.Analyzers,Version=2.0.0.0,Culture=neutral,PublicKeyToken=31bf3856ad364e35",,,,,,,,1.0,0.0,0.0,0.0,0.0,0.0,,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,,59.0,,,0.0,35.0,0.0,0.0,0.0,0.0,,6.0,,28.0,,1.0,,0.0,0.0,0.0,,0.0,,0.0,0.0,0.0,2.0,1.0,1.0,1.0,1.0,4.0,20.0,1.0,0.0,1.0,0.0,0.0,0.0,0.0,0.0,0.0,25.0,0.0,0.0,0.0,1.0,0.0,0.0,0.0,0.0,0.0,,,,,,,,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,,0.0,0.0,,0.0,0.0,0.0,,,,,,,,,,,,,,,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,,,,,,,,,,,,,,,,,0.0,,,,,,,,,,,,,,,,,,,,,,,0.0,0.0,0.0,1.0,0.0,,0.0,0.0,,0.0,0.0,0.0,0.0,,,0.0,,,0.0,,0.0,,0.0,0.0,0.0,0.0,,0.0,,,,36.0,0.0,0.0,0.0,0.0,0.0,,,0.0,,0.0,,,0.0,,0.0,0.0,2.0,0.0,6.0,0.0,1.0,0.0,1.0,0.0,0.0,0.0,0.0,0.0,2.0,0.0,0.0,1.0,1.0,1.0,4.0,0.0,1.0,1.0,0.0,2.0,2.0,0.0,0.0,0.0,0.0,3.0,2.0,0.0,0.0,,0.0,0.0,1.0,0.0,1.0,0.0,,,,0.0,,,,,,,,,,,,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,,,0.0,,,,,,,0.0,,,0.0,,,,,,,,,,,,,,,,,,,0.0,,,,,,,, +"Microsoft.Composition.Analyzers.PartsExportedWithMEFv2MustBeMarkedAsSharedAnalyzer,Microsoft.NetCore.Analyzers,Version=2.0.0.0,Culture=neutral,PublicKeyToken=31bf3856ad364e35",,,,,,,,1.0,0.0,0.0,0.0,0.0,0.0,,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,19.0,0.0,,35.0,,,0.0,0.0,0.0,0.0,0.0,0.0,,5.0,,1.0,,0.0,,0.0,0.0,0.0,,0.0,,0.0,0.0,0.0,0.0,2.0,3.0,0.0,0.0,3.0,1.0,2.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,,,,,,,,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,,0.0,0.0,,0.0,0.0,0.0,,,,,,,,,,,,,,,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,,,,,,,,,,,,,,,,,0.0,,,,,,,,,,,,,,,,,,,,,,,0.0,0.0,0.0,0.0,0.0,,0.0,0.0,,0.0,0.0,0.0,0.0,,,0.0,,,0.0,,0.0,,0.0,0.0,0.0,0.0,,0.0,,,,0.0,0.0,0.0,0.0,0.0,0.0,,,0.0,,0.0,,,0.0,,0.0,0.0,32.0,0.0,4.0,0.0,0.0,0.0,1.0,0.0,0.0,0.0,36.0,0.0,0.0,0.0,0.0,0.0,1.0,0.0,3.0,1.0,3.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,,0.0,0.0,0.0,0.0,0.0,0.0,,,,0.0,,,,,,,,,,,,0.0,0.0,18.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,,,0.0,,,,,,,0.0,,,0.0,,,,,,,,,,,,,,,,,,,0.0,,,,,,,, +"Microsoft.QualityGuidelines.Analyzers.SealMethodsThatSatisfyPrivateInterfacesAnalyzer,Microsoft.CodeQuality.Analyzers,Version=2.0.0.0,Culture=neutral,PublicKeyToken=31bf3856ad364e35",,,,,,,,11.0,0.0,0.0,0.0,0.0,0.0,,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,,0.0,,,0.0,0.0,0.0,0.0,0.0,0.0,,0.0,,0.0,,0.0,,0.0,0.0,0.0,,0.0,,0.0,0.0,0.0,0.0,1.0,1.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,73.0,0.0,0.0,0.0,0.0,0.0,,,,,,,,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,,0.0,0.0,,0.0,0.0,0.0,,,,,,,,,,,,,,,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,,,,,,,,,,,,,,,,,0.0,,,,,,,,,,,,,,,,,,,,,,,0.0,0.0,0.0,0.0,0.0,,0.0,0.0,,0.0,0.0,0.0,0.0,,,0.0,,,0.0,,0.0,,0.0,0.0,0.0,0.0,,0.0,,,,0.0,0.0,0.0,0.0,0.0,0.0,,,0.0,,0.0,,,0.0,,0.0,0.0,1.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,100.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,1.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,44.0,0.0,0.0,0.0,,0.0,0.0,0.0,0.0,0.0,0.0,,,,0.0,,,,,,,,,,,,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,,,0.0,,,,,,,0.0,,,0.0,,,,,,,,,,,,,,,,,,,0.0,,,,,,,, +"Microsoft.QualityGuidelines.CSharp.Analyzers.CSharpRethrowToPreserveStackDetailsAnalyzer,Microsoft.CodeQuality.CSharp.Analyzers,Version=2.0.0.0,Culture=neutral,PublicKeyToken=31bf3856ad364e35",,,,,,,,2.0,0.0,0.0,0.0,0.0,0.0,,0.0,0.0,0.0,0.0,,,,,,,,0.0,,,0.0,0.0,0.0,,0.0,0.0,,0.0,,,,0.0,,0.0,0.0,0.0,,0.0,,,0.0,0.0,0.0,,0.0,0.0,0.0,0.0,0.0,,,,0.0,0.0,,0.0,0.0,,0.0,0.0,,0.0,,0.0,0.0,0.0,0.0,0.0,,,,,,,,0.0,0.0,0.0,0.0,0.0,,,0.0,,0.0,0.0,,0.0,,0.0,,,,,,,,,,,,,,,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,,,,,,,,,,,,,,,,,0.0,,,,,,,,,,,,,,,,,,,,,,,,0.0,,0.0,0.0,,,0.0,,,0.0,,0.0,,,,,,0.0,,0.0,,0.0,,0.0,,,,,,,0.0,0.0,,0.0,0.0,0.0,,,,,0.0,,,,,0.0,0.0,,0.0,0.0,0.0,0.0,0.0,0.0,,0.0,0.0,,0.0,,0.0,0.0,,0.0,,0.0,0.0,0.0,0.0,,0.0,0.0,0.0,0.0,,0.0,0.0,0.0,0.0,0.0,,0.0,0.0,0.0,0.0,0.0,0.0,,,,,,,,,,,,,,,,0.0,0.0,0.0,,,0.0,,0.0,0.0,,0.0,0.0,0.0,0.0,0.0,,,0.0,,,0.0,,,,,,,0.0,,,0.0,,,,,,,,,,,,,,,,,,,0.0,,,,,,,, +"Microsoft.QualityGuidelines.VisualBasic.Analyzers.BasicRethrowToPreserveStackDetailsAnalyzer,Microsoft.CodeQuality.VisualBasic.Analyzers,Version=2.0.0.0,Culture=neutral,PublicKeyToken=31bf3856ad364e35",,,,,,,,,,,,,,,,,,,1.0,0.0,0.0,0.0,0.0,0.0,,,,,,,,0.0,,,,,,0.0,,,,,,,,,,0.0,,,,0.0,,,,,,2.0,0.0,0.0,,,0.0,,,0.0,,,0.0,,0.0,,,,,,,,,,,,,,,,,,0.0,0.0,,,,,,,0.0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0.0,,0.0,,,,0.0,,,0.0,,0.0,,,,0.0,,,,,,,,0.0,,0.0,,0.0,,,,,,0.0,,,,,,0.0,,,,,0.0,,,,0.0,,,,,,,0.0,,,1.0,,32.0,,,0.0,,0.0,,,,,0.0,,,,,0.0,,,,,,,,,,,,,,,,0.0,,,,,,,,,,,,,,,0.0,0.0,,0.0,,,0.0,,,,,,0.0,0.0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +"Microsoft.VisualStudio.Azure.Fabric.DiagnosticAnalyzers.ServiceAssemblyNameMismatchAnalyzer,Microsoft.VisualStudio.Azure.Fabric.DiagnosticAnalyzers,Version=1.6.0.0,Culture=neutral,PublicKeyToken=b03f5f7f11d50a3a",43.0,5.0,0.0,,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,,,,,,,0.0,0.0,0.0,,0.0,0.0,0.0,,0.0,0.0,0.0,0.0,,,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,,,0.0,0.0,0.0,,0.0,0.0,0.0,0.0,0.0,,,,0.0,0.0,,0.0,0.0,,0.0,0.0,,0.0,,0.0,0.0,0.0,0.0,0.0,0.0,0.0,,0.0,0.0,0.0,,0.0,0.0,0.0,0.0,0.0,,,0.0,0.0,0.0,0.0,0.0,0.0,,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,,,,,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,,,0.0,,0.0,0.0,0.0,0.0,,0.0,0.0,0.0,0.0,0.0,0.0,0.0,,0.0,,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,,0.0,0.0,,0.0,0.0,0.0,0.0,0.0,,0.0,,0.0,0.0,0.0,,0.0,,,0.0,,0.0,0.0,,,0.0,0.0,0.0,0.0,0.0,0.0,0.0,,0.0,,,,0.0,0.0,0.0,0.0,0.0,,0.0,0.0,0.0,0.0,,,0.0,0.0,0.0,0.0,,0.0,0.0,0.0,,0.0,0.0,0.0,0.0,0.0,0.0,,0.0,0.0,,0.0,,0.0,0.0,,0.0,,0.0,0.0,0.0,0.0,,0.0,0.0,0.0,0.0,,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,,0.0,,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,,,0.0,,0.0,0.0,,0.0,0.0,0.0,0.0,0.0,,,0.0,,0.0,0.0,0.0,0.0,0.0,0.0,,0.0,0.0,,,0.0,0.0,0.0,0.0,0.0,,0.0,0.0,0.0,,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,,0.0,,0.0,0.0,0.0,,0.0,0.0,0.0 +"Microsoft.VisualStudio.Azure.Fabric.DiagnosticAnalyzers.ServiceNameMismatchSessionAnalyzer,Microsoft.VisualStudio.Azure.Fabric.DiagnosticAnalyzers,Version=1.6.0.0,Culture=neutral,PublicKeyToken=b03f5f7f11d50a3a",32.0,26.0,0.0,,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,,,,,,,0.0,0.0,0.0,,0.0,0.0,0.0,,0.0,0.0,0.0,0.0,,,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,,,0.0,0.0,0.0,,0.0,0.0,0.0,14.0,0.0,,,,0.0,0.0,,0.0,0.0,,0.0,0.0,,0.0,,0.0,0.0,0.0,0.0,0.0,0.0,0.0,,0.0,0.0,0.0,,0.0,0.0,0.0,0.0,0.0,,,0.0,0.0,0.0,0.0,0.0,0.0,,0.0,0.0,0.0,0.0,0.0,0.0,30.0,0.0,0.0,,,,,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,,,0.0,,0.0,0.0,0.0,0.0,,0.0,0.0,0.0,0.0,0.0,0.0,0.0,,0.0,,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,,0.0,0.0,,0.0,0.0,0.0,0.0,0.0,,0.0,,0.0,0.0,0.0,,0.0,,,0.0,,0.0,0.0,,,0.0,0.0,0.0,0.0,0.0,0.0,0.0,,0.0,,,,0.0,0.0,0.0,0.0,0.0,,0.0,0.0,0.0,0.0,,,0.0,0.0,0.0,0.0,,0.0,0.0,0.0,,0.0,0.0,0.0,0.0,0.0,0.0,,0.0,0.0,,0.0,,0.0,0.0,,0.0,,0.0,0.0,1.0,0.0,,0.0,0.0,0.0,0.0,,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,,0.0,,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,,,0.0,,0.0,0.0,,0.0,0.0,0.0,0.0,0.0,,,0.0,,0.0,0.0,0.0,0.0,0.0,0.0,,0.0,0.0,,,0.0,0.0,0.0,0.0,0.0,,0.0,0.0,0.0,,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,,0.0,,0.0,0.0,0.0,,0.0,0.0,0.0 +"Roslyn.Diagnostics.Analyzers.DeclarePublicAPIAnalyzer,Roslyn.Diagnostics.Analyzers,Version=2.0.0.0,Culture=neutral,PublicKeyToken=31bf3856ad364e35",,,,,,,,106.0,0.0,0.0,0.0,0.0,0.0,,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,,154.0,,,0.0,0.0,0.0,0.0,0.0,0.0,,34.0,,1.0,,1.0,,0.0,1.0,0.0,,0.0,,0.0,1.0,0.0,0.0,0.0,0.0,0.0,0.0,40.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,,,,,,,,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,,0.0,0.0,,0.0,0.0,0.0,,,,,,,,,,,,,,,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,1.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,,,,,,,,,,,,,,,,,1.0,,,,,,,,,,,,,,,,,,,,,,,0.0,0.0,0.0,4.0,0.0,,0.0,0.0,,0.0,0.0,0.0,0.0,,,0.0,,,0.0,,0.0,,0.0,0.0,0.0,0.0,,0.0,,,,6.0,0.0,0.0,0.0,0.0,0.0,,,0.0,,0.0,,,0.0,,29.0,2.0,0.0,0.0,71.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,1.0,0.0,0.0,0.0,1.0,0.0,0.0,40.0,0.0,0.0,1.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,1.0,0.0,0.0,,0.0,0.0,0.0,0.0,0.0,0.0,,,,0.0,,,,,,,,,,,,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,,,0.0,,,,,,,0.0,,,0.0,,,,,,,,,,,,,,,,,,,0.0,,,,,,,, +"Roslyn.Diagnostics.CSharp.Analyzers.CSharpCodeActionCreateAnalyzer,Roslyn.Diagnostics.CSharp.Analyzers,Version=2.0.0.0,Culture=neutral,PublicKeyToken=31bf3856ad364e35",,,,,,,,,,2.0,0.0,0.0,,,,,,,,,,,,,,352.0,,,,,,,,39.0,,2163.0,,,,315.0,,64.0,47.0,0.0,,35.0,,,146.0,74.0,,,,,,2602.0,569.0,,,,,0.0,,85.0,0.0,,825.0,39.0,,,,0.0,5.0,6.0,19.0,17.0,,,,,,,,0.0,,,,,,,,,,,,,,0.0,,,,,,,,,,,,,,,,,,,,,0.0,85.0,9.0,165.0,1.0,33.0,0.0,0.0,0.0,0.0,1.0,,0.0,0.0,,0.0,,,,,,,,,,,,,,,,,130.0,,,,,,,,,,,,,,,,,,,,,,,,0.0,,505.0,,,,,,,0.0,,,,,,,,0.0,,,,,,,,,,,,,426.0,0.0,,0.0,0.0,,,,,,,,,,,49.0,198.0,,18.0,1853.0,,,10.0,1002.0,,,,,55.0,,24.0,73.0,,534.0,,1999.0,,,591.0,,,,14.0,0.0,,13.0,,176.0,,0.0,,,67.0,136.0,8.0,18.0,190.0,,,,,,,,,,,,,,,,,,,,,,,,,,,0.0,0.0,0.0,0.0,,,0.0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +"Roslyn.Diagnostics.CSharp.Analyzers.CSharpSpecializedEnumerableCreationAnalyzer,Roslyn.Diagnostics.CSharp.Analyzers,Version=2.0.0.0,Culture=neutral,PublicKeyToken=31bf3856ad364e35",,,,,,,,16.0,47.0,1.0,0.0,0.0,0.0,,0.0,0.0,30.0,57.0,,,,,,,,0.0,,,0.0,0.0,0.0,,0.0,0.0,,0.0,,,,0.0,,0.0,0.0,0.0,,0.0,,,0.0,0.0,0.0,,0.0,13.0,0.0,0.0,0.0,,,,0.0,0.0,,0.0,0.0,,0.0,0.0,,0.0,,0.0,0.0,0.0,0.0,0.0,,,,,,,,0.0,0.0,42.0,0.0,0.0,,,0.0,,0.0,0.0,,0.0,,0.0,,,,,,,,,,,,,,,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,,,,,,,,,,,,,,,,,0.0,,,,,,,,,,,,,,,,,,,,,,,,0.0,,0.0,0.0,,,2.0,,,0.0,,0.0,,,,,,0.0,,2.0,,0.0,,1.0,,,,,,,0.0,0.0,,0.0,1.0,0.0,,,,,3.0,,,,,0.0,0.0,,0.0,0.0,0.0,0.0,0.0,0.0,,0.0,0.0,,0.0,,0.0,0.0,,0.0,,0.0,0.0,0.0,0.0,,0.0,0.0,0.0,0.0,,0.0,0.0,0.0,0.0,0.0,,0.0,0.0,0.0,0.0,0.0,0.0,,,,,,,,,,,,,,,,0.0,1.0,66.0,,,0.0,,0.0,0.0,,0.0,0.0,0.0,0.0,0.0,,,0.0,,,0.0,,,,,,,53.0,,,0.0,,,,,,,,,,,,,,,,,,,3.0,,,,,,,, +"Roslyn.Diagnostics.VisualBasic.Analyzers.BasicCodeActionCreateAnalyzer,Roslyn.Diagnostics.VisualBasic.Analyzers,Version=2.0.0.0,Culture=neutral,PublicKeyToken=31bf3856ad364e35",,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,47.0,,,,,,,,,,23.0,,,,,,,,,,151.0,,,,,0.0,,,0.0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,114.0,,,,,64.0,,,,,,,,,,,,0.0,,,,,,,,,,,,,,,,2.0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +"Roslyn.Diagnostics.VisualBasic.Analyzers.BasicSpecializedEnumerableCreationAnalyzer,Roslyn.Diagnostics.VisualBasic.Analyzers,Version=2.0.0.0,Culture=neutral,PublicKeyToken=31bf3856ad364e35",,,,,,,,,,,,,,,,,,,8.0,0.0,5.0,39.0,28.0,3.0,,,,,,,,0.0,,,,,,0.0,,,,,,,,,,0.0,,,,0.0,,,,,,0.0,0.0,0.0,,,0.0,,,0.0,,,0.0,,0.0,,,,,,,,,,,,,,,,,,215.0,40.0,,,,,,,0.0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,3.0,,5.0,,,,1.0,,,58.0,,320.0,,,,1.0,,,,,,,,1.0,,35.0,,6.0,,,,,,110.0,,,,,,0.0,,,,,4.0,,,,0.0,,,,,,,0.0,,,0.0,,0.0,,,0.0,,0.0,,,,,0.0,,,,,0.0,,,,,,,,,,,,,,,,0.0,,,,,,,,,,,,,,,0.0,51.0,,73.0,,,56.0,,,,,,35.0,2.0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +"System.Runtime.Analyzers.AttributeStringLiteralsShouldParseCorrectlyAnalyzer,Microsoft.NetCore.Analyzers,Version=2.0.0.0,Culture=neutral,PublicKeyToken=31bf3856ad364e35",,,,,,,,15.0,13.0,2.0,1.0,1.0,3.0,,0.0,6.0,816.0,170.0,9.0,5.0,136.0,129.0,40.0,116.0,,12.0,,,0.0,74.0,8.0,7.0,2.0,44.0,,23.0,,9.0,,5.0,,1.0,1.0,0.0,,0.0,,0.0,0.0,2.0,11.0,323.0,335.0,124.0,16.0,45.0,22.0,13.0,2.0,99.0,1.0,0.0,0.0,3.0,0.0,0.0,140.0,0.0,3.0,17.0,109.0,0.0,0.0,0.0,1.0,1.0,,,,,,,,0.0,1.0,9.0,56.0,6.0,7.0,3.0,3.0,,0.0,0.0,,0.0,0.0,0.0,,,,,,,,,,,,,,,0.0,39.0,7.0,0.0,9.0,0.0,0.0,1.0,0.0,3.0,0.0,1.0,0.0,16.0,0.0,1.0,0.0,1.0,1.0,0.0,16.0,0.0,,,,,,,,,,,,,,,,,0.0,,,,,,,,,,,,,,,,,,,,,,,35.0,2.0,133.0,11.0,2.0,,6.0,5.0,,55.0,2.0,112.0,1.0,,,42.0,,,1.0,,14.0,,33.0,37.0,14.0,69.0,,57.0,,,,78.0,1.0,118.0,1.0,2.0,1.0,,,5.0,,33.0,,,85.0,,2.0,4.0,267.0,1.0,54.0,1.0,94.0,0.0,13.0,1.0,1.0,18.0,13.0,1.0,134.0,0.0,1.0,12.0,24.0,83.0,24.0,9.0,239.0,9.0,3.0,78.0,18.0,1.0,0.0,0.0,12.0,13.0,4.0,6.0,0.0,,38.0,1.0,3.0,0.0,1.0,2.0,,,,0.0,,,,,,,,,,,,5.0,14.0,94.0,5.0,115.0,2.0,105.0,0.0,2.0,109.0,0.0,0.0,2.0,1.0,1.0,73.0,25.0,0.0,,,2.0,,,,,,,101.0,,,0.0,,,,,,,,,,,,,,,,,,,5.0,,,,,,,, +"System.Runtime.InteropServices.CSharp.Analyzers.CSharpAlwaysConsumeTheValueReturnedByMethodsMarkedWithPreserveSigAttributeAnalyzer,Microsoft.NetCore.CSharp.Analyzers,Version=2.0.0.0,Culture=neutral,PublicKeyToken=31bf3856ad364e35",,,,,,,,35.0,60.0,1.0,0.0,0.0,2.0,,0.0,35.0,164.0,407.0,,,,,,,,3.0,,,0.0,51.0,29.0,,1.0,0.0,,29.0,,,,3.0,,0.0,1.0,0.0,,0.0,,,1.0,0.0,56.0,,221.0,35.0,20.0,44.0,59.0,,,,0.0,0.0,,0.0,0.0,,3.0,0.0,,5.0,,0.0,0.0,0.0,1.0,0.0,,,,,,,,0.0,1.0,110.0,9.0,43.0,,,79.0,,0.0,0.0,,25.0,,0.0,,,,,,,,,,,,,,,0.0,0.0,4.0,0.0,11.0,0.0,0.0,0.0,0.0,2.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,35.0,0.0,,,,,,,,,,,,,,,,,1.0,,,,,,,,,,,,,,,,,,,,,,,,0.0,,38.0,46.0,,,3.0,,,1.0,,0.0,,,,,,0.0,,20.0,,2.0,,19.0,,,,,,,3.0,0.0,,0.0,1.0,0.0,,,,,3.0,,,,,0.0,2.0,,0.0,69.0,1.0,51.0,0.0,72.0,,1.0,39.0,,1.0,,0.0,0.0,,29.0,,40.0,12.0,140.0,7.0,,55.0,31.0,12.0,0.0,,0.0,32.0,2.0,49.0,0.0,,39.0,1.0,0.0,0.0,2.0,0.0,,,,,,,,,,,,,,,,14.0,107.0,207.0,,,1.0,,0.0,2.0,,0.0,0.0,1.0,0.0,0.0,,,0.0,,,14.0,,,,,,,370.0,,,0.0,,,,,,,,,,,,,,,,,,,3.0,,,,,,,, +"System.Runtime.InteropServices.VisualBasic.Analyzers.BasicAlwaysConsumeTheValueReturnedByMethodsMarkedWithPreserveSigAttributeAnalyzer,Microsoft.NetCore.VisualBasic.Analyzers,Version=2.0.0.0,Culture=neutral,PublicKeyToken=31bf3856ad364e35",,,,,,,,,,,,,,,,,,,384.0,580.0,6976.0,15743.0,6600.0,5695.0,,,,,,,,314.0,,,,,,62.0,,,,,,,,,,0.0,,,,2042.0,,,,,,387.0,12.0,2130.0,,,0.0,,,0.0,,,10.0,,2023.0,,,,,,,,,,,,,,,,,,370.0,176.0,,,,,,,6.0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,3734.0,,8480.0,,,,456.0,,,9310.0,,20826.0,,,,1498.0,,,,,,,,91.0,,9753.0,,9572.0,,,,,,19572.0,,,,,,1160.0,,,,,4641.0,,,,1391.0,,,,,,,11.0,,,525.0,,2261.0,,,210.0,,1405.0,,,,,101.0,,,,,0.0,,,,,,,,,,,,,,,,0.0,,,,,,,,,,,,,,,769.0,7117.0,,4249.0,,,16154.0,,,,,,7166.0,159.0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +"System.Threading.Tasks.Analyzers.DoNotCreateTasksWithoutPassingATaskSchedulerAnalyzer,Microsoft.NetCore.Analyzers,Version=2.0.0.0,Culture=neutral,PublicKeyToken=31bf3856ad364e35",,,,,,,,7.0,86.0,0.0,0.0,0.0,19.0,,0.0,4.0,176.0,555.0,2.0,3.0,126.0,407.0,50.0,141.0,,2.0,,,0.0,71.0,5.0,2.0,0.0,0.0,,10.0,,2.0,,55.0,,0.0,0.0,0.0,,0.0,,0.0,0.0,0.0,3.0,128.0,279.0,55.0,6.0,11.0,5.0,56.0,0.0,436.0,0.0,0.0,1.0,0.0,0.0,0.0,12.0,0.0,0.0,29.0,67.0,0.0,0.0,0.0,0.0,0.0,,,,,,,,0.0,0.0,138.0,22.0,6.0,49.0,19.0,1.0,,0.0,0.0,,0.0,0.0,0.0,,,,,,,,,,,,,,,0.0,0.0,2.0,0.0,4.0,0.0,0.0,0.0,0.0,1.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,1.0,0.0,,,,,,,,,,,,,,,,,28.0,,,,,,,,,,,,,,,,,,,,,,,77.0,0.0,173.0,2.0,2.0,,56.0,1.0,,140.0,55.0,471.0,0.0,,,4.0,,,0.0,,36.0,,1.0,1.0,7.0,205.0,,338.0,,,,2.0,0.0,237.0,0.0,0.0,0.0,,,2.0,,27.0,,,209.0,,0.0,1.0,60.0,0.0,11.0,0.0,113.0,0.0,3.0,0.0,0.0,5.0,29.0,0.0,134.0,0.0,0.0,2.0,67.0,79.0,37.0,4.0,134.0,3.0,0.0,6.0,69.0,0.0,0.0,0.0,0.0,3.0,1.0,5.0,0.0,,2.0,0.0,0.0,0.0,0.0,0.0,,,,0.0,,,,,,,,,,,,5.0,30.0,243.0,3.0,166.0,0.0,15.0,0.0,1.0,419.0,0.0,0.0,29.0,0.0,0.0,168.0,1.0,0.0,,,34.0,,,,,,,214.0,,,0.0,,,,,,,,,,,,,,,,,,,1.0,,,,,,,, +"XmlDocumentationComments.CSharp.Analyzers.CSharpAvoidUsingCrefTagsWithAPrefixAnalyzer,Microsoft.CodeQuality.CSharp.Analyzers,Version=2.0.0.0,Culture=neutral,PublicKeyToken=31bf3856ad364e35",,,,,,,,1.0,0.0,0.0,0.0,0.0,0.0,,0.0,0.0,0.0,0.0,,,,,,,,0.0,,,0.0,0.0,0.0,,0.0,0.0,,0.0,,,,0.0,,0.0,0.0,0.0,,0.0,,,0.0,0.0,0.0,,0.0,0.0,0.0,2.0,0.0,,,,0.0,0.0,,0.0,0.0,,0.0,0.0,,0.0,,0.0,0.0,0.0,0.0,0.0,,,,,,,,0.0,0.0,0.0,0.0,0.0,,,0.0,,0.0,0.0,,0.0,,0.0,,,,,,,,,,,,,,,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,,,,,,,,,,,,,,,,,0.0,,,,,,,,,,,,,,,,,,,,,,,,0.0,,0.0,0.0,,,0.0,,,0.0,,0.0,,,,,,0.0,,0.0,,0.0,,0.0,,,,,,,0.0,0.0,,0.0,0.0,0.0,,,,,0.0,,,,,0.0,0.0,,0.0,0.0,0.0,0.0,0.0,0.0,,0.0,0.0,,0.0,,0.0,0.0,,0.0,,0.0,0.0,0.0,0.0,,0.0,0.0,0.0,0.0,,0.0,0.0,0.0,0.0,0.0,,0.0,0.0,0.0,0.0,0.0,0.0,,,,,,,,,,,,,,,,0.0,0.0,0.0,,,0.0,,0.0,0.0,,0.0,0.0,0.0,0.0,0.0,,,0.0,,,0.0,,,,,,,0.0,,,0.0,,,,,,,,,,,,,,,,,,,0.0,,,,,,,, +"XmlDocumentationComments.VisualBasic.Analyzers.BasicAvoidUsingCrefTagsWithAPrefixAnalyzer,Microsoft.CodeQuality.VisualBasic.Analyzers,Version=2.0.0.0,Culture=neutral,PublicKeyToken=31bf3856ad364e35",,,,,,,,,,,,,,,,,,,1.0,0.0,76.0,299.0,41.0,71.0,,,,,,,,0.0,,,,,,0.0,,,,,,,,,,0.0,,,,0.0,,,,,,0.0,0.0,29.0,,,0.0,,,0.0,,,0.0,,1.0,,,,,,,,,,,,,,,,,,0.0,0.0,,,,,,,0.0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,2.0,,169.0,,,,0.0,,,100.0,,78.0,,,,0.0,,,,,,,,0.0,,90.0,,147.0,,,,,,167.0,,,,,,0.0,,,,,92.0,,,,0.0,,,,,,,0.0,,,0.0,,1.0,,,0.0,,3.0,,,,,0.0,,,,,0.0,,,,,,,,,,,,,,,,0.0,,,,,,,,,,,,,,,0.0,102.0,,2.0,,,60.0,,,,,,3.0,0.0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, diff --git a/src/VisualStudio/Core/Test.Next/VisualStudioTest.Next.csproj b/src/VisualStudio/Core/Test.Next/VisualStudioTest.Next.csproj index a963126adc9..b70300e84d3 100644 --- a/src/VisualStudio/Core/Test.Next/VisualStudioTest.Next.csproj +++ b/src/VisualStudio/Core/Test.Next/VisualStudioTest.Next.csproj @@ -94,4 +94,7 @@ - + + + + \ No newline at end of file diff --git a/src/Workspaces/Core/Portable/Log/FunctionId.cs b/src/Workspaces/Core/Portable/Log/FunctionId.cs index 8fe8c7d0267..aef7bc78527 100644 --- a/src/Workspaces/Core/Portable/Log/FunctionId.cs +++ b/src/Workspaces/Core/Portable/Log/FunctionId.cs @@ -403,7 +403,10 @@ internal enum FunctionId MetadataOnlyImage_EmitFailure, LiveTableDataSource_OnDiagnosticsUpdated, Experiment_KeybindingsReset, - + Diagnostics_GeneratePerformaceReport, + Diagnostics_BadAnalyzer, + CodeAnalysisService_ReportAnalyzerPerformance, + PerformanceTrackerService_AddSnapshot, AbstractProject_SetIntelliSenseBuild, AbstractProject_Created, AbstractProject_PushedToWorkspace, diff --git a/src/Workspaces/Core/Portable/Remote/RemoteHostClientExtensions.cs b/src/Workspaces/Core/Portable/Remote/RemoteHostClientExtensions.cs index d545895d960..0bd5c9310fb 100644 --- a/src/Workspaces/Core/Portable/Remote/RemoteHostClientExtensions.cs +++ b/src/Workspaces/Core/Portable/Remote/RemoteHostClientExtensions.cs @@ -225,6 +225,14 @@ public static bool IsOutOfProcessEnabled(this Workspace workspace, Option this RemoteHostClient client, Solution solution, string targetName, object[] arguments, CancellationToken cancellationToken) => TryRunRemoteAsync(client, WellKnownServiceHubServices.CodeAnalysisService, solution, targetName, arguments, cancellationToken); + public static Task TryRunCodeAnalysisRemoteAsync( + this RemoteHostClient client, string targetName, object argument, CancellationToken cancellationToken) + => TryRunRemoteAsync(client, WellKnownServiceHubServices.CodeAnalysisService, targetName, new object[] { argument }, cancellationToken); + + public static Task TryRunCodeAnalysisRemoteAsync( + this RemoteHostClient client, string targetName, object[] arguments, CancellationToken cancellationToken) + => TryRunRemoteAsync(client, WellKnownServiceHubServices.CodeAnalysisService, targetName, arguments, cancellationToken); + /// /// Synchronize given solution as primary workspace solution in remote host /// diff --git a/src/Workspaces/Core/Portable/Remote/WellKnownServiceHubServices.cs b/src/Workspaces/Core/Portable/Remote/WellKnownServiceHubServices.cs index 9a21a9118ac..00357808a2c 100644 --- a/src/Workspaces/Core/Portable/Remote/WellKnownServiceHubServices.cs +++ b/src/Workspaces/Core/Portable/Remote/WellKnownServiceHubServices.cs @@ -25,7 +25,5 @@ public static void Set64bit(bool x64) public const string ServiceHubServiceBase_Initialize = "Initialize"; public const string AssetService_RequestAssetAsync = "RequestAssetAsync"; - - public const string CodeAnalysisService_CalculateDiagnosticsAsync = "CalculateDiagnosticsAsync"; } } diff --git a/src/Workspaces/Remote/Core/Diagnostics/DiagnosticComputer.cs b/src/Workspaces/Remote/Core/Diagnostics/DiagnosticComputer.cs index fdb8cada810..f7432d59b4f 100644 --- a/src/Workspaces/Remote/Core/Diagnostics/DiagnosticComputer.cs +++ b/src/Workspaces/Remote/Core/Diagnostics/DiagnosticComputer.cs @@ -10,6 +10,7 @@ using Microsoft.CodeAnalysis.Diagnostics.Telemetry; using Microsoft.CodeAnalysis.Host; using Microsoft.CodeAnalysis.Options; +using Microsoft.CodeAnalysis.Shared.Extensions; using Microsoft.CodeAnalysis.Workspaces.Diagnostics; using Roslyn.Utilities; @@ -19,11 +20,15 @@ internal class DiagnosticComputer { private readonly Project _project; private readonly Dictionary> _exceptions; + private readonly IPerformanceTrackerService _performanceTracker; public DiagnosticComputer(Project project) { _project = project; _exceptions = new Dictionary>(); + + // we only track performance from primary branch. all forked branch we don't care such as preview. + _performanceTracker = project.IsFromPrimaryBranch() ? project.Solution.Workspace.Services.GetService() : null; } public async Task> GetDiagnosticsAsync( @@ -87,6 +92,13 @@ public DiagnosticComputer(Project project) // PERF: Run all analyzers at once using the new GetAnalysisResultAsync API. var analysisResult = await analyzerDriver.GetAnalysisResultAsync(cancellationToken).ConfigureAwait(false); + // record performance if tracker is available + if (_performanceTracker != null) + { + // +1 to include project itself + _performanceTracker.AddSnapshot(analysisResult.AnalyzerTelemetryInfo.ToAnalyzerPerformanceInfo(), _project.DocumentIds.Count + 1); + } + var builderMap = analysisResult.ToResultBuilderMap(_project, VersionStamp.Default, compilation, analysisResult.Analyzers, cancellationToken); return DiagnosticAnalysisResultMap.Create( diff --git a/src/Workspaces/Remote/Core/Diagnostics/IPerformanceTrackerService.cs b/src/Workspaces/Remote/Core/Diagnostics/IPerformanceTrackerService.cs new file mode 100644 index 00000000000..fd872c4950c --- /dev/null +++ b/src/Workspaces/Remote/Core/Diagnostics/IPerformanceTrackerService.cs @@ -0,0 +1,39 @@ +// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; +using System.Collections.Generic; +using Microsoft.CodeAnalysis.Diagnostics; +using Microsoft.CodeAnalysis.Host; + +namespace Microsoft.CodeAnalysis.Remote.Diagnostics +{ + internal interface IPerformanceTrackerService : IWorkspaceService + { + void AddSnapshot(IEnumerable snapshot, int unitCount); + void GenerateReport(List badAnalyzers); + + event EventHandler SnapshotAdded; + } + + internal struct ExpensiveAnalyzerInfo + { + public readonly bool BuiltIn; + public readonly string AnalyzerId; + public readonly string AnalyzerIdHash; + public readonly double LocalOutlierFactor; + public readonly double Average; + public readonly double AdjustedStandardDeviation; + + public ExpensiveAnalyzerInfo(bool builtIn, string analyzerId, double lof_value, double average, double stddev) : this() + { + BuiltIn = builtIn; + AnalyzerId = analyzerId; + AnalyzerIdHash = analyzerId.GetHashCode().ToString(); + LocalOutlierFactor = lof_value; + Average = average; + AdjustedStandardDeviation = stddev; + } + + public string PIISafeAnalyzerId => BuiltIn ? AnalyzerId : AnalyzerIdHash; + } +} diff --git a/src/Workspaces/Remote/Core/Diagnostics/PerformanceQueue.cs b/src/Workspaces/Remote/Core/Diagnostics/PerformanceQueue.cs new file mode 100644 index 00000000000..4fbc2607bbc --- /dev/null +++ b/src/Workspaces/Remote/Core/Diagnostics/PerformanceQueue.cs @@ -0,0 +1,227 @@ +// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; +using System.Collections.Generic; +using System.Linq; +using Microsoft.CodeAnalysis.Diagnostics; +using Roslyn.Utilities; + +namespace Microsoft.CodeAnalysis.Remote.Diagnostics +{ + /// + /// This queue hold onto raw performance data. this type itself is not thread safe. the one who uses this type + /// should take care of that. + /// + /// + internal class PerformanceQueue + { + // we need at least 100 samples for result to be stable + private const int MinSampleSize = 100; + + private readonly int _maxSampleSize; + private readonly LinkedList _snapshots; + + public PerformanceQueue(int maxSampleSize) + { + Contract.ThrowIfFalse(maxSampleSize > MinSampleSize); + + _maxSampleSize = maxSampleSize; + _snapshots = new LinkedList(); + } + + public int Count => _snapshots.Count; + + public void Add(IEnumerable<(string analyzerId, TimeSpan timeSpan)> rawData, int unitCount) + { + if (_snapshots.Count < _maxSampleSize) + { + _snapshots.AddLast(new Snapshot(rawData, unitCount)); + } + else + { + // remove the first one + var first = _snapshots.First; + _snapshots.RemoveFirst(); + + // update data to new data and put it back + first.Value.Update(rawData, unitCount); + _snapshots.AddLast(first); + } + } + + public void GetPerformanceData(Dictionary aggregatedPerformanceDataPerAnalyzer) + { + if (_snapshots.Count < MinSampleSize) + { + // we don't have enough data to report this + return; + } + + using (var pooledMap = SharedPools.Default>().GetPooledObject()) + using (var pooledSet = SharedPools.Default>().GetPooledObject()) + using (var pooledList = SharedPools.Default>().GetPooledObject()) + { + var reverseMap = pooledMap.Object; + AnalyzerNumberAssigner.Instance.GetReverseMap(reverseMap); + + var analyzerSet = pooledSet.Object; + + // get all analyzers + foreach (var snapshot in _snapshots) + { + snapshot.AppendAnalyzers(analyzerSet); + } + + var list = pooledList.Object; + + // calculate aggregated data per analyzer + foreach (var assignedAnalyzerNumber in analyzerSet) + { + foreach (var snapshot in _snapshots) + { + var timeSpan = snapshot.GetTimeSpanInMillisecond(assignedAnalyzerNumber); + if (timeSpan == null) + { + // not all snapshot contains all analyzers + continue; + } + + list.Add(timeSpan.Value); + } + + // data is only stable once we have more than certain set + // of samples + if (list.Count < MinSampleSize) + { + continue; + } + + // set performance data + aggregatedPerformanceDataPerAnalyzer[reverseMap[assignedAnalyzerNumber]] = GetAverageAndAdjustedStandardDeviation(list); + + list.Clear(); + } + } + } + + private (double average, double stddev) GetAverageAndAdjustedStandardDeviation(List data) + { + var average = data.Average(); + var stddev = Math.Sqrt(data.Select(ms => Math.Pow(ms - average, 2)).Average()); + var squareLength = Math.Sqrt(data.Count); + + return (average, stddev / squareLength); + } + + private class Snapshot + { + /// + /// Raw performance data. + /// Keyed by analyzer unique number got from AnalyzerNumberAssigner. + /// Value is delta (TimeSpan - minSpan) among span in this snapshot + /// + private readonly Dictionary _performanceMap; + + public Snapshot(IEnumerable<(string analyzerId, TimeSpan timeSpan)> snapshot, int unitCount) : + this(Convert(snapshot), unitCount) + { + } + + public Snapshot(IEnumerable<(int assignedAnalyzerNumber, TimeSpan timeSpan)> rawData, int unitCount) + { + _performanceMap = new Dictionary(); + + Reset(_performanceMap, rawData, unitCount); + } + + public void Update(IEnumerable<(string analyzerId, TimeSpan timeSpan)> rawData, int unitCount) + { + Reset(_performanceMap, Convert(rawData), unitCount); + } + + public void AppendAnalyzers(HashSet analyzerSet) + { + analyzerSet.UnionWith(_performanceMap.Keys); + } + + public double? GetTimeSpanInMillisecond(int assignedAnalyzerNumber) + { + if (!_performanceMap.TryGetValue(assignedAnalyzerNumber, out var value)) + { + return null; + } + + return value; + } + + private void Reset( + Dictionary map, IEnumerable<(int assignedAnalyzerNumber, TimeSpan timeSpan)> rawData, int fileCount) + { + // get smallest timespan in the snapshot + var minSpan = rawData.Select(kv => kv.timeSpan).Min(); + + // for now, we just clear the map, if reusing dictionary blindly became an issue due to + // dictionary grew too big, then we need to do a bit more work to determine such case + // and re-create new dictionary + map.Clear(); + + // map is normalized to current timespan - min timspan of the snapshot + foreach (var (assignedAnalyzerNumber, timeSpan) in rawData) + { + map[assignedAnalyzerNumber] = (timeSpan.TotalMilliseconds - minSpan.TotalMilliseconds) / fileCount; + } + } + + private static IEnumerable<(int assignedAnalyzerNumber, TimeSpan timeSpan)> Convert(IEnumerable<(string analyzerId, TimeSpan timeSpan)> rawData) + { + return rawData.Select(kv => (AnalyzerNumberAssigner.Instance.GetUniqueNumber(kv.analyzerId), kv.timeSpan)); + } + } + + /// + /// Assign unique number to diagnostic analyzers + /// + private class AnalyzerNumberAssigner + { + public static readonly AnalyzerNumberAssigner Instance = new AnalyzerNumberAssigner(); + + private int _currentId; + + // use simple approach for now. we don't expect it to grow too much. so entry added + // won't be removed until process goes away + private readonly Dictionary _idMap; + + private AnalyzerNumberAssigner() + { + _currentId = 0; + _idMap = new Dictionary(); + } + + public int GetUniqueNumber(DiagnosticAnalyzer analyzer) + { + return GetUniqueNumber(analyzer.GetAnalyzerId()); + } + + public int GetUniqueNumber(string analyzerName) + { + if (!_idMap.TryGetValue(analyzerName, out var id)) + { + id = _currentId++; + _idMap.Add(analyzerName, id); + } + + return id; + } + + public void GetReverseMap(Dictionary reverseMap) + { + reverseMap.Clear(); + + foreach (var kv in _idMap) + { + reverseMap.Add(kv.Value, kv.Key); + } + } + } + } +} diff --git a/src/Workspaces/Remote/Core/Diagnostics/PerformanceTrackerService.cs b/src/Workspaces/Remote/Core/Diagnostics/PerformanceTrackerService.cs new file mode 100644 index 00000000000..a3558863725 --- /dev/null +++ b/src/Workspaces/Remote/Core/Diagnostics/PerformanceTrackerService.cs @@ -0,0 +1,447 @@ +// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; +using System.Collections.Concurrent; +using System.Collections.Generic; +using System.Composition; +using System.Linq; +using System.Text; +using Microsoft.CodeAnalysis.Diagnostics; +using Microsoft.CodeAnalysis.Host.Mef; +using Microsoft.CodeAnalysis.Internal.Log; + +namespace Microsoft.CodeAnalysis.Remote.Diagnostics +{ + /// + /// Track diagnostic performance + /// + [ExportWorkspaceService(typeof(IPerformanceTrackerService), WorkspaceKind.Host), Shared] + internal class PerformanceTrackerService : IPerformanceTrackerService + { + private static readonly Func, int, string> s_snapshotLogger = SnapshotLogger; + + private const double DefaultMinLOFValue = 20; + private const double DefaultAverageThreshold = 100; + private const double DefaultStddevThreshold = 100; + + private const int SampleSize = 300; + private const double K_Value_Ratio = 2D / 3D; + + private readonly double _minLOFValue; + private readonly double _averageThreshold; + private readonly double _stddevThreshold; + + private readonly object _gate; + private readonly PerformanceQueue _queue; + private readonly ConcurrentDictionary _builtInMap = new ConcurrentDictionary(concurrencyLevel: 2, capacity: 10); + + public event EventHandler SnapshotAdded; + + public PerformanceTrackerService() : + this(DefaultMinLOFValue, DefaultAverageThreshold, DefaultStddevThreshold) + { + } + + // internal for testing + internal PerformanceTrackerService(double minLOFValue, double averageThreshold, double stddevThreshold) + { + _minLOFValue = minLOFValue; + _averageThreshold = averageThreshold; + _stddevThreshold = stddevThreshold; + + _gate = new object(); + _queue = new PerformanceQueue(SampleSize); + } + + public void AddSnapshot(IEnumerable snapshot, int unitCount) + { + Logger.Log(FunctionId.PerformanceTrackerService_AddSnapshot, s_snapshotLogger, snapshot, unitCount); + + RecordBuiltInAnalyzers(snapshot); + + lock (_gate) + { + _queue.Add(snapshot.Select(entry => (entry.AnalyzerId, entry.TimeSpan)), unitCount); + } + + OnSnapshotAdded(); + } + + public void GenerateReport(List badAnalyzers) + { + using (var pooledRaw = SharedPools.Default>().GetPooledObject()) + { + var rawPerformanceData = pooledRaw.Object; + + lock (_gate) + { + // first get raw aggregated peformance data from the queue + _queue.GetPerformanceData(rawPerformanceData); + } + + // make sure there are some data + if (rawPerformanceData.Count == 0) + { + return; + } + + using (var generator = new ReportGenerator(this, _minLOFValue, _averageThreshold, _stddevThreshold, badAnalyzers)) + { + generator.Report(rawPerformanceData); + } + } + } + + private void RecordBuiltInAnalyzers(IEnumerable snapshot) + { + foreach (var entry in snapshot) + { + _builtInMap[entry.AnalyzerId] = entry.BuiltIn; + } + } + + private bool AllowTelemetry(string analyzerId) + { + if (_builtInMap.TryGetValue(analyzerId, out var builtIn)) + { + return builtIn; + } + + return false; + } + + private void OnSnapshotAdded() + { + SnapshotAdded?.Invoke(this, EventArgs.Empty); + } + + private static string SnapshotLogger(IEnumerable snapshots, int unitCount) + { + using (var pooledObject = SharedPools.Default().GetPooledObject()) + { + var sb = pooledObject.Object; + + sb.Append(unitCount); + + foreach (var snapshot in snapshots) + { + sb.Append("|"); + sb.Append(snapshot.AnalyzerId); + sb.Append(":"); + sb.Append(snapshot.BuiltIn); + sb.Append(":"); + sb.Append(snapshot.TimeSpan.TotalMilliseconds); + } + + sb.Append("*"); + + return sb.ToString(); + } + } + + private sealed class ReportGenerator : IDisposable, IComparer + { + private readonly double _minLOFValue; + private readonly double _averageThreshold; + private readonly double _stddevThreshold; + + private readonly PerformanceTrackerService _owner; + private readonly List _badAnalyzers; + private readonly PooledObject> _pooledObjects; + + public ReportGenerator( + PerformanceTrackerService owner, + double minLOFValue, + double averageThreshold, + double stddevThreshold, + List badAnalyzers) + { + _pooledObjects = SharedPools.Default>().GetPooledObject(); + + _owner = owner; + + _minLOFValue = minLOFValue; + _averageThreshold = averageThreshold; + _stddevThreshold = stddevThreshold; + + _badAnalyzers = badAnalyzers; + } + + public void Report(Dictionary rawPerformanceData) + { + // this is implementation of local outlier factor (LOF) + // see the wiki (https://en.wikipedia.org/wiki/Local_outlier_factor) for more information + + // convert string (analyzerId) to index + var analyzerIdIndex = GetAnalyzerIdIndex(rawPerformanceData.Keys); + + // now calculate normalized value per analyzer + var normalizedMap = GetNormalizedPerformanceMap(analyzerIdIndex, rawPerformanceData); + + // get k value + var k_value = (int)(rawPerformanceData.Count * K_Value_Ratio); + + // calculate distances + + // calculate all distance first + var allDistances = GetAllDistances(normalizedMap); + + // find k distance from all distances + var kDistances = GetKDistances(allDistances, k_value); + + // find k nearest neighbors + var kNeighborIndices = GetKNeighborIndices(allDistances, kDistances); + + var analyzerCount = kNeighborIndices.Count; + for (var index = 0; index < analyzerCount; index++) + { + var analyzerId = analyzerIdIndex[index]; + + // if result performance is lower than our threshold, don't need to calcuate + // LOF value for the analyzer + var rawData = rawPerformanceData[analyzerId]; + if (rawData.average <= _averageThreshold && rawData.stddev <= _stddevThreshold) + { + continue; + } + + // possible bad analyzer, calcuate LOF + var lof_value = TryGetLocalOutlierFactor(allDistances, kNeighborIndices, kDistances, index); + if (!lof_value.HasValue) + { + // this analyzer doesn't have lof value + continue; + } + + if (lof_value <= _minLOFValue) + { + // this doesn't stand out from other analyzers + continue; + } + + // report found possible bad analyzers + _badAnalyzers.Add(new ExpensiveAnalyzerInfo(_owner.AllowTelemetry(analyzerId), analyzerId, lof_value.Value, rawData.average, rawData.stddev)); + } + + _badAnalyzers.Sort(this); + } + + private double? TryGetLocalOutlierFactor( + List> allDistances, List> kNeighborIndices, List kDistances, int analyzerIndex) + { + var rowKNeighborsIndices = kNeighborIndices[analyzerIndex]; + if (rowKNeighborsIndices.Count == 0) + { + // nothing to calculate if there is no neighbor to compare + return null; + } + + var lrda = TryGetLocalReachabilityDensity(allDistances, kNeighborIndices, kDistances, analyzerIndex); + if (!lrda.HasValue) + { + // can't calculate reachability for the analyzer. can't calculate lof for this analyzer + return null; + } + + var lrdb = 0D; + foreach (var neighborIndex in rowKNeighborsIndices) + { + var reachability = TryGetLocalReachabilityDensity(allDistances, kNeighborIndices, kDistances, neighborIndex); + if (!reachability.HasValue) + { + // this neighbor analyzer doesn't have its own neighbor. skip it + continue; + } + + lrdb += reachability.Value; + } + + return (lrdb / rowKNeighborsIndices.Count) / lrda; + } + + private double GetReachabilityDistance( + List> allDistances, List kDistances, int analyzerIndex1, int analyzerIndex2) + { + return Math.Max(allDistances[analyzerIndex1][analyzerIndex2], kDistances[analyzerIndex2]); + } + + private double? TryGetLocalReachabilityDensity( + List> allDistances, List> kNeighborIndices, List kDistances, int analyzerIndex) + { + var rowKNeighborsIndices = kNeighborIndices[analyzerIndex]; + if (rowKNeighborsIndices.Count == 0) + { + // no neighbor to get reachability + return null; + } + + var distanceSum = 0.0; + foreach (var neighborIndex in rowKNeighborsIndices) + { + distanceSum += GetReachabilityDistance(allDistances, kDistances, analyzerIndex, neighborIndex); + } + + return 1 / distanceSum / rowKNeighborsIndices.Count; + } + + private List> GetKNeighborIndices(List> allDistances, List kDistances) + { + var analyzerCount = kDistances.Count; + var kNeighborIndices = GetPooledListAndSetCapacity>(analyzerCount); + + for (var rowIndex = 0; rowIndex < analyzerCount; rowIndex++) + { + var rowKNeighborIndices = GetPooledList(); + + var rowDistances = allDistances[rowIndex]; + var kDistance = kDistances[rowIndex]; + + for (var colIndex = 0; colIndex < analyzerCount; colIndex++) + { + var value = rowDistances[colIndex]; + + // get neighbors closer than k distance + if (value > 0 && value <= kDistance) + { + rowKNeighborIndices.Add(colIndex); + } + } + + kNeighborIndices[rowIndex] = rowKNeighborIndices; + } + + return kNeighborIndices; + } + + private List GetKDistances(List> allDistances, int kValue) + { + var analyzerCount = allDistances.Count; + var kDistances = GetPooledListAndSetCapacity(analyzerCount); + var sortedRowDistance = GetPooledList(); + + for (var index = 0; index < analyzerCount; index++) + { + sortedRowDistance.Clear(); + sortedRowDistance.AddRange(allDistances[index]); + + sortedRowDistance.Sort(); + + kDistances[index] = sortedRowDistance[kValue]; + } + + return kDistances; + } + + private List> GetAllDistances(List<(double normaliedAverage, double normalizedStddev)> normalizedMap) + { + var analyzerCount = normalizedMap.Count; + var allDistances = GetPooledListAndSetCapacity>(analyzerCount); + + for (var rowIndex = 0; rowIndex < analyzerCount; rowIndex++) + { + var rowDistances = GetPooledListAndSetCapacity(analyzerCount); + var rowAnalyzer = normalizedMap[rowIndex]; + + for (var colIndex = 0; colIndex < analyzerCount; colIndex++) + { + var colAnalyzer = normalizedMap[colIndex]; + var distance = Math.Sqrt(Math.Pow(colAnalyzer.normaliedAverage - rowAnalyzer.normaliedAverage, 2) + + Math.Pow(colAnalyzer.normalizedStddev - rowAnalyzer.normalizedStddev, 2)); + + rowDistances[colIndex] = distance; + } + + allDistances[rowIndex] = rowDistances; + } + + return allDistances; + } + + private List<(double normaliedAverage, double normalizedStddev)> GetNormalizedPerformanceMap( + List analyzerIdIndex, Dictionary rawPerformanceData) + { + var averageMin = rawPerformanceData.Values.Select(kv => kv.average).Min(); + var averageMax = rawPerformanceData.Values.Select(kv => kv.average).Max(); + var averageDelta = averageMax - averageMin; + + var stddevMin = rawPerformanceData.Values.Select(kv => kv.stddev).Min(); + var stddevMax = rawPerformanceData.Values.Select(kv => kv.stddev).Max(); + var stddevDelta = stddevMax - stddevMin; + + // make sure delta is not 0 + averageDelta = averageDelta == 0 ? 1 : averageDelta; + stddevDelta = stddevDelta == 0 ? 1 : stddevDelta; + + // calculate normalized average and stddev and convert analyzerId string to index + var analyzerCount = analyzerIdIndex.Count; + var normalizedMap = GetPooledListAndSetCapacity<(double normalizedAverage, double normalizedStddev)>(analyzerCount); + + for (var index = 0; index < analyzerCount; index++) + { + var value = rawPerformanceData[analyzerIdIndex[index]]; + var normalizedAverage = (value.average - averageMin) / averageDelta; + var normalizedStddev = (value.stddev - stddevMin) / stddevDelta; + + normalizedMap[index] = (normalizedAverage, normalizedStddev); + } + + return normalizedMap; + } + + private List GetAnalyzerIdIndex(IEnumerable analyzerIds) + { + var analyzerIdIndex = GetPooledList(); + analyzerIdIndex.AddRange(analyzerIds); + + return analyzerIdIndex; + } + + public void Dispose() + { + foreach (var disposable in _pooledObjects.Object) + { + disposable.Dispose(); + } + + _pooledObjects.Dispose(); + } + + private List GetPooledList() + { + var pooledObject = SharedPools.Default>().GetPooledObject(); + _pooledObjects.Object.Add(pooledObject); + + return pooledObject.Object; + } + + private List GetPooledListAndSetCapacity(int capacity) + { + var pooledObject = SharedPools.Default>().GetPooledObject(); + _pooledObjects.Object.Add(pooledObject); + + for (var i = 0; i < capacity; i++) + { + pooledObject.Object.Add(default(T)); + } + + return pooledObject.Object; + } + + public int Compare(ExpensiveAnalyzerInfo x, ExpensiveAnalyzerInfo y) + { + if (x.LocalOutlierFactor == y.LocalOutlierFactor) + { + return 0; + } + + // want reversed order + if (x.LocalOutlierFactor - y.LocalOutlierFactor > 0) + { + return -1; + } + + return 1; + } + } + } +} diff --git a/src/Workspaces/Remote/ServiceHub/Services/CodeAnalysisService_Diagnostics.cs b/src/Workspaces/Remote/ServiceHub/Services/CodeAnalysisService_Diagnostics.cs index e3f03144f2a..4c2e6b3fae9 100644 --- a/src/Workspaces/Remote/ServiceHub/Services/CodeAnalysisService_Diagnostics.cs +++ b/src/Workspaces/Remote/ServiceHub/Services/CodeAnalysisService_Diagnostics.cs @@ -1,5 +1,6 @@ // Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. +using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Threading; @@ -15,12 +16,12 @@ namespace Microsoft.CodeAnalysis.Remote { // root level service for all Roslyn services - internal partial class CodeAnalysisService + internal partial class CodeAnalysisService : IRemoteDiagnosticAnalyzerService { /// - /// This is top level entry point for diagnostic calculation from client (VS). - /// - /// This will be called by ServiceHub/JsonRpc framework + /// 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 /// public Task CalculateDiagnosticsAsync(DiagnosticArguments arguments, string streamName, CancellationToken cancellationToken) { @@ -53,6 +54,25 @@ public Task CalculateDiagnosticsAsync(DiagnosticArguments arguments, string stre }, cancellationToken); } + public void ReportAnalyzerPerformance(List snapshot, int unitCount, CancellationToken cancellationToken) + { + RunService(token => + { + using (RoslynLogger.LogBlock(FunctionId.CodeAnalysisService_ReportAnalyzerPerformance, token)) + { + token.ThrowIfCancellationRequested(); + + var service = SolutionService.PrimaryWorkspace.Services.GetService(); + if (service == null) + { + return; + } + + service.AddSnapshot(snapshot, unitCount); + } + }, cancellationToken); + } + private async Task SerializeDiagnosticResultAsync(string streamName, DiagnosticAnalysisResultMap result, CancellationToken cancellationToken) { using (RoslynLogger.LogBlock(FunctionId.CodeAnalysisService_SerializeDiagnosticResultAsync, GetResultLogInfo, result, cancellationToken)) diff --git a/src/Workspaces/Remote/ServiceHub/Services/RemoteHostService.PerformanceReporter.cs b/src/Workspaces/Remote/ServiceHub/Services/RemoteHostService.PerformanceReporter.cs new file mode 100644 index 00000000000..d29994c134f --- /dev/null +++ b/src/Workspaces/Remote/ServiceHub/Services/RemoteHostService.PerformanceReporter.cs @@ -0,0 +1,109 @@ +// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Threading; +using System.Threading.Tasks; +using Microsoft.CodeAnalysis.ErrorReporting; +using Microsoft.CodeAnalysis.Internal.Log; +using Microsoft.CodeAnalysis.Notification; +using Microsoft.CodeAnalysis.Remote.Diagnostics; +using Microsoft.CodeAnalysis.Shared.TestHooks; +using Microsoft.CodeAnalysis.SolutionCrawler; +using RoslynLogger = Microsoft.CodeAnalysis.Internal.Log.Logger; + +namespace Microsoft.CodeAnalysis.Remote +{ + internal partial class RemoteHostService : ServiceHubServiceBase, IRemoteHostService + { + /// + /// Track when last time report has sent and send new report if there is update after given internal + /// + private class PerformanceReporter : GlobalOperationAwareIdleProcessor + { + private readonly SemaphoreSlim _event; + private readonly HashSet _reported; + + private readonly IPerformanceTrackerService _diagnosticAnalyzerPerformanceTracker; + private readonly TraceSource _logger; + + public PerformanceReporter(TraceSource logger, IPerformanceTrackerService diagnosticAnalyzerPerformanceTracker, TimeSpan reportingInterval, CancellationToken shutdownToken) : base( + AsynchronousOperationListenerProvider.NullListener, + SolutionService.PrimaryWorkspace.Services.GetService(), + (int)reportingInterval.TotalMilliseconds, shutdownToken) + { + _event = new SemaphoreSlim(initialCount: 0); + _reported = new HashSet(); + + _logger = logger; + _diagnosticAnalyzerPerformanceTracker = diagnosticAnalyzerPerformanceTracker; + _diagnosticAnalyzerPerformanceTracker.SnapshotAdded += OnSnapshotAdded; + Start(); + } + + protected override void PauseOnGlobalOperation() + { + // we won't cancel report already running. we will just prevent + // new one from starting. + } + + protected override async Task ExecuteAsync() + { + // wait for global operation such as build + await GlobalOperationTask.ConfigureAwait(false); + + using (var pooledObject = SharedPools.Default>().GetPooledObject()) + using (RoslynLogger.LogBlock(FunctionId.Diagnostics_GeneratePerformaceReport, CancellationToken)) + { + _diagnosticAnalyzerPerformanceTracker.GenerateReport(pooledObject.Object); + + foreach (var badAnalyzerInfo in pooledObject.Object) + { + var newAnalyzer = _reported.Add(badAnalyzerInfo.AnalyzerId); + var internalUser = WatsonReporter.IsUserMicrosoftInternal; + + // we only report same analyzer once unless it is internal user + if (internalUser || newAnalyzer) + { + // this will report telemetry under VS. this will let us see how accurate our performance tracking is + RoslynLogger.Log(FunctionId.Diagnostics_BadAnalyzer, KeyValueLogMessage.Create(m => + { + // since it is telemetry, we hash analyzer name if it is not builtin analyzer + m[nameof(badAnalyzerInfo.AnalyzerId)] = internalUser ? badAnalyzerInfo.AnalyzerId : badAnalyzerInfo.PIISafeAnalyzerId; + m[nameof(badAnalyzerInfo.LocalOutlierFactor)] = badAnalyzerInfo.LocalOutlierFactor; + m[nameof(badAnalyzerInfo.Average)] = badAnalyzerInfo.Average; + m[nameof(badAnalyzerInfo.AdjustedStandardDeviation)] = badAnalyzerInfo.AdjustedStandardDeviation; + })); + } + + // for logging, we only log once. we log here so that we can ask users to provide this log to us + // when we want to find out VS performance issue that could be caused by analyzer + if (newAnalyzer) + { + _logger.TraceEvent(TraceEventType.Error, 0, $"[{badAnalyzerInfo.AnalyzerId} ({badAnalyzerInfo.AnalyzerIdHash})] LOF: {badAnalyzerInfo.LocalOutlierFactor}, Avg: {badAnalyzerInfo.Average}, Stddev: {badAnalyzerInfo.AdjustedStandardDeviation}"); + } + } + } + } + + protected override Task WaitAsync(CancellationToken cancellationToken) + { + return _event.WaitAsync(cancellationToken); + } + + private void OnSnapshotAdded(object sender, EventArgs e) + { + // this acts like Monitor.Pulse. (wake up event if it is currently waiting + // if not, ignore. this can have race, but that's fine for this usage case) + // not using Monitor.Pulse since that doesn't support WaitAsync + if (_event.CurrentCount > 0) + { + return; + } + + _event.Release(); + } + } + } +} diff --git a/src/Workspaces/Remote/ServiceHub/Services/RemoteHostService.cs b/src/Workspaces/Remote/ServiceHub/Services/RemoteHostService.cs index 78fe65e1da4..69130e99533 100644 --- a/src/Workspaces/Remote/ServiceHub/Services/RemoteHostService.cs +++ b/src/Workspaces/Remote/ServiceHub/Services/RemoteHostService.cs @@ -13,6 +13,7 @@ using Microsoft.CodeAnalysis.Host; using Microsoft.CodeAnalysis.Internal.Log; using Microsoft.CodeAnalysis.Notification; +using Microsoft.CodeAnalysis.Remote.Diagnostics; using Microsoft.CodeAnalysis.Remote.Services; using Microsoft.CodeAnalysis.Remote.Storage; using Microsoft.CodeAnalysis.Storage; @@ -29,13 +30,16 @@ namespace Microsoft.CodeAnalysis.Remote /// /// basically, this is used to manage lifetime of the service hub. /// - internal class RemoteHostService : ServiceHubServiceBase, IRemoteHostService + internal partial class RemoteHostService : ServiceHubServiceBase, IRemoteHostService { + private readonly static TimeSpan s_reportInterval = TimeSpan.FromMinutes(2); + // it is saved here more on debugging purpose. private static Func s_logChecker = _ => false; private string _host; private int _primaryInstance; + private PerformanceReporter _performanceReporter; static RemoteHostService() { @@ -195,7 +199,7 @@ private void SetSessionInfo(Dictionary m) m["InstanceId"] = _primaryInstance; } - private static void SetGlobalContext(int uiCultureLCID, int cultureLCID, string serializedSession) + private void SetGlobalContext(int uiCultureLCID, int cultureLCID, string serializedSession) { // set global telemetry session var session = GetTelemetrySession(serializedSession); @@ -214,6 +218,13 @@ private static void SetGlobalContext(int uiCultureLCID, int cultureLCID, string // set both handler as NFW FatalError.Handler = WatsonReporter.Report; FatalError.NonFatalHandler = WatsonReporter.Report; + + // start performance reporter + var diagnosticAnalyzerPerformanceTracker = SolutionService.PrimaryWorkspace.Services.GetService(); + if (diagnosticAnalyzerPerformanceTracker != null) + { + _performanceReporter = new PerformanceReporter(Logger, diagnosticAnalyzerPerformanceTracker, s_reportInterval, ShutdownCancellationToken); + } } private static void EnsureCulture(int uiCultureLCID, int cultureLCID) diff --git a/src/Workspaces/Remote/ServiceHub/Shared/RoslynJsonConverter.RoslynOnly.cs b/src/Workspaces/Remote/ServiceHub/Shared/RoslynJsonConverter.RoslynOnly.cs index 4d3204ca26e..b29e449ecb3 100644 --- a/src/Workspaces/Remote/ServiceHub/Shared/RoslynJsonConverter.RoslynOnly.cs +++ b/src/Workspaces/Remote/ServiceHub/Shared/RoslynJsonConverter.RoslynOnly.cs @@ -7,6 +7,7 @@ using Microsoft.CodeAnalysis.AddImport; using Microsoft.CodeAnalysis.CodeActions; using Microsoft.CodeAnalysis.DesignerAttributes; +using Microsoft.CodeAnalysis.Diagnostics; using Microsoft.CodeAnalysis.DocumentHighlighting; using Microsoft.CodeAnalysis.Packaging; using Microsoft.CodeAnalysis.SymbolSearch; @@ -34,6 +35,8 @@ internal partial class AggregateJsonConverter : JsonConverter Add(builder, new ReferenceAssemblyWithTypeResultJsonConverter()); Add(builder, new AddImportFixDataJsonConverter()); + + Add(builder, new AnalyzerPerformanceInfoConverter()); } private class TodoCommentDescriptorJsonConverter : BaseJsonConverter @@ -73,7 +76,7 @@ protected override TodoComment ReadValue(JsonReader reader, JsonSerializer seria Contract.ThrowIfFalse(reader.TokenType == JsonToken.StartObject); // all integer is long - var descriptor = ReadProperty(serializer, reader); + var descriptor = ReadProperty(reader, serializer); var message = ReadProperty(reader); var position = ReadProperty(reader); @@ -168,7 +171,7 @@ protected override HighlightSpan ReadValue(JsonReader reader, JsonSerializer ser { Contract.ThrowIfFalse(reader.TokenType == JsonToken.StartObject); - var textSpan = ReadProperty(serializer, reader); + var textSpan = ReadProperty(reader, serializer); var kind = (HighlightSpanKind)ReadProperty(reader); Contract.ThrowIfFalse(reader.Read()); @@ -201,7 +204,7 @@ protected override PackageWithTypeResult ReadValue(JsonReader reader, JsonSerial var typeName = ReadProperty(reader); var version = ReadProperty(reader); var rank = (int)ReadProperty(reader); - var containingNamespaceNames = ReadProperty>(serializer, reader); + var containingNamespaceNames = ReadProperty>(reader, serializer); Contract.ThrowIfFalse(reader.Read()); Contract.ThrowIfFalse(reader.TokenType == JsonToken.EndObject); @@ -273,7 +276,7 @@ protected override ReferenceAssemblyWithTypeResult ReadValue(JsonReader reader, var assemblyName = ReadProperty(reader); var typeName = ReadProperty(reader); - var containingNamespaceNames = ReadProperty>(serializer, reader); + var containingNamespaceNames = ReadProperty>(reader, serializer); Contract.ThrowIfFalse(reader.Read()); Contract.ThrowIfFalse(reader.TokenType == JsonToken.EndObject); @@ -334,14 +337,14 @@ protected override AddImportFixData ReadValue(JsonReader reader, JsonSerializer Contract.ThrowIfFalse(reader.TokenType == JsonToken.StartObject); var kind = (AddImportFixKind)ReadProperty(reader); - var textChanges = ReadProperty>(serializer, reader).ToImmutableArrayOrEmpty(); + var textChanges = ReadProperty>(reader, serializer).ToImmutableArrayOrEmpty(); var title = ReadProperty(reader); - var tags = ReadProperty>(serializer, reader).ToImmutableArrayOrEmpty(); + var tags = ReadProperty>(reader, serializer).ToImmutableArrayOrEmpty(); var priority = (CodeActionPriority)ReadProperty(reader); - var projectReferenceToAdd = ReadProperty(serializer, reader); + var projectReferenceToAdd = ReadProperty(reader, serializer); - var portableExecutableReferenceProjectId = ReadProperty(serializer, reader); + var portableExecutableReferenceProjectId = ReadProperty(reader, serializer); var portableExecutableReferenceFilePathToAdd = ReadProperty(reader); var assemblyReferenceAssemblyName = ReadProperty(reader); @@ -418,5 +421,38 @@ protected override void WriteValue(JsonWriter writer, AddImportFixData source, J writer.WriteEndObject(); } } + + private class AnalyzerPerformanceInfoConverter : BaseJsonConverter + { + protected override AnalyzerPerformanceInfo ReadValue(JsonReader reader, JsonSerializer serializer) + { + Contract.ThrowIfFalse(reader.TokenType == JsonToken.StartObject); + + var analyzerid = ReadProperty(reader); + var builtIn = ReadProperty(reader); + var timeSpan = ReadProperty(reader, serializer); + + Contract.ThrowIfFalse(reader.Read()); + Contract.ThrowIfFalse(reader.TokenType == JsonToken.EndObject); + + return new AnalyzerPerformanceInfo(analyzerid, builtIn, timeSpan); + } + + protected override void WriteValue(JsonWriter writer, AnalyzerPerformanceInfo info, JsonSerializer serializer) + { + writer.WriteStartObject(); + + writer.WritePropertyName(nameof(AnalyzerPerformanceInfo.AnalyzerId)); + writer.WriteValue(info.AnalyzerId); + + writer.WritePropertyName(nameof(AnalyzerPerformanceInfo.BuiltIn)); + writer.WriteValue(info.BuiltIn); + + writer.WritePropertyName(nameof(AnalyzerPerformanceInfo.TimeSpan)); + serializer.Serialize(writer, info.TimeSpan); + + writer.WriteEndObject(); + } + } } } diff --git a/src/Workspaces/Remote/ServiceHub/Shared/RoslynJsonConverter.SolutionIdConverters.cs b/src/Workspaces/Remote/ServiceHub/Shared/RoslynJsonConverter.SolutionIdConverters.cs index e5fea048378..ea029041d05 100644 --- a/src/Workspaces/Remote/ServiceHub/Shared/RoslynJsonConverter.SolutionIdConverters.cs +++ b/src/Workspaces/Remote/ServiceHub/Shared/RoslynJsonConverter.SolutionIdConverters.cs @@ -87,7 +87,7 @@ protected override DocumentId ReadValue(JsonReader reader, JsonSerializer serial Contract.ThrowIfFalse(reader.TokenType == JsonToken.StartObject); - var projectId = ReadProperty(serializer, reader); + var projectId = ReadProperty(reader, serializer); var (id, debugName) = ReadIdAndName(reader); diff --git a/src/Workspaces/Remote/ServiceHub/Shared/RoslynJsonConverter.cs b/src/Workspaces/Remote/ServiceHub/Shared/RoslynJsonConverter.cs index 7b9acbcf92b..a97d85c2827 100644 --- a/src/Workspaces/Remote/ServiceHub/Shared/RoslynJsonConverter.cs +++ b/src/Workspaces/Remote/ServiceHub/Shared/RoslynJsonConverter.cs @@ -72,7 +72,7 @@ public sealed override void WriteJson(JsonWriter writer, object value, JsonSeria protected abstract T ReadValue(JsonReader reader, JsonSerializer serializer); protected abstract void WriteValue(JsonWriter writer, T value, JsonSerializer serializer); - protected static U ReadProperty(JsonSerializer serializer, JsonReader reader) + protected static U ReadProperty(JsonReader reader, JsonSerializer serializer) { // read property Contract.ThrowIfFalse(reader.Read()); @@ -189,7 +189,7 @@ protected override PinnedSolutionInfo ReadValue(JsonReader reader, JsonSerialize // all integer is long var scopeId = ReadProperty(reader); var fromPrimaryBranch = ReadProperty(reader); - var checksum = ReadProperty(serializer, reader); + var checksum = ReadProperty(reader, serializer); Contract.ThrowIfFalse(reader.Read()); Contract.ThrowIfFalse(reader.TokenType == JsonToken.EndObject); diff --git a/src/Workspaces/Remote/ServiceHub/Telemetry/WatsonReporter.cs b/src/Workspaces/Remote/ServiceHub/Telemetry/WatsonReporter.cs index b5016b97579..2b058c937ca 100644 --- a/src/Workspaces/Remote/ServiceHub/Telemetry/WatsonReporter.cs +++ b/src/Workspaces/Remote/ServiceHub/Telemetry/WatsonReporter.cs @@ -30,6 +30,11 @@ public static void SetTelemetrySession(TelemetrySession session) /// public static TelemetrySession SessionOpt => s_sessionOpt; + /// + /// Check whether current user is microsoft internal or not + /// + public static bool IsUserMicrosoftInternal => SessionOpt?.IsUserMicrosoftInternal ?? false; + /// /// Report Non-Fatal Watson /// -- GitLab