public IncrementalAnalyzerRunner(Workspace workspace, Options options)
 {
     _workspace = workspace;
     _options   = options;
 }
        private static IEnumerable<DiagnosticAnalyzer> FilterAnalyzers(IEnumerable<DiagnosticAnalyzer> analyzers, Options options)
        {
            if (options.IncrementalAnalyzerNames.Any())
            {
                // AnalyzerRunner is running for IIncrementalAnalyzer testing. DiagnosticAnalyzer testing is disabled
                // unless /all or /a was used.
                if (!options.UseAll && options.AnalyzerNames.IsEmpty)
                {
                    yield break;
                }
            }

            if (options.RefactoringNodes.Any())
            {
                // AnalyzerRunner is running for CodeRefactoringProvider testing. DiagnosticAnalyzer testing is disabled.
                yield break;
            }

            var analyzerTypes = new HashSet<Type>();

            foreach (var analyzer in analyzers)
            {
                if (!analyzerTypes.Add(analyzer.GetType()))
                {
                    // Avoid running the same analyzer multiple times
                    continue;
                }

                if (options.UseAll)
                {
                    yield return analyzer;
                }
                else if (options.AnalyzerNames.Count == 0)
                {
                    if (analyzer.SupportedDiagnostics.Any(diagnosticDescriptor => diagnosticDescriptor.IsEnabledByDefault))
                    {
                        yield return analyzer;
                    }
                }
                else if (options.AnalyzerNames.Contains(analyzer.GetType().Name))
                {
                    yield return analyzer;
                }
            }
        }
        private static async Task<DocumentAnalyzerPerformance> TestDocumentPerformanceAsync(ImmutableDictionary<string, ImmutableArray<DiagnosticAnalyzer>> analyzers, Project project, DocumentId documentId, Options analyzerOptionsInternal, CancellationToken cancellationToken)
        {
            // update the project compilation options
            var modifiedSpecificDiagnosticOptions = project.CompilationOptions.SpecificDiagnosticOptions
                .Add("AD0001", ReportDiagnostic.Error)
                .Add("AD0002", ReportDiagnostic.Error);
            // Report exceptions during the analysis process as errors
            var modifiedCompilationOptions = project.CompilationOptions.WithSpecificDiagnosticOptions(modifiedSpecificDiagnosticOptions);
            var processedProject = project.WithCompilationOptions(modifiedCompilationOptions);

            if (!analyzers.TryGetValue(project.Language, out var languageAnalyzers))
            {
                languageAnalyzers = ImmutableArray<DiagnosticAnalyzer>.Empty;
            }

            var stopwatch = Stopwatch.StartNew();
            for (int i = 0; i < analyzerOptionsInternal.TestDocumentIterations; i++)
            {
                Compilation compilation = await processedProject.GetCompilationAsync(cancellationToken).ConfigureAwait(false);

                var workspaceAnalyzerOptions = new WorkspaceAnalyzerOptions(project.AnalyzerOptions, project.Solution.Options, project.Solution);
                CompilationWithAnalyzers compilationWithAnalyzers = compilation.WithAnalyzers(languageAnalyzers, new CompilationWithAnalyzersOptions(workspaceAnalyzerOptions, null, analyzerOptionsInternal.RunConcurrent, logAnalyzerExecutionTime: true, reportSuppressedDiagnostics: analyzerOptionsInternal.ReportSuppressedDiagnostics));

                SyntaxTree tree = await project.GetDocument(documentId).GetSyntaxTreeAsync(cancellationToken).ConfigureAwait(false);
                await compilationWithAnalyzers.GetAnalyzerSyntaxDiagnosticsAsync(tree, cancellationToken).ConfigureAwait(false);
                await compilationWithAnalyzers.GetAnalyzerSemanticDiagnosticsAsync(compilation.GetSemanticModel(tree), null, cancellationToken).ConfigureAwait(false);
            }

            return new DocumentAnalyzerPerformance(analyzerOptionsInternal.TestDocumentIterations / stopwatch.Elapsed.TotalSeconds);
        }
 private static ImmutableDictionary<string, ImmutableArray<DiagnosticAnalyzer>> FilterAnalyzers(ImmutableDictionary<string, ImmutableArray<DiagnosticAnalyzer>> analyzers, Options options)
 {
     return analyzers.ToImmutableDictionary(
         pair => pair.Key,
         pair => FilterAnalyzers(pair.Value, options).ToImmutableArray());
 }
Esempio n. 5
0
        public static async Task Main(string[] args)
        {
            Options options;

            try
            {
                options = Options.Create(args);
            }
            catch (InvalidDataException)
            {
                PrintHelp();
                return;
            }

            var cts = new CancellationTokenSource();

            Console.CancelKeyPress += (sender, e) =>
            {
                e.Cancel = true;
                cts.Cancel();
            };

            var cancellationToken = cts.Token;

            if (!string.IsNullOrEmpty(options.ProfileRoot))
            {
                Directory.CreateDirectory(options.ProfileRoot);
                ProfileOptimization.SetProfileRoot(options.ProfileRoot);
            }

            using var workspace = AnalyzerRunnerHelper.CreateWorkspace();

            var incrementalAnalyzerRunner = new IncrementalAnalyzerRunner(workspace, options);
            var diagnosticAnalyzerRunner  = new DiagnosticAnalyzerRunner(workspace, options);
            var codeRefactoringRunner     = new CodeRefactoringRunner(workspace, options);

            if (
                !incrementalAnalyzerRunner.HasAnalyzers &&
                !diagnosticAnalyzerRunner.HasAnalyzers &&
                !codeRefactoringRunner.HasRefactorings
                )
            {
                WriteLine("No analyzers found", ConsoleColor.Red);
                PrintHelp();
                return;
            }

            var stopwatch = PerformanceTracker.StartNew();

            if (!string.IsNullOrEmpty(options.ProfileRoot))
            {
                ProfileOptimization.StartProfile(nameof(MSBuildWorkspace.OpenSolutionAsync));
            }

            await workspace
            .OpenSolutionAsync(options.SolutionPath, progress : null, cancellationToken)
            .ConfigureAwait(false);

            foreach (var workspaceDiagnostic in workspace.Diagnostics)
            {
                if (workspaceDiagnostic.Kind == WorkspaceDiagnosticKind.Failure)
                {
                    Console.WriteLine(workspaceDiagnostic.Message);
                }
            }

            Console.WriteLine($"Loaded solution in {stopwatch.GetSummary(preciseMemory: true)}");

            if (options.ShowStats)
            {
                stopwatch = PerformanceTracker.StartNew();
                ShowSolutionStatistics(workspace.CurrentSolution, cancellationToken);
                Console.WriteLine(
                    $"Statistics gathered in {stopwatch.GetSummary(preciseMemory: true)}"
                    );
            }

            if (options.ShowCompilerDiagnostics)
            {
                await ShowCompilerDiagnosticsAsync(workspace.CurrentSolution, cancellationToken)
                .ConfigureAwait(false);
            }

            Console.WriteLine("Pausing 5 seconds before starting analysis...");
            await Task.Delay(TimeSpan.FromSeconds(5)).ConfigureAwait(false);

            if (incrementalAnalyzerRunner.HasAnalyzers)
            {
                if (!string.IsNullOrEmpty(options.ProfileRoot))
                {
                    ProfileOptimization.StartProfile(
                        nameof(Microsoft.CodeAnalysis.SolutionCrawler.IIncrementalAnalyzer)
                        );
                }

                await incrementalAnalyzerRunner.RunAsync(cancellationToken).ConfigureAwait(false);
            }

            if (diagnosticAnalyzerRunner.HasAnalyzers)
            {
                if (!string.IsNullOrEmpty(options.ProfileRoot))
                {
                    ProfileOptimization.StartProfile(nameof(DiagnosticAnalyzerRunner));
                }

                await diagnosticAnalyzerRunner.RunAllAsync(cancellationToken).ConfigureAwait(false);
            }

            if (codeRefactoringRunner.HasRefactorings)
            {
                if (!string.IsNullOrEmpty(options.ProfileRoot))
                {
                    ProfileOptimization.StartProfile(nameof(CodeRefactoringRunner));
                }

                await codeRefactoringRunner.RunAsync(cancellationToken).ConfigureAwait(false);
            }
        }