From 57f429206c5431aaf0ef45dbe1b0f9b606db2632 Mon Sep 17 00:00:00 2001 From: Anna Kozlova Date: Sat, 10 Jun 2023 12:59:24 +0200 Subject: [PATCH] [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. --- .../classes/symbol/fields/SymbolLightFieldForProperty.kt | 4 +++- .../classes/symbol/methods/SymbolLightAccessorMethod.kt | 4 ++++ .../testData/equivalentTo/ClassPropertyWithAccessor.kt | 6 ++++++ .../base/AbstractSymbolLightClassesEquivalentTest.kt | 9 +++++++++ .../base/SymbolLightClassesEquivalentTestGenerated.java | 6 ++++++ 5 files changed, 28 insertions(+), 1 deletion(-) create mode 100644 analysis/symbol-light-classes/testData/equivalentTo/ClassPropertyWithAccessor.kt diff --git a/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/fields/SymbolLightFieldForProperty.kt b/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/fields/SymbolLightFieldForProperty.kt index 29a39c4056f..d6cab7b6d2f 100644 --- a/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/fields/SymbolLightFieldForProperty.kt +++ b/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/fields/SymbolLightFieldForProperty.kt @@ -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 diff --git a/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/methods/SymbolLightAccessorMethod.kt b/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/methods/SymbolLightAccessorMethod.kt index 94766b44814..8a3fcd9d81e 100644 --- a/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/methods/SymbolLightAccessorMethod.kt +++ b/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/methods/SymbolLightAccessorMethod.kt @@ -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 || diff --git a/analysis/symbol-light-classes/testData/equivalentTo/ClassPropertyWithAccessor.kt b/analysis/symbol-light-classes/testData/equivalentTo/ClassPropertyWithAccessor.kt new file mode 100644 index 00000000000..206984ffae5 --- /dev/null +++ b/analysis/symbol-light-classes/testData/equivalentTo/ClassPropertyWithAccessor.kt @@ -0,0 +1,6 @@ +// org.jetbrains.kotlin.light.classes.symbol.fields.SymbolLightFieldForProperty +class FooBar { + var foo : String = "42" + get() = "42" + +} \ No newline at end of file diff --git a/analysis/symbol-light-classes/tests/org/jetbrains/kotlin/light/classes/symbol/base/AbstractSymbolLightClassesEquivalentTest.kt b/analysis/symbol-light-classes/tests/org/jetbrains/kotlin/light/classes/symbol/base/AbstractSymbolLightClassesEquivalentTest.kt index da4b6ce4b58..e9fa0f46e7f 100644 --- a/analysis/symbol-light-classes/tests/org/jetbrains/kotlin/light/classes/symbol/base/AbstractSymbolLightClassesEquivalentTest.kt +++ b/analysis/symbol-light-classes/tests/org/jetbrains/kotlin/light/classes/symbol/base/AbstractSymbolLightClassesEquivalentTest.kt @@ -24,6 +24,15 @@ abstract class AbstractSymbolLightClassesEquivalentTest : AbstractAnalysisApiBas val declaration = testServices.expressionMarkerProvider.getElementOfTypeAtCaret(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" } diff --git a/analysis/symbol-light-classes/tests/org/jetbrains/kotlin/light/classes/symbol/base/SymbolLightClassesEquivalentTestGenerated.java b/analysis/symbol-light-classes/tests/org/jetbrains/kotlin/light/classes/symbol/base/SymbolLightClassesEquivalentTestGenerated.java index afd30b58290..a0bfb963c05 100644 --- a/analysis/symbol-light-classes/tests/org/jetbrains/kotlin/light/classes/symbol/base/SymbolLightClassesEquivalentTestGenerated.java +++ b/analysis/symbol-light-classes/tests/org/jetbrains/kotlin/light/classes/symbol/base/SymbolLightClassesEquivalentTestGenerated.java @@ -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 {