KTIJ-26627 [AA] Correctly handle object receivers of property accesses
Also remove redundant code from `canBePossibleToDropReceiver` ^KTIJ-26627 Fixed
This commit is contained in:
+6
-11
@@ -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.element.builder.FirTowerContextProvider
|
||||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.resolver.AllCandidatesResolver
|
import org.jetbrains.kotlin.analysis.low.level.api.fir.resolver.AllCandidatesResolver
|
||||||
import org.jetbrains.kotlin.analysis.utils.printer.parentsOfType
|
import org.jetbrains.kotlin.analysis.utils.printer.parentsOfType
|
||||||
import org.jetbrains.kotlin.descriptors.ClassKind
|
|
||||||
import org.jetbrains.kotlin.fir.*
|
import org.jetbrains.kotlin.fir.*
|
||||||
import org.jetbrains.kotlin.fir.analysis.checkers.toRegularClassSymbol
|
import org.jetbrains.kotlin.fir.analysis.checkers.toRegularClassSymbol
|
||||||
import org.jetbrains.kotlin.fir.declarations.*
|
import org.jetbrains.kotlin.fir.declarations.*
|
||||||
@@ -985,6 +984,9 @@ private class ElementsToShortenCollector(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun processPropertyAccess(firPropertyAccess: FirPropertyAccessExpression) {
|
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
|
val propertyReferenceExpression = firPropertyAccess.correspondingNameReference ?: return
|
||||||
if (!propertyReferenceExpression.textRange.intersects(selection)) return
|
if (!propertyReferenceExpression.textRange.intersects(selection)) return
|
||||||
|
|
||||||
@@ -996,10 +998,6 @@ private class ElementsToShortenCollector(
|
|||||||
|
|
||||||
val scopes = shorteningContext.findScopesAtPosition(qualifiedProperty, getNamesToImport(), towerContextProvider) ?: return
|
val scopes = shorteningContext.findScopesAtPosition(qualifiedProperty, getNamesToImport(), towerContextProvider) ?: return
|
||||||
val availableCallables = shorteningContext.findPropertiesInScopes(scopes, propertySymbol.name)
|
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)) {
|
if (availableCallables.isNotEmpty() && shortenIfAlreadyImported(firPropertyAccess, propertySymbol, qualifiedProperty)) {
|
||||||
addElementToShorten(ShortenQualifier(qualifiedProperty))
|
addElementToShorten(ShortenQualifier(qualifiedProperty))
|
||||||
return
|
return
|
||||||
@@ -1100,15 +1098,12 @@ private class ElementsToShortenCollector(
|
|||||||
callToShorten?.let(::addElementToShorten)
|
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
|
// 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 there is no extension receiver necessary, then it can be removed
|
||||||
if (functionCall.extensionReceiver is FirNoReceiverExpression) return true
|
return qualifiedAccess.extensionReceiver is FirNoReceiverExpression
|
||||||
|
|
||||||
val receiverType = shorteningContext.getRegularClass(explicitReceiver.typeRef) ?: return true
|
|
||||||
return receiverType.classKind != ClassKind.OBJECT
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun findUnambiguousReferencedCallableId(namedReference: FirNamedReference): FirCallableSymbol<*>? {
|
private fun findUnambiguousReferencedCallableId(namedReference: FirNamedReference): FirCallableSymbol<*>? {
|
||||||
|
|||||||
+12
@@ -244,6 +244,18 @@ public class FirIdeNormalAnalysisSourceModuleReferenceShortenerTestGenerated ext
|
|||||||
runTest("analysis/analysis-api/testData/components/referenceShortener/referenceShortener/extensionFromObject.kt");
|
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
|
@Test
|
||||||
@TestMetadata("kdoc.kt")
|
@TestMetadata("kdoc.kt")
|
||||||
public void testKdoc() throws Exception {
|
public void testKdoc() throws Exception {
|
||||||
|
|||||||
+12
@@ -244,6 +244,18 @@ public class FirStandaloneNormalAnalysisSourceModuleReferenceShortenerTestGenera
|
|||||||
runTest("analysis/analysis-api/testData/components/referenceShortener/referenceShortener/extensionFromObject.kt");
|
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
|
@Test
|
||||||
@TestMetadata("kdoc.kt")
|
@TestMetadata("kdoc.kt")
|
||||||
public void testKdoc() throws Exception {
|
public void testKdoc() throws Exception {
|
||||||
|
|||||||
+11
@@ -0,0 +1,11 @@
|
|||||||
|
package test
|
||||||
|
|
||||||
|
fun <T> T.extFun(): T = this
|
||||||
|
|
||||||
|
object Bar
|
||||||
|
|
||||||
|
class Other
|
||||||
|
|
||||||
|
fun Other.usage() {
|
||||||
|
<expr>Bar.extFun()</expr>
|
||||||
|
}
|
||||||
+5
@@ -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:
|
||||||
+12
@@ -0,0 +1,12 @@
|
|||||||
|
package test
|
||||||
|
|
||||||
|
val <T> T.extProperty: T
|
||||||
|
get() = this
|
||||||
|
|
||||||
|
object Bar
|
||||||
|
|
||||||
|
class Other
|
||||||
|
|
||||||
|
fun Other.usage() {
|
||||||
|
<expr>Bar.extProperty</expr>
|
||||||
|
}
|
||||||
+5
@@ -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:
|
||||||
Reference in New Issue
Block a user