diff --git a/java/java-impl/src/com/intellij/refactoring/extractMethod/newImpl/JavaDuplicatesFinder.kt b/java/java-impl/src/com/intellij/refactoring/extractMethod/newImpl/JavaDuplicatesFinder.kt index 6f259239fdfd..979f8a1ed8f7 100644 --- a/java/java-impl/src/com/intellij/refactoring/extractMethod/newImpl/JavaDuplicatesFinder.kt +++ b/java/java-impl/src/com/intellij/refactoring/extractMethod/newImpl/JavaDuplicatesFinder.kt @@ -22,40 +22,41 @@ class JavaDuplicatesFinder(pattern: List, private val terminalNodes: } fun findDuplicates(scope: PsiElement): List { - val ignoredElements = pattern.toSet() + val ignoredElements = HashSet(pattern) + val duplicates = mutableListOf() val patternExpression = pattern.singleOrNull() as? PsiExpression - if (patternExpression != null) { - val expressionVisitor = object : JavaRecursiveElementWalkingVisitor(){ + val visitor = if (patternExpression != null) { + object : JavaRecursiveElementWalkingVisitor(){ override fun visitExpression(expression: PsiExpression) { if (expression in ignoredElements) return val duplicate = createDuplicate(childrenOf(patternExpression), childrenOf(expression)) - if (duplicate != null && ! isOvercomplicated(duplicate)) { + if (duplicate != null) { duplicates += duplicate.copy(pattern = listOf(patternExpression), candidate = listOf(expression)) } else { super.visitExpression(expression) } } } - scope.accept(expressionVisitor) } else { - val visitor = object: JavaRecursiveElementWalkingVisitor() { + object: JavaRecursiveElementWalkingVisitor() { override fun visitStatement(statement: PsiStatement) { if (statement in ignoredElements) return val siblings = siblingsOf(statement).take(pattern.size).toList() val duplicate = createDuplicate(pattern, siblings) - if (duplicate != null && ! isOvercomplicated(duplicate)) { + if (duplicate != null) { duplicates += duplicate + ignoredElements += duplicate.candidate } else { super.visitStatement(statement) } } } - scope.accept(visitor) } + scope.accept(visitor) - return duplicates + return duplicates.filterNot(::isOvercomplicated) } private fun isNoise(it: PsiElement) = it is PsiWhiteSpace || it is PsiComment || it is PsiEmptyStatement diff --git a/java/java-tests/testData/refactoring/extractMethodAndDuplicatesInplace/OverlappingRanges.java b/java/java-tests/testData/refactoring/extractMethodAndDuplicatesInplace/OverlappingRanges.java new file mode 100644 index 000000000000..6bdae6017e64 --- /dev/null +++ b/java/java-tests/testData/refactoring/extractMethodAndDuplicatesInplace/OverlappingRanges.java @@ -0,0 +1,12 @@ +public class Test { + void test(){ + System.out.println(); + System.out.println(); + System.out.println(); + System.out.println(); + System.out.println(); + System.out.println(); + System.out.println(); + System.out.println(); + } +} \ No newline at end of file diff --git a/java/java-tests/testData/refactoring/extractMethodAndDuplicatesInplace/OverlappingRanges_after.java b/java/java-tests/testData/refactoring/extractMethodAndDuplicatesInplace/OverlappingRanges_after.java new file mode 100644 index 000000000000..f5b2f140ed5e --- /dev/null +++ b/java/java-tests/testData/refactoring/extractMethodAndDuplicatesInplace/OverlappingRanges_after.java @@ -0,0 +1,14 @@ +public class Test { + void test(){ + extracted(); + extracted(); + System.out.println(); + System.out.println(); + } + + private void extracted() { + System.out.println(); + System.out.println(); + System.out.println(); + } +} \ No newline at end of file diff --git a/java/java-tests/testSrc/com/intellij/java/refactoring/ExtractMethodAndDuplicatesInplaceTest.kt b/java/java-tests/testSrc/com/intellij/java/refactoring/ExtractMethodAndDuplicatesInplaceTest.kt index 26b3f5317bc4..0c388e022f92 100644 --- a/java/java-tests/testSrc/com/intellij/java/refactoring/ExtractMethodAndDuplicatesInplaceTest.kt +++ b/java/java-tests/testSrc/com/intellij/java/refactoring/ExtractMethodAndDuplicatesInplaceTest.kt @@ -123,6 +123,10 @@ class ExtractMethodAndDuplicatesInplaceTest: LightJavaCodeInsightTestCase() { doTest() } + fun testOverlappingRanges(){ + doTest() + } + fun testRefactoringListener(){ templateTest { configureByFile("$BASE_PATH/${getTestName(false)}.java")