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 <Dictionary <DiagnosticAnalyzer, AnalyzerTelemetryInfo> >().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
            }
        }
        private async Task FormatWithAnalyzersCoreAsync(Workspace workspace, ProjectId projectId, IEnumerable <DiagnosticAnalyzer> analyzers, CancellationToken cancellationToken)
        {
            if (analyzers != null && analyzers.Count() != 0)
            {
                var project     = workspace.CurrentSolution.GetProject(projectId);
                var diagnostics = await GetDiagnostics(project, analyzers, cancellationToken).ConfigureAwait(false);

                // Ensure at least 1 analyzer supporting the current project's language ran
                if (_compilationWithAnalyzers != null)
                {
                    var extension  = StringComparer.OrdinalIgnoreCase.Equals(project.Language, "C#") ? ".csproj" : ".vbproj";
                    var resultFile = project.FilePath?.Substring(project.FilePath.LastIndexOf(Path.DirectorySeparatorChar)).Replace(extension, "_CodeFormatterResults.txt");

                    foreach (var analyzer in analyzers)
                    {
                        var diags = await _compilationWithAnalyzers.GetAnalyzerDiagnosticsAsync(ImmutableArray.Create(analyzer), cancellationToken);

                        if (Verbose || LogOutputPath != null)
                        {
                            var analyzerTelemetryInfo = await _compilationWithAnalyzers.GetAnalyzerTelemetryInfoAsync(analyzer, cancellationToken);

                            FormatLogger.WriteLine("{0}\t{1}\t{2}\t{3}", project.Name, analyzer.ToString(), diags.Count(), analyzerTelemetryInfo.ExecutionTime);
                            var resultPath = Path.ChangeExtension(LogOutputPath + resultFile, "json");
                            LogDiagnostics(resultPath, diags);
                        }
                    }
                }

                if (ApplyFixes)
                {
                    var batchFixer = WellKnownFixAllProviders.BatchFixer;
                    var context    = new FixAllContext(
                        project.Documents.First(), // TODO: Shouldn't this be the whole project?
                        new UberCodeFixer(_diagnosticIdToFixerMap),
                        FixAllScope.Project,
                        null,
                        diagnostics.Select(d => d.Id),
                        new FormattingEngineDiagnosticProvider(project, diagnostics),
                        cancellationToken);

                    var fix = await batchFixer.GetFixAsync(context).ConfigureAwait(false);

                    if (fix != null)
                    {
                        foreach (var operation in await fix.GetOperationsAsync(cancellationToken).ConfigureAwait(false))
                        {
                            operation.Apply(workspace, cancellationToken);
                        }
                    }
                }
            }
        }
            private async Task UpdateAnalyzerTelemetryDataAsync(CompilationWithAnalyzers analyzerDriver, DiagnosticAnalyzer analyzer, Project project, CancellationToken cancellationToken)
            {
                try
                {
                    var analyzerTelemetryInfo = await analyzerDriver.GetAnalyzerTelemetryInfoAsync(analyzer, cancellationToken).ConfigureAwait(false);

                    DiagnosticAnalyzerLogger.UpdateAnalyzerTypeCount(analyzer, analyzerTelemetryInfo, project, _owner.DiagnosticLogAggregator);
                }
                catch (Exception e) when(FatalError.ReportUnlessCanceled(e))
                {
                    throw ExceptionUtilities.Unreachable;
                }
            }
        public void GetAnalyzerTelemetry()
        {
            var compilation             = CSharpCompilation.Create("c", options: new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary));
            DiagnosticAnalyzer analyzer = new AnalyzerWithDisabledRules();
            var analyzers         = ImmutableArray.Create(analyzer);
            var analyzerOptions   = new AnalyzerOptions(ImmutableArray <AdditionalText> .Empty);
            var compWithAnalyzers = new CompilationWithAnalyzers(compilation, analyzers, analyzerOptions, CancellationToken.None);

            var analysisResult = compWithAnalyzers.GetAnalysisResultAsync(CancellationToken.None).Result;

            Assert.Empty(analysisResult.CompilationDiagnostics);

            // Even though the analyzer registers a symbol action, it should never be invoked because all of its rules are disabled.
            var analyzerTelemetry = compWithAnalyzers.GetAnalyzerTelemetryInfoAsync(analyzer, CancellationToken.None).Result;

            Assert.Equal(0, analyzerTelemetry.SymbolActionsCount);
        }
 private async Task UpdateAnalyzerTelemetryDataAsync(DiagnosticAnalyzer analyzer, CompilationWithAnalyzers compilationWithAnalyzers)
 {
     try
     {
         var analyzerTelemetryInfo = await compilationWithAnalyzers.GetAnalyzerTelemetryInfoAsync(analyzer, _cancellationToken).ConfigureAwait(false);
         DiagnosticAnalyzerLogger.UpdateAnalyzerTypeCount(analyzer, analyzerTelemetryInfo, _project, _owner.DiagnosticLogAggregator);
     }
     catch (Exception e) when (FatalError.ReportUnlessCanceled(e))
     {
         throw ExceptionUtilities.Unreachable;
     }
 }