public async Task <ImmutableArray <SymbolRenameResult> > AnalyzeSolutionAsync( Func <Project, bool> predicate, CancellationToken cancellationToken = default) { ImmutableArray <ProjectId> projects = CurrentSolution .GetProjectDependencyGraph() .GetTopologicallySortedProjects(cancellationToken) .ToImmutableArray(); var results = new List <ImmutableArray <SymbolRenameResult> >(); Stopwatch stopwatch = Stopwatch.StartNew(); TimeSpan lastElapsed = TimeSpan.Zero; List <RenameScope> renameScopes = GetRenameScopes(); for (int i = 0; i < renameScopes.Count; i++) { WriteLine($"Rename {GetPluralName(renameScopes[i])} {$"{i + 1}/{renameScopes.Count}"}", Verbosity.Minimal); for (int j = 0; j < projects.Length; j++) { cancellationToken.ThrowIfCancellationRequested(); Project project = CurrentSolution.GetProject(projects[j]); if (predicate == null || predicate(project)) { WriteLine($" Rename {GetPluralName(renameScopes[i])} in '{project.Name}' {$"{j + 1}/{projects.Length}"}", ConsoleColors.Cyan, Verbosity.Minimal); ImmutableArray <SymbolRenameResult> projectResults = await AnalyzeProjectAsync(project, renameScopes[i], cancellationToken).ConfigureAwait(false); results.Add(projectResults); WriteLine($" Done renaming {GetPluralName(renameScopes[i])} in '{project.Name}' in {stopwatch.Elapsed - lastElapsed:mm\\:ss\\.ff}", Verbosity.Normal); } else { WriteLine($" Skip '{project.Name}' {$"{j + 1}/{projects.Length}"}", ConsoleColors.DarkGray, Verbosity.Minimal); } lastElapsed = stopwatch.Elapsed; } } stopwatch.Stop(); WriteLine($"Done renaming symbols in solution '{CurrentSolution.FilePath}' in {stopwatch.Elapsed:mm\\:ss\\.ff}", Verbosity.Minimal); return(results.SelectMany(f => f).ToImmutableArray()); }