private async Task <ImmutableArray <(Diagnostic diagnostic, CodeAction action)> > GetDiagnosticsAndCodeActionsAsync( ImmutableDictionary <Document, ImmutableArray <Diagnostic> > documentsAndDiagnosticsToFixMap, FixAllState fixAllState, CancellationToken cancellationToken) { var fixesBag = new ConcurrentBag <(Diagnostic diagnostic, CodeAction action)>(); using (Logger.LogBlock( FunctionId.CodeFixes_FixAllOccurrencesComputation_Document_Fixes, FixAllLogger.CreateCorrelationLogMessage(fixAllState.CorrelationId), cancellationToken)) { cancellationToken.ThrowIfCancellationRequested(); var tasks = new List <Task>(); foreach (var kvp in documentsAndDiagnosticsToFixMap) { var document = kvp.Key; var diagnosticsToFix = kvp.Value; Debug.Assert(!diagnosticsToFix.IsDefaultOrEmpty); if (!diagnosticsToFix.IsDefaultOrEmpty) { tasks.Add(AddDocumentFixesAsync( document, diagnosticsToFix, fixesBag, fixAllState, cancellationToken)); } } await Task.WhenAll(tasks).ConfigureAwait(false); } return(fixesBag.ToImmutableArray()); }
private async Task <CodeAction?> GetFixAsync( ImmutableDictionary <Document, ImmutableArray <Diagnostic> > documentsAndDiagnosticsToFixMap, FixAllState fixAllState, CancellationToken cancellationToken) { if (documentsAndDiagnosticsToFixMap?.Any() == true) { FixAllLogger.LogDiagnosticsStats(fixAllState.CorrelationId, documentsAndDiagnosticsToFixMap); var diagnosticsAndCodeActions = await GetDiagnosticsAndCodeActionsAsync( documentsAndDiagnosticsToFixMap, fixAllState, cancellationToken).ConfigureAwait(false); if (diagnosticsAndCodeActions.Length > 0) { var functionId = FunctionId.CodeFixes_FixAllOccurrencesComputation_Document_Merge; using (Logger.LogBlock(functionId, FixAllLogger.CreateCorrelationLogMessage(fixAllState.CorrelationId), cancellationToken)) { FixAllLogger.LogFixesToMergeStats(functionId, fixAllState.CorrelationId, diagnosticsAndCodeActions.Length); return(await TryGetMergedFixAsync( diagnosticsAndCodeActions, fixAllState, cancellationToken).ConfigureAwait(false)); } } } return(null); }
internal virtual async Task <ImmutableDictionary <Document, ImmutableArray <Diagnostic> > > GetDocumentDiagnosticsToFixWorkerAsync( FixAllContext fixAllContext) { using (Logger.LogBlock( FunctionId.CodeFixes_FixAllOccurrencesComputation_Document_Diagnostics, FixAllLogger.CreateCorrelationLogMessage(fixAllContext.State.CorrelationId), fixAllContext.CancellationToken)) { return(await FixAllContextHelper.GetDocumentDiagnosticsToFixAsync( fixAllContext, fixAllContext.ProgressTracker, (document, cancellationToken) => document.IsGeneratedCode(cancellationToken)).ConfigureAwait(false)); } }
static async Task <ImmutableDictionary <Document, ImmutableArray <Diagnostic> > > GetDocumentDiagnosticsToFixWorkerAsync(FixAllContext fixAllContext) { if (fixAllContext.State.DiagnosticProvider is FixAllState.FixMultipleDiagnosticProvider fixMultipleDiagnosticProvider) { return(fixMultipleDiagnosticProvider.DocumentDiagnosticsMap); } using (Logger.LogBlock( FunctionId.CodeFixes_FixAllOccurrencesComputation_Document_Diagnostics, FixAllLogger.CreateCorrelationLogMessage(fixAllContext.State.CorrelationId), fixAllContext.CancellationToken)) { return(await FixAllContextHelper.GetDocumentDiagnosticsToFixAsync(fixAllContext).ConfigureAwait(false)); } }
internal virtual async Task <ImmutableDictionary <Project, ImmutableArray <Diagnostic> > > GetProjectDiagnosticsToFixAsync( FixAllContext fixAllContext) { using (Logger.LogBlock( FunctionId.CodeFixes_FixAllOccurrencesComputation_Project_Diagnostics, FixAllLogger.CreateCorrelationLogMessage(fixAllContext.State.CorrelationId), fixAllContext.CancellationToken)) { var project = fixAllContext.Project; if (project != null) { switch (fixAllContext.Scope) { case FixAllScope.Project: var diagnostics = await fixAllContext.GetProjectDiagnosticsAsync(project).ConfigureAwait(false); var kvp = SpecializedCollections.SingletonEnumerable(KeyValuePairUtil.Create(project, diagnostics)); return(ImmutableDictionary.CreateRange(kvp)); case FixAllScope.Solution: var projectsAndDiagnostics = ImmutableDictionary.CreateBuilder <Project, ImmutableArray <Diagnostic> >(); var tasks = project.Solution.Projects.Select(async p => new { Project = p, Diagnostics = await fixAllContext.GetProjectDiagnosticsAsync(p).ConfigureAwait(false) }).ToArray(); await Task.WhenAll(tasks).ConfigureAwait(false); foreach (var task in tasks) { var projectAndDiagnostics = await task.ConfigureAwait(false); if (projectAndDiagnostics.Diagnostics.Any()) { projectsAndDiagnostics[projectAndDiagnostics.Project] = projectAndDiagnostics.Diagnostics; } } return(projectsAndDiagnostics.ToImmutable()); } } return(ImmutableDictionary <Project, ImmutableArray <Diagnostic> > .Empty); } }
private async Task <ImmutableArray <(Diagnostic diagnostic, CodeAction action)> > GetDiagnosticsAndCodeActionsAsync( ImmutableDictionary <Document, ImmutableArray <Diagnostic> > documentsAndDiagnosticsToFixMap, FixAllContext fixAllContext) { var cancellationToken = fixAllContext.CancellationToken; var fixAllState = fixAllContext.State; var fixesBag = new ConcurrentBag <(Diagnostic diagnostic, CodeAction action)>(); using (Logger.LogBlock( FunctionId.CodeFixes_FixAllOccurrencesComputation_Document_Fixes, FixAllLogger.CreateCorrelationLogMessage(fixAllState.CorrelationId), cancellationToken)) { cancellationToken.ThrowIfCancellationRequested(); var progressTracker = fixAllContext.GetProgressTracker(); progressTracker.Description = WorkspaceExtensionsResources.Applying_fix_all; using var _1 = ArrayBuilder <Task> .GetInstance(out var tasks); using var _2 = ArrayBuilder <Document> .GetInstance(out var documentsToFix); // Determine the set of documents to actually fix. We can also use this to update the progress bar with // the amount of remaining work to perform. We'll update the progress bar as we compute each fix in // AddDocumentFixesAsync. foreach (var(document, diagnosticsToFix) in documentsAndDiagnosticsToFixMap) { if (!diagnosticsToFix.IsDefaultOrEmpty) { documentsToFix.Add(document); } } progressTracker.AddItems(documentsToFix.Count); foreach (var document in documentsToFix) { var diagnosticsToFix = documentsAndDiagnosticsToFixMap[document]; tasks.Add(AddDocumentFixesAsync( document, diagnosticsToFix, fixesBag, fixAllState, progressTracker, cancellationToken)); } await Task.WhenAll(tasks).ConfigureAwait(false); } return(fixesBag.ToImmutableArray()); }
internal virtual async Task <ImmutableDictionary <Document, ImmutableArray <Diagnostic> > > GetDocumentDiagnosticsToFixWorkerAsync( FixAllContext fixAllContext) { var cancellationToken = fixAllContext.CancellationToken; using (Logger.LogBlock( FunctionId.CodeFixes_FixAllOccurrencesComputation_Document_Diagnostics, FixAllLogger.CreateCorrelationLogMessage(fixAllContext.State.CorrelationId), cancellationToken)) { var allDiagnostics = ImmutableArray <Diagnostic> .Empty; var projectsToFix = ImmutableArray <Project> .Empty; var document = fixAllContext.Document; var project = fixAllContext.Project; switch (fixAllContext.Scope) { case FixAllScope.Document: if (document != null && !document.IsGeneratedCode(cancellationToken)) { var documentDiagnostics = await fixAllContext.GetDocumentDiagnosticsAsync(document).ConfigureAwait(false); var kvp = SpecializedCollections.SingletonEnumerable(KeyValuePair.Create(document, documentDiagnostics)); return(ImmutableDictionary.CreateRange(kvp)); } break; case FixAllScope.Project: projectsToFix = ImmutableArray.Create(project); allDiagnostics = await fixAllContext.GetAllDiagnosticsAsync(project).ConfigureAwait(false); break; case FixAllScope.Solution: projectsToFix = project.Solution.Projects .Where(p => p.Language == project.Language) .ToImmutableArray(); var progressTracker = fixAllContext.ProgressTracker; progressTracker.AddItems(projectsToFix.Length); var diagnostics = new ConcurrentBag <Diagnostic>(); var tasks = new Task[projectsToFix.Length]; for (int i = 0; i < projectsToFix.Length; i++) { cancellationToken.ThrowIfCancellationRequested(); var projectToFix = projectsToFix[i]; tasks[i] = Task.Run(async() => { var projectDiagnostics = await fixAllContext.GetAllDiagnosticsAsync(projectToFix).ConfigureAwait(false); foreach (var diagnostic in projectDiagnostics) { cancellationToken.ThrowIfCancellationRequested(); diagnostics.Add(diagnostic); } progressTracker.ItemCompleted(); }, cancellationToken); } await Task.WhenAll(tasks).ConfigureAwait(false); allDiagnostics = allDiagnostics.AddRange(diagnostics); break; } if (allDiagnostics.IsEmpty) { return(ImmutableDictionary <Document, ImmutableArray <Diagnostic> > .Empty); } return(await GetDocumentDiagnosticsToFixAsync( allDiagnostics, projectsToFix, fixAllContext.CancellationToken).ConfigureAwait(false)); } }