[FIR][AA] Rely more on `isInBestCandidates` flag `KtFirReferenceShortener`
After the KT-61568 has been fixed, `isInBestCandidates`
correctly works in more cases, and can be more
reliably used in `KtFirReferenceShortener`
^KTIJ-26808 Fixed
^KTIJ-26840 Fixed
diff --git a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/components/KtFirReferenceShortener.kt b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/components/KtFirReferenceShortener.kt
index 079620d..1af10a3 100644
--- a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/components/KtFirReferenceShortener.kt
+++ b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/components/KtFirReferenceShortener.kt
@@ -977,31 +977,10 @@
if (candidates.mapNotNull { it.candidate.originScope }
.hasScopeCloserThan(scopeForQualifiedAccess, expressionInScope)) return false
val candidatesWithinSamePriorityScopes = candidates.filter { it.candidate.originScope == scopeForQualifiedAccess }
- if (candidatesWithinSamePriorityScopes.isEmpty() || candidatesWithinSamePriorityScopes.size == 1) return true
- /**
- * This is a conservative decision to avoid false positives.
- *
- * TODO: Figure out the priorities among `candidatesWithinSamePriorityScopes` and determine if [firQualifiedAccess] matches the
- * one with the highest priority. At this moment, we have some counter examples that [OverloadCandidate.isInBestCandidates] is true
- * and its symbol matches [firQualifiedAccess], but we cannot shorten it.
- *
- * For example:
- * package foo
- * class Foo {
- * fun test() {
- * // It references FIRST. Removing `foo` lets it reference SECOND. However, the one has true for
- * // [OverloadCandidate.isInBestCandidates] is FIRST. Therefore, making a decision based on `isInBestCandidates` can
- * // cause false positives i.e., shortening changes the referenced symbol.
- * <caret>foo.myRun {
- * 42
- * }
- * }
- * }
- * inline fun <R> myRun(block: () -> R): R = block() // FIRST
- * inline fun <T, R> T.myRun(block: T.() -> R): R = block() // SECOND
- */
- return false
+ // TODO isInBestCandidates should probably be used more actively to filter candidates
+ return candidatesWithinSamePriorityScopes.isEmpty() ||
+ candidatesWithinSamePriorityScopes.singleOrNull()?.isInBestCandidates == true
}
private fun processPropertyAccess(firPropertyAccess: FirPropertyAccessExpression) {
diff --git a/analysis/analysis-api-fir/tests-gen/org/jetbrains/kotlin/analysis/api/fir/test/cases/generated/cases/references/FirIdeNormalAnalysisSourceModuleReferenceShortenerTestGenerated.java b/analysis/analysis-api-fir/tests-gen/org/jetbrains/kotlin/analysis/api/fir/test/cases/generated/cases/references/FirIdeNormalAnalysisSourceModuleReferenceShortenerTestGenerated.java
index d4b44eb..ffcd580 100644
--- a/analysis/analysis-api-fir/tests-gen/org/jetbrains/kotlin/analysis/api/fir/test/cases/generated/cases/references/FirIdeNormalAnalysisSourceModuleReferenceShortenerTestGenerated.java
+++ b/analysis/analysis-api-fir/tests-gen/org/jetbrains/kotlin/analysis/api/fir/test/cases/generated/cases/references/FirIdeNormalAnalysisSourceModuleReferenceShortenerTestGenerated.java
@@ -299,6 +299,12 @@
}
@Test
+ @TestMetadata("memberVsCompanionObjectMemberConflict.kt")
+ public void testMemberVsCompanionObjectMemberConflict() throws Exception {
+ runTest("analysis/analysis-api/testData/components/referenceShortener/referenceShortener/memberVsCompanionObjectMemberConflict.kt");
+ }
+
+ @Test
@TestMetadata("multipleImport.kt")
public void testMultipleImport() throws Exception {
runTest("analysis/analysis-api/testData/components/referenceShortener/referenceShortener/multipleImport.kt");
@@ -437,6 +443,12 @@
}
@Test
+ @TestMetadata("staticMethodFromBaseClassConflict.kt")
+ public void testStaticMethodFromBaseClassConflict() throws Exception {
+ runTest("analysis/analysis-api/testData/components/referenceShortener/referenceShortener/staticMethodFromBaseClassConflict.kt");
+ }
+
+ @Test
@TestMetadata("superClass.kt")
public void testSuperClass() throws Exception {
runTest("analysis/analysis-api/testData/components/referenceShortener/referenceShortener/superClass.kt");
diff --git a/analysis/analysis-api-standalone/tests-gen/org/jetbrains/kotlin/analysis/api/standalone/fir/test/cases/generated/cases/references/FirStandaloneNormalAnalysisSourceModuleReferenceShortenerTestGenerated.java b/analysis/analysis-api-standalone/tests-gen/org/jetbrains/kotlin/analysis/api/standalone/fir/test/cases/generated/cases/references/FirStandaloneNormalAnalysisSourceModuleReferenceShortenerTestGenerated.java
index 482e022..084e606 100644
--- a/analysis/analysis-api-standalone/tests-gen/org/jetbrains/kotlin/analysis/api/standalone/fir/test/cases/generated/cases/references/FirStandaloneNormalAnalysisSourceModuleReferenceShortenerTestGenerated.java
+++ b/analysis/analysis-api-standalone/tests-gen/org/jetbrains/kotlin/analysis/api/standalone/fir/test/cases/generated/cases/references/FirStandaloneNormalAnalysisSourceModuleReferenceShortenerTestGenerated.java
@@ -299,6 +299,12 @@
}
@Test
+ @TestMetadata("memberVsCompanionObjectMemberConflict.kt")
+ public void testMemberVsCompanionObjectMemberConflict() throws Exception {
+ runTest("analysis/analysis-api/testData/components/referenceShortener/referenceShortener/memberVsCompanionObjectMemberConflict.kt");
+ }
+
+ @Test
@TestMetadata("multipleImport.kt")
public void testMultipleImport() throws Exception {
runTest("analysis/analysis-api/testData/components/referenceShortener/referenceShortener/multipleImport.kt");
@@ -437,6 +443,12 @@
}
@Test
+ @TestMetadata("staticMethodFromBaseClassConflict.kt")
+ public void testStaticMethodFromBaseClassConflict() throws Exception {
+ runTest("analysis/analysis-api/testData/components/referenceShortener/referenceShortener/staticMethodFromBaseClassConflict.kt");
+ }
+
+ @Test
@TestMetadata("superClass.kt")
public void testSuperClass() throws Exception {
runTest("analysis/analysis-api/testData/components/referenceShortener/referenceShortener/superClass.kt");
diff --git a/analysis/analysis-api/testData/components/referenceShortener/referenceShortener/memberVsCompanionObjectMemberConflict.kt b/analysis/analysis-api/testData/components/referenceShortener/referenceShortener/memberVsCompanionObjectMemberConflict.kt
new file mode 100644
index 0000000..ad507b5
--- /dev/null
+++ b/analysis/analysis-api/testData/components/referenceShortener/referenceShortener/memberVsCompanionObjectMemberConflict.kt
@@ -0,0 +1,15 @@
+package test
+
+class MyClass {
+ companion object {
+ val prop = ""
+ }
+
+ object Other {
+ val prop = ""
+
+ fun usage() {
+ println(<expr>MyClass.prop</expr>)
+ }
+ }
+}
\ No newline at end of file
diff --git a/analysis/analysis-api/testData/components/referenceShortener/referenceShortener/memberVsCompanionObjectMemberConflict.txt b/analysis/analysis-api/testData/components/referenceShortener/referenceShortener/memberVsCompanionObjectMemberConflict.txt
new file mode 100644
index 0000000..a28388a
--- /dev/null
+++ b/analysis/analysis-api/testData/components/referenceShortener/referenceShortener/memberVsCompanionObjectMemberConflict.txt
@@ -0,0 +1,5 @@
+Before shortening: MyClass.prop
+with DO_NOT_SHORTEN:
+with SHORTEN_IF_ALREADY_IMPORTED:
+with SHORTEN_AND_IMPORT:
+with SHORTEN_AND_STAR_IMPORT:
diff --git a/analysis/analysis-api/testData/components/referenceShortener/referenceShortener/staticMethodFromBaseClassConflict.kt b/analysis/analysis-api/testData/components/referenceShortener/referenceShortener/staticMethodFromBaseClassConflict.kt
new file mode 100644
index 0000000..945861d
--- /dev/null
+++ b/analysis/analysis-api/testData/components/referenceShortener/referenceShortener/staticMethodFromBaseClassConflict.kt
@@ -0,0 +1,26 @@
+// FILE: main.kt
+package test
+
+import dependency.Middle
+import dependency.Base
+
+class MyClass : Middle {
+ <expr>fun usage() {
+ Middle.test()
+ Base.test()
+ }</expr>
+}
+
+// FILE: dependency/Middle.java
+package dependency;
+
+public class Middle extends Base {
+ public static void test() {}
+}
+
+// FILE: dependency/Base.java
+package dependency;
+
+public class Base {
+ public static void test() {}
+}
diff --git a/analysis/analysis-api/testData/components/referenceShortener/referenceShortener/staticMethodFromBaseClassConflict.txt b/analysis/analysis-api/testData/components/referenceShortener/referenceShortener/staticMethodFromBaseClassConflict.txt
new file mode 100644
index 0000000..9ab993a
--- /dev/null
+++ b/analysis/analysis-api/testData/components/referenceShortener/referenceShortener/staticMethodFromBaseClassConflict.txt
@@ -0,0 +1,11 @@
+Before shortening: fun usage() {
+ Middle.test()
+ Base.test()
+ }
+with DO_NOT_SHORTEN:
+with SHORTEN_IF_ALREADY_IMPORTED:
+[qualifier] Middle.test()
+with SHORTEN_AND_IMPORT:
+[qualifier] Middle.test()
+with SHORTEN_AND_STAR_IMPORT:
+[qualifier] Middle.test()