[kotlin] k2 change signature: add conflict for new property declared in constructor

^KTIJ-28589 fixed

GitOrigin-RevId: 4e9010d0b47ebff62b1af7401133ef384d5cac58
This commit is contained in:
Anna Kozlova
2024-04-24 08:44:19 +00:00
committed by intellij-monorepo-bot
parent 6a315e8160
commit 37e44bd3ec
10 changed files with 69 additions and 4 deletions
@@ -0,0 +1,5 @@
class Foo<caret>() {
class c {}
}
// IGNORE_K1
@@ -0,0 +1 @@
Class 'c' is already declared in class 'Foo'
@@ -0,0 +1,3 @@
class Foo(val f: () -> Unit) {
fun f() {}
}
@@ -0,0 +1 @@
Property 'p' is already declared in class 'Foo'
@@ -1284,6 +1284,24 @@ abstract class BaseKotlinChangeSignatureTest<C: KotlinModifiableChangeInfo<P>, 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)
@@ -186,6 +186,23 @@ fun checkDeclarationNewNameConflicts(
}
}
fun checkNewPropertyConflicts(
containingClass: KtClassOrObject,
newName: String,
result: MutableList<UsageInfo>,
) {
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<UsageInfo>) {
val candidate = candidateSymbol.psi as? PsiNamedElement ?: return
@@ -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<UsageInfo>()
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 -> {