public static async Task Main(string[] args) { MSBuildLocator.RegisterDefaults(); using var workspace = MSBuildWorkspace.Create(); var solutionPath = args[0]; Console.WriteLine($"Loading {solutionPath}..."); var originalSolution = await workspace.OpenSolutionAsync(solutionPath); // Enables dynamically-loaded analyzers to resolve their dependencies. Utils.ResolveAssembliesWithVersionRollforward(AppDomain.CurrentDomain); Console.WriteLine($"Searching for unnecessary suppressions..."); var diagnosticsComparer = new SolutionDiagnosticsComparer(originalSolution); var newSolution = originalSolution; foreach (var projectId in originalSolution.ProjectIds) { var project = newSolution.GetProject(projectId); if (project is null) { continue; } foreach (var documentId in project.DocumentIds) { var document = newSolution.GetDocument(documentId); if (document is null) { continue; } var newDocument = await SuppressionFixer.FixAllInDocumentAsync(document, diagnosticsComparer, removal => { var fileLineSpan = removal.RemovalLocation.GetLineSpan(); Console.WriteLine($"Removed '{removal.RemovedText}' from {fileLineSpan.Path} ({fileLineSpan.StartLinePosition})"); }, CancellationToken.None); newSolution = newDocument.Project.Solution; Utils.UpdateWorkspace(workspace, ref newSolution); } } if (newSolution == originalSolution) { Console.WriteLine("No suppressions found that the tool could remove."); } else { Utils.UpdateWorkspace(workspace, ref newSolution); } }
public static async Task <Document> FixAllInDocumentAsync( Document document, SolutionDiagnosticsComparer diagnosticsComparer, Action <SuppressionRemoval> afterRemoval, CancellationToken cancellationToken) { var syntaxRoot = await document.GetSyntaxRootAsync(); if (syntaxRoot is null) { return(document); } var suppressions = FindSuppressions(syntaxRoot).ToList(); syntaxRoot = syntaxRoot.TrackNodes(suppressions); foreach (var suppressionSyntax in suppressions) { foreach (var removal in GetPotentialRemovals(syntaxRoot, syntaxRoot.GetCurrentNode(suppressionSyntax))) { var modifiedDocument = document.WithSyntaxRoot(removal.NewRoot); if (await diagnosticsComparer.HasNewCompileDiagnosticsAsync(modifiedDocument, cancellationToken).ConfigureAwait(false)) { continue; } if (removal.RequiredAnalyzerDiagnosticIds.Any() && await diagnosticsComparer.HasNewAnalyzerDiagnosticsAsync(modifiedDocument, removal.RequiredAnalyzerDiagnosticIds, cancellationToken).ConfigureAwait(false)) { continue; } syntaxRoot = removal.NewRoot; document = modifiedDocument; afterRemoval(removal); break; } } return(document); }