static async Task Main(string[] args) { var projectPath = "/Users/wk/Source/DotNetCodeFix/tests/MyApp/MyApp.csproj"; var manager = new AnalyzerManager(); var project = manager.GetProject(projectPath); var sources = project.GetSourceFiles(); var workspace = new AdhocWorkspace(); var roslynProject = project.AddToWorkspace(workspace, true); CancellationTokenSource cts = new CancellationTokenSource(); var analyzers = GetAllAnalyzers(); Console.WriteLine($"{string.Join(", ", analyzers.Select(x => x.GetType().Name))}"); var codeFixers = GetAllCodeFixers().SelectMany(x => x.Value).Distinct(); Console.WriteLine($"{string.Join(", ", codeFixers.Select(x => x.GetType().Name))}"); var equivalenceGroups = new List <CodeFixEquivalenceGroup>(); var diagnostics = await GetAnalyzerDiagnosticsAsync(roslynProject, analyzers, cts.Token).ConfigureAwait(true); var empty = new AdhocWorkspace(); var solution = empty.AddSolution(SolutionInfo.Create(SolutionId.CreateNewId(), VersionStamp.Create(DateTime.Now), "/Users/wk/Temp/MyApp.sln")); foreach (var codeFixer in codeFixers) { //Console.WriteLine($"{codeFixer.GetFixAllProvider().GetType().Name}"); equivalenceGroups.AddRange(await CodeFixEquivalenceGroup.CreateAsync(codeFixer, diagnostics, solution, cts.Token).ConfigureAwait(true)); } var stopwatch = new Stopwatch(); foreach (var fix in equivalenceGroups) { try { stopwatch.Restart(); Console.WriteLine($"Calculating fix for {fix.CodeFixEquivalenceKey} using {fix.FixAllProvider} for {fix.NumberOfDiagnostics} instances."); var rs = await fix.GetOperationsAsync(cts.Token).ConfigureAwait(true); foreach (var item in rs) { Console.WriteLine($"Apply {item.Title}"); item.Apply(empty, cts.Token); } WriteLine($"Calculating changes completed in {stopwatch.ElapsedMilliseconds}ms. This is {fix.NumberOfDiagnostics / stopwatch.Elapsed.TotalSeconds:0.000} instances/second.", ConsoleColor.Yellow); } catch (Exception ex) { // Report thrown exceptions WriteLine($"The fix '{fix.CodeFixEquivalenceKey}' threw an exception after {stopwatch.ElapsedMilliseconds}ms:", ConsoleColor.Yellow); WriteLine(ex.ToString(), ConsoleColor.Yellow); } } }
static void Main(string[] args) { Log.Logger = new LoggerConfiguration() .WriteTo.LiterateConsole() .CreateLogger(); if (args.Length == 0) { Console.WriteLine(Args.Usage); return; } try { AppDomain.CurrentDomain.AssemblyResolve += CurrentDomainOnAssemblyResolve; var options = new Args(args); if (options.ShowVersion) { Log.Information($"Saritasa Prettify - {GetVersionOfExecutionAssembly()}"); } var styleCopAnalyzerAssembly = AssembliesHelper.GetAnalyzersAssembly(); var styleCopFixersAssembly = AssembliesHelper.GetCodeFixAssembly(); var analyzers = DiagnosticHelper.GetAnalyzersFromAssemblies(new[] { styleCopAnalyzerAssembly, styleCopFixersAssembly }); var codeFixes = CodeFixProviderHelper.GetFixProviders(new[] { styleCopAnalyzerAssembly, styleCopFixersAssembly }) .Where(x => options.Rules == null || options.Rules.Contains(x.Key)) .ToList(); var workspace = MSBuildWorkspace.Create(); var solution = workspace.OpenSolutionAsync(options.SolutionPath).Result; foreach (var solutionProject in solution.Projects) { var diagnostics = ProjectHelper.GetProjectAnalyzerDiagnosticsAsync(analyzers, solutionProject, true).Result .Where(x => options.Rules == null || options.Rules.Contains(x.Id)) .ToList(); Log.Information("<======= Project: {project} =======>", solutionProject.Name); if (!diagnostics.Any()) { Log.Information("Can't find any diagnostic issues for {@rules}", options.Rules); continue; } foreach (var projectAnalyzer in diagnostics) { Log.Information("DiagnosticId {@id} - {message} in file {path}({row},{column})", projectAnalyzer.Id, projectAnalyzer.GetMessage(), GetFormattedFileName(projectAnalyzer.Location.GetLineSpan().Path), projectAnalyzer.Location.GetLineSpan().StartLinePosition.Line, projectAnalyzer.Location.GetLineSpan().StartLinePosition.Character); } if (options.Rules == null && options.Mode == Args.RunningMode.Fix) { Log.Warning("Please specify rules for fix"); break; } if (options.Mode == Args.RunningMode.Fix) { var diagnistics = DiagnosticHelper.GetAnalyzerDiagnosticsAsync(solution, analyzers, true).Result; foreach (var keyValuePair in codeFixes) { var equivalenceGroups = new List <CodeFixEquivalenceGroup>(); keyValuePair.Value.ForEach(x => { equivalenceGroups.AddRange(CodeFixEquivalenceGroup.CreateAsync(x, diagnistics, solution).Result); }); if (!equivalenceGroups.Any()) { continue; } var fix = equivalenceGroups[0]; if (equivalenceGroups.Count() > 1) { Log.Warning("Allowed only one equivalence group for fix"); continue; } var operations = fix.GetOperationsAsync().Result; if (operations.Length == 0) { Log.Information("No changes was found for this fixer"); } else { operations[0].Apply(workspace, default(CancellationToken)); Log.Information("Fixer with DiagnosticId {@id} was applied ", keyValuePair.Key); } } } } } catch (Exception ex) { Log.Fatal(ex, string.Empty); } }
private async Task Run(bool fixIssues = false) { var workspace = MSBuildWorkspace.Create(); var solution = await workspace.OpenSolutionAsync(solutionFile); var rules = checkedItems .Select(RetrieveId) .ToList(); var filesToBeFixed = new HashSet <string>(); var diagnosticsToBeFixes = new HashSet <string>(); foreach (var solutionProject in solution.Projects) { var diagnostics = await ProjectHelper.GetProjectAnalyzerDiagnosticsAsync(analyzers, solutionProject, true); var projectAnalyzers = diagnostics.Where(x => !rules.Any() || rules.Contains(x.Descriptor.Id)) .ToList(); outputTextBox.AppendText($"<======= Project: {solutionProject.Name} =======>\r\n"); if (!projectAnalyzers.Any()) { outputTextBox.AppendText($"Can't find any diagnostic issues for {string.Join(",", rules)}\r\n"); } else { foreach (var projectAnalyzer in projectAnalyzers) { outputTextBox.AppendText(string.Format("DiagnosticId {0} - {1} in file {2}({3},{4})", projectAnalyzer.Id, projectAnalyzer.GetMessage(), GetFormattedFileName(projectAnalyzer.Location.GetLineSpan().Path), projectAnalyzer.Location.GetLineSpan().StartLinePosition.Line, projectAnalyzer.Location.GetLineSpan().StartLinePosition.Character) + "\r\n"); filesToBeFixed.Add(projectAnalyzer.Location.GetLineSpan().Path); diagnosticsToBeFixes.Add(projectAnalyzer.Id); } if (fixIssues) { var codeFixes = CodeFixProviderHelper.GetFixProviders(new[] { styleCopAnalyzerAssembly, styleCopFixersAssembly }) .Where(x => !rules.Any() || rules.Contains(x.Key)) .ToList(); var diagnistics = await DiagnosticHelper.GetAnalyzerDiagnosticsAsync(solution, analyzers, true); foreach (var keyValuePair in codeFixes) { var equivalenceGroups = new List <CodeFixEquivalenceGroup>(); keyValuePair.Value.ForEach(x => { equivalenceGroups.AddRange(CodeFixEquivalenceGroup.CreateAsync(x, diagnistics, solution).Result); }); if (!equivalenceGroups.Any()) { continue; } var fix = equivalenceGroups[0]; if (equivalenceGroups.Count() > 1) { outputTextBox.AppendText("[Warning] Allowed only one equivalence group for fix\r\n"); continue; } var operations = await fix.GetOperationsAsync(); if (operations.Length == 0) { outputTextBox.AppendText("[Information] No changes was found for this fixer\r\n"); continue; } operations[0].Apply(workspace, default(CancellationToken)); outputTextBox.AppendText($"[Information] Fixer with DiagnosticId {keyValuePair.Key} was applied\r\n"); } } } } outputTextBox.AppendText($"Done, found {diagnosticsToBeFixes.Count} issues in {filesToBeFixed.Count} files.\r\n"); }