public static async Task Main(string[] args) { Options options; try { options = Options.Create(args); } catch (InvalidDataException) { PrintHelp(); return; } CancellationTokenSource cts = new CancellationTokenSource(); Console.CancelKeyPress += (sender, e) => { e.Cancel = true; cts.Cancel(); }; // QueryVisualStudioInstances returns Visual Studio installations on .NET Framework, and .NET Core SDK // installations on .NET Core. We use the one with the most recent version. var msBuildInstance = MSBuildLocator.QueryVisualStudioInstances().OrderByDescending(x => x.Version).First(); #if NETCOREAPP // Since we do not inherit msbuild.deps.json when referencing the SDK copy // of MSBuild and because the SDK no longer ships with version matched assemblies, we // register an assembly loader that will load assemblies from the msbuild path with // equal or higher version numbers than requested. LooseVersionAssemblyLoader.Register(msBuildInstance.MSBuildPath); #endif MSBuildLocator.RegisterInstance(msBuildInstance); var incrementalAnalyzerRunner = new IncrementalAnalyzerRunner(options); var diagnosticAnalyzerRunner = new DiagnosticAnalyzerRunner(options); var codeRefactoringRunner = new CodeRefactoringRunner(options); if (!incrementalAnalyzerRunner.HasAnalyzers && !diagnosticAnalyzerRunner.HasAnalyzers && !codeRefactoringRunner.HasRefactorings) { WriteLine("No analyzers found", ConsoleColor.Red); PrintHelp(); return; } var cancellationToken = cts.Token; if (!string.IsNullOrEmpty(options.ProfileRoot)) { Directory.CreateDirectory(options.ProfileRoot); ProfileOptimization.SetProfileRoot(options.ProfileRoot); } var stopwatch = PerformanceTracker.StartNew(); var properties = new Dictionary <string, string> { #if NETCOREAPP // This property ensures that XAML files will be compiled in the current AppDomain // rather than a separate one. Any tasks isolated in AppDomains or tasks that create // AppDomains will likely not work due to https://github.com/Microsoft/MSBuildLocator/issues/16. { "AlwaysCompileMarkupFilesInSeparateDomain", bool.FalseString }, #endif // Use the latest language version to force the full set of available analyzers to run on the project. { "LangVersion", "latest" }, }; if (!string.IsNullOrEmpty(options.ProfileRoot)) { ProfileOptimization.StartProfile(nameof(MSBuildWorkspace.OpenSolutionAsync)); } using (MSBuildWorkspace workspace = MSBuildWorkspace.Create(properties, AnalyzerRunnerMefHostServices.DefaultServices)) { Solution solution = await workspace.OpenSolutionAsync(options.SolutionPath, progress : null, cancellationToken).ConfigureAwait(false); var projectIds = solution.ProjectIds; foreach (var workspaceDiagnostic in workspace.Diagnostics) { if (workspaceDiagnostic.Kind == WorkspaceDiagnosticKind.Failure) { Console.WriteLine(workspaceDiagnostic.Message); } } foreach (var projectId in projectIds) { solution = solution.WithProjectAnalyzerReferences(projectId, ImmutableArray <AnalyzerReference> .Empty); } Console.WriteLine($"Loaded solution in {stopwatch.GetSummary(preciseMemory: true)}"); if (options.ShowStats) { stopwatch = PerformanceTracker.StartNew(); List <Project> projects = solution.Projects.Where(project => project.Language == LanguageNames.CSharp || project.Language == LanguageNames.VisualBasic).ToList(); Console.WriteLine("Number of projects:\t\t" + projects.Count); Console.WriteLine("Number of documents:\t\t" + projects.Sum(x => x.DocumentIds.Count)); var statistics = GetSolutionStatistics(projects, cancellationToken); Console.WriteLine("Number of syntax nodes:\t\t" + statistics.NumberofNodes); Console.WriteLine("Number of syntax tokens:\t" + statistics.NumberOfTokens); Console.WriteLine("Number of syntax trivia:\t" + statistics.NumberOfTrivia); Console.WriteLine($"Statistics gathered in {stopwatch.GetSummary(preciseMemory: true)}"); } if (options.ShowCompilerDiagnostics) { var projects = solution.Projects.Where(project => project.Language == LanguageNames.CSharp || project.Language == LanguageNames.VisualBasic).ToList(); var diagnosticStatistics = new Dictionary <string, (string description, DiagnosticSeverity severity, int count)>(); foreach (var project in projects) { var compilation = await project.GetCompilationAsync(cancellationToken).ConfigureAwait(false); foreach (var diagnostic in compilation.GetDiagnostics(cancellationToken)) { diagnosticStatistics.TryGetValue(diagnostic.Id, out var existing); var description = existing.description; if (string.IsNullOrEmpty(description)) { description = diagnostic.Descriptor?.Title.ToString(); if (string.IsNullOrEmpty(description)) { description = diagnostic.Descriptor?.MessageFormat.ToString(); } } diagnosticStatistics[diagnostic.Id] = (description, diagnostic.Descriptor.DefaultSeverity, existing.count + 1); } } foreach (var pair in diagnosticStatistics) { Console.WriteLine($" {pair.Value.severity} {pair.Key}: {pair.Value.count} instances ({pair.Value.description})"); } } Console.WriteLine("Pausing 5 seconds before starting analysis..."); await Task.Delay(TimeSpan.FromSeconds(5)).ConfigureAwait(false); await incrementalAnalyzerRunner.RunAsync(workspace, cancellationToken).ConfigureAwait(false); await diagnosticAnalyzerRunner.RunAsync(workspace, cancellationToken).ConfigureAwait(false); await codeRefactoringRunner.RunAsync(workspace, cancellationToken).ConfigureAwait(false); } }
public static async Task Main(string[] args) { Options options; try { options = Options.Create(args); } catch (InvalidDataException) { PrintHelp(); return; } CancellationTokenSource cts = new CancellationTokenSource(); Console.CancelKeyPress += (sender, e) => { e.Cancel = true; cts.Cancel(); }; MSBuildLocator.RegisterDefaults(); var incrementalAnalyzerRunner = new IncrementalAnalyzerRunner(options); var diagnosticAnalyzerRunner = new DiagnosticAnalyzerRunner(options); var codeRefactoringRunner = new CodeRefactoringRunner(options); if (!incrementalAnalyzerRunner.HasAnalyzers && !diagnosticAnalyzerRunner.HasAnalyzers && !codeRefactoringRunner.HasRefactorings) { WriteLine("No analyzers found", ConsoleColor.Red); PrintHelp(); return; } var cancellationToken = cts.Token; if (!string.IsNullOrEmpty(options.ProfileRoot)) { Directory.CreateDirectory(options.ProfileRoot); ProfileOptimization.SetProfileRoot(options.ProfileRoot); } Stopwatch stopwatch = Stopwatch.StartNew(); var properties = new Dictionary <string, string> { // Use the latest language version to force the full set of available analyzers to run on the project. { "LangVersion", "latest" }, }; if (!string.IsNullOrEmpty(options.ProfileRoot)) { ProfileOptimization.StartProfile(nameof(MSBuildWorkspace.OpenSolutionAsync)); } using (MSBuildWorkspace workspace = MSBuildWorkspace.Create(properties, AnalyzerRunnerMefHostServices.DefaultServices)) { Solution solution = await workspace.OpenSolutionAsync(options.SolutionPath, cancellationToken : cancellationToken).ConfigureAwait(false); var projectIds = solution.ProjectIds; foreach (var projectId in projectIds) { solution = solution.WithProjectAnalyzerReferences(projectId, ImmutableArray <AnalyzerReference> .Empty); } Console.WriteLine($"Loaded solution in {stopwatch.ElapsedMilliseconds}ms"); if (options.ShowStats) { List <Project> projects = solution.Projects.Where(project => project.Language == LanguageNames.CSharp || project.Language == LanguageNames.VisualBasic).ToList(); Console.WriteLine("Number of projects:\t\t" + projects.Count); Console.WriteLine("Number of documents:\t\t" + projects.Sum(x => x.DocumentIds.Count)); var statistics = GetSolutionStatistics(projects, cancellationToken); Console.WriteLine("Number of syntax nodes:\t\t" + statistics.NumberofNodes); Console.WriteLine("Number of syntax tokens:\t" + statistics.NumberOfTokens); Console.WriteLine("Number of syntax trivia:\t" + statistics.NumberOfTrivia); } Console.WriteLine("Pausing 5 seconds before starting analysis..."); await Task.Delay(TimeSpan.FromSeconds(5)).ConfigureAwait(false); await incrementalAnalyzerRunner.RunAsync(workspace, cancellationToken).ConfigureAwait(false); await diagnosticAnalyzerRunner.RunAsync(workspace, cancellationToken).ConfigureAwait(false); await codeRefactoringRunner.RunAsync(workspace, cancellationToken).ConfigureAwait(false); } }
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); } }