diff --git a/idea/src/org/jetbrains/kotlin/idea/refactoring/introduce/introduceParameter/KotlinIntroduceParameterHandler.kt b/idea/src/org/jetbrains/kotlin/idea/refactoring/introduce/introduceParameter/KotlinIntroduceParameterHandler.kt index 8ac6201f16d..858b4b9bd85 100644 --- a/idea/src/org/jetbrains/kotlin/idea/refactoring/introduce/introduceParameter/KotlinIntroduceParameterHandler.kt +++ b/idea/src/org/jetbrains/kotlin/idea/refactoring/introduce/introduceParameter/KotlinIntroduceParameterHandler.kt @@ -248,11 +248,13 @@ open class KotlinIntroduceParameterHandler( val replacementType = expressionType.approximateWithResolvableType(targetParent.getResolutionScope(context, targetParent.getResolutionFacade()), false) val body = when (targetParent) { - is KtFunction -> targetParent.bodyExpression - is KtClass -> targetParent.getBody() - else -> null - } ?: throw AssertionError("Body element is not found: ${targetParent.getElementTextWithContext()}") - val nameValidator = NewDeclarationNameValidator(body, sequenceOf(body), NewDeclarationNameValidator.Target.VARIABLES) + is KtFunction -> targetParent.bodyExpression + is KtClass -> targetParent.getBody() + else -> null + } + val bodyValidator: ((String) -> Boolean)? = + body?.let { NewDeclarationNameValidator(it, sequenceOf(it), NewDeclarationNameValidator.Target.VARIABLES) } + val nameValidator = CollectingNameValidator(targetParent.getValueParameters().mapNotNull { it.name }, bodyValidator ?: { true }) val suggestedNames = SmartList().apply { if (physicalExpression is KtProperty && !ApplicationManager.getApplication().isUnitTestMode) { @@ -271,7 +273,7 @@ open class KotlinIntroduceParameterHandler( } else { expression.toRange() - .match(body, KotlinPsiUnifier.DEFAULT) + .match(targetParent, KotlinPsiUnifier.DEFAULT) .filterNot { val textRange = it.range.getPhysicalTextRange() forbiddenRanges.any { it.intersects(textRange) } diff --git a/idea/testData/refactoring/introduceParameter/avoidClassDuplicatingParameters.kt b/idea/testData/refactoring/introduceParameter/avoidClassDuplicatingParameters.kt new file mode 100644 index 00000000000..b06c8e614a3 --- /dev/null +++ b/idea/testData/refactoring/introduceParameter/avoidClassDuplicatingParameters.kt @@ -0,0 +1,3 @@ +class Foo(i: Int) { + val x = 1 + 2 + 3 +} \ No newline at end of file diff --git a/idea/testData/refactoring/introduceParameter/avoidClassDuplicatingParameters.kt.after b/idea/testData/refactoring/introduceParameter/avoidClassDuplicatingParameters.kt.after new file mode 100644 index 00000000000..002752aeec7 --- /dev/null +++ b/idea/testData/refactoring/introduceParameter/avoidClassDuplicatingParameters.kt.after @@ -0,0 +1,3 @@ +class Foo(i: Int, i1: Int = 1 + 2) { + val x = i1 + 3 +} diff --git a/idea/testData/refactoring/introduceParameter/avoidFunDuplicatingParameters.kt b/idea/testData/refactoring/introduceParameter/avoidFunDuplicatingParameters.kt new file mode 100644 index 00000000000..05c38f42d87 --- /dev/null +++ b/idea/testData/refactoring/introduceParameter/avoidFunDuplicatingParameters.kt @@ -0,0 +1,3 @@ +fun foo(i: Int) { + val x = 1 + 2 + 3 +} \ No newline at end of file diff --git a/idea/testData/refactoring/introduceParameter/avoidFunDuplicatingParameters.kt.after b/idea/testData/refactoring/introduceParameter/avoidFunDuplicatingParameters.kt.after new file mode 100644 index 00000000000..01fff29f4c5 --- /dev/null +++ b/idea/testData/refactoring/introduceParameter/avoidFunDuplicatingParameters.kt.after @@ -0,0 +1,3 @@ +fun foo(i: Int, i1: Int = 1 + 2) { + val x = i1 + 3 +} diff --git a/idea/testData/refactoring/introduceParameter/superCallArgument.kt b/idea/testData/refactoring/introduceParameter/superCallArgument.kt new file mode 100644 index 00000000000..ede8f9823ae --- /dev/null +++ b/idea/testData/refactoring/introduceParameter/superCallArgument.kt @@ -0,0 +1,9 @@ +class A : B({ "${C.c}" }) + +class C() { + companion object { + val c = 23 + } +} + +open class B(param: () -> String) \ No newline at end of file diff --git a/idea/testData/refactoring/introduceParameter/superCallArgument.kt.after b/idea/testData/refactoring/introduceParameter/superCallArgument.kt.after new file mode 100644 index 00000000000..b86a1ce9382 --- /dev/null +++ b/idea/testData/refactoring/introduceParameter/superCallArgument.kt.after @@ -0,0 +1,9 @@ +class A(val i: Int = C.c) : B({ "$i" }) + +class C() { + companion object { + val c = 23 + } +} + +open class B(param: () -> String) diff --git a/idea/tests/org/jetbrains/kotlin/idea/refactoring/introduce/ExtractionTestGenerated.java b/idea/tests/org/jetbrains/kotlin/idea/refactoring/introduce/ExtractionTestGenerated.java index c66bb9c930f..d6224bb2a43 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/refactoring/introduce/ExtractionTestGenerated.java +++ b/idea/tests/org/jetbrains/kotlin/idea/refactoring/introduce/ExtractionTestGenerated.java @@ -3356,6 +3356,18 @@ public class ExtractionTestGenerated extends AbstractExtractionTest { doIntroduceSimpleParameterTest(fileName); } + @TestMetadata("avoidClassDuplicatingParameters.kt") + public void testAvoidClassDuplicatingParameters() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/refactoring/introduceParameter/avoidClassDuplicatingParameters.kt"); + doIntroduceSimpleParameterTest(fileName); + } + + @TestMetadata("avoidFunDuplicatingParameters.kt") + public void testAvoidFunDuplicatingParameters() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/refactoring/introduceParameter/avoidFunDuplicatingParameters.kt"); + doIntroduceSimpleParameterTest(fileName); + } + @TestMetadata("classInAnonymousInitializer.kt") public void testClassInAnonymousInitializer() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("idea/testData/refactoring/introduceParameter/classInAnonymousInitializer.kt"); @@ -3596,6 +3608,12 @@ public class ExtractionTestGenerated extends AbstractExtractionTest { doIntroduceSimpleParameterTest(fileName); } + @TestMetadata("superCallArgument.kt") + public void testSuperCallArgument() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/refactoring/introduceParameter/superCallArgument.kt"); + doIntroduceSimpleParameterTest(fileName); + } + @TestMetadata("throw.kt") public void testThrow() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("idea/testData/refactoring/introduceParameter/throw.kt");