Introduce Parameter: Fix parameter name validation

Respect existing parameter names and fix some exceptions

 #KT-19439 Fixed
 #KT-20402 Fixed
 #KT-20403 Fixed
This commit is contained in:
Alexey Sedunov
2017-09-28 16:38:11 +03:00
parent bf3769f37e
commit 790b615fa1
8 changed files with 56 additions and 6 deletions
@@ -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<String>().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) }
@@ -0,0 +1,3 @@
class Foo(i: Int) {
val x = <selection>1 + 2</selection> + 3
}
@@ -0,0 +1,3 @@
class Foo(i: Int, i1: Int = 1 + 2) {
val x = i1 + 3
}
@@ -0,0 +1,3 @@
fun foo(i: Int) {
val x = <selection>1 + 2</selection> + 3
}
@@ -0,0 +1,3 @@
fun foo(i: Int, i1: Int = 1 + 2) {
val x = i1 + 3
}
@@ -0,0 +1,9 @@
class A : B({ "${<selection>C.c</selection>}" })
class C() {
companion object {
val c = 23
}
}
open class B(param: () -> String)
@@ -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)
@@ -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");