private static async Task <CodeAction> GetFixAllCodeActionAsync(FixAllContext fixAllContext) { using (Logger.LogBlock( FunctionId.CodeFixes_FixAllOccurrencesComputation, KeyValueLogMessage.Create(LogType.UserAction, m => { m[FixAllLogger.CorrelationId] = fixAllContext.State.CorrelationId; m[FixAllLogger.FixAllScope] = fixAllContext.State.Scope.ToString(); }), fixAllContext.CancellationToken)) { CodeAction action = null; try { action = await fixAllContext.FixAllProvider.GetFixAsync(fixAllContext).ConfigureAwait(false); } catch (OperationCanceledException) { FixAllLogger.LogComputationResult(fixAllContext.State.CorrelationId, completed: false); } finally { if (action != null) { FixAllLogger.LogComputationResult(fixAllContext.State.CorrelationId, completed: true); } else { FixAllLogger.LogComputationResult(fixAllContext.State.CorrelationId, completed: false, timedOut: true); } } return(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(); 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()); }
private async Task <CodeAction> GetFixAllCodeActionAsync(FixAllProvider fixAllProvider, FixAllContext fixAllContext) { using (Logger.LogBlock(FunctionId.CodeFixes_FixAllOccurrencesComputation, fixAllContext.CancellationToken)) { CodeAction action = null; try { action = await fixAllProvider.GetFixAsync(fixAllContext).ConfigureAwait(false); } catch (OperationCanceledException) { FixAllLogger.LogComputationResult(completed: false); } finally { if (action != null) { FixAllLogger.LogComputationResult(completed: true); } else { FixAllLogger.LogComputationResult(completed: false, timedOut: true); } } return(action); } }
private async Task <CodeAction?> GetFixAsync( ImmutableDictionary <Document, ImmutableArray <Diagnostic> > documentsAndDiagnosticsToFixMap, FixAllContext fixAllContext) { var cancellationToken = fixAllContext.CancellationToken; if (documentsAndDiagnosticsToFixMap?.Any() == true) { var progressTracker = fixAllContext.GetProgressTracker(); progressTracker.Description = FixAllContextHelper.GetDefaultFixAllTitle(fixAllContext); var fixAllState = fixAllContext.State; FixAllLogger.LogDiagnosticsStats(fixAllState.CorrelationId, documentsAndDiagnosticsToFixMap); var diagnosticsAndCodeActions = await GetDiagnosticsAndCodeActionsAsync(documentsAndDiagnosticsToFixMap, fixAllContext).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 static Solution PreviewChanges( Solution currentSolution, Solution newSolution, string fixAllPreviewChangesTitle, string fixAllTopLevelHeader, string languageOpt, Workspace workspace, int?correlationId = null, CancellationToken cancellationToken = default) { cancellationToken.ThrowIfCancellationRequested(); using (Logger.LogBlock( FunctionId.CodeFixes_FixAllOccurrencesPreviewChanges, KeyValueLogMessage.Create(LogType.UserAction, m => { // only set when correlation id is given // we might not have this info for suppression if (correlationId.HasValue) { m[FixAllLogger.CorrelationId] = correlationId; } }), cancellationToken)) { var previewService = workspace.Services.GetService <IPreviewDialogService>(); var glyph = languageOpt == null ? Glyph.Assembly : languageOpt == LanguageNames.CSharp ? Glyph.CSharpProject : Glyph.BasicProject; // Until IPreviewDialogService is implemented, just execute all changes without user ability to pick and choose if (previewService == null) { return(newSolution); } var changedSolution = previewService.PreviewChanges( string.Format(EditorFeaturesResources.Preview_Changes_0, fixAllPreviewChangesTitle), "vs.codefix.fixall", fixAllTopLevelHeader, fixAllPreviewChangesTitle, glyph, newSolution, currentSolution); if (changedSolution == null) { // User clicked cancel. FixAllLogger.LogPreviewChangesResult(correlationId, applied: false); return(null); } FixAllLogger.LogPreviewChangesResult(correlationId, applied: true, allChangesApplied: changedSolution == newSolution); return(changedSolution); } }
protected override void InnerInvoke( IProgressTracker progressTracker, CancellationToken cancellationToken) { this.AssertIsForeground(); using (Logger.LogBlock(FunctionId.CodeFixes_FixAllOccurrencesSession, FixAllLogger.CreateCorrelationLogMessage(_fixAllState.CorrelationId), cancellationToken)) { base.InnerInvoke(progressTracker, cancellationToken); } }
protected override async Task InnerInvokeAsync( IProgressTracker progressTracker, CancellationToken cancellationToken) { await this.ThreadingContext.JoinableTaskFactory.SwitchToMainThreadAsync(cancellationToken); using (Logger.LogBlock(FunctionId.CodeFixes_FixAllOccurrencesSession, FixAllLogger.CreateCorrelationLogMessage(FixAllState.CorrelationId), cancellationToken)) { await base.InnerInvokeAsync(progressTracker, cancellationToken).ConfigureAwait(false); } }
private async Task <IEnumerable <CodeActionOperation> > GetFixAllOperationsAsync(CodeAction codeAction, FixAllContext fixAllContext) { // We have computed the fix all occurrences code fix. // Now fetch the new solution with applied fix and bring up the Preview changes dialog. var cancellationToken = fixAllContext.CancellationToken; var workspace = fixAllContext.Project.Solution.Workspace; cancellationToken.ThrowIfCancellationRequested(); var operations = await codeAction.GetOperationsAsync(cancellationToken).ConfigureAwait(false); if (operations == null) { return(null); } cancellationToken.ThrowIfCancellationRequested(); var newSolution = await codeAction.GetChangedSolutionInternalAsync(cancellationToken).ConfigureAwait(false); cancellationToken.ThrowIfCancellationRequested(); using (Logger.LogBlock(FunctionId.CodeFixes_FixAllOccurrencesPreviewChanges, cancellationToken)) { var previewService = workspace.Services.GetService <IPreviewDialogService>(); var glyph = fixAllContext.Project.Language == LanguageNames.CSharp ? Glyph.CSharpProject : Glyph.BasicProject; var changedSolution = previewService.PreviewChanges( string.Format(EditorFeaturesResources.PreviewChangesOf, EditorFeaturesResources.FixAllOccurrences), "vs.codefix.fixall", codeAction.Title, EditorFeaturesResources.FixAllOccurrences, glyph, newSolution, fixAllContext.Project.Solution); if (changedSolution == null) { // User clicked cancel. FixAllLogger.LogPreviewChangesResult(applied: false); return(null); } FixAllLogger.LogPreviewChangesResult(applied: true, allChangesApplied: changedSolution == newSolution); newSolution = changedSolution; } // Get a code action, with apply changes operation replaced with the newSolution. return(GetNewFixAllOperations(operations, newSolution, cancellationToken)); }
private CodeAction GetFixAllCodeAction(FixAllProvider fixAllProvider, FixAllContext fixAllContext, string fixAllTitle, string waitDialogMessage, out bool userCancelled) { userCancelled = false; // Compute fix all occurrences code fix for the given fix all context. // Bring up a cancellable wait dialog. CodeAction codeAction = null; using (Logger.LogBlock(FunctionId.CodeFixes_FixAllOccurrencesComputation, fixAllContext.CancellationToken)) { var result = _waitIndicator.Wait( fixAllTitle, waitDialogMessage, allowCancel: true, action: waitContext => { fixAllContext.CancellationToken.ThrowIfCancellationRequested(); using (var linkedCts = CancellationTokenSource.CreateLinkedTokenSource(waitContext.CancellationToken, fixAllContext.CancellationToken)) { try { var fixAllContextWithCancellation = fixAllContext.WithCancellationToken(linkedCts.Token); var fixTask = fixAllProvider.GetFixAsync(fixAllContextWithCancellation); if (fixTask != null) { codeAction = fixTask.WaitAndGetResult(linkedCts.Token); } } catch (OperationCanceledException) { fixAllContext.CancellationToken.ThrowIfCancellationRequested(); } } }); userCancelled = result == WaitIndicatorResult.Canceled; var cancelled = userCancelled || codeAction == null; if (cancelled) { FixAllLogger.LogComputationResult(completed: false, timedOut: result != WaitIndicatorResult.Canceled); return(null); } } FixAllLogger.LogComputationResult(completed: true); return(codeAction); }
public async Task <IEnumerable <CodeActionOperation> > GetFixAllOperationsAsync(FixAllProvider fixAllProvider, FixAllContext fixAllContext) { // Compute fix all occurrences code fix for the given fix all context. // Bring up a cancellable wait dialog. CodeAction codeAction = null; using (Logger.LogBlock(FunctionId.CodeFixes_FixAllOccurrencesComputation, fixAllContext.CancellationToken)) { var result = _waitIndicator.Wait( EditorFeaturesResources.FixAllOccurrences, EditorFeaturesResources.ComputingFixAllOccurrences, allowCancel: true, action: waitContext => { fixAllContext.CancellationToken.ThrowIfCancellationRequested(); using (var linkedCts = CancellationTokenSource.CreateLinkedTokenSource(waitContext.CancellationToken, fixAllContext.CancellationToken)) { try { var fixAllContextWithCancellation = fixAllContext.WithCancellationToken(linkedCts.Token); var fixTask = fixAllProvider.GetFixAsync(fixAllContextWithCancellation); if (fixTask != null) { codeAction = fixTask.WaitAndGetResult(linkedCts.Token); } } catch (OperationCanceledException) { fixAllContext.CancellationToken.ThrowIfCancellationRequested(); } } }); var cancelled = result == WaitIndicatorResult.Canceled || codeAction == null; if (cancelled) { FixAllLogger.LogComputationResult(completed: false, timedOut: result != WaitIndicatorResult.Canceled); return(null); } } FixAllLogger.LogComputationResult(completed: true); return(await GetFixAllOperationsAsync(codeAction, fixAllContext).ConfigureAwait(false)); }
protected override async Task InnerInvokeAsync( IProgressTracker progressTracker, CancellationToken cancellationToken) { await this.ThreadingContext.JoinableTaskFactory.SwitchToMainThreadAsync(cancellationToken); var fixAllKind = FixAllState.FixAllKind; var functionId = fixAllKind switch { FixAllKind.CodeFix => FunctionId.CodeFixes_FixAllOccurrencesSession, FixAllKind.Refactoring => FunctionId.Refactoring_FixAllOccurrencesSession, _ => throw ExceptionUtilities.UnexpectedValue(fixAllKind) }; using (Logger.LogBlock(functionId, FixAllLogger.CreateCorrelationLogMessage(FixAllState.CorrelationId), cancellationToken)) { await base.InnerInvokeAsync(progressTracker, cancellationToken).ConfigureAwait(false); } } }
private static async Task <CodeAction> GetFixAllCodeActionAsync(IFixAllContext fixAllContext) { var fixAllKind = fixAllContext.State.FixAllKind; var functionId = fixAllKind switch { FixAllKind.CodeFix => FunctionId.CodeFixes_FixAllOccurrencesComputation, FixAllKind.Refactoring => FunctionId.Refactoring_FixAllOccurrencesComputation, _ => throw ExceptionUtilities.UnexpectedValue(fixAllKind) }; using (Logger.LogBlock( functionId, KeyValueLogMessage.Create(LogType.UserAction, m => { m[FixAllLogger.CorrelationId] = fixAllContext.State.CorrelationId; m[FixAllLogger.FixAllScope] = fixAllContext.State.Scope.ToString(); }), fixAllContext.CancellationToken)) { CodeAction action = null; try { action = await fixAllContext.FixAllProvider.GetFixAsync(fixAllContext).ConfigureAwait(false); } catch (OperationCanceledException) { FixAllLogger.LogComputationResult(fixAllKind, fixAllContext.State.CorrelationId, completed: false); } finally { if (action != null) { FixAllLogger.LogComputationResult(fixAllKind, fixAllContext.State.CorrelationId, completed: true); } else { FixAllLogger.LogComputationResult(fixAllKind, fixAllContext.State.CorrelationId, completed: false, timedOut: true); } } return(action); } }
internal static Solution PreviewChanges( Solution currentSolution, Solution newSolution, string fixAllPreviewChangesTitle, string fixAllTopLevelHeader, string languageOpt, Workspace workspace, CancellationToken cancellationToken = default(CancellationToken)) { cancellationToken.ThrowIfCancellationRequested(); using (Logger.LogBlock(FunctionId.CodeFixes_FixAllOccurrencesPreviewChanges, cancellationToken)) { var previewService = workspace.Services.GetService <IPreviewDialogService>(); var glyph = languageOpt == null ? Glyph.Assembly : languageOpt == LanguageNames.CSharp ? Glyph.CSharpProject : Glyph.BasicProject; var changedSolution = previewService.PreviewChanges( string.Format(EditorFeaturesResources.PreviewChangesOf, fixAllPreviewChangesTitle), "vs.codefix.fixall", fixAllTopLevelHeader, fixAllPreviewChangesTitle, glyph, newSolution, currentSolution); if (changedSolution == null) { // User clicked cancel. FixAllLogger.LogPreviewChangesResult(applied: false); return(null); } FixAllLogger.LogPreviewChangesResult(applied: true, allChangesApplied: changedSolution == newSolution); return(changedSolution); } }