예제 #1
0
        public static void ExtractMethodTest(string codeText)
        {
            if (ParseDesc(codeText).StartsWith("Ignore", true, null)) // TODO: Would be better to assign TestOutcome.Ignored to the TestCase instance directly.
            {
                Assert.Ignore();
            }

            var parser = ParseCSharp(codeText);

            var targetMethod   = parser.CompilationUnit.FindMethod("Target");
            var expectedMethod = parser.CompilationUnit.FindMethod("Expected");

            var markedUpSection = FindMarkedUpAstSection(targetMethod, parser.Lexer.SpecialTracker.RetrieveSpecials());

            CSharpMethodExtractor extractor = new CSharpMethodExtractor();
            var success = extractor.Extract(targetMethod, markedUpSection.Window);

            Assert.IsTrue(success, "The extract method operation failed.");

            TestLog.EmbedPlainText("Target", targetMethod.Print());
            TestLog.EmbedPlainText("Expected", expectedMethod.Print());
            TestLog.EmbedPlainText("Actual extracted", extractor.ExtractedMethod.Print());

            Assert.IsTrue(expectedMethod.Matches(extractor.ExtractedMethod), "Expected the extracted method to match method named 'Expected'");
        }
예제 #2
0
        public static MethodDeclaration ExtractMethod(MethodDeclaration md, Window window)
        {
            CSharpMethodExtractor extractor = new CSharpMethodExtractor();

            extractor.Extract(md, window);
            return(extractor.ExtractedMethod);
        }
예제 #3
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 void CanBePerformedOnArbitrarilyDeepNodes()
        {
            const string codeText      = @"                
                using System;
                public class One
                {
                    void Foo()
                    {
                        double w = 7;
                        double l = 8;

                        if (DateTime.Now.Day == 3)
                        {
                            Console.WriteLine(""stuff"");
                            Console.WriteLine(""stuff"");
                        }
                        double area = l*w;
                    }
                    void Bar()
                    {
                        Console.WriteLine(""stuff"");                        
                    }
                }";
            var          code_text_ast = AstMatchHelper.ParseToCompilationUnit(codeText);

            IndexableMethodFinderVisitor v = new IndexableMethodFinderVisitor();

            code_text_ast.AcceptVisitor(v, null);
            MethodDeclaration method = v.Methods["Foo"];

            FindFirstIfElseVisitor v2 = new FindFirstIfElseVisitor();

            method.AcceptVisitor(v2, null);
            IfElseStatement ifelse_stmt = v2.IfElse;

            List <Statement> statements = ifelse_stmt.TrueStatement;

            Assert.AreEqual(1, statements.Count,
                            "Expect TrueStatement to always return a single element, and it's a block.");
            Assert.IsInstanceOf <BlockStatement>(statements[0], "Expect TrueStatement to always return a single element, and it's a block.");

            BlockStatement block = (BlockStatement)statements[0];

            CSharpMethodExtractor extractor = new CSharpMethodExtractor();
            var success = extractor.Extract(method, new Window(0, 0), block.Children);

            Assert.IsTrue(success);

            Console.WriteLine(extractor.ExtractedMethod.Print());

            MethodDeclaration expected_method = v.BarMethod;

            Assert.IsTrue(expected_method.Matches(extractor.ExtractedMethod),
                          "The expected AST did not match the actual extracted AST.\nExpected: {0} \nActual:{1}",
                          expected_method.Print(), extractor.ExtractedMethod.Print());
        }
예제 #5
0
 public static MethodDeclaration ExtractMethod(MethodDeclaration md, Window window, List <INode> children)
 {
     try
     {
         CSharpMethodExtractor extractor = new CSharpMethodExtractor();
         extractor.Extract(md, window, children);
         return(extractor.ExtractedMethod);
     }
     catch (Exception ex)
     {
         throw new Exception("Window: " + window + " Method: " + md.Print(), ex);
     }
 }
        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);
            }
        }
        private void RunWhitespaceTest(string whitespace)
        {
            var target = AstMatchHelper.ParseToMethodDeclaration(
                string.Format(@"public void Target()
                    {{
                        int x = 7;
                        Console.WriteLine(x);
                        Console.WriteLine(x);
                    {0}}}", whitespace));

            CSharpMethodExtractor extractor = new CSharpMethodExtractor();

            extractor.Extract(target, new Window(1, 2));

            Assert.AreEqual(1, extractor.ExtractedMethod.Parameters.Count, "Expected a new method with exactly one parameter.");
        }
예제 #8
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());
        }
예제 #9
0
        internal static CloneDesc ExtractMethodAsCloneDesc(Window window, MethodDeclaration right, List <INode> children)
        {
            CSharpMethodExtractor extractor = new CSharpMethodExtractor();

            extractor.Extract(right, window, children);

            MethodDeclaration md = extractor.ExtractedMethod;

            if (md != null)
            {
                return new CloneDesc(md, window, children)
                       {
                           ReplacementInvocation = extractor.GetCall(right, md, new VariableDeclaration("heyman"))
                       }
            }
            ;
            return(null);
        }
예제 #10
0
        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);
        }