From 3ac3edd1bdc1d2e5e98d6a558ae20dc7c56c4b15 Mon Sep 17 00:00:00 2001 From: Alexey Sedunov Date: Thu, 24 Apr 2014 19:06:15 +0400 Subject: [PATCH] Extract Function: Allow to select fragments which start with comment --- .../jet/plugin/codeInsight/CodeInsightUtils.java | 15 ++++----------- .../refactoring/extractFunction/ExtractionData.kt | 9 ++++++++- .../extractFunction/extractFunctionUtils.kt | 5 +---- .../extractFunction/basic/fragmentWithComment.kt | 7 +++++++ .../basic/fragmentWithComment.kt.after | 12 ++++++++++++ .../basic/fragmentWithMultilineComment.kt | 9 +++++++++ .../basic/fragmentWithMultilineComment.kt.after | 14 ++++++++++++++ .../JetExtractionTestGenerated.java | 10 ++++++++++ 8 files changed, 65 insertions(+), 16 deletions(-) create mode 100644 idea/testData/refactoring/extractFunction/basic/fragmentWithComment.kt create mode 100644 idea/testData/refactoring/extractFunction/basic/fragmentWithComment.kt.after create mode 100644 idea/testData/refactoring/extractFunction/basic/fragmentWithMultilineComment.kt create mode 100644 idea/testData/refactoring/extractFunction/basic/fragmentWithMultilineComment.kt.after diff --git a/idea/src/org/jetbrains/jet/plugin/codeInsight/CodeInsightUtils.java b/idea/src/org/jetbrains/jet/plugin/codeInsight/CodeInsightUtils.java index 982549b5652..bf3d6ff478f 100644 --- a/idea/src/org/jetbrains/jet/plugin/codeInsight/CodeInsightUtils.java +++ b/idea/src/org/jetbrains/jet/plugin/codeInsight/CodeInsightUtils.java @@ -97,18 +97,11 @@ public class CodeInsightUtils { } if (endOffset != element2.getTextRange().getEndOffset()) return PsiElement.EMPTY_ARRAY; - PsiElement[] children = parent.getChildren(); ArrayList array = new ArrayList(); - boolean flag = false; - for (PsiElement child : children) { - if (child.equals(element1)) { - flag = true; - } - if (flag && !(child instanceof PsiWhiteSpace)) { - array.add(child); - } - if (child.equals(element2)) { - break; + PsiElement stopElement = element2.getNextSibling(); + for (PsiElement currentElement = element1; currentElement != stopElement; currentElement = currentElement.getNextSibling()) { + if (!(currentElement instanceof PsiWhiteSpace)) { + array.add(currentElement); } } diff --git a/idea/src/org/jetbrains/jet/plugin/refactoring/extractFunction/ExtractionData.kt b/idea/src/org/jetbrains/jet/plugin/refactoring/extractFunction/ExtractionData.kt index 6078746f22e..86e984d8eee 100644 --- a/idea/src/org/jetbrains/jet/plugin/refactoring/extractFunction/ExtractionData.kt +++ b/idea/src/org/jetbrains/jet/plugin/refactoring/extractFunction/ExtractionData.kt @@ -106,7 +106,7 @@ class ExtractionData( } fun getBrokenReferencesInfo(body: JetBlockExpression): List { - val startOffset = body.getStatements().first!!.getTextRange()!!.getStartOffset() + val startOffset = body.getBlockContentOffset() val referencesInfo = ArrayList() for ((ref, context) in JetFileReferencesResolver.resolve(body)) { @@ -138,4 +138,11 @@ private fun compareDescriptors(d1: DeclarationDescriptor?, d2: DeclarationDescri return d1 == d2 || (d1 != null && d2 != null && DescriptorRenderer.FQ_NAMES_IN_TYPES.render(d1) == DescriptorRenderer.FQ_NAMES_IN_TYPES.render(d2)) +} + +// Hack: +// we can't get first element offset through getStatement()/getChildren() since they skip comments and whitespaces +// So we take offset of the left brace instead and increase it by 2 (which is length of "{\n" separating block start and its first element) +private fun JetBlockExpression.getBlockContentOffset(): Int { + return getLBrace()!!.getTextRange()!!.getStartOffset() + 2 } \ No newline at end of file diff --git a/idea/src/org/jetbrains/jet/plugin/refactoring/extractFunction/extractFunctionUtils.kt b/idea/src/org/jetbrains/jet/plugin/refactoring/extractFunction/extractFunctionUtils.kt index ce3992ecba9..5da9af55e42 100644 --- a/idea/src/org/jetbrains/jet/plugin/refactoring/extractFunction/extractFunctionUtils.kt +++ b/idea/src/org/jetbrains/jet/plugin/refactoring/extractFunction/extractFunctionUtils.kt @@ -681,10 +681,7 @@ fun ExtractionDescriptor.generateFunction( val exprReplacementMap = HashMap JetElement>() val originalOffsetByExpr = HashMap() - val range = body.getStatements().first?.getTextRange() - if (range == null) return - - val bodyOffset = range.getStartOffset() + val bodyOffset = body.getBlockContentOffset() val file = body.getContainingFile()!! for ((offsetInBody, resolveResult) in extractionData.refOffsetToDeclaration) { diff --git a/idea/testData/refactoring/extractFunction/basic/fragmentWithComment.kt b/idea/testData/refactoring/extractFunction/basic/fragmentWithComment.kt new file mode 100644 index 00000000000..3785a529228 --- /dev/null +++ b/idea/testData/refactoring/extractFunction/basic/fragmentWithComment.kt @@ -0,0 +1,7 @@ +// NEXT_SIBLING: +fun foo(a: Int): Int { + // test + println(a) + if (a > 0) return a + return -a +} \ No newline at end of file diff --git a/idea/testData/refactoring/extractFunction/basic/fragmentWithComment.kt.after b/idea/testData/refactoring/extractFunction/basic/fragmentWithComment.kt.after new file mode 100644 index 00000000000..47ec420ceaa --- /dev/null +++ b/idea/testData/refactoring/extractFunction/basic/fragmentWithComment.kt.after @@ -0,0 +1,12 @@ +// NEXT_SIBLING: +fun b(a: Int): Boolean { + // test + println(a) + if (a > 0) return true + return false +} + +fun foo(a: Int): Int { + if (b(a)) return a + return -a +} \ No newline at end of file diff --git a/idea/testData/refactoring/extractFunction/basic/fragmentWithMultilineComment.kt b/idea/testData/refactoring/extractFunction/basic/fragmentWithMultilineComment.kt new file mode 100644 index 00000000000..16c55e37ef9 --- /dev/null +++ b/idea/testData/refactoring/extractFunction/basic/fragmentWithMultilineComment.kt @@ -0,0 +1,9 @@ +// NEXT_SIBLING: +fun foo(a: Int): Int { + /* + test + */ + println(a) + if (a > 0) return a + return -a +} \ No newline at end of file diff --git a/idea/testData/refactoring/extractFunction/basic/fragmentWithMultilineComment.kt.after b/idea/testData/refactoring/extractFunction/basic/fragmentWithMultilineComment.kt.after new file mode 100644 index 00000000000..ebcfb60ffba --- /dev/null +++ b/idea/testData/refactoring/extractFunction/basic/fragmentWithMultilineComment.kt.after @@ -0,0 +1,14 @@ +// NEXT_SIBLING: +fun b(a: Int): Boolean { + /* + test + */ + println(a) + if (a > 0) return true + return false +} + +fun foo(a: Int): Int { + if (b(a)) return a + return -a +} \ No newline at end of file diff --git a/idea/tests/org/jetbrains/jet/plugin/refactoring/introduce/introduceVariable/JetExtractionTestGenerated.java b/idea/tests/org/jetbrains/jet/plugin/refactoring/introduce/introduceVariable/JetExtractionTestGenerated.java index 8f6dc8d095a..452e1f02fe2 100644 --- a/idea/tests/org/jetbrains/jet/plugin/refactoring/introduce/introduceVariable/JetExtractionTestGenerated.java +++ b/idea/tests/org/jetbrains/jet/plugin/refactoring/introduce/introduceVariable/JetExtractionTestGenerated.java @@ -198,6 +198,16 @@ public class JetExtractionTestGenerated extends AbstractJetExtractionTest { JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.TestsPackage", new File("idea/testData/refactoring/extractFunction/basic"), Pattern.compile("^(.+)\\.kt$"), true); } + @TestMetadata("fragmentWithComment.kt") + public void testFragmentWithComment() throws Exception { + doExtractFunctionTest("idea/testData/refactoring/extractFunction/basic/fragmentWithComment.kt"); + } + + @TestMetadata("fragmentWithMultilineComment.kt") + public void testFragmentWithMultilineComment() throws Exception { + doExtractFunctionTest("idea/testData/refactoring/extractFunction/basic/fragmentWithMultilineComment.kt"); + } + @TestMetadata("localClassFunctionRef.kt") public void testLocalClassFunctionRef() throws Exception { doExtractFunctionTest("idea/testData/refactoring/extractFunction/basic/localClassFunctionRef.kt");