KTIJ-26103 [Analysis API] Ignore implicit dispatch receivers in Reference Shortener
Calls to extension functions imported from objects have implicit dispatch receivers, but those receivers are not present in the code and should not be analyzed by the shortener ^KTIJ-26103 Fixed
This commit is contained in:
@@ -5,6 +5,7 @@
|
||||
|
||||
package org.jetbrains.kotlin.analysis.api.fir
|
||||
|
||||
import org.jetbrains.kotlin.KtFakeSourceElementKind
|
||||
import org.jetbrains.kotlin.analysis.api.annotations.KtAnnotationApplicationInfo
|
||||
import org.jetbrains.kotlin.analysis.api.annotations.KtAnnotationApplicationWithArgumentsInfo
|
||||
import org.jetbrains.kotlin.analysis.api.annotations.KtNamedAnnotationValue
|
||||
@@ -17,6 +18,7 @@ import org.jetbrains.kotlin.fir.diagnostics.ConeDiagnostic
|
||||
import org.jetbrains.kotlin.fir.expressions.FirAnnotation
|
||||
import org.jetbrains.kotlin.fir.expressions.FirAnnotationCall
|
||||
import org.jetbrains.kotlin.fir.expressions.FirFunctionCall
|
||||
import org.jetbrains.kotlin.fir.expressions.FirResolvedQualifier
|
||||
import org.jetbrains.kotlin.fir.expressions.arguments
|
||||
import org.jetbrains.kotlin.fir.psi
|
||||
import org.jetbrains.kotlin.fir.references.FirErrorNamedReference
|
||||
@@ -94,3 +96,21 @@ internal fun FirAnnotation.toKtAnnotationInfo(
|
||||
isCallWithArguments = this is FirAnnotationCall && arguments.isNotEmpty(),
|
||||
index = index,
|
||||
)
|
||||
|
||||
/**
|
||||
* Implicit dispatch receiver is present when an extension function declared in object
|
||||
* is imported somewhere else and used without directly referencing the object instance
|
||||
* itself:
|
||||
*
|
||||
* ```kt
|
||||
* import Foo.bar
|
||||
*
|
||||
* object Foo { fun String.bar() {} }
|
||||
*
|
||||
* fun usage() {
|
||||
* "hello".bar() // this call has implicit 'Foo' dispatch receiver
|
||||
* }
|
||||
* ```
|
||||
*/
|
||||
internal val FirResolvedQualifier.isImplicitDispatchReceiver: Boolean
|
||||
get() = source?.kind == KtFakeSourceElementKind.ImplicitReceiver
|
||||
|
||||
+2
-2
@@ -5,11 +5,11 @@
|
||||
|
||||
package org.jetbrains.kotlin.analysis.api.fir.components
|
||||
|
||||
import org.jetbrains.kotlin.KtFakeSourceElementKind
|
||||
import org.jetbrains.kotlin.KtRealSourceElementKind
|
||||
import org.jetbrains.kotlin.analysis.api.components.KtImportOptimizer
|
||||
import org.jetbrains.kotlin.analysis.api.components.KtImportOptimizerResult
|
||||
import org.jetbrains.kotlin.analysis.api.fir.getCandidateSymbols
|
||||
import org.jetbrains.kotlin.analysis.api.fir.isImplicitDispatchReceiver
|
||||
import org.jetbrains.kotlin.analysis.api.fir.utils.FirBodyReanalyzingVisitorVoid
|
||||
import org.jetbrains.kotlin.analysis.api.fir.utils.computeImportableName
|
||||
import org.jetbrains.kotlin.analysis.api.lifetime.KtLifetimeToken
|
||||
@@ -274,7 +274,7 @@ internal class KtFirImportOptimizer(
|
||||
val dispatchReceiver = dispatchReceiver
|
||||
if (
|
||||
dispatchReceiver !is FirResolvedQualifier ||
|
||||
dispatchReceiver.source?.kind != KtFakeSourceElementKind.ImplicitReceiver
|
||||
!dispatchReceiver.isImplicitDispatchReceiver
|
||||
) {
|
||||
return null
|
||||
}
|
||||
|
||||
+3
@@ -14,6 +14,7 @@ import org.jetbrains.kotlin.analysis.api.components.ShortenCommand
|
||||
import org.jetbrains.kotlin.analysis.api.components.ShortenOption
|
||||
import org.jetbrains.kotlin.analysis.api.fir.KtFirAnalysisSession
|
||||
import org.jetbrains.kotlin.analysis.api.fir.components.ElementsToShortenCollector.PartialOrderOfScope.Companion.toPartialOrder
|
||||
import org.jetbrains.kotlin.analysis.api.fir.isImplicitDispatchReceiver
|
||||
import org.jetbrains.kotlin.analysis.api.fir.utils.FirBodyReanalyzingVisitorVoid
|
||||
import org.jetbrains.kotlin.analysis.api.fir.utils.computeImportableName
|
||||
import org.jetbrains.kotlin.analysis.api.lifetime.KtLifetimeToken
|
||||
@@ -427,6 +428,8 @@ private class ElementsToShortenCollector(
|
||||
}
|
||||
|
||||
private fun processTypeQualifier(resolvedQualifier: FirResolvedQualifier) {
|
||||
if (resolvedQualifier.isImplicitDispatchReceiver) return
|
||||
|
||||
val wholeClassQualifier = resolvedQualifier.classId ?: return
|
||||
val qualifierPsi = resolvedQualifier.psi ?: return
|
||||
if (!qualifierPsi.textRange.intersects(selection)) return
|
||||
|
||||
+6
@@ -232,6 +232,12 @@ public class FirIdeNormalAnalysisSourceModuleReferenceShortenerTestGenerated ext
|
||||
runTest("analysis/analysis-api/testData/components/referenceShortener/referenceShortener/enumEntryInitUsesCompanion2.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("extensionFromObject.kt")
|
||||
public void testExtensionFromObject() throws Exception {
|
||||
runTest("analysis/analysis-api/testData/components/referenceShortener/referenceShortener/extensionFromObject.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("multipleImport.kt")
|
||||
public void testMultipleImport() throws Exception {
|
||||
|
||||
Reference in New Issue
Block a user