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 65def45640b..20f34310032 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 @@ -30,7 +30,6 @@ import org.jetbrains.kotlin.analysis.low.level.api.fir.api.resolveToFirSymbol import org.jetbrains.kotlin.analysis.low.level.api.fir.element.builder.FirTowerContextProvider import org.jetbrains.kotlin.analysis.low.level.api.fir.resolver.AllCandidatesResolver import org.jetbrains.kotlin.analysis.utils.printer.parentsOfType -import org.jetbrains.kotlin.descriptors.ClassKind import org.jetbrains.kotlin.fir.* import org.jetbrains.kotlin.fir.analysis.checkers.toRegularClassSymbol import org.jetbrains.kotlin.fir.declarations.* @@ -985,6 +984,9 @@ private class ElementsToShortenCollector( } private fun processPropertyAccess(firPropertyAccess: FirPropertyAccessExpression) { + // if explicit receiver is a property access or a function call, we cannot shorten it + if (!canBePossibleToDropReceiver(firPropertyAccess)) return + val propertyReferenceExpression = firPropertyAccess.correspondingNameReference ?: return if (!propertyReferenceExpression.textRange.intersects(selection)) return @@ -996,10 +998,6 @@ private class ElementsToShortenCollector( val scopes = shorteningContext.findScopesAtPosition(qualifiedProperty, getNamesToImport(), towerContextProvider) ?: return val availableCallables = shorteningContext.findPropertiesInScopes(scopes, propertySymbol.name) - - // if explicit receiver is a property access or a function call, we cannot shorten it - if (firPropertyAccess.explicitReceiver !is FirResolvedQualifier) return - if (availableCallables.isNotEmpty() && shortenIfAlreadyImported(firPropertyAccess, propertySymbol, qualifiedProperty)) { addElementToShorten(ShortenQualifier(qualifiedProperty)) return @@ -1100,15 +1098,12 @@ private class ElementsToShortenCollector( callToShorten?.let(::addElementToShorten) } - private fun canBePossibleToDropReceiver(functionCall: FirFunctionCall): Boolean { + private fun canBePossibleToDropReceiver(qualifiedAccess: FirQualifiedAccessExpression): Boolean { // we can remove receiver only if it is a qualifier - val explicitReceiver = functionCall.explicitReceiver as? FirResolvedQualifier ?: return false + if (qualifiedAccess.explicitReceiver !is FirResolvedQualifier) return false // if there is no extension receiver necessary, then it can be removed - if (functionCall.extensionReceiver is FirNoReceiverExpression) return true - - val receiverType = shorteningContext.getRegularClass(explicitReceiver.typeRef) ?: return true - return receiverType.classKind != ClassKind.OBJECT + return qualifiedAccess.extensionReceiver is FirNoReceiverExpression } private fun findUnambiguousReferencedCallableId(namedReference: FirNamedReference): FirCallableSymbol<*>? { 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 514a6234080..4c4a9c16f83 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 @@ -244,6 +244,18 @@ public class FirIdeNormalAnalysisSourceModuleReferenceShortenerTestGenerated ext runTest("analysis/analysis-api/testData/components/referenceShortener/referenceShortener/extensionFromObject.kt"); } + @Test + @TestMetadata("extensionFunction_objectReceiverWithOtherThisInScope.kt") + public void testExtensionFunction_objectReceiverWithOtherThisInScope() throws Exception { + runTest("analysis/analysis-api/testData/components/referenceShortener/referenceShortener/extensionFunction_objectReceiverWithOtherThisInScope.kt"); + } + + @Test + @TestMetadata("extensionProperty_objectReceiverWithOtherThisInScope.kt") + public void testExtensionProperty_objectReceiverWithOtherThisInScope() throws Exception { + runTest("analysis/analysis-api/testData/components/referenceShortener/referenceShortener/extensionProperty_objectReceiverWithOtherThisInScope.kt"); + } + @Test @TestMetadata("kdoc.kt") public void testKdoc() throws Exception { 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 b413405e88b..550a7d46a13 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 @@ -244,6 +244,18 @@ public class FirStandaloneNormalAnalysisSourceModuleReferenceShortenerTestGenera runTest("analysis/analysis-api/testData/components/referenceShortener/referenceShortener/extensionFromObject.kt"); } + @Test + @TestMetadata("extensionFunction_objectReceiverWithOtherThisInScope.kt") + public void testExtensionFunction_objectReceiverWithOtherThisInScope() throws Exception { + runTest("analysis/analysis-api/testData/components/referenceShortener/referenceShortener/extensionFunction_objectReceiverWithOtherThisInScope.kt"); + } + + @Test + @TestMetadata("extensionProperty_objectReceiverWithOtherThisInScope.kt") + public void testExtensionProperty_objectReceiverWithOtherThisInScope() throws Exception { + runTest("analysis/analysis-api/testData/components/referenceShortener/referenceShortener/extensionProperty_objectReceiverWithOtherThisInScope.kt"); + } + @Test @TestMetadata("kdoc.kt") public void testKdoc() throws Exception { diff --git a/analysis/analysis-api/testData/components/referenceShortener/referenceShortener/extensionFunction_objectReceiverWithOtherThisInScope.kt b/analysis/analysis-api/testData/components/referenceShortener/referenceShortener/extensionFunction_objectReceiverWithOtherThisInScope.kt new file mode 100644 index 00000000000..6aea25fe8dd --- /dev/null +++ b/analysis/analysis-api/testData/components/referenceShortener/referenceShortener/extensionFunction_objectReceiverWithOtherThisInScope.kt @@ -0,0 +1,11 @@ +package test + +fun T.extFun(): T = this + +object Bar + +class Other + +fun Other.usage() { + Bar.extFun() +} diff --git a/analysis/analysis-api/testData/components/referenceShortener/referenceShortener/extensionFunction_objectReceiverWithOtherThisInScope.txt b/analysis/analysis-api/testData/components/referenceShortener/referenceShortener/extensionFunction_objectReceiverWithOtherThisInScope.txt new file mode 100644 index 00000000000..adbdab4c0ed --- /dev/null +++ b/analysis/analysis-api/testData/components/referenceShortener/referenceShortener/extensionFunction_objectReceiverWithOtherThisInScope.txt @@ -0,0 +1,5 @@ +Before shortening: Bar.extFun() +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/extensionProperty_objectReceiverWithOtherThisInScope.kt b/analysis/analysis-api/testData/components/referenceShortener/referenceShortener/extensionProperty_objectReceiverWithOtherThisInScope.kt new file mode 100644 index 00000000000..c7487509252 --- /dev/null +++ b/analysis/analysis-api/testData/components/referenceShortener/referenceShortener/extensionProperty_objectReceiverWithOtherThisInScope.kt @@ -0,0 +1,12 @@ +package test + +val T.extProperty: T + get() = this + +object Bar + +class Other + +fun Other.usage() { + Bar.extProperty +} diff --git a/analysis/analysis-api/testData/components/referenceShortener/referenceShortener/extensionProperty_objectReceiverWithOtherThisInScope.txt b/analysis/analysis-api/testData/components/referenceShortener/referenceShortener/extensionProperty_objectReceiverWithOtherThisInScope.txt new file mode 100644 index 00000000000..a49fe73b860 --- /dev/null +++ b/analysis/analysis-api/testData/components/referenceShortener/referenceShortener/extensionProperty_objectReceiverWithOtherThisInScope.txt @@ -0,0 +1,5 @@ +Before shortening: Bar.extProperty +with DO_NOT_SHORTEN: +with SHORTEN_IF_ALREADY_IMPORTED: +with SHORTEN_AND_IMPORT: +with SHORTEN_AND_STAR_IMPORT: