Exemplo n.º 1
0
        private static void RefactoringSetup(
            TestWorkspace workspace,
            CodeRefactoringProvider provider,
            List <CodeAction> codeActions,
            out EditorLayerExtensionManager.ExtensionManager extensionManager,
            out VisualStudio.Text.ITextBuffer textBuffer
            )
        {
            var document = GetDocument(workspace);

            textBuffer = workspace.GetTestDocument(document.Id).GetTextBuffer();
            var span    = document.GetSyntaxRootAsync().Result.Span;
            var context = new CodeRefactoringContext(
                document,
                span,
                (a) => codeActions.Add(a),
                CancellationToken.None
                );

            provider.ComputeRefactoringsAsync(context).Wait();
            var action = codeActions.Single();

            extensionManager =
                document.Project.Solution.Workspace.Services.GetService <IExtensionManager>()
                as EditorLayerExtensionManager.ExtensionManager;
        }
Exemplo n.º 2
0
        private static async Task <CodeRefactoring> GetCodeRefactoringAsync(
            CodeRefactoringProvider provider,
            TestWorkspace workspace
            )
        {
            var documentsWithSelections = workspace.Documents.Where(
                d => !d.IsLinkFile && d.SelectedSpans.Count == 1
                );

            Debug.Assert(
                documentsWithSelections.Count() == 1,
                "One document must have a single span annotation"
                );
            var span    = documentsWithSelections.Single().SelectedSpans.Single();
            var actions = ArrayBuilder <(CodeAction, TextSpan?)> .GetInstance();

            var document = workspace.CurrentSolution.GetDocument(
                documentsWithSelections.Single().Id
                );
            var context = new CodeRefactoringContext(
                document,
                span,
                (a, t) => actions.Add((a, t)),
                isBlocking: false,
                CancellationToken.None
                );
            await provider.ComputeRefactoringsAsync(context);

            var result =
                actions.Count > 0 ? new CodeRefactoring(provider, actions.ToImmutable()) : null;

            actions.Free();
            return(result);
        }
Exemplo n.º 3
0
        public static void VerifyNoRefactoring(
            string source,
            TextSpan span,
            CodeRefactoringProvider refactoringProvider,
            string language,
            string equivalenceKey = null)
        {
            Document document = WorkspaceFactory.CreateDocument(source, language);

            DiagnosticVerifier.VerifyNoCompilerError(document);

            List <CodeAction> actions = null;

            var context = new CodeRefactoringContext(
                document,
                span,
                codeAction =>
            {
                if (equivalenceKey == null ||
                    string.Equals(codeAction.EquivalenceKey, equivalenceKey, StringComparison.Ordinal))
                {
                    (actions ?? (actions = new List <CodeAction>())).Add(codeAction);
                }
            },
                CancellationToken.None);

            refactoringProvider.ComputeRefactoringsAsync(context).Wait();

            Assert.True(actions == null, $"Expected no code refactoring, actual: {actions?.Count ?? 0}");
        }
        internal static List <CodeAction> GetRefactoringActions(string language, CodeRefactoringProvider codeRefactoringProvider, string source, TextSpan span)
        {
            var document = CodeAnalysisHelper.CreateDocument(source, language);
            var actions  = new List <CodeAction>();
            var context  = new CodeRefactoringContext(document, span, (a) => actions.Add(a), CancellationToken.None);

            codeRefactoringProvider.ComputeRefactoringsAsync(context).Wait();
            return(actions);
        }
Exemplo n.º 5
0
        private IEnumerable <CodeAction> GetRefactoring(Document document, TextSpan span)
        {
            CodeRefactoringProvider provider = CreateCodeRefactoringProvider;
            List <CodeAction>       actions  = new List <CodeAction>();
            CodeRefactoringContext  context  = new CodeRefactoringContext(document, span, (a) => actions.Add(a), CancellationToken.None);

            provider.ComputeRefactoringsAsync(context).Wait();
            return(actions);
        }
Exemplo n.º 6
0
 private async Task<CodeRefactoring> GetCodeRefactoringAsync(
     CodeRefactoringProvider provider,
     TestWorkspace workspace)
 {
     var document = GetDocument(workspace);
     var span = workspace.Documents.Single(d => !d.IsLinkFile && d.SelectedSpans.Count == 1).SelectedSpans.Single();
     var actions = new List<CodeAction>();
     var context = new CodeRefactoringContext(document, span, (a) => actions.Add(a), CancellationToken.None);
     await provider.ComputeRefactoringsAsync(context);
     return actions.Count > 0 ? new CodeRefactoring(provider, actions) : null;
 }
        private static ImmutableArray <CodeAction> GetCodeRefactorings(CodeRefactoringProvider provider, Document document, TextSpan span)
        {
            var builder = ImmutableArray.CreateBuilder <CodeAction>();
            Action <CodeAction> registerRefactoring = a => builder.Add(a);

            var context = new CodeRefactoringContext(document, span, registerRefactoring, CancellationToken.None);

            provider.ComputeRefactoringsAsync(context).GetAwaiter().GetResult();

            return(builder.ToImmutable());
        }
Exemplo n.º 8
0
        private static CodeAction SingleAction(Document document, CodeRefactoringProvider refactoring, int position)
        {
            var context = new RefactoringContext(document, refactoring, position);
            var token   = context.SyntaxRoot.FindToken(position);

            refactoring.ComputeRefactoringsAsync(context.CreateRefactoringContext(token.Span)).GetAwaiter().GetResult();
            return(context.Actions.Count switch
            {
                0 => SingleAction(context, token.Parent),
                1 => context.Actions[0],
                _ => throw new NotSupportedException("More than one action available. Currently not supporting invoking action by index. We should add support for it."),
            });
    public async Task InvokeAsync()
    {
        var codeActions = new List <CodeAction>();
        Action <CodeAction> registerRefactoring = codeActions.Add;

        var context = new CodeRefactoringContext(document, span, registerRefactoring, CancellationToken.None);

        await provider.ComputeRefactoringsAsync(context).ConfigureAwait(false);

        var codeAction = codeActions.Single();

        operations = await codeAction.GetOperationsAsync(CancellationToken.None).ConfigureAwait(false);
    }
Exemplo n.º 10
0
        private static IReadOnlyList <CodeAction> CodeActions(CodeRefactoringProvider refactoring, string testCode, TextSpan span, IEnumerable <MetadataReference> metadataReferences)
        {
            var sln = CodeFactory.CreateSolutionWithOneProject(
                testCode,
                CodeFactory.DefaultCompilationOptions(Array.Empty <DiagnosticAnalyzer>()),
                metadataReferences);
            var document = sln.Projects.Single().Documents.Single();
            var actions  = new List <CodeAction>();
            var context  = new CodeRefactoringContext(document, span, a => actions.Add(a), CancellationToken.None);

            refactoring.ComputeRefactoringsAsync(context).GetAwaiter().GetResult();
            return(actions);
        }
Exemplo n.º 11
0
        private static IReadOnlyList <CodeAction> CodeActions(CodeRefactoringProvider refactoring, string testCode, int position, IEnumerable <MetadataReference> metadataReferences)
        {
            var sln = CodeFactory.CreateSolutionWithOneProject(
                testCode,
                CodeFactory.DefaultCompilationOptions(Array.Empty <DiagnosticAnalyzer>()),
                metadataReferences);
            var document = sln.Projects.Single().Documents.Single();
            var context  = new RefactoringContext(document, refactoring, position);
            var token    = context.SyntaxRoot.FindToken(position);

            refactoring.ComputeRefactoringsAsync(context.CreateRefactoringContext(token.Span)).GetAwaiter().GetResult();

            var node = token.Parent;

            while (node != null &&
                   node.SpanStart == position)
            {
                refactoring.ComputeRefactoringsAsync(context.CreateRefactoringContext(node.Span)).GetAwaiter().GetResult();
                node = node.Parent;
            }

            return(context.Actions);
        }
Exemplo n.º 12
0
        private async Task <CodeRefactoring> GetCodeRefactoringAsync(
            CodeRefactoringProvider provider,
            TestWorkspace workspace)
        {
            var document = GetDocument(workspace);
            var span     = workspace.Documents.Single(d => !d.IsLinkFile && d.SelectedSpans.Count == 1).SelectedSpans.Single();
            var actions  = ArrayBuilder <CodeAction> .GetInstance();

            var context = new CodeRefactoringContext(document, span, actions.Add, CancellationToken.None);
            await provider.ComputeRefactoringsAsync(context);

            var result = actions.Count > 0 ? new CodeRefactoring(provider, actions.ToImmutable()) : null;

            actions.Free();
            return(result);
        }
Exemplo n.º 13
0
        /// <summary>
        /// General verifier for refactorings.
        /// Creates a Document from the source string, then applies the relevant refactorings.
        /// Then gets the string after the refactoring is applied and compares it with the expected result.
        /// Note: If any refactoring causes new compiler diagnostics to show up, the test fails unless allowNewCompilerDiagnostics is set to true.
        /// </summary>
        /// <param name="language">The language the source code is in</param>
        /// <param name="codeRefactoringProvider">The refactoring to be applied to the code</param>
        /// <param name="oldSource">A class in the form of a string before the refactoring was applied to it</param>
        /// <param name="newSource">A class in the form of a string after the refactoring was applied to it</param>
        /// <param name="nodeToRefactor">A function that finds selected node for refactoring accepting the root node as an argument</param>
        /// <param name="codeRefactoringIndex">Index determining which refactoring to apply if there are multiple</param>
        /// <param name="allowNewCompilerDiagnostics">A bool controlling whether or not the test will fail if the refactoring introduces other warnings after being applied</param>
        private async Task VerifyRefactoringAsync(string language, CodeRefactoringProvider codeRefactoringProvider,
                                                  string oldSource, string newSource, Func <SyntaxNode, SyntaxNode> nodeToRefactor,
                                                  int?codeRefactoringIndex, bool allowNewCompilerDiagnostics)
        {
            var document            = CreateDocument(oldSource, language);
            var compilerDiagnostics = (await GetCompilerDiagnosticsAsync(document).ConfigureAwait(false)).ToArray();

            var actions = new List <CodeAction>();
            var root    = await document.GetSyntaxRootAsync().ConfigureAwait(false);

            var node    = nodeToRefactor(root);
            var context = new CodeRefactoringContext(document, node.FullSpan, a => actions.Add(a),
                                                     CancellationToken.None);

            await codeRefactoringProvider.ComputeRefactoringsAsync(context).ConfigureAwait(false);

            if (actions.Count > 0)
            {
                document = await ApplyCodeActionAsync(document, codeRefactoringIndex != null
                                                      ?actions[(int)codeRefactoringIndex]
                                                      : actions[0]).ConfigureAwait(false);

                var newCompilerDiagnostics = GetNewDiagnostics(compilerDiagnostics,
                                                               await GetCompilerDiagnosticsAsync(document).ConfigureAwait(false));

                //check if applying the code fix introduced any new compiler diagnostics
                if (!allowNewCompilerDiagnostics && newCompilerDiagnostics.Any())
                {
                    // Format and get the compiler diagnostics again so that the locations make sense in the output
                    document = document.WithSyntaxRoot(Formatter.Format(await document.GetSyntaxRootAsync().ConfigureAwait(false),
                                                                        Formatter.Annotation, document.Project.Solution.Workspace));
                    newCompilerDiagnostics = GetNewDiagnostics(compilerDiagnostics,
                                                               await GetCompilerDiagnosticsAsync(document).ConfigureAwait(false));

                    var newSyntaxRoot = await document.GetSyntaxRootAsync().ConfigureAwait(false);

                    Assert.True(false,
                                string.Format("Refactoring introduced new compiler diagnostics:\r\n{0}\r\n\r\nNew document:\r\n{1}\r\n",
                                              string.Join("\r\n", newCompilerDiagnostics.Select(d => d.ToString())), newSyntaxRoot.ToFullString()));
                }
            }

            //after applying all of the refactorings, compare the resulting string to the inputted one
            var actual = await GetStringFromDocumentAsync(document).ConfigureAwait(false);

            Assert.Equal(newSource, actual);
        }
        internal static string GetRefactoringResult(string language, CodeRefactoringProvider codeRefactoringProvider, string oldSource, TextSpan span, string equivalenceKey)
        {
            var document = CodeAnalysisHelper.CreateDocument(oldSource, language);
            var actions  = new List <CodeAction>();
            var context  = new CodeRefactoringContext(document, span, (a) => actions.Add(a), CancellationToken.None);

            codeRefactoringProvider.ComputeRefactoringsAsync(context).Wait();

            if (equivalenceKey != null)
            {
                document = CodeAnalysisHelper.ApplyFix(document, actions.Single(n => n.EquivalenceKey == equivalenceKey));
            }
            else
            {
                document = CodeAnalysisHelper.ApplyFix(document, actions[0]);
            }

            var newSource = CodeAnalysisHelper.GetStringFromDocument(document);

            return(newSource);
        }
Exemplo n.º 15
0
        private static Document VerifyRefactoring(
            Document document,
            TextSpan span,
            CodeRefactoringProvider refactoringProvider,
            string equivalenceKey,
            bool allowNewCompilerDiagnostics)
        {
            ImmutableArray <Diagnostic> compilerDiagnostics = document.GetCompilerDiagnostics();

            DiagnosticVerifier.VerifyNoCompilerError(compilerDiagnostics);

            List <CodeAction> actions = null;

            var context = new CodeRefactoringContext(
                document,
                span,
                a =>
            {
                if (equivalenceKey == null ||
                    string.Equals(a.EquivalenceKey, equivalenceKey, StringComparison.Ordinal))
                {
                    (actions ?? (actions = new List <CodeAction>())).Add(a);
                }
            },
                CancellationToken.None);

            refactoringProvider.ComputeRefactoringsAsync(context).Wait();

            Assert.True(actions != null, "No code refactoring has been registered.");

            document = document.ApplyCodeAction(actions[0]);

            if (!allowNewCompilerDiagnostics)
            {
                DiagnosticVerifier.VerifyNoNewCompilerDiagnostics(document, compilerDiagnostics);
            }

            return(document);
        }
Exemplo n.º 16
0
        /// <summary>
        /// General verifier for code refactorings.
        /// Creates a Document from the source string and applies the relevant code refactorings to the marked selection.
        /// Then gets the string after the code refactoring is applied and compares it with the expected result.
        /// </summary>
        /// <param name="language">The language the source code is in</param>
        /// <param name="codeRefactoringProvider">The code refactoring to be applied to the code</param>
        /// <param name="oldSource">A class in the form of a string with [| |] selection markings before the CodeRefactoring was applied to it</param>
        /// <param name="newSource">A class in the form of a string after the CodeRefactoring was applied to it</param>
        /// <param name="codeRefactoringTitle">Titel determining which CodeRefactoring to apply if there are multiple</param>
        private void VerifyRefactoring(string language, CodeRefactoringProvider codeRefactoringProvider, string oldSource, string newSource, string codeRefactoringTitle)
        {
            TextSpan span;

            if (!TryGetCodeAndSpanFromMarkup(oldSource, out oldSource, out span))
            {
                throw new ArgumentException("There are no selection markings in the code", nameof(oldSource));
            }

            var document = CreateDocument(oldSource, language);

            var actions = new List <CodeAction>();
            var context = new CodeRefactoringContext(document, span, (a) => actions.Add(a), CancellationToken.None);

            codeRefactoringProvider.ComputeRefactoringsAsync(context).Wait();

            if (actions.Any())
            {
                if (codeRefactoringTitle != null)
                {
                    CodeAction codeAction = actions.FirstOrDefault(x => x.Title == codeRefactoringTitle);
                    if (codeAction != null)
                    {
                        document = ApplyCodeAction(document, codeAction);
                    }
                }
                else
                {
                    document = ApplyCodeAction(document, actions.First());
                }
            }

            //after applying all of the code actions, compare the resulting string to the inputted one
            var actual = GetStringFromDocument(document);

            Assert.AreEqual(newSource, actual);
        }
        static List <CodeAction> GetActions(CodeRefactoringProvider action, string input, out DiagnosticTestBase.TestWorkspace workspace, out Document doc, VisualBasicParseOptions parseOptions = null)
        {
            TextSpan selectedSpan;
            TextSpan markedSpan;
            string   text = ParseText(input, out selectedSpan, out markedSpan);

            workspace = new DiagnosticTestBase.TestWorkspace();
            var projectId  = ProjectId.CreateNewId();
            var documentId = DocumentId.CreateNewId(projectId);

            if (parseOptions == null)
            {
                parseOptions = new VisualBasicParseOptions(
                    LanguageVersion.VisualBasic14,
                    DocumentationMode.Diagnose | DocumentationMode.Parse,
                    SourceCodeKind.Regular,
                    ImmutableArray.Create(
                        new KeyValuePair <string, object>("DEBUG", null),
                        new KeyValuePair <string, object>("TEST", null))
                    );
            }
            //workspace.Options.WithChangedOption(VisualBasicFormattingOptions.NewLinesForBracesInControlBlocks, false);
            workspace.Open(ProjectInfo.Create(
                               projectId,
                               VersionStamp.Create(),
                               "TestProject",
                               "TestProject",
                               LanguageNames.VisualBasic,
                               null,
                               null,
                               new VisualBasicCompilationOptions(
                                   OutputKind.DynamicallyLinkedLibrary,
                                   "",
                                   "",
                                   "Script",
                                   null,
                                   null,
                                   OptionStrict.Off,
                                   true,
                                   true,
                                   false,
                                   parseOptions
                                   ),
                               parseOptions,
                               new[] {
                DocumentInfo.Create(
                    documentId,
                    "a.cs",
                    null,
                    SourceCodeKind.Regular,
                    TextLoader.From(TextAndVersion.Create(SourceText.From(text), VersionStamp.Create()))
                    )
            },
                               null,
                               DiagnosticTestBase.DefaultMetadataReferences
                               )
                           );
            doc = workspace.CurrentSolution.GetProject(projectId).GetDocument(documentId);
            var actions = new List <CodeAction>();
            var context = new CodeRefactoringContext(doc, selectedSpan, actions.Add, default(CancellationToken));

            action.ComputeRefactoringsAsync(context).Wait();
            if (markedSpan.Start > 0)
            {
                foreach (var nra in actions.OfType <NRefactoryCodeAction>())
                {
                    Assert.AreEqual(markedSpan, nra.TextSpan, "Activation span does not match.");
                }
            }
            return(actions);
        }
Exemplo n.º 18
0
        static List <CodeAction> GetActions(CodeRefactoringProvider action, string input, out CSharpDiagnosticTestBase.TestWorkspace workspace, out Document doc, CSharpParseOptions parseOptions = null)
        {
            TextSpan selectedSpan;
            TextSpan markedSpan;
            string   text = ParseText(input, out selectedSpan, out markedSpan);

            workspace = new CSharpDiagnosticTestBase.TestWorkspace();
            var projectId  = ProjectId.CreateNewId();
            var documentId = DocumentId.CreateNewId(projectId);

            if (parseOptions == null)
            {
                parseOptions = new CSharpParseOptions(
                    LanguageVersion.CSharp6,
                    DocumentationMode.Diagnose | DocumentationMode.Parse,
                    SourceCodeKind.Regular,
                    ImmutableArray.Create("DEBUG", "TEST")
                    );
            }
            workspace.Options = workspace.Options
                                .WithChangedOption(CSharpFormattingOptions.NewLinesForBracesInControlBlocks, true)
                                .WithChangedOption(SimplificationOptions.PreferIntrinsicPredefinedTypeKeywordInDeclaration, LanguageNames.CSharp, true)
                                .WithChangedOption(SimplificationOptions.PreferIntrinsicPredefinedTypeKeywordInMemberAccess, LanguageNames.CSharp, true);
            workspace.Open(ProjectInfo.Create(
                               projectId,
                               VersionStamp.Create(),
                               "TestProject",
                               "TestProject",
                               LanguageNames.CSharp,
                               null,
                               null,
                               new CSharpCompilationOptions(
                                   OutputKind.DynamicallyLinkedLibrary,
                                   false,
                                   "",
                                   "",
                                   "Script",
                                   null,
                                   OptimizationLevel.Debug,
                                   false,
                                   true
                                   ),
                               parseOptions,
                               new[] {
                DocumentInfo.Create(
                    documentId,
                    "a.cs",
                    null,
                    SourceCodeKind.Regular,
                    TextLoader.From(TextAndVersion.Create(SourceText.From(text), VersionStamp.Create()))
                    )
            },
                               null,
                               DiagnosticTestBase.DefaultMetadataReferences
                               )
                           );
            doc = workspace.CurrentSolution.GetProject(projectId).GetDocument(documentId);
            var actions = new List <CodeAction>();
            var context = new CodeRefactoringContext(doc, selectedSpan, actions.Add, default(CancellationToken));

            action.ComputeRefactoringsAsync(context).Wait();
            if (markedSpan.Start > 0)
            {
                foreach (var nra in actions.OfType <NRefactoryCodeAction>())
                {
                    Assert.True(markedSpan == nra.TextSpan, "Activation span does not match.");
                }
            }
            return(actions);
        }
 // Helpers/Refactoring
 private static async Task GetRefactoringActionsAsync(CodeRefactoringProvider refactorer, Document document, List <CodeAction> actions, CancellationToken cancellationToken)
 {
     var root    = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false) ?? throw new Exception("Document is not found");;
     var context = new CodeRefactoringContext(document, root.FullSpan, action => actions.Add(action), cancellationToken);
     await refactorer.ComputeRefactoringsAsync(context).ConfigureAwait(false);
 }