예제 #1
0
        private static VSCodeAction GenerateVSCodeAction(
            CodeActionParams request,
            CodeAction codeAction,
            CodeActionKind codeActionKind,
            string currentTitle = "")
        {
            using var _ = ArrayBuilder <VSCodeAction> .GetInstance(out var nestedActions);

            if (!string.IsNullOrEmpty(currentTitle))
            {
                // Adding a delimiter for nested code actions, e.g. 'Suppress or Configure issues|Suppress IDEXXXX|in Source'
                currentTitle += '|';
            }

            currentTitle += codeAction.Title;

            // Nested code actions' unique identifiers consist of: parent code action unique identifier + '|' + title of code action
            foreach (var action in codeAction.NestedCodeActions)
            {
                nestedActions.Add(GenerateVSCodeAction(request, action, codeActionKind, currentTitle));
            }

            return(new VSCodeAction
            {
                Title = codeAction.Title,
                Kind = codeActionKind,
                Diagnostics = request.Context.Diagnostics,
                Children = nestedActions.ToArray(),
                Data = new CodeActionResolveData(currentTitle, request.Range, request.TextDocument)
            });
        }
예제 #2
0
 internal CodeFix(Project project, CodeAction action, ImmutableArray<Diagnostic> diagnostics)
 {
     Debug.Assert(!diagnostics.IsDefault);
     this.Project = project;
     this.Action = action;
     this.Diagnostics = diagnostics;
 }
 public SuggestedActionWithNestedActions(
     SuggestedActionsSourceProvider sourceProvider, Workspace workspace, 
     ITextBuffer subjectBuffer, object provider, 
     CodeAction codeAction, SuggestedActionSet nestedActionSet) 
     : base(sourceProvider, workspace, subjectBuffer, provider, codeAction)
 {
     NestedActionSet = nestedActionSet;
 }
 private async Task ExecuteCodeAction(CodeAction codeAction)
 {
     var operations = await codeAction.GetOperationsAsync(CancellationToken.None).ConfigureAwait(true);
     foreach (var operation in operations)
     {
         operation.Apply(_roslynHost.GetDocument(_documentId).Project.Solution.Workspace, CancellationToken.None);
     }
 }
 protected SuggestedActionWithFlavors(
     Workspace workspace,
     ITextBuffer subjectBuffer,
     ICodeActionEditHandlerService editHandler,
     CodeAction codeAction,
     object provider) : base(workspace, subjectBuffer, editHandler, codeAction, provider)
 {
 }
예제 #6
0
 public SuggestedActionWithPreview(
     Workspace workspace, ITextBuffer subjectBuffer, ICodeActionEditHandlerService editHandler, 
     IWaitIndicator waitIndicator, CodeAction codeAction, object provider, 
     IAsynchronousOperationListener operationListener) 
     : base(workspace, subjectBuffer, editHandler, waitIndicator, codeAction,
           provider, operationListener, actionSets: null)
 {
 }
예제 #7
0
        /// <summary>
        /// Add supplied <paramref name="action"/> to the list of refactorings that will be offered to the user.
        /// </summary>
        /// <param name="action">The <see cref="CodeAction"/> that will be invoked to apply the refactoring.</param>
        public void RegisterRefactoring(CodeAction action)
        {
            if (action == null)
            {
                throw new ArgumentNullException(nameof(action));
            }

            _registerRefactoring(action);
        }
 public CodeRefactoringSuggestedAction(
     Workspace workspace,
     ITextBuffer subjectBuffer,
     ICodeActionEditHandlerService editHandler,
     CodeAction codeAction,
     CodeRefactoringProvider provider)
     : base(workspace, subjectBuffer, editHandler, codeAction, provider)
 {
 }
 public CodeRefactoringSuggestedAction(
     SuggestedActionsSourceProvider sourceProvider,
     Workspace workspace,
     ITextBuffer subjectBuffer,
     CodeRefactoringProvider provider,
     CodeAction codeAction)
     : base(sourceProvider, workspace, subjectBuffer, provider, codeAction)
 {
 }
예제 #10
0
 protected SuggestedActionWithFlavors(
     Workspace workspace,
     ITextBuffer subjectBuffer,
     ICodeActionEditHandlerService editHandler,
     IWaitIndicator waitIndicator,
     CodeAction codeAction,
     object provider,
     IAsynchronousOperationListener operationListener) : base(workspace, subjectBuffer, editHandler, waitIndicator, codeAction, provider, operationListener)
 {
 }
 public SuggestedActionWithNestedFlavors(
     SuggestedActionsSourceProvider sourceProvider,
     Workspace workspace, ITextBuffer subjectBuffer,
     object provider, CodeAction codeAction, 
     SuggestedActionSet additionalFlavors = null) 
     : base(sourceProvider, workspace, subjectBuffer, 
            provider, codeAction)
 {
     _additionalFlavors = additionalFlavors;
 }
예제 #12
0
 public CodeRefactoringSuggestedAction(
     Workspace workspace,
     ITextBuffer subjectBuffer,
     ICodeActionEditHandlerService editHandler,
     IWaitIndicator waitIndicator,
     CodeAction codeAction,
     CodeRefactoringProvider provider,
     IAsynchronousOperationListener operationListener)
     : base(workspace, subjectBuffer, editHandler, waitIndicator, codeAction, provider, operationListener)
 {
 }
예제 #13
0
        private async Task<IEnumerable<CodeActionOperation>> GetFixAllOperationsAsync(CodeAction codeAction, FixAllContext fixAllContext, string fixAllPreviewChangesTitle, bool showPreviewChangesDialog)
        {
            // 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);

            if (showPreviewChangesDialog)
            {
                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, fixAllPreviewChangesTitle),
                    "vs.codefix.fixall",
                    codeAction.Title,
                    fixAllPreviewChangesTitle,
                    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);
        }
		public RefactoringPreviewTooltipWindow (TextEditor editor, DocumentContext documentContext, CodeAction codeAction)
		{
			this.editor = editor;
			this.documentContext = documentContext;
			this.codeAction = codeAction;
			TransientFor = IdeApp.Workbench.RootWindow;

			fontDescription = Pango.FontDescription.FromString (DefaultSourceEditorOptions.Instance.FontName);
			fontDescription.Size = (int)(fontDescription.Size * 0.8f);

			using (var metrics = PangoContext.GetMetrics (fontDescription, PangoContext.Language)) {
				lineHeight = (int)Math.Ceiling (0.5 + (metrics.Ascent + metrics.Descent) / Pango.Scale.PangoScale);
			}
		}
예제 #15
0
        public static void CodeAction(CodeAction codeAction, Document document, string expectedCode)
        {
            var operations = codeAction.GetOperationsAsync(CancellationToken.None).Result;

            Assert.That(operations.Count(), Is.EqualTo(1));

            var operation = operations.Single();
            var workspace = document.Project.Solution.Workspace;
            operation.Apply(workspace, CancellationToken.None);

            var newDocument = workspace.CurrentSolution.GetDocument(document.Id);

            var sourceText = newDocument.GetTextAsync(CancellationToken.None).Result;
            var text = sourceText.ToString();

            Assert.That(text, Is.EqualTo(expectedCode));
        }
        private static bool TryGetRedundantLambdaParameterAction(SyntaxNode syntaxNode, SyntaxNode root,
            Document document, out CodeAction action)
        {
            var parameterList = syntaxNode.Parent?.Parent as ParameterListSyntax;
            if (parameterList == null)
            {
                action = null;
                return false;
            }

            action = CodeAction.Create(TitleRedundantLambdaParameterType, c =>
            {
                var newParameterList = parameterList.WithParameters(
                    SyntaxFactory.SeparatedList(parameterList.Parameters.Select(p =>
                        SyntaxFactory.Parameter(p.Identifier).WithTriviaFrom(p))));
                var newRoot = root.ReplaceNode(parameterList, newParameterList);
                return Task.FromResult(document.WithSyntaxRoot(newRoot));
            }, TitleRedundantLambdaParameterType);
            return true;
        }
예제 #17
0
        public static void CodeAction(CodeAction codeAction, Document document, string expectedCode)
        {
            var operations = codeAction.GetOperationsAsync(CancellationToken.None).Result;

            Assert.That(operations.Count(), Is.EqualTo(1));

            var operation = operations.Single();
            var workspace = document.Project.Solution.Workspace;
            operation.Apply(workspace, CancellationToken.None);

            var newDocument = workspace.CurrentSolution.GetDocument(document.Id);

            var sourceText = newDocument.GetTextAsync(CancellationToken.None).Result;
            var text = sourceText.ToString();
            Console.WriteLine($"New code:\r\n{text}");

            // Need to replace win-style line ending to unix-style to avoid build breaks on AppVeyor
            text = text.Replace("\r\n", "\n");
            expectedCode = expectedCode.Replace("\r\n", "\n");

            Assert.That(text, Is.EqualTo(expectedCode));
        }
예제 #18
0
            static VSCodeAction GenerateVSCodeAction(
                CodeActionParams request,
                CodeAction codeAction,
                CodeActionKind codeActionKind,
                string currentTitle = "")
            {
                using var _ = ArrayBuilder <VSCodeAction> .GetInstance(out var nestedActions);

                if (!string.IsNullOrEmpty(currentTitle))
                {
                    // Adding a delimiter for nested code actions, e.g. 'Suppress IDEXXXX|in Source'
                    currentTitle += '|';
                }

                // Don't include Suppress or Configure issues in the unique identifier, as when we
                // resolve these code actions, we won't be able to see the Suppress or Configure title
                // (since it utilizes special logic).
                // Once we make the logic between local and LSP uniform, this should no longer be necessary.
                // https://github.com/dotnet/roslyn/issues/45726
                if (codeAction.Title != CodeFixesResources.Suppress_or_Configure_issues)
                {
                    currentTitle += codeAction.Title;
                }

                // Nested code actions' unique identifiers consist of: parent code action unique identifier + '|' + title of code action
                foreach (var action in codeAction.NestedCodeActions)
                {
                    nestedActions.Add(GenerateVSCodeAction(request, action, codeActionKind, currentTitle));
                }

                return(new VSCodeAction
                {
                    Title = codeAction.Title,
                    Kind = codeActionKind,
                    Diagnostics = request.Context.Diagnostics,
                    Children = nestedActions.ToArray(),
                    Data = new CodeActionResolveData(currentTitle, request.Range, request.TextDocument)
                });
            }
        private async Task<IEnumerable<CodeActionOperation>> GetFixAllOperationsAsync(CodeAction codeAction, FixAllContext fixAllContext, bool showPreviewChangesDialog)
        {
            // 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: cancellationToken).ConfigureAwait(false);

            if (showPreviewChangesDialog)
            {
                newSolution = PreviewChanges(
                    fixAllContext.Project.Solution,
                    newSolution,
                    FeaturesResources.FixAllOccurrences,
                    codeAction.Title,
                    fixAllContext.Project.Language,
                    workspace,
                    cancellationToken);
                if (newSolution == null)
                {
                    return null;
                }
            }

            // Get a code action, with apply changes operation replaced with the newSolution.
            return GetNewFixAllOperations(operations, newSolution, cancellationToken);
        }
예제 #20
0
 internal CodeFix(Project project, CodeAction action, Diagnostic diagnostic)
 {
     this.Project = project;
     this.Action = action;
     this.Diagnostics = ImmutableArray.Create(diagnostic);
 }
예제 #21
0
 /// <summary>
 ///     Apply the inputted CodeAction to the inputted document.
 ///     Meant to be used to apply codefixes.
 /// </summary>
 /// <param name="document">The Document to apply the fix on</param>
 /// <param name="codeAction">A CodeAction that will be applied to the Document.</param>
 /// <returns>A Document with the changes from the CodeAction</returns>
 private static Document ApplyFix(Document document, CodeAction codeAction)
 {
     var operations = codeAction.GetOperationsAsync(CancellationToken.None).Result;
     var solution = operations.OfType<ApplyChangesOperation>().Single().ChangedSolution;
     return solution.GetDocument(document.Id);
 }
예제 #22
0
 public PreviewChangesCodeAction(Workspace workspace, CodeAction originalCodeAction, SolutionChangeSummary changeSummary)
 {
     _workspace = workspace;
     _originalCodeAction = originalCodeAction;
     _changeSummary = changeSummary;
 }
예제 #23
0
        /// <summary>
        /// Add supplied <paramref name="action"/> to the list of fixes that will be offered to the user.
        /// </summary>
        /// <param name="action">The <see cref="CodeAction"/> that will be invoked to apply the fix.</param>
        /// <param name="diagnostics">The subset of <see cref="Diagnostics"/> being addressed / fixed by the <paramref name="action"/>.</param>
        public void RegisterCodeFix(CodeAction action, ImmutableArray<Diagnostic> diagnostics)
        {
            if (action == null)
            {
                throw new ArgumentNullException(nameof(action));
            }

            VerifyDiagnosticsArgument(diagnostics, _span);

            // TODO: 
            // - Check that all diagnostics are unique (no duplicates).
            // - Check that supplied diagnostics form subset of diagnostics originally
            //   passed to the provider via CodeFixContext.Diagnostics.

            _registerCodeFix(action, diagnostics);
        }
예제 #24
0
        /// <summary>
        /// Add supplied <paramref name="action"/> to the list of fixes that will be offered to the user.
        /// </summary>
        /// <param name="action">The <see cref="CodeAction"/> that will be invoked to apply the fix.</param>
        /// <param name="diagnostics">The subset of <see cref="Diagnostics"/> being addressed / fixed by the <paramref name="action"/>.</param>
        public void RegisterCodeFix(CodeAction action, IEnumerable<Diagnostic> diagnostics)
        {
            if (diagnostics == null)
            {
                throw new ArgumentNullException(nameof(diagnostics));
            }

            RegisterCodeFix(action, diagnostics.ToImmutableArray());
        }
예제 #25
0
        /// <summary>
        /// Add supplied <paramref name="action"/> to the list of fixes that will be offered to the user.
        /// </summary>
        /// <param name="action">The <see cref="CodeAction"/> that will be invoked to apply the fix.</param>
        /// <param name="diagnostic">The subset of <see cref="Diagnostics"/> being addressed / fixed by the <paramref name="action"/>.</param>
        public void RegisterCodeFix(CodeAction action, Diagnostic diagnostic)
        {
            if (action == null)
            {
                throw new ArgumentNullException(nameof(action));
            }

            if (diagnostic == null)
            {
                throw new ArgumentNullException(nameof(diagnostic));
            }

            _registerCodeFix(action, ImmutableArray.Create(diagnostic));
        }
 private static bool TryGetAction(SyntaxNode syntaxNode, SyntaxNode root, RedundantDeclaration.RedundancyType diagnosticType,
     Document document, out CodeAction action)
 {
     switch (diagnosticType)
     {
         case RedundantDeclaration.RedundancyType.LambdaParameterType:
             return TryGetRedundantLambdaParameterAction(syntaxNode, root, document, out action);
         case RedundantDeclaration.RedundancyType.ArraySize:
             return TryGetRedundantArraySizeAction(syntaxNode, root, document, out action);
         case RedundantDeclaration.RedundancyType.ArrayType:
             return TryGetRedundantArrayTypeAction(syntaxNode, root, document, out action);
         case RedundantDeclaration.RedundancyType.ExplicitDelegate:
         case RedundantDeclaration.RedundancyType.ExplicitNullable:
             return TryGetRedundantExplicitObjectCreationAction(syntaxNode, root, document, diagnosticType, out action);
         case RedundantDeclaration.RedundancyType.ObjectInitializer:
             return TryGetRedundantObjectInitializerAction(syntaxNode, root, document, out action);
         case RedundantDeclaration.RedundancyType.DelegateParameterList:
             return TryGetRedundantParameterTypeAction(syntaxNode, root, document, out action);
         default:
             throw new NotSupportedException();
     }
 }
        private static bool TryGetRedundantArraySizeAction(SyntaxNode syntaxNode, SyntaxNode root,
            Document document, out CodeAction action)
        {
            var arrayRank = syntaxNode.Parent as ArrayRankSpecifierSyntax;
            if (arrayRank == null)
            {
                action = null;
                return false;
            }

            action = CodeAction.Create(TitleRedundantArraySize, c =>
            {
                var newArrayRankSpecifier = arrayRank.WithSizes(
                    SyntaxFactory.SeparatedList<ExpressionSyntax>(arrayRank.Sizes.Select(s =>
                        SyntaxFactory.OmittedArraySizeExpression())));
                var newRoot = root.ReplaceNode(arrayRank, newArrayRankSpecifier);
                return Task.FromResult(document.WithSyntaxRoot(newRoot));
            }, TitleRedundantArraySize);
            return true;
        }
            /// <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);
            }
            private bool IsApplicable(CodeAction action, Workspace workspace)
            {
                if (!action.PerformFinalApplicabilityCheck)
                {
                    // If we don't even need to perform the final applicability check,
                    // then the code actoin is applicable.
                    return true;
                }

                // Otherwise, defer to the action to make the decision.
                this.AssertIsForeground();
                return action.IsApplicable(workspace);
            }
예제 #30
0
        private static bool TryGetCodeActionToApply(string codeFixTitle, IEnumerable<CodeAction> codeActions,
            out CodeAction codeAction)
        {
            codeAction = codeFixTitle != null
                ? codeActions.SingleOrDefault(action => action.Title == codeFixTitle)
                : codeActions.FirstOrDefault();

            return codeAction != null;
        }
예제 #31
0
		private static Document ApplyFix(Document document, CodeAction codeAction) => codeAction.GetOperationsAsync(CancellationToken.None).Result.OfType<ApplyChangesOperation>().Single().ChangedSolution.GetDocument(document.Id);
 internal static bool IsAnalysisOrErrorFix(Microsoft.CodeAnalysis.CodeActions.CodeAction act)
 {
     return(false);
 }
 /// <summary>
 /// Apply the inputted CodeAction to the inputted document.
 /// Meant to be used to apply codefixes.
 /// </summary>
 /// <param name="document">The Document to apply the fix on</param>
 /// <param name="codeAction">A CodeAction that will be applied to the Document.</param>
 /// <returns>A Document with the changes from the CodeAction</returns>
 private static Document ApplyFix(Document document, CodeAction codeAction)
 {
     System.Collections.Immutable.ImmutableArray<CodeActionOperation> operations = codeAction.GetOperationsAsync(CancellationToken.None).Result;
     Solution solution = operations.OfType<ApplyChangesOperation>().Single().ChangedSolution;
     return solution.GetDocument(document.Id);
 }