private static FixAllState GetFixAllState( FixAllProvider fixAllProvider, IEnumerable <Diagnostic> diagnostics, CodeFixProvider fixer, TestDiagnosticAnalyzerDriver testDriver, Document document, FixAllScope scope, string equivalenceKey) { Assert.NotEmpty(diagnostics); if (scope == FixAllScope.Custom) { // Bulk fixing diagnostics in selected scope. var diagnosticsToFix = ImmutableDictionary.CreateRange(SpecializedCollections.SingletonEnumerable(KeyValuePairUtil.Create(document, diagnostics.ToImmutableArray()))); return(FixAllState.Create(fixAllProvider, diagnosticsToFix, fixer, equivalenceKey)); } var diagnostic = diagnostics.First(); var diagnosticIds = ImmutableHashSet.Create(diagnostic.Id); var fixAllDiagnosticProvider = new FixAllDiagnosticProvider(testDriver, diagnosticIds); return(diagnostic.Location.IsInSource ? new FixAllState(fixAllProvider, document, fixer, scope, equivalenceKey, diagnosticIds, fixAllDiagnosticProvider) : new FixAllState(fixAllProvider, document.Project, fixer, scope, equivalenceKey, diagnosticIds, fixAllDiagnosticProvider)); }
/// <summary> /// If the provided fix all context is non-null and the context's code action Id matches the given code action's Id then, /// returns the set of fix all occurrences actions associated with the code action. /// </summary> internal SuggestedActionSet GetFixAllSuggestedActionSet( CodeAction action, int actionCount, FixAllState fixAllState, ImmutableArray <FixAllScope> supportedScopes, Diagnostic firstDiagnostic, Workspace workspace) { if (fixAllState == null) { return(null); } if (actionCount > 1 && action.EquivalenceKey == null) { return(null); } var fixAllSuggestedActions = ArrayBuilder <FixAllSuggestedAction> .GetInstance(); foreach (var scope in supportedScopes) { var fixAllStateForScope = fixAllState.WithScopeAndEquivalenceKey(scope, action.EquivalenceKey); var fixAllSuggestedAction = new FixAllSuggestedAction( _owner, workspace, _subjectBuffer, fixAllStateForScope, firstDiagnostic, action); fixAllSuggestedActions.Add(fixAllSuggestedAction); } return(new SuggestedActionSet( fixAllSuggestedActions.ToImmutableAndFree(), title: EditorFeaturesResources.Fix_all_occurrences_in)); }
internal sealed override async Task<CodeAction> GetFixAsync( ImmutableDictionary<Document, ImmutableArray<Diagnostic>> documentsAndDiagnosticsToFixMap, FixAllState fixAllState, CancellationToken cancellationToken) { // Process all documents in parallel. var updatedDocumentTasks = documentsAndDiagnosticsToFixMap.Select( kvp => FixDocumentAsync(kvp.Key, kvp.Value, cancellationToken)); await Task.WhenAll(updatedDocumentTasks).ConfigureAwait(false); var currentSolution = fixAllState.Solution; foreach (var task in updatedDocumentTasks) { // 'await' the tasks so that if any completed in a cancelled manner then we'll // throw the right exception here. Calling .Result on the tasks might end up // with AggregateExceptions being thrown instead. var updatedDocument = await task.ConfigureAwait(false); currentSolution = currentSolution.WithDocumentSyntaxRoot( updatedDocument.Id, await updatedDocument.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false)); } var title = fixAllState.GetDefaultFixAllTitle(); return new CodeAction.SolutionChangeAction(title, _ => Task.FromResult(currentSolution)); }
internal sealed override async Task <CodeAction> GetFixAsync( ImmutableDictionary <Document, ImmutableArray <Diagnostic> > documentsAndDiagnosticsToFixMap, FixAllState fixAllState, CancellationToken cancellationToken) { // Process all documents in parallel. var updatedDocumentTasks = documentsAndDiagnosticsToFixMap.Select( kvp => FixDocumentAsync(kvp.Key, kvp.Value, cancellationToken)); await Task.WhenAll(updatedDocumentTasks).ConfigureAwait(false); var currentSolution = fixAllState.Solution; foreach (var task in updatedDocumentTasks) { // 'await' the tasks so that if any completed in a cancelled manner then we'll // throw the right exception here. Calling .Result on the tasks might end up // with AggregateExceptions being thrown instead. var updatedDocument = await task.ConfigureAwait(false); currentSolution = currentSolution.WithDocumentSyntaxRoot( updatedDocument.Id, await updatedDocument.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false)); } var title = fixAllState.GetDefaultFixAllTitle(); return(new CodeAction.SolutionChangeAction(title, _ => Task.FromResult(currentSolution))); }
public static CodeAction CreateBatchPragmaFix( AbstractSuppressionCodeFixProvider suppressionFixProvider, Document document, ImmutableArray <IPragmaBasedCodeAction> pragmaActions, ImmutableArray <Diagnostic> pragmaDiagnostics, FixAllState fixAllState, CancellationToken cancellationToken ) { // This is a temporary generated code action, which doesn't need telemetry, hence suppressing RS0005. #pragma warning disable RS0005 // Do not use generic CodeAction.Create to create CodeAction return(CodeAction.Create( ((CodeAction)pragmaActions[0]).Title, createChangedDocument: ct => BatchPragmaFixesAsync( suppressionFixProvider, document, pragmaActions, pragmaDiagnostics, cancellationToken ), equivalenceKey: fixAllState.CodeActionEquivalenceKey )); #pragma warning restore RS0005 // Do not use generic CodeAction.Create to create CodeAction }
internal FixMultipleCodeAction( FixAllState fixAllState, string title, string computingFixWaitDialogMessage) : base(fixAllState, showPreviewChangesDialog: false) { _title = title; _computingFixWaitDialogMessage = computingFixWaitDialogMessage; }
public override async Task <CodeAction> TryGetMergedFixAsync( IEnumerable <CodeAction> batchOfFixes, FixAllState fixAllState, CancellationToken cancellationToken) { // Batch all the attribute removal fixes into a single fix. // Pragma removal fixes have already been batch for each document AddDocumentFixes method. // This ensures no merge conflicts in merging all fixes by our base implementation. var oldSolution = fixAllState.Project.Solution; var currentSolution = oldSolution; var attributeRemoveFixes = new List <AttributeRemoveAction>(); var newBatchOfFixes = new List <CodeAction>(); foreach (var codeAction in batchOfFixes) { var attributeRemoveFix = codeAction as AttributeRemoveAction; if (attributeRemoveFix != null) { attributeRemoveFixes.Add(attributeRemoveFix); } else { newBatchOfFixes.Add(codeAction); } } if (attributeRemoveFixes.Count > 0) { // Batch all of attribute removal fixes. foreach (var removeSuppressionFixesForTree in attributeRemoveFixes.GroupBy(fix => fix.SyntaxTreeToModify)) { var tree = removeSuppressionFixesForTree.Key; var attributeRemoveFixesForTree = removeSuppressionFixesForTree.OfType <AttributeRemoveAction>().ToImmutableArray(); var attributesToRemove = await GetAttributeNodesToFixAsync(attributeRemoveFixesForTree, cancellationToken).ConfigureAwait(false); var document = oldSolution.GetDocument(tree); var root = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false); var newRoot = root.RemoveNodes(attributesToRemove, SyntaxRemoveOptions.KeepLeadingTrivia | SyntaxRemoveOptions.AddElasticMarker); currentSolution = currentSolution.WithDocumentSyntaxRoot(document.Id, newRoot); } // This is a temporary generated code action, which doesn't need telemetry, hence suppressing RS0005. #pragma warning disable RS0005 // Do not use generic CodeAction.Create to create CodeAction var batchAttributeRemoveFix = Create( attributeRemoveFixes.First().Title, createChangedSolution: ct => Task.FromResult(currentSolution), equivalenceKey: fixAllState.CodeActionEquivalenceKey); #pragma warning restore RS0005 // Do not use generic CodeAction.Create to create CodeAction newBatchOfFixes.Insert(0, batchAttributeRemoveFix); } return(await base.TryGetMergedFixAsync(newBatchOfFixes, fixAllState, cancellationToken).ConfigureAwait(false)); }
private async Task AppendFixesOrSuppressionsAsync( Document document, TextSpan span, IEnumerable <DiagnosticData> diagnosticsWithSameSpan, IList <CodeFixCollection> result, object fixer, Func <Diagnostic, bool> hasFix, Func <ImmutableArray <Diagnostic>, Task <ImmutableArray <CodeFix> > > getFixes, CancellationToken cancellationToken) { var allDiagnostics = await diagnosticsWithSameSpan.OrderByDescending(d => d.Severity) .ToDiagnosticsAsync(document.Project, cancellationToken).ConfigureAwait(false); var diagnostics = allDiagnostics.Where(hasFix).AsImmutable(); if (diagnostics.Length <= 0) { // this can happen for suppression case where all diagnostics can't be suppressed return; } var extensionManager = document.Project.Solution.Workspace.Services.GetService <IExtensionManager>(); var fixes = await extensionManager.PerformFunctionAsync(fixer, () => getFixes(diagnostics), defaultValue : ImmutableArray <CodeFix> .Empty).ConfigureAwait(false); if (fixes.IsDefaultOrEmpty) { return; } // If the fix provider supports fix all occurrences, then get the corresponding FixAllProviderInfo and fix all context. var fixAllProviderInfo = extensionManager.PerformFunction(fixer, () => ImmutableInterlocked.GetOrAdd(ref _fixAllProviderMap, fixer, FixAllProviderInfo.Create), defaultValue: null); FixAllState fixAllState = null; var supportedScopes = ImmutableArray <FixAllScope> .Empty; if (fixAllProviderInfo != null) { var codeFixProvider = (fixer as CodeFixProvider) ?? new WrapperCodeFixProvider((ISuppressionFixProvider)fixer, diagnostics.Select(d => d.Id)); fixAllState = FixAllState.Create( fixAllProviderInfo.FixAllProvider, document, fixAllProviderInfo, codeFixProvider, diagnostics, GetDocumentDiagnosticsAsync, GetProjectDiagnosticsAsync); supportedScopes = fixAllProviderInfo.SupportedScopes.AsImmutable(); } var codeFix = new CodeFixCollection( fixer, span, fixes, fixAllState, supportedScopes, diagnostics.First()); result.Add(codeFix); }
internal FixMultipleCodeAction( FixAllState fixAllState, Diagnostic triggerDiagnostic, string title, string computingFixWaitDialogMessage, bool showPreviewChangesDialog) : base(fixAllState, showPreviewChangesDialog) { _triggerDiagnostic = triggerDiagnostic; _title = title; _computingFixWaitDialogMessage = computingFixWaitDialogMessage; }
internal FixMultipleCodeAction( FixAllState fixAllState, Diagnostic triggerDiagnostic, string title, string computingFixWaitDialogMessage, bool showPreviewChangesDialog) : base(fixAllState, showPreviewChangesDialog) { _triggerDiagnostic = triggerDiagnostic; _title = title; _computingFixWaitDialogMessage = computingFixWaitDialogMessage; }
public override async Task AddDocumentFixesAsync( Document document, ImmutableArray <Diagnostic> diagnostics, Action <CodeAction> addFix, FixAllState fixAllState, CancellationToken cancellationToken) { // Batch all the pragma remove suppression fixes by executing them sequentially for the document. var pragmaActionsBuilder = ArrayBuilder <IPragmaBasedCodeAction> .GetInstance(); var pragmaDiagnosticsBuilder = ArrayBuilder <Diagnostic> .GetInstance(); foreach (var diagnostic in diagnostics.Where(d => d.Location.IsInSource && d.IsSuppressed)) { var span = diagnostic.Location.SourceSpan; var removeSuppressionFixes = await _suppressionFixProvider.GetSuppressionsAsync( document, span, SpecializedCollections.SingletonEnumerable(diagnostic), cancellationToken).ConfigureAwait(false); var removeSuppressionFix = removeSuppressionFixes.SingleOrDefault(); if (removeSuppressionFix != null) { var codeAction = removeSuppressionFix.Action as RemoveSuppressionCodeAction; if (codeAction != null) { if (fixAllState.IsFixMultiple) { codeAction = codeAction.CloneForFixMultipleContext(); } var pragmaRemoveAction = codeAction as PragmaRemoveAction; if (pragmaRemoveAction != null) { pragmaActionsBuilder.Add(pragmaRemoveAction); pragmaDiagnosticsBuilder.Add(diagnostic); } else { addFix(codeAction); } } } } // Get the pragma batch fix. if (pragmaActionsBuilder.Count > 0) { var pragmaBatchFix = PragmaBatchFixHelpers.CreateBatchPragmaFix( _suppressionFixProvider, document, pragmaActionsBuilder.ToImmutableAndFree(), pragmaDiagnosticsBuilder.ToImmutableAndFree(), fixAllState, cancellationToken); addFix(pragmaBatchFix); } }
static CodeFixMenuEntry CreateFixAllMenuEntry(Ide.Editor.TextEditor editor, FixAllState fixState, ref int mnemonic, CancellationToken token) { var provider = fixState?.FixAllProvider; if (provider == null) { return(null); } var doc = editor.DocumentContext; var workspace = doc?.RoslynWorkspace; if (workspace == null) { return(null); } var title = fixState.GetDefaultFixAllTitle(); var label = mnemonic < 0 ? title : CreateLabel(title, ref mnemonic); var item = new CodeFixMenuEntry(label, async delegate { // Task.Run here so we don't end up binding the whole document on popping the menu, also there is no cancellation token support Microsoft.CodeAnalysis.Text.TextChange[] result = await Task.Run(async() => { var context = fixState.CreateFixAllContext(new RoslynProgressTracker(), token); var fix = await provider.GetFixAsync(context); var previewOperations = await fix.GetPreviewOperationsAsync(token); return(await Runtime.RunInMainThread(() => { var engine = Xwt.Toolkit.CurrentEngine; // NativeEngine return engine.Invoke(async() => { using (var dialog = new FixAllPreviewDialog(string.Join(", ", fixState.DiagnosticIds), doc.Name, fixState.Scope, previewOperations, editor)) { await dialog.InitializeEditor(); var parent = Xwt.Toolkit.CurrentEngine.WrapWindow(IdeApp.Workbench.RootWindow); var changes = dialog.Run(parent) == Xwt.Command.Apply ? dialog.GetApplicableChanges().ToArray() : Array.Empty <Microsoft.CodeAnalysis.Text.TextChange> (); return changes; } }); })); }); if (result.Length == 0) { return; } editor.ApplyTextChanges(result); }); return(item); }
public static CodeAction CreateBatchPragmaFix( AbstractSuppressionCodeFixProvider suppressionFixProvider, Document document, ImmutableArray <IPragmaBasedCodeAction> pragmaActions, ImmutableArray <Diagnostic> pragmaDiagnostics, FixAllState fixAllState, CancellationToken cancellationToken) { return(CodeAction.Create( ((CodeAction)pragmaActions[0]).Title, createChangedDocument: ct => BatchPragmaFixesAsync(suppressionFixProvider, document, pragmaActions, pragmaDiagnostics, fixAllState.CodeActionOptionsProvider, cancellationToken), equivalenceKey: fixAllState.CodeActionEquivalenceKey)); }
public override async Task AddDocumentFixesAsync( Document document, ImmutableArray<Diagnostic> diagnostics, Action<CodeAction> addFix, FixAllState fixAllState, CancellationToken cancellationToken) { // Batch all the pragma remove suppression fixes by executing them sequentially for the document. var pragmaActionsBuilder = ArrayBuilder<IPragmaBasedCodeAction>.GetInstance(); var pragmaDiagnosticsBuilder = ArrayBuilder<Diagnostic>.GetInstance(); foreach (var diagnostic in diagnostics.Where(d => d.Location.IsInSource && d.IsSuppressed)) { var span = diagnostic.Location.SourceSpan; var removeSuppressionFixes = await _suppressionFixProvider.GetSuppressionsAsync( document, span, SpecializedCollections.SingletonEnumerable(diagnostic), cancellationToken).ConfigureAwait(false); var removeSuppressionFix = removeSuppressionFixes.SingleOrDefault(); if (removeSuppressionFix != null) { var codeAction = removeSuppressionFix.Action as RemoveSuppressionCodeAction; if (codeAction != null) { if (fixAllState.IsFixMultiple) { codeAction = codeAction.CloneForFixMultipleContext(); } var pragmaRemoveAction = codeAction as PragmaRemoveAction; if (pragmaRemoveAction != null) { pragmaActionsBuilder.Add(pragmaRemoveAction); pragmaDiagnosticsBuilder.Add(diagnostic); } else { addFix(codeAction); } } } } // Get the pragma batch fix. if (pragmaActionsBuilder.Count > 0) { var pragmaBatchFix = PragmaBatchFixHelpers.CreateBatchPragmaFix( _suppressionFixProvider, document, pragmaActionsBuilder.ToImmutableAndFree(), pragmaDiagnosticsBuilder.ToImmutableAndFree(), fixAllState, cancellationToken); addFix(pragmaBatchFix); } }
internal FixAllSuggestedAction( SuggestedActionsSourceProvider sourceProvider, Workspace workspace, ITextBuffer subjectBuffer, FixAllState fixAllState, Diagnostic originalFixedDiagnostic, CodeAction originalCodeAction) : base(sourceProvider, workspace, subjectBuffer, fixAllState.FixAllProvider, new FixAllCodeAction(fixAllState)) { _fixedDiagnostic = originalFixedDiagnostic; _originalCodeAction = originalCodeAction; _fixAllState = fixAllState; }
private static FixAllState GetFixAllState( FixAllProvider fixAllProvider, IEnumerable <Diagnostic> diagnostics, DiagnosticAnalyzer provider, CodeFixProvider fixer, TestDiagnosticAnalyzerDriver testDriver, Document document, FixAllScope scope, string fixAllActionId) { Assert.NotEmpty(diagnostics); if (scope == FixAllScope.Custom) { // Bulk fixing diagnostics in selected scope. var diagnosticsToFix = ImmutableDictionary.CreateRange(SpecializedCollections.SingletonEnumerable(KeyValuePair.Create(document, diagnostics.ToImmutableArray()))); return(FixAllState.Create(fixAllProvider, diagnosticsToFix, fixer, fixAllActionId)); } var diagnostic = diagnostics.First(); Func <Document, ImmutableHashSet <string>, CancellationToken, Task <IEnumerable <Diagnostic> > > getDocumentDiagnosticsAsync = async(d, diagIds, c) => { var root = await d.GetSyntaxRootAsync(); var diags = await testDriver.GetDocumentDiagnosticsAsync(provider, d, root.FullSpan); diags = diags.Where(diag => diagIds.Contains(diag.Id)); return(diags); }; Func <Project, bool, ImmutableHashSet <string>, CancellationToken, Task <IEnumerable <Diagnostic> > > getProjectDiagnosticsAsync = async(p, includeAllDocumentDiagnostics, diagIds, c) => { var diags = includeAllDocumentDiagnostics ? await testDriver.GetAllDiagnosticsAsync(provider, p) : await testDriver.GetProjectDiagnosticsAsync(provider, p); diags = diags.Where(diag => diagIds.Contains(diag.Id)); return(diags); }; var diagnosticIds = ImmutableHashSet.Create(diagnostic.Id); var fixAllDiagnosticProvider = new FixAllState.FixAllDiagnosticProvider(diagnosticIds, getDocumentDiagnosticsAsync, getProjectDiagnosticsAsync); return(diagnostic.Location.IsInSource ? new FixAllState(fixAllProvider, document, fixer, scope, fixAllActionId, diagnosticIds, fixAllDiagnosticProvider) : new FixAllState(fixAllProvider, document.Project, fixer, scope, fixAllActionId, diagnosticIds, fixAllDiagnosticProvider)); }
internal FixAllSuggestedAction( IThreadingContext threadingContext, SuggestedActionsSourceProvider sourceProvider, Workspace workspace, ITextBuffer subjectBuffer, FixAllState fixAllState, Diagnostic originalFixedDiagnostic, CodeAction originalCodeAction) : base(threadingContext, sourceProvider, workspace, subjectBuffer, fixAllState.FixAllProvider, new FixAllCodeAction(fixAllState)) { Diagnostic = originalFixedDiagnostic; OriginalCodeAction = originalCodeAction; FixAllState = fixAllState; }
private FixMultipleSuggestedAction GetSuggestedAction( FixAllState fixAllState, Diagnostic triggerDiagnostic, Workspace workspace, string title, string waitDialogMessage, bool showPreviewChangesDialog, CancellationToken cancellationToken) { var fixMultipleCodeAction = new FixMultipleCodeAction(fixAllState, triggerDiagnostic, title, waitDialogMessage, showPreviewChangesDialog); return(new FixMultipleSuggestedAction( _listener, workspace, _editHandler, _waitIndicator, fixMultipleCodeAction, fixAllState.FixAllProvider)); }
private static async Task <ImmutableArray <CodeActionOperation> > GetFixAllOperationsAsync( CodeAction codeAction, bool showPreviewChangesDialog, FixAllState fixAllState, CancellationToken cancellationToken ) { // 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 workspace = fixAllState.Project.Solution.Workspace; cancellationToken.ThrowIfCancellationRequested(); var operations = await codeAction .GetOperationsAsync(cancellationToken) .ConfigureAwait(false); if (operations == null) { return(ImmutableArray <CodeActionOperation> .Empty); } cancellationToken.ThrowIfCancellationRequested(); var newSolution = await codeAction .GetChangedSolutionInternalAsync(cancellationToken : cancellationToken) .ConfigureAwait(false); if (showPreviewChangesDialog) { newSolution = PreviewChanges( fixAllState.Project.Solution, newSolution, FeaturesResources.Fix_all_occurrences, codeAction.Title, fixAllState.Project.Language, workspace, fixAllState.CorrelationId, cancellationToken ); if (newSolution == null) { return(ImmutableArray <CodeActionOperation> .Empty); } } // Get a code action, with apply changes operation replaced with the newSolution. return(GetNewFixAllOperations(operations, newSolution, cancellationToken)); }
public Solution GetFix( ImmutableDictionary <Project, ImmutableArray <Diagnostic> > diagnosticsToFix, Workspace workspace, CodeFixProvider fixProvider, FixAllProvider fixAllProvider, string equivalenceKey, string waitDialogTitle, string waitDialogMessage, CancellationToken cancellationToken) { var fixMultipleState = FixAllState.Create(fixAllProvider, diagnosticsToFix, fixProvider, equivalenceKey); var triggerDiagnostic = diagnosticsToFix.First().Value.First(); var suggestedAction = GetSuggestedAction(fixMultipleState, triggerDiagnostic, workspace, waitDialogTitle, waitDialogMessage, showPreviewChangesDialog: false, cancellationToken: cancellationToken); return(suggestedAction.GetChangedSolution(cancellationToken)); }
public static CodeAction CreateBatchPragmaFix( AbstractSuppressionCodeFixProvider suppressionFixProvider, Document document, ImmutableArray<IPragmaBasedCodeAction> pragmaActions, ImmutableArray<Diagnostic> pragmaDiagnostics, FixAllState fixAllState, CancellationToken cancellationToken) { // This is a temporary generated code action, which doesn't need telemetry, hence suppressing RS0005. #pragma warning disable RS0005 // Do not use generic CodeAction.Create to create CodeAction return CodeAction.Create( ((CodeAction)pragmaActions[0]).Title, createChangedDocument: ct => BatchPragmaFixesAsync(suppressionFixProvider, document, pragmaActions, pragmaDiagnostics, cancellationToken), equivalenceKey: fixAllState.CodeActionEquivalenceKey); #pragma warning restore RS0005 // Do not use generic CodeAction.Create to create CodeAction }
public Solution GetFix( ImmutableDictionary <Project, ImmutableArray <Diagnostic> > diagnosticsToFix, Workspace workspace, CodeFixProvider fixProvider, FixAllProvider fixAllProvider, string equivalenceKey, string waitDialogTitle, string waitDialogMessage, CancellationToken cancellationToken) { var fixMultipleState = FixAllState.Create( fixAllProvider, diagnosticsToFix, fixProvider, equivalenceKey); return(GetFixedSolution( fixMultipleState, workspace, waitDialogTitle, waitDialogMessage, cancellationToken)); }
public Solution GetFix( ImmutableDictionary <Document, ImmutableArray <Diagnostic> > diagnosticsToFix, Workspace workspace, CodeFixProvider fixProvider, FixAllProvider fixAllProvider, string equivalenceKey, string waitDialogTitle, string waitDialogMessage, CancellationToken cancellationToken) { var fixMultipleState = FixAllState.Create(fixAllProvider, diagnosticsToFix, fixProvider, equivalenceKey); var triggerDiagnostic = diagnosticsToFix.First().Value.First(); var result = GetFixedSolution( fixMultipleState, triggerDiagnostic, workspace, waitDialogTitle, waitDialogMessage, cancellationToken); return(result); }
private static async Task <CodeAction> GetFixAllFixAsync( CodeAction originalCodeAction, CodeRefactoringProvider provider, CodeActionOptionsProvider optionsProvider, Document document, TextSpan selectionSpan, FixAllScope scope) { var fixAllProvider = provider.GetFixAllProvider(); if (fixAllProvider == null || !fixAllProvider.GetSupportedFixAllScopes().Contains(scope)) { return(null); } var fixAllState = new FixAllState(fixAllProvider, document, selectionSpan, provider, optionsProvider, scope, originalCodeAction); var fixAllContext = new FixAllContext(fixAllState, new ProgressTracker(), CancellationToken.None); return(await fixAllProvider.GetFixAsync(fixAllContext).ConfigureAwait(false)); }
public async override Task AddProjectFixesAsync( Project project, ImmutableArray<Diagnostic> diagnostics, Action<CodeAction> addFix, FixAllState fixAllState, CancellationToken cancellationToken) { foreach (var diagnostic in diagnostics.Where(d => !d.Location.IsInSource && d.IsSuppressed)) { var removeSuppressionFixes = await _suppressionFixProvider.GetSuppressionsAsync( project, SpecializedCollections.SingletonEnumerable(diagnostic), cancellationToken).ConfigureAwait(false); var removeSuppressionCodeAction = removeSuppressionFixes.SingleOrDefault()?.Action as RemoveSuppressionCodeAction; if (removeSuppressionCodeAction != null) { if (fixAllState.IsFixMultiple) { removeSuppressionCodeAction = removeSuppressionCodeAction.CloneForFixMultipleContext(); } addFix(removeSuppressionCodeAction); } } }
public async override Task AddProjectFixesAsync( Project project, ImmutableArray <Diagnostic> diagnostics, Action <CodeAction> addFix, FixAllState fixAllState, CancellationToken cancellationToken) { foreach (var diagnostic in diagnostics.Where(d => !d.Location.IsInSource && d.IsSuppressed)) { var removeSuppressionFixes = await _suppressionFixProvider.GetSuppressionsAsync( project, SpecializedCollections.SingletonEnumerable(diagnostic), cancellationToken).ConfigureAwait(false); var removeSuppressionCodeAction = removeSuppressionFixes.SingleOrDefault()?.Action as RemoveSuppressionCodeAction; if (removeSuppressionCodeAction != null) { if (fixAllState.IsFixMultiple) { removeSuppressionCodeAction = removeSuppressionCodeAction.CloneForFixMultipleContext(); } addFix(removeSuppressionCodeAction); } } }
private static Solution GetFixedSolution( FixAllState fixAllState, Workspace workspace, string title, string waitDialogMessage, CancellationToken cancellationToken) { var fixMultipleCodeAction = new FixMultipleCodeAction( fixAllState, title, waitDialogMessage); Solution newSolution = null; var extensionManager = workspace.Services.GetService <IExtensionManager>(); extensionManager.PerformAction(fixAllState.FixAllProvider, () => { // We don't need to post process changes here as the inner code action created for Fix multiple code fix already executes. newSolution = fixMultipleCodeAction.GetChangedSolutionInternalAsync( postProcessChanges: false, cancellationToken: cancellationToken).WaitAndGetResult(cancellationToken); }); return(newSolution); }
/// <summary> /// If the provided fix all context is non-null and the context's code action Id matches the given code action's Id then, /// returns the set of fix all occurrences actions associated with the code action. /// </summary> internal static SuggestedActionSet GetFixAllSuggestedActionSet( CodeAction action, int actionCount, FixAllState fixAllState, IEnumerable <FixAllScope> supportedScopes, Diagnostic firstDiagnostic, Workspace workspace, ITextBuffer subjectBuffer, ICodeActionEditHandlerService editHandler, IWaitIndicator waitIndicator, IAsynchronousOperationListener operationListener) { if (fixAllState == null) { return(null); } if (actionCount > 1 && action.EquivalenceKey == null) { return(null); } var fixAllSuggestedActions = ArrayBuilder <FixAllSuggestedAction> .GetInstance(); foreach (var scope in supportedScopes) { var fixAllStateForScope = fixAllState.WithScopeAndEquivalenceKey(scope, action.EquivalenceKey); var fixAllAction = new FixAllCodeAction(fixAllStateForScope, showPreviewChangesDialog: true); var fixAllSuggestedAction = new FixAllSuggestedAction( workspace, subjectBuffer, editHandler, waitIndicator, fixAllAction, fixAllStateForScope.FixAllProvider, firstDiagnostic, operationListener); fixAllSuggestedActions.Add(fixAllSuggestedAction); } return(new SuggestedActionSet( fixAllSuggestedActions.ToImmutableAndFree(), title: EditorFeaturesResources.Fix_all_occurrences_in)); }
static CodeFixMenuEntry CreateFixAllMenuEntry(TextEditor editor, FixAllState fixState, ref int mnemonic, CancellationToken token) { var provider = fixState?.FixAllProvider; if (provider == null) { return(null); } var context = fixState.CreateFixAllContext(new RoslynProgressTracker(), token); var title = fixState.GetDefaultFixAllTitle(); var label = mnemonic < 0 ? title : CreateLabel(title, ref mnemonic); var item = new CodeFixMenuEntry(label, async delegate { // Task.Run here so we don't end up binding the whole document on popping the menu, also there is no cancellation token support var fix = Task.Run(() => provider.GetFixAsync(context)); await new ContextActionRunner(editor, await fix).Run(); }); return(item); }
public override async Task AddDocumentFixesAsync( Document document, ImmutableArray <Diagnostic> diagnostics, Action <CodeAction> addFix, FixAllState fixAllState, CancellationToken cancellationToken) { var pragmaActionsBuilder = ImmutableArray.CreateBuilder <IPragmaBasedCodeAction>(); var pragmaDiagnosticsBuilder = ImmutableArray.CreateBuilder <Diagnostic>(); foreach (var diagnostic in diagnostics.Where(d => d.Location.IsInSource && !d.IsSuppressed)) { var span = diagnostic.Location.SourceSpan; var pragmaSuppressions = await _suppressionFixProvider.GetPragmaSuppressionsAsync( document, span, SpecializedCollections.SingletonEnumerable(diagnostic), cancellationToken).ConfigureAwait(false); var pragmaSuppression = pragmaSuppressions.SingleOrDefault(); if (pragmaSuppression != null) { if (fixAllState.IsFixMultiple) { pragmaSuppression = pragmaSuppression.CloneForFixMultipleContext(); } pragmaActionsBuilder.Add(pragmaSuppression); pragmaDiagnosticsBuilder.Add(diagnostic); } } // Get the pragma batch fix. if (pragmaActionsBuilder.Count > 0) { var pragmaBatchFix = PragmaBatchFixHelpers.CreateBatchPragmaFix( _suppressionFixProvider, document, pragmaActionsBuilder.ToImmutable(), pragmaDiagnosticsBuilder.ToImmutable(), fixAllState, cancellationToken); addFix(pragmaBatchFix); } }
public override async Task AddDocumentFixesAsync( Document document, ImmutableArray<Diagnostic> diagnostics, Action<CodeAction> addFix, FixAllState fixAllState, CancellationToken cancellationToken) { var pragmaActionsBuilder = ImmutableArray.CreateBuilder<IPragmaBasedCodeAction>(); var pragmaDiagnosticsBuilder = ImmutableArray.CreateBuilder<Diagnostic>(); foreach (var diagnostic in diagnostics.Where(d => d.Location.IsInSource && !d.IsSuppressed)) { var span = diagnostic.Location.SourceSpan; var pragmaSuppressions = await _suppressionFixProvider.GetPragmaSuppressionsAsync( document, span, SpecializedCollections.SingletonEnumerable(diagnostic), cancellationToken).ConfigureAwait(false); var pragmaSuppression = pragmaSuppressions.SingleOrDefault(); if (pragmaSuppression != null) { if (fixAllState.IsFixMultiple) { pragmaSuppression = pragmaSuppression.CloneForFixMultipleContext(); } pragmaActionsBuilder.Add(pragmaSuppression); pragmaDiagnosticsBuilder.Add(diagnostic); } } // Get the pragma batch fix. if (pragmaActionsBuilder.Count > 0) { var pragmaBatchFix = PragmaBatchFixHelpers.CreateBatchPragmaFix( _suppressionFixProvider, document, pragmaActionsBuilder.ToImmutable(), pragmaDiagnosticsBuilder.ToImmutable(), fixAllState, cancellationToken); addFix(pragmaBatchFix); } }
public override async Task<CodeAction> TryGetMergedFixAsync( IEnumerable<CodeAction> batchOfFixes, FixAllState fixAllState, CancellationToken cancellationToken) { // Batch all the attribute removal fixes into a single fix. // Pragma removal fixes have already been batch for each document AddDocumentFixes method. // This ensures no merge conflicts in merging all fixes by our base implementation. var oldSolution = fixAllState.Project.Solution; var currentSolution = oldSolution; var attributeRemoveFixes = new List<AttributeRemoveAction>(); var newBatchOfFixes = new List<CodeAction>(); foreach (var codeAction in batchOfFixes) { var attributeRemoveFix = codeAction as AttributeRemoveAction; if (attributeRemoveFix != null) { attributeRemoveFixes.Add(attributeRemoveFix); } else { newBatchOfFixes.Add(codeAction); } } if (attributeRemoveFixes.Count > 0) { // Batch all of attribute removal fixes. foreach (var removeSuppressionFixesForTree in attributeRemoveFixes.GroupBy(fix => fix.SyntaxTreeToModify)) { var tree = removeSuppressionFixesForTree.Key; var attributeRemoveFixesForTree = removeSuppressionFixesForTree.OfType<AttributeRemoveAction>().ToImmutableArray(); var attributesToRemove = await GetAttributeNodesToFixAsync(attributeRemoveFixesForTree, cancellationToken).ConfigureAwait(false); var document = oldSolution.GetDocument(tree); var root = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false); var newRoot = root.RemoveNodes(attributesToRemove, SyntaxRemoveOptions.KeepLeadingTrivia | SyntaxRemoveOptions.AddElasticMarker); currentSolution = currentSolution.WithDocumentSyntaxRoot(document.Id, newRoot); } // This is a temporary generated code action, which doesn't need telemetry, hence suppressing RS0005. #pragma warning disable RS0005 // Do not use generic CodeAction.Create to create CodeAction var batchAttributeRemoveFix = Create( attributeRemoveFixes.First().Title, createChangedSolution: ct => Task.FromResult(currentSolution), equivalenceKey: fixAllState.CodeActionEquivalenceKey); #pragma warning restore RS0005 // Do not use generic CodeAction.Create to create CodeAction newBatchOfFixes.Insert(0, batchAttributeRemoveFix); } return await base.TryGetMergedFixAsync(newBatchOfFixes, fixAllState, cancellationToken).ConfigureAwait(false); }
protected override bool IncludeDiagnosticDuringFixAll(FixAllState state, Diagnostic diagnostic, CancellationToken cancellationToken) => diagnostic.Properties.ContainsKey(AddRequiredParenthesesConstants.IncludeInFixAll) && diagnostic.Properties[AddRequiredParenthesesConstants.EquivalenceKey] == state.CodeActionEquivalenceKey;
protected override bool IncludeDiagnosticDuringFixAll(FixAllState fixAllState, Diagnostic diagnostic, CancellationToken cancellationToken) { return(fixAllState.CodeActionEquivalenceKey == GetEquivalenceKey(diagnostic) && !IsForEachIterationVariableDiagnostic(diagnostic, fixAllState.Document, cancellationToken)); }
protected override bool IncludeDiagnosticDuringFixAll(FixAllState state, Diagnostic diagnostic, CancellationToken cancellationToken) => diagnostic.Properties.ContainsKey(PreferFrameworkTypeConstants.PreferFrameworkType);
static void AddFixMenuItem(Ide.Editor.TextEditor editor, CodeFixMenu menu, CodeFixMenu fixAllMenu, ref int mnemonic, CodeAction fix, FixAllState fixState, CancellationToken token) { if (fix is CodeAction.CodeActionWithNestedActions nested) { // Inline code actions if they are, otherwise add a nested fix menu if (nested.IsInlinable) { int actionCount = nested.NestedCodeActions.Length; foreach (var nestedFix in nested.NestedCodeActions) { var nestedFixState = actionCount > 1 && nestedFix.EquivalenceKey == null ? null : fixState; AddFixMenuItem(editor, menu, fixAllMenu, ref mnemonic, nestedFix, nestedFixState, token); } return; } if (nested.NestedCodeActions.Length > 0) { AddNestedFixMenu(editor, menu, fixAllMenu, nested, fixState, token); } return; } menu.Add(CreateFixMenuEntry(editor, fix, ref mnemonic)); // TODO: Add support for more than doc when we have global undo. fixState = fixState?.WithScopeAndEquivalenceKey(FixAllScope.Document, fix.EquivalenceKey); var fixAllMenuEntry = CreateFixAllMenuEntry(editor, fixState, ref mnemonic, token); if (fixAllMenuEntry != null) { fixAllMenu.Add(new CodeFixMenuEntry(fix.Message, null)); fixAllMenu.Add(fixAllMenuEntry); } }
static void AddNestedFixMenu(Ide.Editor.TextEditor editor, CodeFixMenu menu, CodeFixMenu fixAllMenu, CodeAction.CodeActionWithNestedActions fixes, FixAllState fixState, CancellationToken token) { int subMnemonic = 0; var subMenu = new CodeFixMenu(fixes.Title); foreach (var fix in fixes.NestedCodeActions) { AddFixMenuItem(editor, subMenu, fixAllMenu, ref subMnemonic, fix, fixState, token); } menu.Add(subMenu); }