diff --git a/plugins/kotlin/idea/tests/testData/refactoring/changeSignature/AddValParameterToConstructorConflictWithClassBefore.kt b/plugins/kotlin/idea/tests/testData/refactoring/changeSignature/AddValParameterToConstructorConflictWithClassBefore.kt new file mode 100644 index 000000000000..755bd66b40d2 --- /dev/null +++ b/plugins/kotlin/idea/tests/testData/refactoring/changeSignature/AddValParameterToConstructorConflictWithClassBefore.kt @@ -0,0 +1,5 @@ +class Foo() { + class c {} +} + +// IGNORE_K1 \ No newline at end of file diff --git a/plugins/kotlin/idea/tests/testData/refactoring/changeSignature/AddValParameterToConstructorConflictWithClassMessages.txt b/plugins/kotlin/idea/tests/testData/refactoring/changeSignature/AddValParameterToConstructorConflictWithClassMessages.txt new file mode 100644 index 000000000000..34d34a7b5735 --- /dev/null +++ b/plugins/kotlin/idea/tests/testData/refactoring/changeSignature/AddValParameterToConstructorConflictWithClassMessages.txt @@ -0,0 +1 @@ +Class 'c' is already declared in class 'Foo' \ No newline at end of file diff --git a/plugins/kotlin/idea/tests/testData/refactoring/changeSignature/AddValParameterToConstructorConflictWithFunctionAfter.kt b/plugins/kotlin/idea/tests/testData/refactoring/changeSignature/AddValParameterToConstructorConflictWithFunctionAfter.kt new file mode 100644 index 000000000000..f48288ec1636 --- /dev/null +++ b/plugins/kotlin/idea/tests/testData/refactoring/changeSignature/AddValParameterToConstructorConflictWithFunctionAfter.kt @@ -0,0 +1,3 @@ +class Foo(val f: () -> Unit) { + fun f() {} +} \ No newline at end of file diff --git a/plugins/kotlin/idea/tests/testData/refactoring/changeSignature/AddValParameterToConstructorConflictWithFunctionBefore.kt b/plugins/kotlin/idea/tests/testData/refactoring/changeSignature/AddValParameterToConstructorConflictWithFunctionBefore.kt new file mode 100644 index 000000000000..33827020e7ff --- /dev/null +++ b/plugins/kotlin/idea/tests/testData/refactoring/changeSignature/AddValParameterToConstructorConflictWithFunctionBefore.kt @@ -0,0 +1,3 @@ +class Foo() { + fun f() {} +} \ No newline at end of file diff --git a/plugins/kotlin/idea/tests/testData/refactoring/changeSignature/AddValParameterToConstructorConflictWithPropertyBefore.kt b/plugins/kotlin/idea/tests/testData/refactoring/changeSignature/AddValParameterToConstructorConflictWithPropertyBefore.kt new file mode 100644 index 000000000000..74ad3f6cb404 --- /dev/null +++ b/plugins/kotlin/idea/tests/testData/refactoring/changeSignature/AddValParameterToConstructorConflictWithPropertyBefore.kt @@ -0,0 +1,3 @@ +class Foo() { + val p = 42 +} \ No newline at end of file diff --git a/plugins/kotlin/idea/tests/testData/refactoring/changeSignature/AddValParameterToConstructorConflictWithPropertyMessages.k2.txt b/plugins/kotlin/idea/tests/testData/refactoring/changeSignature/AddValParameterToConstructorConflictWithPropertyMessages.k2.txt new file mode 100644 index 000000000000..224759030113 --- /dev/null +++ b/plugins/kotlin/idea/tests/testData/refactoring/changeSignature/AddValParameterToConstructorConflictWithPropertyMessages.k2.txt @@ -0,0 +1 @@ +Property 'p' is already declared in class 'Foo' \ No newline at end of file diff --git a/plugins/kotlin/idea/tests/testData/refactoring/changeSignature/AddValParameterToConstructorConflictWithPropertyMessages.txt b/plugins/kotlin/idea/tests/testData/refactoring/changeSignature/AddValParameterToConstructorConflictWithPropertyMessages.txt new file mode 100644 index 000000000000..8331f5834275 --- /dev/null +++ b/plugins/kotlin/idea/tests/testData/refactoring/changeSignature/AddValParameterToConstructorConflictWithPropertyMessages.txt @@ -0,0 +1 @@ +Duplicating property 'p' \ No newline at end of file diff --git a/plugins/kotlin/refactorings/kotlin.refactorings.common.tests/test/org/jetbrains/kotlin/idea/refactoring/changeSignature/BaseKotlinChangeSignatureTest.kt b/plugins/kotlin/refactorings/kotlin.refactorings.common.tests/test/org/jetbrains/kotlin/idea/refactoring/changeSignature/BaseKotlinChangeSignatureTest.kt index 0cb8a84edef4..1a3e2bcb17c0 100644 --- a/plugins/kotlin/refactorings/kotlin.refactorings.common.tests/test/org/jetbrains/kotlin/idea/refactoring/changeSignature/BaseKotlinChangeSignatureTest.kt +++ b/plugins/kotlin/refactorings/kotlin.refactorings.common.tests/test/org/jetbrains/kotlin/idea/refactoring/changeSignature/BaseKotlinChangeSignatureTest.kt @@ -1284,6 +1284,24 @@ abstract class BaseKotlinChangeSignatureTest, P newParameters[1].setType("Float?") } + fun testAddValParameterToConstructorConflictWithClass() = doTestConflict { + val parameter = createKotlinIntParameter("c") + parameter.valOrVar = KotlinValVar.Val + addParameter(parameter) + } + + fun testAddValParameterToConstructorConflictWithProperty() = doTestConflict { + val parameter = createKotlinIntParameter("p") + parameter.valOrVar = KotlinValVar.Val + addParameter(parameter) + } + + fun testAddValParameterToConstructorConflictWithFunction() = doTest { + val parameter = createKotlinParameter("f", "() -> Unit", null, false) + parameter.valOrVar = KotlinValVar.Val + addParameter(parameter) + } + fun testGenericConstructor() = doTest { setNewVisibility(Public) diff --git a/plugins/kotlin/refactorings/kotlin.refactorings.common/src/org/jetbrains/kotlin/idea/refactoring/conflicts/kotlinMembersNameConflicts.kt b/plugins/kotlin/refactorings/kotlin.refactorings.common/src/org/jetbrains/kotlin/idea/refactoring/conflicts/kotlinMembersNameConflicts.kt index 5df9daef171c..e29948651d68 100644 --- a/plugins/kotlin/refactorings/kotlin.refactorings.common/src/org/jetbrains/kotlin/idea/refactoring/conflicts/kotlinMembersNameConflicts.kt +++ b/plugins/kotlin/refactorings/kotlin.refactorings.common/src/org/jetbrains/kotlin/idea/refactoring/conflicts/kotlinMembersNameConflicts.kt @@ -186,6 +186,23 @@ fun checkDeclarationNewNameConflicts( } } +fun checkNewPropertyConflicts( + containingClass: KtClassOrObject, + newName: String, + result: MutableList, +) { + analyze(containingClass) { + val containingSymbol = containingClass.getNamedClassOrObjectSymbol() ?: return + var potentialCandidates = containingSymbol + .getCombinedMemberScope() + .findSiblingsByName(containingSymbol, Name.identifier(newName), containingSymbol) + .filter { candidateSymbol -> candidateSymbol !is KtFunctionLikeSymbol } + for (candidateSymbol in potentialCandidates) { + registerAlreadyDeclaredConflict(candidateSymbol, result) + } + } +} + fun registerAlreadyDeclaredConflict(candidateSymbol: KtDeclarationSymbol, result: MutableList) { val candidate = candidateSymbol.psi as? PsiNamedElement ?: return diff --git a/plugins/kotlin/refactorings/kotlin.refactorings.k2/src/org/jetbrains/kotlin/idea/k2/refactoring/changeSignature/KotlinChangeSignatureConflictSearcher.kt b/plugins/kotlin/refactorings/kotlin.refactorings.k2/src/org/jetbrains/kotlin/idea/k2/refactoring/changeSignature/KotlinChangeSignatureConflictSearcher.kt index 1f3a3ae17cd1..e19dac9125fe 100644 --- a/plugins/kotlin/refactorings/kotlin.refactorings.k2/src/org/jetbrains/kotlin/idea/k2/refactoring/changeSignature/KotlinChangeSignatureConflictSearcher.kt +++ b/plugins/kotlin/refactorings/kotlin.refactorings.k2/src/org/jetbrains/kotlin/idea/k2/refactoring/changeSignature/KotlinChangeSignatureConflictSearcher.kt @@ -4,7 +4,6 @@ package org.jetbrains.kotlin.idea.k2.refactoring.changeSignature import com.intellij.openapi.util.Ref import com.intellij.psi.PsiElement import com.intellij.psi.PsiNamedElement -import com.intellij.psi.search.LocalSearchScope import com.intellij.psi.search.searches.ReferencesSearch import com.intellij.refactoring.changeSignature.JavaChangeSignatureUsageProcessor import com.intellij.refactoring.changeSignature.MethodCallUsageInfo @@ -24,12 +23,13 @@ import org.jetbrains.kotlin.idea.k2.refactoring.changeSignature.usages.KotlinCha import org.jetbrains.kotlin.idea.k2.refactoring.changeSignature.usages.KotlinFunctionCallUsage import org.jetbrains.kotlin.idea.k2.refactoring.changeSignature.usages.KotlinOverrideUsageInfo import org.jetbrains.kotlin.idea.k2.refactoring.changeSignature.usages.KotlinPropertyCallUsage +import org.jetbrains.kotlin.idea.refactoring.changeSignature.KotlinValVar import org.jetbrains.kotlin.idea.refactoring.conflicts.areSameSignatures +import org.jetbrains.kotlin.idea.refactoring.conflicts.checkNewPropertyConflicts import org.jetbrains.kotlin.idea.refactoring.conflicts.checkRedeclarationConflicts import org.jetbrains.kotlin.idea.refactoring.conflicts.registerAlreadyDeclaredConflict import org.jetbrains.kotlin.idea.refactoring.conflicts.registerRetargetJobOnPotentialCandidates import org.jetbrains.kotlin.idea.refactoring.rename.BasicUnresolvableCollisionUsageInfo -import org.jetbrains.kotlin.idea.references.KtDestructuringDeclarationReference import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.psiUtil.containingClassOrObject import org.jetbrains.kotlin.psi.psiUtil.getQualifiedExpressionForSelector @@ -70,9 +70,22 @@ class KotlinChangeSignatureConflictSearcher( for (parameter in originalInfo.getNonReceiverParameters()) { - if (parameter.oldName != parameter.name && !parameter.isNewParameter) {//todo conflicts with new parameter + if (parameter.oldName != parameter.name || parameter.isNewParameter) { val unresolvableCollisions = mutableListOf() - checkRedeclarationConflicts(function.valueParameters[max(0, parameter.oldIndex - if (function.receiverTypeReference != null) 1 else 0)], parameter.name, unresolvableCollisions) + val ktParameter = if (!parameter.isNewParameter) + function.valueParameters[max(0, parameter.oldIndex - if (function.receiverTypeReference != null) 1 else 0)] + else null + if (ktParameter != null) { //todo conflicts with new parameter + checkRedeclarationConflicts(ktParameter, parameter.name, unresolvableCollisions) + } + + if (function is KtConstructor<*> && parameter.valOrVar != KotlinValVar.None && !(ktParameter != null && ktParameter.hasValOrVar())) { + + val containingClass = function.containingClassOrObject + if (containingClass != null) { + checkNewPropertyConflicts(containingClass, parameter.name, unresolvableCollisions) + } + } for (info in unresolvableCollisions) { when (info) { is BasicUnresolvableCollisionUsageInfo -> {