Move isEquivalentTo() from KtClass to KtClassOrObject
This makes objects and companions with the same qualified name compatible from find usages point of view So #KT-25326 Fixed So #KT-25438 Fixed
This commit is contained in:
@@ -49,53 +49,6 @@ open class KtClass : KtClassOrObject {
|
||||
fun isSealed(): Boolean = hasModifier(KtTokens.SEALED_KEYWORD)
|
||||
fun isInner(): Boolean = hasModifier(KtTokens.INNER_KEYWORD)
|
||||
|
||||
override fun isEquivalentTo(another: PsiElement?): Boolean {
|
||||
if (this === another) {
|
||||
return true
|
||||
}
|
||||
|
||||
if (another !is KtClass) {
|
||||
return false
|
||||
}
|
||||
|
||||
val fq1 = getQualifiedName() ?: return false
|
||||
val fq2 = another.getQualifiedName() ?: return false
|
||||
if (fq1 == fq2) {
|
||||
val thisLocal = isLocal
|
||||
if (thisLocal != another.isLocal) {
|
||||
return false
|
||||
}
|
||||
|
||||
// For non-local classes same fqn is enough
|
||||
// Consider different instances of local classes non-equivalent
|
||||
return !thisLocal
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
protected fun getQualifiedName(): String? {
|
||||
val stub = stub
|
||||
if (stub != null) {
|
||||
val fqName = stub.getFqName()
|
||||
return fqName?.asString()
|
||||
}
|
||||
|
||||
val parts = ArrayList<String>()
|
||||
var current: KtClassOrObject? = this
|
||||
while (current != null) {
|
||||
parts.add(current.name!!)
|
||||
current = PsiTreeUtil.getParentOfType<KtClassOrObject>(current, KtClassOrObject::class.java)
|
||||
}
|
||||
val file = containingFile as? KtFile ?: return null
|
||||
val fileQualifiedName = file.packageFqName.asString()
|
||||
if (!fileQualifiedName.isEmpty()) {
|
||||
parts.add(fileQualifiedName)
|
||||
}
|
||||
Collections.reverse(parts)
|
||||
return StringUtil.join(parts, ".")
|
||||
}
|
||||
|
||||
override fun getCompanionObjects(): List<KtObjectDeclaration> = getBody()?.allCompanionObjects.orEmpty()
|
||||
|
||||
fun getClassOrInterfaceKeyword(): PsiElement? = findChildByType(TokenSet.create(KtTokens.CLASS_KEYWORD, KtTokens.INTERFACE_KEYWORD))
|
||||
|
||||
@@ -128,6 +128,53 @@ abstract class KtClassOrObject :
|
||||
file.delete()
|
||||
}
|
||||
}
|
||||
|
||||
override fun isEquivalentTo(another: PsiElement?): Boolean {
|
||||
if (this === another) {
|
||||
return true
|
||||
}
|
||||
|
||||
if (another !is KtClassOrObject) {
|
||||
return false
|
||||
}
|
||||
|
||||
val fq1 = getQualifiedName() ?: return false
|
||||
val fq2 = another.getQualifiedName() ?: return false
|
||||
if (fq1 == fq2) {
|
||||
val thisLocal = isLocal
|
||||
if (thisLocal != another.isLocal) {
|
||||
return false
|
||||
}
|
||||
|
||||
// For non-local classes same fqn is enough
|
||||
// Consider different instances of local classes non-equivalent
|
||||
return !thisLocal
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
protected fun getQualifiedName(): String? {
|
||||
val stub = stub
|
||||
if (stub != null) {
|
||||
val fqName = stub.getFqName()
|
||||
return fqName?.asString()
|
||||
}
|
||||
|
||||
val parts = mutableListOf<String>()
|
||||
var current: KtClassOrObject? = this
|
||||
while (current != null) {
|
||||
parts.add(current.name!!)
|
||||
current = PsiTreeUtil.getParentOfType(current, KtClassOrObject::class.java)
|
||||
}
|
||||
val file = containingFile as? KtFile ?: return null
|
||||
val fileQualifiedName = file.packageFqName.asString()
|
||||
if (!fileQualifiedName.isEmpty()) {
|
||||
parts.add(fileQualifiedName)
|
||||
}
|
||||
parts.reverse()
|
||||
return parts.joinToString(separator = ".")
|
||||
}
|
||||
}
|
||||
|
||||
fun KtClassOrObject.getOrCreateBody(): KtClassBody {
|
||||
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module type="JAVA_MODULE" version="4">
|
||||
<component name="FacetManager">
|
||||
<facet type="kotlin-language" name="Kotlin">
|
||||
<configuration version="2" platform="Common (experimental) " useProjectSettings="false">
|
||||
<compilerSettings/>
|
||||
<compilerArguments/>
|
||||
</configuration>
|
||||
</facet>
|
||||
</component>
|
||||
<component name="NewModuleRootManager" inherit-compiler-output="true">
|
||||
<exclude-output />
|
||||
<content url="file://$MODULE_DIR$">
|
||||
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
|
||||
</content>
|
||||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
</component>
|
||||
</module>
|
||||
Vendored
+4
@@ -0,0 +1,4 @@
|
||||
package test
|
||||
|
||||
expect class A {
|
||||
}
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module type="JAVA_MODULE" version="4">
|
||||
<component name="FacetManager">
|
||||
<facet type="kotlin-language" name="Kotlin">
|
||||
<configuration version="2" platform="JavaScript " useProjectSettings="false">
|
||||
<implements>Common</implements>
|
||||
<compilerSettings/>
|
||||
<compilerArguments/>
|
||||
</configuration>
|
||||
</facet>
|
||||
</component>
|
||||
<component name="NewModuleRootManager" inherit-compiler-output="true">
|
||||
<exclude-output />
|
||||
<content url="file://$MODULE_DIR$">
|
||||
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
|
||||
</content>
|
||||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
<orderEntry type="module" module-name="Common" />
|
||||
</component>
|
||||
</module>
|
||||
Vendored
+6
@@ -0,0 +1,6 @@
|
||||
package test
|
||||
|
||||
actual class A {
|
||||
}
|
||||
|
||||
val co = A
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module type="JAVA_MODULE" version="4">
|
||||
<component name="FacetManager">
|
||||
<facet type="kotlin-language" name="Kotlin">
|
||||
<configuration version="2" platform="JVM 1.6" useProjectSettings="false">
|
||||
<implements>Common</implements>
|
||||
<compilerSettings/>
|
||||
<compilerArguments/>
|
||||
</configuration>
|
||||
</facet>
|
||||
</component>
|
||||
<component name="NewModuleRootManager" inherit-compiler-output="true">
|
||||
<exclude-output />
|
||||
<content url="file://$MODULE_DIR$">
|
||||
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
|
||||
</content>
|
||||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
<orderEntry type="module" module-name="Common" />
|
||||
</component>
|
||||
</module>
|
||||
Vendored
+6
@@ -0,0 +1,6 @@
|
||||
package test
|
||||
|
||||
actual class A {
|
||||
}
|
||||
|
||||
val usage = A.useful
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module type="JAVA_MODULE" version="4">
|
||||
<component name="FacetManager">
|
||||
<facet type="kotlin-language" name="Kotlin">
|
||||
<configuration version="2" platform="Common (experimental) " useProjectSettings="false">
|
||||
<compilerSettings/>
|
||||
<compilerArguments/>
|
||||
</configuration>
|
||||
</facet>
|
||||
</component>
|
||||
<component name="NewModuleRootManager" inherit-compiler-output="true">
|
||||
<exclude-output />
|
||||
<content url="file://$MODULE_DIR$">
|
||||
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
|
||||
</content>
|
||||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
</component>
|
||||
</module>
|
||||
Vendored
+7
@@ -0,0 +1,7 @@
|
||||
package test
|
||||
|
||||
expect class A {
|
||||
companion <caret>object {
|
||||
val useful: Int
|
||||
}
|
||||
}
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module type="JAVA_MODULE" version="4">
|
||||
<component name="FacetManager">
|
||||
<facet type="kotlin-language" name="Kotlin">
|
||||
<configuration version="2" platform="JavaScript " useProjectSettings="false">
|
||||
<implements>Common</implements>
|
||||
<compilerSettings/>
|
||||
<compilerArguments/>
|
||||
</configuration>
|
||||
</facet>
|
||||
</component>
|
||||
<component name="NewModuleRootManager" inherit-compiler-output="true">
|
||||
<exclude-output />
|
||||
<content url="file://$MODULE_DIR$">
|
||||
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
|
||||
</content>
|
||||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
<orderEntry type="module" module-name="Common" />
|
||||
</component>
|
||||
</module>
|
||||
Vendored
+9
@@ -0,0 +1,9 @@
|
||||
package test
|
||||
|
||||
actual class A {
|
||||
actual companion object {
|
||||
actual val useful: Int = 42
|
||||
}
|
||||
}
|
||||
|
||||
val co = A
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module type="JAVA_MODULE" version="4">
|
||||
<component name="FacetManager">
|
||||
<facet type="kotlin-language" name="Kotlin">
|
||||
<configuration version="2" platform="JVM 1.6" useProjectSettings="false">
|
||||
<implements>Common</implements>
|
||||
<compilerSettings/>
|
||||
<compilerArguments/>
|
||||
</configuration>
|
||||
</facet>
|
||||
</component>
|
||||
<component name="NewModuleRootManager" inherit-compiler-output="true">
|
||||
<exclude-output />
|
||||
<content url="file://$MODULE_DIR$">
|
||||
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
|
||||
</content>
|
||||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
<orderEntry type="module" module-name="Common" />
|
||||
</component>
|
||||
</module>
|
||||
Vendored
+9
@@ -0,0 +1,9 @@
|
||||
package test
|
||||
|
||||
actual class A {
|
||||
actual companion object {
|
||||
actual val useful: Int = 42
|
||||
}
|
||||
}
|
||||
|
||||
val usage = A.useful
|
||||
+4
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"mainFile": "Common/src/test/test.kt",
|
||||
"elementClass": "org.jetbrains.kotlin.psi.KtClassOrObject"
|
||||
}
|
||||
+1
@@ -0,0 +1 @@
|
||||
companion object A.Companion has 2 usages that are not safe to delete.
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module type="JAVA_MODULE" version="4">
|
||||
<component name="FacetManager">
|
||||
<facet type="kotlin-language" name="Kotlin">
|
||||
<configuration version="2" platform="Common (experimental) " useProjectSettings="false">
|
||||
<compilerSettings/>
|
||||
<compilerArguments/>
|
||||
</configuration>
|
||||
</facet>
|
||||
</component>
|
||||
<component name="NewModuleRootManager" inherit-compiler-output="true">
|
||||
<exclude-output />
|
||||
<content url="file://$MODULE_DIR$">
|
||||
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
|
||||
</content>
|
||||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
</component>
|
||||
</module>
|
||||
Vendored
+3
@@ -0,0 +1,3 @@
|
||||
package test
|
||||
|
||||
fun barr() {}
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module type="JAVA_MODULE" version="4">
|
||||
<component name="FacetManager">
|
||||
<facet type="kotlin-language" name="Kotlin">
|
||||
<configuration version="2" platform="JavaScript " useProjectSettings="false">
|
||||
<implements>Common</implements>
|
||||
<compilerSettings/>
|
||||
<compilerArguments/>
|
||||
</configuration>
|
||||
</facet>
|
||||
</component>
|
||||
<component name="NewModuleRootManager" inherit-compiler-output="true">
|
||||
<exclude-output />
|
||||
<content url="file://$MODULE_DIR$">
|
||||
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
|
||||
</content>
|
||||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
<orderEntry type="module" module-name="Common" />
|
||||
</component>
|
||||
</module>
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
package test
|
||||
|
||||
fun foo(o: Obj) {
|
||||
o.hashCode()
|
||||
}
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module type="JAVA_MODULE" version="4">
|
||||
<component name="FacetManager">
|
||||
<facet type="kotlin-language" name="Kotlin">
|
||||
<configuration version="2" platform="JVM 1.6" useProjectSettings="false">
|
||||
<implements>Common</implements>
|
||||
<compilerSettings/>
|
||||
<compilerArguments/>
|
||||
</configuration>
|
||||
</facet>
|
||||
</component>
|
||||
<component name="NewModuleRootManager" inherit-compiler-output="true">
|
||||
<exclude-output />
|
||||
<content url="file://$MODULE_DIR$">
|
||||
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
|
||||
</content>
|
||||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
<orderEntry type="module" module-name="Common" />
|
||||
</component>
|
||||
</module>
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
package test
|
||||
|
||||
val o = Obj
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module type="JAVA_MODULE" version="4">
|
||||
<component name="FacetManager">
|
||||
<facet type="kotlin-language" name="Kotlin">
|
||||
<configuration version="2" platform="Common (experimental) " useProjectSettings="false">
|
||||
<compilerSettings/>
|
||||
<compilerArguments/>
|
||||
</configuration>
|
||||
</facet>
|
||||
</component>
|
||||
<component name="NewModuleRootManager" inherit-compiler-output="true">
|
||||
<exclude-output />
|
||||
<content url="file://$MODULE_DIR$">
|
||||
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
|
||||
</content>
|
||||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
</component>
|
||||
</module>
|
||||
Vendored
+5
@@ -0,0 +1,5 @@
|
||||
package test
|
||||
|
||||
expect object <caret>Obj
|
||||
|
||||
fun barr() {}
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module type="JAVA_MODULE" version="4">
|
||||
<component name="FacetManager">
|
||||
<facet type="kotlin-language" name="Kotlin">
|
||||
<configuration version="2" platform="JavaScript " useProjectSettings="false">
|
||||
<implements>Common</implements>
|
||||
<compilerSettings/>
|
||||
<compilerArguments/>
|
||||
</configuration>
|
||||
</facet>
|
||||
</component>
|
||||
<component name="NewModuleRootManager" inherit-compiler-output="true">
|
||||
<exclude-output />
|
||||
<content url="file://$MODULE_DIR$">
|
||||
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
|
||||
</content>
|
||||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
<orderEntry type="module" module-name="Common" />
|
||||
</component>
|
||||
</module>
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
package test
|
||||
|
||||
actual object Obj
|
||||
|
||||
fun foo(o: Obj) {
|
||||
o.hashCode()
|
||||
}
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module type="JAVA_MODULE" version="4">
|
||||
<component name="FacetManager">
|
||||
<facet type="kotlin-language" name="Kotlin">
|
||||
<configuration version="2" platform="JVM 1.6" useProjectSettings="false">
|
||||
<implements>Common</implements>
|
||||
<compilerSettings/>
|
||||
<compilerArguments/>
|
||||
</configuration>
|
||||
</facet>
|
||||
</component>
|
||||
<component name="NewModuleRootManager" inherit-compiler-output="true">
|
||||
<exclude-output />
|
||||
<content url="file://$MODULE_DIR$">
|
||||
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
|
||||
</content>
|
||||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
<orderEntry type="module" module-name="Common" />
|
||||
</component>
|
||||
</module>
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
package test
|
||||
|
||||
actual object Obj
|
||||
|
||||
val o = Obj
|
||||
+4
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"mainFile": "Common/src/test/test.kt",
|
||||
"elementClass": "org.jetbrains.kotlin.psi.KtClassOrObject"
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
object test.Obj has 2 usages that are not safe to delete.
|
||||
Generated
+10
@@ -119,6 +119,11 @@ public class MultiModuleSafeDeleteTestGenerated extends AbstractMultiModuleSafeD
|
||||
runTest("idea/testData/refactoring/safeDeleteMultiModule/byExpectClassSecondaryConstructorParameter/expectsAndActualsByExpectClassSecondaryConstructorParameter.test");
|
||||
}
|
||||
|
||||
@TestMetadata("byExpectCompanion/byExpectCompanion.test")
|
||||
public void testByExpectCompanion_ByExpectCompanion() throws Exception {
|
||||
runTest("idea/testData/refactoring/safeDeleteMultiModule/byExpectCompanion/byExpectCompanion.test");
|
||||
}
|
||||
|
||||
@TestMetadata("byExpectFun/byExpectFun.test")
|
||||
public void testByExpectFun_ByExpectFun() throws Exception {
|
||||
runTest("idea/testData/refactoring/safeDeleteMultiModule/byExpectFun/byExpectFun.test");
|
||||
@@ -134,6 +139,11 @@ public class MultiModuleSafeDeleteTestGenerated extends AbstractMultiModuleSafeD
|
||||
runTest("idea/testData/refactoring/safeDeleteMultiModule/byExpectFunVarargParamerer/byExpectFunVarargParameter.test");
|
||||
}
|
||||
|
||||
@TestMetadata("byExpectObject/byExpectObject.test")
|
||||
public void testByExpectObject_ByExpectObject() throws Exception {
|
||||
runTest("idea/testData/refactoring/safeDeleteMultiModule/byExpectObject/byExpectObject.test");
|
||||
}
|
||||
|
||||
@TestMetadata("byExpectVal/byExpectVal.test")
|
||||
public void testByExpectVal_ByExpectVal() throws Exception {
|
||||
runTest("idea/testData/refactoring/safeDeleteMultiModule/byExpectVal/byExpectVal.test");
|
||||
|
||||
Reference in New Issue
Block a user