protected void IterateAll(string code)
        {
            using (var workspace = CSharpWorkspaceFactory.CreateWorkspaceFromLines(new string[] { code }, CodeAnalysis.CSharp.Test.Utilities.TestOptions.Regular))
            {
                var document = workspace.CurrentSolution.GetDocument(workspace.Documents.First().Id);
                Assert.NotNull(document);

                var semanticDocument = SemanticDocument.CreateAsync(document, CancellationToken.None).Result;
                var tree             = document.GetSyntaxTreeAsync().Result;
                var iterator         = tree.GetRoot().DescendantNodesAndSelf().Cast <SyntaxNode>();

                var options = document.Project.Solution.Workspace.Options
                              .WithChangedOption(ExtractMethodOptions.AllowMovingDeclaration, document.Project.Language, true);

                foreach (var node in iterator)
                {
                    try
                    {
                        var validator = new CSharpSelectionValidator(semanticDocument, node.Span, options);
                        var result    = validator.GetValidSelectionAsync(CancellationToken.None).Result;

                        // check the obvious case
                        if (!(node is ExpressionSyntax) && !node.UnderValidContext())
                        {
                            Assert.True(result.Status.FailedWithNoBestEffortSuggestion());
                        }
                    }
                    catch (ArgumentException)
                    {
                        // catch and ignore unknown issue. currently control flow analysis engine doesn't support field initializer.
                    }
                }
            }
        }
Exemple #2
0
        protected static async Task IterateAllAsync(string code)
        {
            using var workspace = TestWorkspace.CreateCSharp(code, CodeAnalysis.CSharp.Test.Utilities.TestOptions.Regular);
            var document = workspace.CurrentSolution.GetDocument(workspace.Documents.First().Id);

            Assert.NotNull(document);

            var semanticDocument = await SemanticDocument.CreateAsync(document, CancellationToken.None);

            var root = await document.GetSyntaxRootAsync();

            var iterator = root.DescendantNodesAndSelf().Cast <SyntaxNode>();

            var originalOptions = await document.GetOptionsAsync();

            foreach (var node in iterator)
            {
                var validator = new CSharpSelectionValidator(semanticDocument, node.Span, originalOptions);
                var result    = await validator.GetValidSelectionAsync(CancellationToken.None);

                // check the obvious case
                if (!(node is ExpressionSyntax) && !node.UnderValidContext())
                {
                    Assert.True(result.Status.FailedWithNoBestEffortSuggestion());
                }
            }
        }
        protected void TestSelection(string codeWithMarker, bool expectedFail = false, CSharpParseOptions parseOptions = null)
        {
            using (var workspace = CSharpWorkspaceFactory.CreateWorkspaceFromLines(new[] { codeWithMarker }, parseOptions: parseOptions))
            {
                var testDocument = workspace.Documents.Single();
                var namedSpans   = testDocument.AnnotatedSpans;

                var document = workspace.CurrentSolution.GetDocument(testDocument.Id);
                Assert.NotNull(document);

                var options = document.Project.Solution.Workspace.Options
                              .WithChangedOption(ExtractMethodOptions.AllowMovingDeclaration, document.Project.Language, true);

                var semanticDocument = SemanticDocument.CreateAsync(document, CancellationToken.None).Result;
                var validator        = new CSharpSelectionValidator(semanticDocument, namedSpans["b"].Single(), options);
                var result           = validator.GetValidSelectionAsync(CancellationToken.None).Result;

                Assert.True(expectedFail ? result.Status.Failed() : result.Status.Succeeded());

                if ((result.Status.Succeeded() || result.Status.Flag.HasBestEffort()) && result.Status.Flag.HasSuggestion())
                {
                    Assert.Equal(namedSpans["r"].Single(), result.FinalSpan);
                }
            }
        }
        public static async Task <bool> IsValid(MonoDevelop.Ide.Gui.Document doc, CancellationToken cancellationToken = default(CancellationToken))
        {
            if (doc == null)
            {
                return(false);
            }
            if (doc.Editor == null || !doc.Editor.IsSomethingSelected)
            {
                return(false);
            }
            var ad = doc.AnalysisDocument;

            if (ad == null)
            {
                return(false);
            }
            var selectionRange = doc.Editor.SelectionRange;

            try {
                var selection = new CSharpSelectionValidator(await SemanticDocument.CreateAsync(ad, cancellationToken).ConfigureAwait(false), new TextSpan(selectionRange.Offset, selectionRange.Length), doc.GetOptionSet());
                var result    = await selection.GetValidSelectionAsync(cancellationToken).ConfigureAwait(false);

                return(result.ContainsValidContext);
            } catch (Exception) {
                return(false);
            }
        }
Exemple #5
0
        protected static async Task <SyntaxNode> ExtractMethodAsync(
            TestWorkspace workspace,
            TestHostDocument testDocument,
            bool succeed = true,
            bool dontPutOutOrRefOnStruct = true,
            bool allowBestEffort         = false
            )
        {
            var document = workspace.CurrentSolution.GetDocument(testDocument.Id);

            Assert.NotNull(document);

            var originalOptions = await document.GetOptionsAsync();

            var options = originalOptions.WithChangedOption(
                ExtractMethodOptions.DontPutOutOrRefOnStruct,
                document.Project.Language,
                dontPutOutOrRefOnStruct
                );

            var semanticDocument = await SemanticDocument.CreateAsync(
                document,
                CancellationToken.None
                );

            var validator = new CSharpSelectionValidator(
                semanticDocument,
                testDocument.SelectedSpans.Single(),
                options
                );

            var selectedCode = await validator.GetValidSelectionAsync(CancellationToken.None);

            if (!succeed && selectedCode.Status.FailedWithNoBestEffortSuggestion())
            {
                return(null);
            }

            Assert.True(selectedCode.ContainsValidContext);

            // extract method
            var extractor = new CSharpMethodExtractor(
                (CSharpSelectionResult)selectedCode,
                localFunction: false
                );
            var result = await extractor.ExtractMethodAsync(CancellationToken.None);

            Assert.NotNull(result);
            Assert.Equal(
                succeed,
                result.Succeeded ||
                result.SucceededWithSuggestion ||
                (allowBestEffort && result.Status.HasBestEffort())
                );

            var doc = result.Document;

            return(doc == null ? null : await doc.GetSyntaxRootAsync());
        }
        public async static Task Run(MonoDevelop.Ide.Gui.Document doc)
        {
            if (!doc.Editor.IsSomethingSelected)
            {
                return;
            }
            var ad = doc.AnalysisDocument;

            if (ad == null || !await IsValid(doc))
            {
                return;
            }
            try {
                var selectionRange = doc.Editor.SelectionRange;
                var token          = default(CancellationToken);
                var selection      = new CSharpSelectionValidator(await SemanticDocument.CreateAsync(ad, token).ConfigureAwait(false), new TextSpan(selectionRange.Offset, selectionRange.Length), doc.GetOptionSet());
                var result         = await selection.GetValidSelectionAsync(token).ConfigureAwait(false);

                if (!result.ContainsValidContext)
                {
                    return;
                }
                var extractor        = new CSharpMethodExtractor((CSharpSelectionResult)result);
                var extractionResult = await extractor.ExtractMethodAsync(token).ConfigureAwait(false);

                var changes = await extractionResult.Document.GetTextChangesAsync(ad, token);

                using (var undo = doc.Editor.OpenUndoGroup()) {
                    foreach (var change in changes.OrderByDescending(ts => ts.Span.Start))
                    {
                        doc.Editor.ReplaceText(change.Span.Start, change.Span.Length, change.NewText);
                    }
                    // hack to remove the redundant private modifier.
                    if (doc.Editor.GetTextAt(extractionResult.MethodDeclarationNode.SpanStart, "private ".Length) == "private ")
                    {
                        doc.Editor.RemoveText(extractionResult.MethodDeclarationNode.SpanStart, "private ".Length);
                    }
                }
                await doc.UpdateParseDocument();

                var info = RefactoringSymbolInfo.GetSymbolInfoAsync(doc, extractionResult.InvocationNameToken.Span.Start).Result;
                var sym  = info.DeclaredSymbol ?? info.Symbol;
                if (sym != null)
                {
                    await new MonoDevelop.Refactoring.Rename.RenameRefactoring().Rename(sym);
                }
            }
            catch (Exception e) {
                LoggingService.LogError("Error while extracting method", e);
            }
        }
Exemple #7
0
        protected static async Task <SyntaxNode> ExtractMethodAsync(
            TestWorkspace workspace,
            TestHostDocument testDocument,
            bool succeed = true,
            bool dontPutOutOrRefOnStruct = true,
            bool allowBestEffort         = false)
        {
            var document = workspace.CurrentSolution.GetDocument(testDocument.Id);

            Assert.NotNull(document);

            var options = new ExtractMethodGenerationOptions(
                ExtractOptions: new ExtractMethodOptions(dontPutOutOrRefOnStruct),
                CodeGenerationOptions: CodeGenerationOptions.GetDefault(document.Project.LanguageServices),
                AddImportOptions: AddImportPlacementOptions.Default,
                NamingPreferences: _ => NamingStylePreferences.Default);

            var semanticDocument = await SemanticDocument.CreateAsync(document, CancellationToken.None);

            var validator = new CSharpSelectionValidator(semanticDocument, testDocument.SelectedSpans.Single(), options.ExtractOptions, localFunction: false);

            var selectedCode = await validator.GetValidSelectionAsync(CancellationToken.None);

            if (!succeed && selectedCode.Status.FailedWithNoBestEffortSuggestion())
            {
                return(null);
            }

            Assert.True(selectedCode.ContainsValidContext);

            // extract method
            var extractor = new CSharpMethodExtractor((CSharpSelectionResult)selectedCode, options, localFunction: false);
            var result    = await extractor.ExtractMethodAsync(CancellationToken.None);

            Assert.NotNull(result);
            Assert.Equal(succeed,
                         result.Succeeded ||
                         result.SucceededWithSuggestion ||
                         (allowBestEffort && result.Status.HasBestEffort()));

            var(doc, _) = await result.GetFormattedDocumentAsync(CodeCleanupOptions.GetDefault(document.Project.LanguageServices), CancellationToken.None);

            return(doc == null
                ? null
                : await doc.GetSyntaxRootAsync());
        }
Exemple #8
0
        protected static async Task TestSelectionAsync(
            string codeWithMarker,
            bool expectedFail = false,
            CSharpParseOptions parseOptions = null,
            TextSpan?textSpanOverride       = null
            )
        {
            using var workspace = TestWorkspace.CreateCSharp(
                      codeWithMarker,
                      parseOptions: parseOptions
                      );
            var testDocument = workspace.Documents.Single();
            var namedSpans   = testDocument.AnnotatedSpans;

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

            Assert.NotNull(document);

            var options = await document.GetOptionsAsync(CancellationToken.None);

            var semanticDocument = await SemanticDocument.CreateAsync(
                document,
                CancellationToken.None
                );

            var validator = new CSharpSelectionValidator(
                semanticDocument,
                textSpanOverride ?? namedSpans["b"].Single(),
                options
                );
            var result = await validator.GetValidSelectionAsync(CancellationToken.None);

            Assert.True(expectedFail ? result.Status.Failed() : result.Status.Succeeded());

            if (
                (result.Status.Succeeded() || result.Status.Flag.HasBestEffort()) &&
                result.Status.Flag.HasSuggestion()
                )
            {
                Assert.Equal(namedSpans["r"].Single(), result.FinalSpan);
            }
        }
        protected static SyntaxNode ExtractMethod(
            TestWorkspace workspace,
            TestHostDocument testDocument,
            bool succeed = true,
            bool allowMovingDeclaration  = true,
            bool dontPutOutOrRefOnStruct = true)
        {
            var document = workspace.CurrentSolution.GetDocument(testDocument.Id);

            Assert.NotNull(document);

            var options = document.Project.Solution.Workspace.Options
                          .WithChangedOption(ExtractMethodOptions.AllowMovingDeclaration, document.Project.Language, allowMovingDeclaration)
                          .WithChangedOption(ExtractMethodOptions.DontPutOutOrRefOnStruct, document.Project.Language, dontPutOutOrRefOnStruct);

            var semanticDocument = SemanticDocument.CreateAsync(document, CancellationToken.None).Result;
            var validator        = new CSharpSelectionValidator(semanticDocument, testDocument.SelectedSpans.Single(), options);

            var selectedCode = validator.GetValidSelectionAsync(CancellationToken.None).Result;

            if (!succeed && selectedCode.Status.FailedWithNoBestEffortSuggestion())
            {
                return(null);
            }

            Assert.True(selectedCode.ContainsValidContext);

            // extract method
            var extractor = new CSharpMethodExtractor((CSharpSelectionResult)selectedCode);
            var result    = extractor.ExtractMethodAsync(CancellationToken.None).Result;

            Assert.NotNull(result);
            Assert.Equal(succeed, result.Succeeded || result.SucceededWithSuggestion);

            return((SyntaxNode)result.Document.GetSyntaxRootAsync().Result);
        }