[light classes] Improve isEquivalence checks

^KTIJ-25412

Update equivalence checks for light accessor methods and light fields
 to make them equivalent if they share the same underlying property.
 Follow the `kotlinOrigin` declaration:
 even if there is a property accessor,
 use property declaration.
This commit is contained in:
Anna Kozlova
2023-06-10 12:59:24 +02:00
committed by Space Team
parent 0252f7c586
commit 57f429206c
5 changed files with 28 additions and 1 deletions
@@ -89,7 +89,9 @@ internal class SymbolLightFieldForProperty private constructor(
}
override fun isEquivalentTo(another: PsiElement?): Boolean {
return super.isEquivalentTo(another) || isOriginEquivalentTo(another)
return super.isEquivalentTo(another) ||
basicIsEquivalentTo(this, another as? PsiMethod) ||
isOriginEquivalentTo(another)
}
override fun isDeprecated(): Boolean = _isDeprecated
@@ -262,6 +262,10 @@ internal class SymbolLightAccessorMethod private constructor(
override fun getReturnType(): PsiType = _returnedType
override fun isEquivalentTo(another: PsiElement?): Boolean {
return super.isEquivalentTo(another) || basicIsEquivalentTo(this, another as? PsiField)
}
override fun equals(other: Any?): Boolean {
if (this === other) return true
if (other !is SymbolLightAccessorMethod ||
@@ -0,0 +1,6 @@
// org.jetbrains.kotlin.light.classes.symbol.fields.SymbolLightFieldForProperty
class FooBar {
var f<caret>oo : String = "42"
get() = "42"
}
@@ -24,6 +24,15 @@ abstract class AbstractSymbolLightClassesEquivalentTest : AbstractAnalysisApiBas
val declaration = testServices.expressionMarkerProvider.getElementOfTypeAtCaret<KtDeclaration>(ktFile)
val lightElements = declaration.toLightElements()
testServices.assertions.assertFalse(lightElements.isEmpty())
if (lightElements.size > 1) {
for (lightElement in lightElements) {
for (other in lightElements) {
testServices.assertions.assertTrue(lightElement.isEquivalentTo(other)) {
"Light elements are not equivalent: $lightElement and $other"
}
}
}
}
val lightElement = lightElements.find { it.javaClass.name == lightQName }
testServices.assertions.assertNotNull(lightElement) { "Expected $lightQName, got: " + lightElements.joinToString { it::class.java.name } }
testServices.assertions.assertTrue(lightElement!!.isEquivalentTo(declaration)) { "Light element is not equivalent to the corresponding ktElement" }
@@ -36,6 +36,12 @@ public class SymbolLightClassesEquivalentTestGenerated extends AbstractSymbolLig
runTest("analysis/symbol-light-classes/testData/equivalentTo/AnonymousClass.kt");
}
@Test
@TestMetadata("ClassPropertyWithAccessor.kt")
public void testClassPropertyWithAccessor() throws Exception {
runTest("analysis/symbol-light-classes/testData/equivalentTo/ClassPropertyWithAccessor.kt");
}
@Test
@TestMetadata("CompanionProperty.kt")
public void testCompanionProperty() throws Exception {