public async Task FixAsync(CancellationToken cancellationToken = default) { ImmutableArray <ProjectId> projects = CurrentSolution .GetProjectDependencyGraph() .GetTopologicallySortedProjects(cancellationToken) .ToImmutableArray(); foreach (string projectName in Options.IgnoredProjectNames.OrderBy(f => f)) { WriteLine($"Project '{projectName}' will be ignored"); } foreach (string id in Options.IgnoredDiagnosticIds.OrderBy(f => f)) { WriteLine($"Diagnostic '{id}' will be ignored"); } foreach (string id in Options.IgnoredCompilerDiagnosticIds.OrderBy(f => f)) { WriteLine($"Compiler diagnostic '{id}' will be ignored"); } Stopwatch stopwatch = Stopwatch.StartNew(); TimeSpan lastElapsed = TimeSpan.Zero; for (int i = 0; i < projects.Length; i++) { cancellationToken.ThrowIfCancellationRequested(); Project project = CurrentSolution.GetProject(projects[i]); WriteLine($"Fix project {$"{i + 1}/{projects.Length}"} '{project.Name}'", ConsoleColor.Cyan); if (Options.IgnoredProjectNames.Contains(project.Name)) { WriteLine($" Project '{project.Name}' is ignored"); } else { FixResult result = await FixProjectAsync(project, cancellationToken).ConfigureAwait(false); if (result == FixResult.CompilerError) { break; } } TimeSpan elapsed = stopwatch.Elapsed; WriteLine($"Done fixing project {$"{i + 1}/{projects.Length}"} {elapsed - lastElapsed:mm\\:ss\\.ff} '{project.Name}'", ConsoleColor.Green); lastElapsed = elapsed; } stopwatch.Stop(); WriteLine($"Done fixing solution {stopwatch.Elapsed:mm\\:ss\\.ff} '{CurrentSolution.FilePath}'", ConsoleColor.Green); }
public bool BetterThan(FixResult anotherResult) { if (Success && !anotherResult.Success || Length < anotherResult.Length || ErrSum / anotherResult.ErrSum < 0.01) { return(true); } return(false); }
public async Task <ProjectFixResult> FixProjectAsync(Project project, CancellationToken cancellationToken = default) { (ImmutableArray <DiagnosticAnalyzer> analyzers, ImmutableArray <CodeFixProvider> fixers) = _analyzerLoader.GetAnalyzersAndFixers(project: project); FixResult fixResult = await FixProjectAsync(project, analyzers, fixers, cancellationToken).ConfigureAwait(false); project = CurrentSolution.GetProject(project.Id); Compilation compilation = await project.GetCompilationAsync(cancellationToken).ConfigureAwait(false); Dictionary <string, ImmutableArray <CodeFixProvider> > fixersById = fixers .SelectMany(f => f.FixableDiagnosticIds.Select(id => (id, fixer: f))) .GroupBy(f => f.id) .ToDictionary(f => f.Key, g => g.Select(f => f.fixer).Distinct().ToImmutableArray()); ImmutableArray <Diagnostic> unfixableDiagnostics = await GetDiagnosticsAsync( analyzers, fixResult.FixedDiagnostics, compilation, project.AnalyzerOptions, f => !fixersById.ContainsKey(f.id), cancellationToken) .ConfigureAwait(false); ImmutableArray <Diagnostic> unfixedDiagnostics = await GetDiagnosticsAsync( analyzers, fixResult.FixedDiagnostics.Concat(unfixableDiagnostics), compilation, project.AnalyzerOptions, f => fixersById.ContainsKey(f.id), cancellationToken) .ConfigureAwait(false); int numberOfAddedFileBanners = 0; if (Options.FileBannerLines.Any()) { numberOfAddedFileBanners = await AddFileBannerAsync(CurrentSolution.GetProject(project.Id), Options.FileBannerLines, cancellationToken).ConfigureAwait(false); } ImmutableArray <DocumentId> formattedDocuments = ImmutableArray <DocumentId> .Empty; if (Options.Format) { formattedDocuments = await FormatProjectAsync(CurrentSolution.GetProject(project.Id), cancellationToken).ConfigureAwait(false); } var result = new ProjectFixResult( kind: fixResult.Kind, fixedDiagnostics: fixResult.FixedDiagnostics.Select(f => DiagnosticInfo.Create(f)), unfixedDiagnostics: unfixedDiagnostics.Select(f => DiagnosticInfo.Create(f)), unfixableDiagnostics: unfixableDiagnostics.Select(f => DiagnosticInfo.Create(f)), numberOfFormattedDocuments: (Options.FileBannerLines.Any()) ? formattedDocuments.Length : -1, numberOfAddedFileBanners: (Options.Format) ? numberOfAddedFileBanners : -1); LogHelpers.WriteFixSummary( fixResult.FixedDiagnostics, unfixedDiagnostics, unfixableDiagnostics, baseDirectoryPath: Path.GetDirectoryName(project.FilePath), indentation: " ", formatProvider: FormatProvider, verbosity: Verbosity.Detailed); return(result); }
private async Task <FixResult> FixProjectAsync(Project project, CancellationToken cancellationToken = default) { string language = project.Language; ImmutableArray <Assembly> assemblies = (Options.IgnoreAnalyzerReferences) ? ImmutableArray <Assembly> .Empty : project.AnalyzerReferences .Distinct() .OfType <AnalyzerFileReference>() .Select(f => f.GetAssembly()) .Where(f => !_analyzerFiles.Contains(f.FullName)) .ToImmutableArray(); ImmutableArray <DiagnosticAnalyzer> analyzers = _analyzerFiles .GetAnalyzers(language) .AddRange(_analyzerFileCache.GetAnalyzers(assemblies, language)); if (!analyzers.Any()) { return(FixResult.NoAnalyzers); } ImmutableArray <CodeFixProvider> fixers = _analyzerFiles .GetFixers(language) .AddRange(_analyzerFileCache.GetFixers(assemblies, language)); if (!fixers.Any()) { return(FixResult.NoFixers); } Dictionary <string, ImmutableArray <DiagnosticAnalyzer> > analyzersById = analyzers .SelectMany(f => f.SupportedDiagnostics.Select(id => (id.Id, analyzer: f))) .GroupBy(f => f.Id) .ToDictionary(f => f.Key, g => g.Select(f => f.analyzer).Distinct().ToImmutableArray()); Dictionary <string, ImmutableArray <CodeFixProvider> > fixersById = fixers .Where(f => f.GetFixAllProvider() != null) .SelectMany(f => f.FixableDiagnosticIds.Select(id => (id, fixer: f))) .GroupBy((f) => f.id) .ToDictionary(f => f.Key, g => g.Select(f => f.fixer).ToImmutableArray()); ImmutableArray <Diagnostic> previousDiagnostics = ImmutableArray <Diagnostic> .Empty; int iterationCount = 1; while (true) { cancellationToken.ThrowIfCancellationRequested(); project = CurrentSolution.GetProject(project.Id); WriteLine($" Compile '{project.Name}'{((iterationCount > 1) ? $" iteration {iterationCount}" : "")}"); Compilation compilation = await project.GetCompilationAsync(cancellationToken).ConfigureAwait(false); if (!VerifyCompilerDiagnostics(compilation, cancellationToken)) { return(FixResult.CompilerError); } var compilationWithAnalyzers = new CompilationWithAnalyzers(compilation, analyzers, DefaultCompilationWithAnalyzersOptions); WriteLine($" Analyze '{project.Name}'"); ImmutableArray <Diagnostic> diagnostics = await compilationWithAnalyzers.GetAnalyzerDiagnosticsAsync(cancellationToken).ConfigureAwait(false); foreach (string message in diagnostics .Where(f => f.Id.StartsWith("AD", StringComparison.Ordinal)) .Select(f => f.ToString()) .Distinct()) { WriteLine(message, ConsoleColor.Yellow); } diagnostics = diagnostics .Where(f => f.Severity != DiagnosticSeverity.Hidden && analyzersById.ContainsKey(f.Id) && fixersById.ContainsKey(f.Id) && !Options.IgnoredDiagnosticIds.Contains(f.Id)) .ToImmutableArray(); int length = diagnostics.Length; if (length == 0) { break; } if (length == previousDiagnostics.Length && !diagnostics.Except(previousDiagnostics, DiagnosticDeepEqualityComparer.Instance).Any()) { break; } WriteLine($" Found {length} {((length == 1) ? "diagnostic" : "diagnostics")} in '{project.Name}'"); foreach (string diagnosticId in diagnostics .Select(f => f.Id) .Distinct() .OrderBy(f => f)) { cancellationToken.ThrowIfCancellationRequested(); FixResult result = await FixDiagnosticsAsync( diagnosticId, CurrentSolution.GetProject(project.Id), analyzersById[diagnosticId], fixersById[diagnosticId], cancellationToken).ConfigureAwait(false); if (result == FixResult.CompilerError) { return(result); } } previousDiagnostics = diagnostics; iterationCount++; } return(FixResult.Success); }
private void InitializeBackgroundWorker() { this.MainProgressBar.Value = 5; var backgroundWorker = new BackgroundWorker(); backgroundWorker.WorkerReportsProgress = true; backgroundWorker.DoWork += (sender, e) => { var bgWorker = sender as BackgroundWorker; if (bgWorker != null) { OverallResult overallResult = OverallResult.None; var stringTable = Localization.LocalizationManager.Get(); var agents = Utilities.RemovalAgentFactory.GetRemovalAgents().ToList(); if (agents != null && agents.Any()) { foreach (var agent in agents) { try { double percentageComplete = ((double)(agents.IndexOf(agent) + 1) / (double)agents.Count) * 100; FixResult removalResult = TryToExecuteRemoval(agent); bgWorker.ReportProgress(Convert.ToInt32(percentageComplete), removalResult); OverallResult thisResult = CalculateSingleResult(removalResult); overallResult = CalculateMergedResult(overallResult, thisResult); System.Threading.Thread.Sleep(1000); // Some of the agents perform very quickly. Slow it down to show each step } catch (Exception ex) { Logging.Logger.Log(Logging.LogSeverity.Error, ex.Message); } } } bgWorker.ReportProgress(100, overallResult); System.Threading.Thread.Sleep(500); // Let the user see the final 100% before hiding progress bar } }; backgroundWorker.ProgressChanged += (sender, e) => { if (e != null) { if (e.UserState == null) { this.UpdateOverallStatusLabel(OverallResult.Error); } else { this.MainProgressBar.Value = e.ProgressPercentage; var result = e.UserState as Utilities.FixResult; if (result != null) { this.AddLabelBasedOnIndividualResult(result); } else { var overallStatus = (OverallResult)e.UserState; if (overallStatus != OverallResult.None) { this.UpdateOverallStatusLabel(overallStatus); this.UpdateRestartButtons(overallStatus); } } } } }; backgroundWorker.RunWorkerCompleted += (sender, e) => { this.IsDoingWork = false; this.MainProgressBar.Value = 0; }; backgroundWorker.RunWorkerAsync(); // Start! }