コード例 #1
0
        private async Task <CodeRefactoring> GetRefactoringFromProvider(
            CodeRefactoringProvider provider,
            IExtensionManager extensionManager,
            CodeRefactoringContext context)
        {
            context.CancellationToken.ThrowIfCancellationRequested();
            if (extensionManager.IsDisabled(provider))
            {
                return(null);
            }

            try
            {
                var actions = await provider.GetRefactoringsAsync(context).ConfigureAwait(false);

                if (actions != null && actions.Count() > 0)
                {
                    return(new CodeRefactoring(provider, actions));
                }
            }
            catch (OperationCanceledException)
            {
                // We don't want to catch operation canceled exceptions in the catch block
                // below. So catch is here and rethrow it.
                throw;
            }
            catch (Exception e)
            {
                extensionManager.HandleException(provider, e);
            }

            return(null);
        }
コード例 #2
0
        protected string RunContextAction(CodeRefactoringProvider action, string input, int actionIndex = 0, bool expectErrors = false, CSharpParseOptions parseOptions = null)
        {
            Document doc;

            CSharpDiagnosticTestBase.TestWorkspace workspace;
            var actions = GetActions(action, input, out workspace, out doc, parseOptions);

            if (actions.Count < actionIndex)
            {
                Console.WriteLine("invalid input is:" + input);
            }
            var a = actions[actionIndex];

            foreach (var op in a.GetOperationsAsync(default(CancellationToken)).Result)
            {
                op.Apply(workspace, default(CancellationToken));
            }
            var result = workspace.CurrentSolution.GetDocument(doc.Id).GetTextAsync().Result.ToString();

            if (Environment.NewLine != "\r\n")
            {
                result = result.Replace("\r\n", Environment.NewLine);
            }
            return(result);
        }
コード例 #3
0
        public static void VerifyRefactoring(
            string source,
            string[] additionalSources,
            string newSource,
            IEnumerable <TextSpan> spans,
            CodeRefactoringProvider refactoringProvider,
            string language,
            string equivalenceKey            = null,
            bool allowNewCompilerDiagnostics = false)
        {
            Document document = WorkspaceFactory.CreateDocument(source, additionalSources, language);

            foreach (TextSpan span in spans.OrderByDescending(f => f.Start))
            {
                document = VerifyRefactoring(
                    document: document,
                    span: span,
                    refactoringProvider: refactoringProvider,
                    equivalenceKey: equivalenceKey,
                    allowNewCompilerDiagnostics: allowNewCompilerDiagnostics);
            }

            string actual = document.ToSimplifiedAndFormattedFullString();

            Assert.Equal(newSource, actual);
        }
コード例 #4
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}");
        }
コード例 #5
0
        /// <summary>
        /// For testing a <see cref="CodeRefactoringProvider"/>.
        /// </summary>
        /// <param name="refactoring">The <see cref="CodeRefactoringProvider"/>.</param>
        /// <param name="before">The code to analyze with <paramref name="refactoring"/>. Position is provided by <paramref name="span"/>.</param>
        /// <param name="span">A <see cref="TextSpan"/> indicating the position.</param>
        /// <param name="after">The expected code produced by <paramref name="refactoring"/>.</param>
        /// <param name="title">The title of the refactoring to apply.</param>
        public static void Refactoring(CodeRefactoringProvider refactoring, string before, TextSpan span, string after, string title)
        {
#pragma warning disable CS0618 // Suppress until removed. Will be replaced with Metadatareferences.FromAttributes()
            var refactored = Refactor.Apply(refactoring, before, span, title, MetadataReferences);
#pragma warning restore CS0618 // Suppress until removed. Will be replaced with Metadatareferences.FromAttributes()
            CodeAssert.AreEqual(after, refactored);
        }
コード例 #6
0
        /// <summary>
        /// Apply the single refactoring registered at <paramref name="position"/>.
        /// </summary>
        /// <param name="refactoring">The <see cref="CodeRefactoringProvider"/>.</param>
        /// <param name="testCode">The code to refactor.</param>
        /// <param name="position">The position to pass in to the RefactoringContext.</param>
        /// <param name="index">The index of the refactoring to apply.</param>
        /// <param name="metadataReferences">The <see cref="MetadataReference"/> to use when compiling.</param>
        /// <returns>The refactored document.</returns>
        public static Document Apply(CodeRefactoringProvider refactoring, string testCode, int position, int index, IEnumerable <MetadataReference> metadataReferences = null)
        {
            if (refactoring == null)
            {
                throw new ArgumentNullException(nameof(refactoring));
            }

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

            var actions = CodeActions(refactoring, testCode, position, metadataReferences);

            if (actions.Count == 0)
            {
                throw new InvalidOperationException("The refactoring did not register any refactorings at the current position.");
            }

            if (actions.Count < index)
            {
                throw new InvalidOperationException("The refactoring did not register a refactoring for the current index.");
            }

            var edit = actions[index].GetOperationsAsync(CancellationToken.None).GetAwaiter().GetResult().OfType <ApplyChangesOperation>().First();

            return(edit.ChangedSolution.Projects.Single().Documents.Single());
        }
コード例 #7
0
        /// <summary>
        /// Apply the single refactoring registered at <paramref name="span"/>.
        /// </summary>
        /// <param name="refactoring">The <see cref="CodeRefactoringProvider"/>.</param>
        /// <param name="testCode">The code to refactor.</param>
        /// <param name="span">The position to pass in to the RefactoringContext.</param>
        /// <param name="metadataReferences">The <see cref="MetadataReference"/> to use when compiling.</param>
        /// <returns>The refactored document.</returns>
        public static Document Apply(CodeRefactoringProvider refactoring, string testCode, TextSpan span, IEnumerable <MetadataReference> metadataReferences = null)
        {
            if (refactoring == null)
            {
                throw new ArgumentNullException(nameof(refactoring));
            }

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

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

            var actions = CodeActions(refactoring, testCode, span, metadataReferences);

            switch (actions.Count)
            {
            case 0:
                throw new InvalidOperationException("The refactoring did not register any refactorings at the current position.");

            case 1:
                var edit = actions[0].GetOperationsAsync(CancellationToken.None).Result.OfType <ApplyChangesOperation>().First();
                return(edit.ChangedSolution.Projects.Single().Documents.Single());

            default:
                throw new NotSupportedException("More than one action available. Currently not supporting invoking action by index. We should add support for it.");
            }
        }
コード例 #8
0
        /// <summary>
        /// For testing a <see cref="CodeRefactoringProvider"/>.
        /// </summary>
        /// <param name="refactoring">The <see cref="CodeRefactoringProvider"/>.</param>
        /// <param name="codeWithPositionIndicated">The code to refactor with position indicated with ↓.</param>
        /// <param name="title">The title of the refactoring to apply.</param>
        /// <param name="fixedCode">The expected code produced by the refactoring.</param>
        public static void Refactoring(CodeRefactoringProvider refactoring, string codeWithPositionIndicated, string title, string fixedCode)
        {
            var position   = GetPosition(codeWithPositionIndicated, out var testCode);
            var refactored = Refactor.Apply(refactoring, testCode, position, title, MetadataReferences);

            CodeAssert.AreEqual(refactored, fixedCode);
        }
コード例 #9
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);
        }
コード例 #10
0
        public static void VerifyRefactoring(
            string sourceTemplate,
            string fixableCode,
            string fixedCode,
            CodeRefactoringProvider refactoringProvider,
            string equivalenceKey            = null,
            bool allowNewCompilerDiagnostics = false)
        {
            (string source, string newSource, TextSpan span) = TextUtility.GetMarkedSpan(sourceTemplate, fixableCode, fixedCode);

            (string source2, List <TextSpan> spans) = TextUtility.GetMarkedSpans(source);

            if (spans != null)
            {
                source = source2;
                span   = spans[0];
            }

            CodeRefactoringVerifier.VerifyRefactoring(
                source: source,
                newSource: newSource,
                span: span,
                refactoringProvider: refactoringProvider,
                language: LanguageNames.CSharp,
                equivalenceKey: equivalenceKey,
                allowNewCompilerDiagnostics: allowNewCompilerDiagnostics);
        }
        public static void ShouldNotProvideRefactoring(this CodeRefactoringProvider provider, string sourceCode)
        {
            var document     = GetDocument(sourceCode);
            var span         = new TextSpan(0, sourceCode.Length);
            var refactorings = GetCodeRefactorings(provider, document, span);

            refactorings.Length.Should().Be(0);
        }
コード例 #12
0
 /// <summary>
 /// Gets the roslyn code action provider.
 /// </summary>
 public CodeRefactoringProvider GetProvider()
 {
     if (instance == null)
     {
         instance = (CodeRefactoringProvider)Activator.CreateInstance(codeActionType);
     }
     return(instance);
 }
コード例 #13
0
        public static async Task <(Project, CodeAction)[]> RefactorAsync(CodeRefactoringProvider refactorer, Document document, CancellationToken cancellationToken)
        {
            var actions = new List <CodeAction>();

            await GetRefactoringActionsAsync(refactorer, document, actions, cancellationToken).ConfigureAwait(false);

            return(await ApplyCodeActionsAsync(actions, cancellationToken).ConfigureAwait(false));
        }
コード例 #14
0
 public RefactoringContext(Document document, CodeRefactoringProvider refactoring, int position)
 {
     this.Document    = document;
     this.Refactoring = refactoring;
     this.Position    = position;
     this.SyntaxRoot  = document.GetSyntaxRootAsync(CancellationToken.None).GetAwaiter().GetResult();
     this.actions     = new List <CodeAction>();
 }
コード例 #15
0
 public CodeRefactoringSuggestedAction(
     Workspace workspace,
     ITextBuffer subjectBuffer,
     ICodeActionEditHandlerService editHandler,
     CodeAction codeAction,
     CodeRefactoringProvider provider)
     : base(workspace, subjectBuffer, editHandler, codeAction, provider)
 {
 }
コード例 #16
0
 public CodeRefactoringSuggestedAction(
     SuggestedActionsSourceProvider sourceProvider,
     Workspace workspace,
     ITextBuffer subjectBuffer,
     CodeRefactoringProvider provider,
     CodeAction codeAction)
     : base(sourceProvider, workspace, subjectBuffer, provider, codeAction)
 {
 }
コード例 #17
0
        /// <summary>
        /// For testing a <see cref="CodeRefactoringProvider"/>.
        /// </summary>
        /// <param name="refactoring">The <see cref="CodeRefactoringProvider"/>.</param>
        /// <param name="before">The code to analyze with <paramref name="refactoring"/>. Indicate position with ↓ (alt + 25).</param>
        /// <param name="after">The expected code produced by <paramref name="refactoring"/>.</param>
        public static void Refactoring(CodeRefactoringProvider refactoring, string before, string after)
        {
            var position = GetPosition(before, out var testCode);

#pragma warning disable CS0618 // Suppress until removed. Will be replaced with Metadatareferences.FromAttributes()
            var refactored = Refactor.Apply(refactoring, testCode, position, MetadataReferences);
#pragma warning restore CS0618 // Suppress until removed. Will be replaced with Metadatareferences.FromAttributes()
            CodeAssert.AreEqual(after, refactored);
        }
コード例 #18
0
 public UnifiedCodeRefactoringSuggestedAction(
     Workspace workspace,
     CodeAction codeAction,
     CodeActionPriority codeActionPriority,
     CodeRefactoringProvider codeRefactoringProvider)
     : base(workspace, codeAction, codeActionPriority)
 {
     CodeRefactoringProvider = codeRefactoringProvider;
 }
コード例 #19
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);
        }
コード例 #20
0
        protected void TestWrongContext(CodeRefactoringProvider action, string input)
        {
            Document doc;

            RefactoringEssentials.Tests.CSharp.Diagnostics.CSharpDiagnosticTestBase.TestWorkspace workspace;
            var actions = GetActions(action, input, out workspace, out doc);

            Assert.True(actions == null || actions.Count == 0, action.GetType() + " shouldn't be valid there.");
        }
コード例 #21
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);
        }
コード例 #22
0
        /// <summary>
        /// For testing a <see cref="CodeRefactoringProvider"/>.
        /// </summary>
        /// <param name="refactoring">The <see cref="CodeRefactoringProvider"/>.</param>
        /// <param name="code">The code to analyze with <paramref name="refactoring"/>. Position is provided by <paramref name="span"/>.</param>
        /// <param name="span">A <see cref="TextSpan"/> indicating the position.</param>
        /// <param name="title">The title of the refactoring to apply.</param>
        public static void NoRefactoring(CodeRefactoringProvider refactoring, string code, TextSpan span, string title)
        {
#pragma warning disable CS0618 // Suppress until removed. Will be replaced with Metadatareferences.FromAttributes()
            var actions = Refactor.CodeActions(refactoring, code, span, MetadataReferences);
#pragma warning restore CS0618 // Suppress until removed. Will be replaced with Metadatareferences.FromAttributes()
            if (actions.Any(x => x.Title == title))
            {
                throw new AssertException("Expected the refactoring to not register any code actions.");
            }
        }
コード例 #23
0
        public CodeRefactoring(CodeRefactoringProvider provider, IEnumerable <CodeAction> actions)
        {
            _provider = provider;
            _actions  = actions.ToImmutableArray();

            if (_actions.Count == 0)
            {
                throw new ArgumentException("Actions can not be empty", "actions");
            }
        }
コード例 #24
0
 public CodeRefactoringSuggestedAction(
     IThreadingContext threadingContext,
     SuggestedActionsSourceProvider sourceProvider,
     Workspace workspace,
     ITextBuffer subjectBuffer,
     CodeRefactoringProvider provider,
     CodeAction codeAction)
     : base(threadingContext, sourceProvider, workspace, subjectBuffer, provider, codeAction)
 {
 }
コード例 #25
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());
        }
コード例 #27
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)
 {
 }
コード例 #28
0
 public UnifiedCodeRefactoringSuggestedAction(
     Workspace workspace,
     CodeAction codeAction,
     CodeActionPriority codeActionPriority,
     CodeRefactoringProvider codeRefactoringProvider,
     UnifiedSuggestedActionSet?fixAllFlavors)
     : base(workspace, codeAction, codeActionPriority)
 {
     CodeRefactoringProvider = codeRefactoringProvider;
     FixAllFlavors           = fixAllFlavors;
 }
コード例 #29
0
 public CodeRefactoringSuggestedAction(
     IThreadingContext threadingContext,
     SuggestedActionsSourceProvider sourceProvider,
     Workspace workspace,
     ITextBuffer subjectBuffer,
     CodeRefactoringProvider provider,
     CodeAction codeAction,
     SuggestedActionSet fixAllFlavors)
     : base(threadingContext, sourceProvider, workspace, subjectBuffer, provider, codeAction, fixAllFlavors)
 {
     CodeRefactoringProvider = provider;
 }
コード例 #30
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."),
            });