Beispiel #1
0
        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));
        }
Beispiel #2
0
            /// <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));
        }
Beispiel #4
0
        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)));
        }
Beispiel #5
0
            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));
                }
Beispiel #8
0
            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;
 }
Beispiel #11
0
                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);
                    }
                }
Beispiel #12
0
        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));
        }
Beispiel #19
0
        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
            }
Beispiel #22
0
        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));
        }
Beispiel #23
0
        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);
                        }
                    }
                }
Beispiel #27
0
        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);
        }
Beispiel #28
0
        /// <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);
        }
Beispiel #30
0
            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);
                }
Beispiel #33
0
 protected override bool IncludeDiagnosticDuringFixAll(FixAllState state, Diagnostic diagnostic, CancellationToken cancellationToken)
 => diagnostic.Properties.ContainsKey(AddRequiredParenthesesConstants.IncludeInFixAll) &&
 diagnostic.Properties[AddRequiredParenthesesConstants.EquivalenceKey] == state.CodeActionEquivalenceKey;
Beispiel #34
0
 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);
Beispiel #36
0
        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);
            }
        }
Beispiel #37
0
        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);
        }