[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
This commit is contained in:
+3
-24
@@ -977,31 +977,10 @@ private class ElementsToShortenCollector(
|
|||||||
if (candidates.mapNotNull { it.candidate.originScope }
|
if (candidates.mapNotNull { it.candidate.originScope }
|
||||||
.hasScopeCloserThan(scopeForQualifiedAccess, expressionInScope)) return false
|
.hasScopeCloserThan(scopeForQualifiedAccess, expressionInScope)) return false
|
||||||
val candidatesWithinSamePriorityScopes = candidates.filter { it.candidate.originScope == scopeForQualifiedAccess }
|
val candidatesWithinSamePriorityScopes = candidates.filter { it.candidate.originScope == scopeForQualifiedAccess }
|
||||||
if (candidatesWithinSamePriorityScopes.isEmpty() || candidatesWithinSamePriorityScopes.size == 1) return true
|
|
||||||
|
|
||||||
/**
|
// TODO isInBestCandidates should probably be used more actively to filter candidates
|
||||||
* This is a conservative decision to avoid false positives.
|
return candidatesWithinSamePriorityScopes.isEmpty() ||
|
||||||
*
|
candidatesWithinSamePriorityScopes.singleOrNull()?.isInBestCandidates == true
|
||||||
* 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
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun processPropertyAccess(firPropertyAccess: FirPropertyAccessExpression) {
|
private fun processPropertyAccess(firPropertyAccess: FirPropertyAccessExpression) {
|
||||||
|
|||||||
+12
@@ -298,6 +298,12 @@ public class FirIdeNormalAnalysisSourceModuleReferenceShortenerTestGenerated ext
|
|||||||
runTest("analysis/analysis-api/testData/components/referenceShortener/referenceShortener/kdocUnresolved.kt");
|
runTest("analysis/analysis-api/testData/components/referenceShortener/referenceShortener/kdocUnresolved.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("memberVsCompanionObjectMemberConflict.kt")
|
||||||
|
public void testMemberVsCompanionObjectMemberConflict() throws Exception {
|
||||||
|
runTest("analysis/analysis-api/testData/components/referenceShortener/referenceShortener/memberVsCompanionObjectMemberConflict.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("multipleImport.kt")
|
@TestMetadata("multipleImport.kt")
|
||||||
public void testMultipleImport() throws Exception {
|
public void testMultipleImport() throws Exception {
|
||||||
@@ -436,6 +442,12 @@ public class FirIdeNormalAnalysisSourceModuleReferenceShortenerTestGenerated ext
|
|||||||
runTest("analysis/analysis-api/testData/components/referenceShortener/referenceShortener/shortenAlreadyImportedFunction4.kt");
|
runTest("analysis/analysis-api/testData/components/referenceShortener/referenceShortener/shortenAlreadyImportedFunction4.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("staticMethodFromBaseClassConflict.kt")
|
||||||
|
public void testStaticMethodFromBaseClassConflict() throws Exception {
|
||||||
|
runTest("analysis/analysis-api/testData/components/referenceShortener/referenceShortener/staticMethodFromBaseClassConflict.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("superClass.kt")
|
@TestMetadata("superClass.kt")
|
||||||
public void testSuperClass() throws Exception {
|
public void testSuperClass() throws Exception {
|
||||||
|
|||||||
+12
@@ -298,6 +298,12 @@ public class FirStandaloneNormalAnalysisSourceModuleReferenceShortenerTestGenera
|
|||||||
runTest("analysis/analysis-api/testData/components/referenceShortener/referenceShortener/kdocUnresolved.kt");
|
runTest("analysis/analysis-api/testData/components/referenceShortener/referenceShortener/kdocUnresolved.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("memberVsCompanionObjectMemberConflict.kt")
|
||||||
|
public void testMemberVsCompanionObjectMemberConflict() throws Exception {
|
||||||
|
runTest("analysis/analysis-api/testData/components/referenceShortener/referenceShortener/memberVsCompanionObjectMemberConflict.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("multipleImport.kt")
|
@TestMetadata("multipleImport.kt")
|
||||||
public void testMultipleImport() throws Exception {
|
public void testMultipleImport() throws Exception {
|
||||||
@@ -436,6 +442,12 @@ public class FirStandaloneNormalAnalysisSourceModuleReferenceShortenerTestGenera
|
|||||||
runTest("analysis/analysis-api/testData/components/referenceShortener/referenceShortener/shortenAlreadyImportedFunction4.kt");
|
runTest("analysis/analysis-api/testData/components/referenceShortener/referenceShortener/shortenAlreadyImportedFunction4.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("staticMethodFromBaseClassConflict.kt")
|
||||||
|
public void testStaticMethodFromBaseClassConflict() throws Exception {
|
||||||
|
runTest("analysis/analysis-api/testData/components/referenceShortener/referenceShortener/staticMethodFromBaseClassConflict.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("superClass.kt")
|
@TestMetadata("superClass.kt")
|
||||||
public void testSuperClass() throws Exception {
|
public void testSuperClass() throws Exception {
|
||||||
|
|||||||
+15
@@ -0,0 +1,15 @@
|
|||||||
|
package test
|
||||||
|
|
||||||
|
class MyClass {
|
||||||
|
companion object {
|
||||||
|
val prop = ""
|
||||||
|
}
|
||||||
|
|
||||||
|
object Other {
|
||||||
|
val prop = ""
|
||||||
|
|
||||||
|
fun usage() {
|
||||||
|
println(<expr>MyClass.prop</expr>)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+5
@@ -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:
|
||||||
+26
@@ -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() {}
|
||||||
|
}
|
||||||
+11
@@ -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()
|
||||||
Reference in New Issue
Block a user