diff --git a/compiler/fir/psi2fir/testData/rawBuilder/expressions/these.txt b/compiler/fir/psi2fir/testData/rawBuilder/expressions/these.txt index 09ff96cf3ee..3c28f5184fa 100644 --- a/compiler/fir/psi2fir/testData/rawBuilder/expressions/these.txt +++ b/compiler/fir/psi2fir/testData/rawBuilder/expressions/these.txt @@ -14,11 +14,11 @@ FILE: these.kt public? final? val instance: Some public? get(): Some { - ^ this@Some + ^ this@Some# } public? final? fun String.extension(): Int { - ^extension this@Some.bar#().plus#(this#.length#) + ^extension this@Some#.bar#().plus#(this#.length#) } } @@ -27,7 +27,7 @@ FILE: these.kt } public? final? fun test(some: Some): Int { ^test with#(some#, = with@fun .(): { - this#.foo#().plus#(this@with.extension#()) + this#.foo#().plus#(this@with#.extension#()) } ) } diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/FirCallResolver.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/FirCallResolver.kt index 3ca414dd130..186424f54bf 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/FirCallResolver.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/FirCallResolver.kt @@ -39,7 +39,7 @@ class FirCallResolver( private val transformer: FirBodyResolveTransformer, private val topLevelScopes: List, private val localScopes: List, - private val implicitReceiverStack: List, + private val implicitReceiverStack: List>, private val qualifiedResolver: FirQualifiedNameResolver ) : BodyResolveComponents by transformer { diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/ResolveUtils.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/ResolveUtils.kt index 5749375fe25..6c21d5aad5d 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/ResolveUtils.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/ResolveUtils.kt @@ -274,9 +274,9 @@ fun BodyResolveComponents.typeFromCallee(access: T): FirReso } is FirThisReference -> { val labelName = newCallee.labelName - val types = if (labelName == null) labels.values() else labels[Name.identifier(labelName)] - val type = types.lastOrNull() ?: ConeKotlinErrorType("Unresolved this@$labelName") - FirResolvedTypeRefImpl(null, type, emptyList()) + val implicitReceivers = if (labelName == null) implicitReceiverPerLabel.values() else implicitReceiverPerLabel[Name.identifier(labelName)] + val implicitReceiver = implicitReceivers.lastOrNull() + FirResolvedTypeRefImpl(null, implicitReceiver?.type ?: ConeKotlinErrorType("Unresolved this@$labelName"), emptyList()) } else -> error("Failed to extract type from: $newCallee") } diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/SessionHolder.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/SessionHolder.kt index a703a9098ff..7b10ef28c74 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/SessionHolder.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/SessionHolder.kt @@ -10,6 +10,7 @@ import org.jetbrains.kotlin.fir.FirSession import org.jetbrains.kotlin.fir.declarations.FirDeclaration import org.jetbrains.kotlin.fir.declarations.FirFile import org.jetbrains.kotlin.fir.declarations.FirResolvePhase +import org.jetbrains.kotlin.fir.resolve.calls.ImplicitReceiverValue import org.jetbrains.kotlin.fir.resolve.calls.InferenceComponents import org.jetbrains.kotlin.fir.resolve.calls.ResolutionStageRunner import org.jetbrains.kotlin.fir.resolve.transformers.ReturnTypeCalculator @@ -26,7 +27,7 @@ interface SessionHolder { interface BodyResolveComponents : SessionHolder { val returnTypeCalculator: ReturnTypeCalculator - val labels: SetMultimap + val implicitReceiverPerLabel: SetMultimap> val noExpectedType: FirTypeRef val symbolProvider: FirSymbolProvider val file: FirFile diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/CallResolver.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/CallResolver.kt index 1580d30b115..32a4f3f5bad 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/CallResolver.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/CallResolver.kt @@ -27,7 +27,7 @@ class CallResolver( private fun processImplicitReceiver( towerDataConsumer: TowerDataConsumer, - implicitReceiverValue: ImplicitReceiverValue, + implicitReceiverValue: ImplicitReceiverValue<*>, oldGroup: Int ): Int { var group = oldGroup @@ -147,9 +147,9 @@ class CallResolver( val collector by lazy { CandidateCollector(components, resolutionStageRunner) } lateinit var towerDataConsumer: TowerDataConsumer - private lateinit var implicitReceiverValues: List + private lateinit var implicitReceiverValues: List> - fun runTowerResolver(consumer: TowerDataConsumer, implicitReceiverValues: List): CandidateCollector { + fun runTowerResolver(consumer: TowerDataConsumer, implicitReceiverValues: List>): CandidateCollector { this.implicitReceiverValues = implicitReceiverValues towerDataConsumer = consumer diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/Candidate.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/Candidate.kt index a319e59e9eb..7c5b671cf16 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/Candidate.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/Candidate.kt @@ -46,7 +46,7 @@ enum class CandidateApplicability { class Candidate( val symbol: AbstractFirBasedSymbol<*>, val dispatchReceiverValue: ClassDispatchReceiverValue?, - val implicitExtensionReceiverValue: ImplicitReceiverValue?, + val implicitExtensionReceiverValue: ImplicitReceiverValue<*>?, val explicitReceiverKind: ExplicitReceiverKind, private val inferenceComponents: InferenceComponents, private val baseSystem: ConstraintStorage, diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/CandidateFactory.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/CandidateFactory.kt index 8c9cf3a6687..2e2d272a1e2 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/CandidateFactory.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/CandidateFactory.kt @@ -31,7 +31,7 @@ class CandidateFactory( fun createCandidate( symbol: AbstractFirBasedSymbol<*>, dispatchReceiverValue: ClassDispatchReceiverValue?, - implicitExtensionReceiverValue: ImplicitReceiverValue?, + implicitExtensionReceiverValue: ImplicitReceiverValue<*>?, explicitReceiverKind: ExplicitReceiverKind ): Candidate { return Candidate( diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/FirReceivers.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/FirReceivers.kt index a14d100e9ca..9d051c9b3a2 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/FirReceivers.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/FirReceivers.kt @@ -13,6 +13,8 @@ import org.jetbrains.kotlin.fir.resolve.FirSymbolProvider import org.jetbrains.kotlin.fir.resolve.ScopeSession import org.jetbrains.kotlin.fir.resolve.scope import org.jetbrains.kotlin.fir.scopes.FirScope +import org.jetbrains.kotlin.fir.symbols.AbstractFirBasedSymbol +import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirClassSymbol import org.jetbrains.kotlin.fir.types.* import org.jetbrains.kotlin.fir.types.impl.ConeClassTypeImpl @@ -41,7 +43,8 @@ class ExpressionReceiverValue( ?: ConeKotlinErrorType("No type calculated for: ${explicitReceiverExpression.renderWithType()}") // TODO: assert here } -abstract class ImplicitReceiverValue( +abstract class ImplicitReceiverValue>( + val boundSymbol: S, final override val type: ConeKotlinType, useSiteSession: FirSession, scopeSession: ScopeSession @@ -52,19 +55,20 @@ abstract class ImplicitReceiverValue( } class ImplicitDispatchReceiverValue( - val boundSymbol: FirClassSymbol, + boundSymbol: FirClassSymbol, type: ConeKotlinType, symbolProvider: FirSymbolProvider, useSiteSession: FirSession, scopeSession: ScopeSession -) : ImplicitReceiverValue(type, useSiteSession, scopeSession) { +) : ImplicitReceiverValue(boundSymbol, type, useSiteSession, scopeSession) { val implicitCompanionScope: FirScope? = boundSymbol.fir.companionObject?.let { companionObject -> symbolProvider.getClassUseSiteMemberScope(companionObject.classId, useSiteSession, scopeSession) } } class ImplicitExtensionReceiverValue( + boundSymbol: FirCallableSymbol<*>, type: ConeKotlinType, useSiteSession: FirSession, scopeSession: ScopeSession -) : ImplicitReceiverValue(type, useSiteSession, scopeSession) +) : ImplicitReceiverValue>(boundSymbol, type, useSiteSession, scopeSession) diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/TowerDataConsumers.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/TowerDataConsumers.kt index 4d5099e6748..72c6825f55c 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/TowerDataConsumers.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/TowerDataConsumers.kt @@ -64,7 +64,7 @@ class QualifiedReceiverTowerDataConsumer>( override fun consumeCandidate( symbol: T, dispatchReceiverValue: ClassDispatchReceiverValue?, - implicitExtensionReceiverValue: ImplicitReceiverValue? + implicitExtensionReceiverValue: ImplicitReceiverValue<*>? ): ProcessorAction { assert(dispatchReceiverValue == null) resultCollector.consumeCandidate( @@ -191,7 +191,7 @@ class ExplicitReceiverTowerDataConsumer>( override fun consumeCandidate( symbol: T, dispatchReceiverValue: ClassDispatchReceiverValue?, - implicitExtensionReceiverValue: ImplicitReceiverValue? + implicitExtensionReceiverValue: ImplicitReceiverValue<*>? ): ProcessorAction { resultCollector.consumeCandidate( group, @@ -210,7 +210,7 @@ class ExplicitReceiverTowerDataConsumer>( override fun consumeCandidate( symbol: T, dispatchReceiverValue: ClassDispatchReceiverValue?, - implicitExtensionReceiverValue: ImplicitReceiverValue? + implicitExtensionReceiverValue: ImplicitReceiverValue<*>? ): ProcessorAction { if (symbol is FirNamedFunctionSymbol && symbol.callableId.packageName.startsWith(defaultPackage)) { val explicitReceiverType = explicitReceiver.type @@ -280,7 +280,7 @@ class NoExplicitReceiverTowerDataConsumer>( override fun consumeCandidate( symbol: T, dispatchReceiverValue: ClassDispatchReceiverValue?, - implicitExtensionReceiverValue: ImplicitReceiverValue? + implicitExtensionReceiverValue: ImplicitReceiverValue<*>? ): ProcessorAction { resultCollector.consumeCandidate( group, diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/TowerLevels.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/TowerLevels.kt index c251216294a..de986b1acdf 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/TowerLevels.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/TowerLevels.kt @@ -51,7 +51,7 @@ interface TowerScopeLevel { fun consumeCandidate( symbol: T, dispatchReceiverValue: ClassDispatchReceiverValue?, - implicitExtensionReceiverValue: ImplicitReceiverValue? + implicitExtensionReceiverValue: ImplicitReceiverValue<*>? ): ProcessorAction } @@ -90,7 +90,7 @@ abstract class SessionBasedTowerLevel(val session: FirSession) : TowerScopeLevel class MemberScopeTowerLevel( session: FirSession, val dispatchReceiver: ReceiverValue, - val implicitExtensionReceiver: ImplicitReceiverValue? = null, + val implicitExtensionReceiver: ImplicitReceiverValue<*>? = null, val scopeSession: ScopeSession ) : SessionBasedTowerLevel(session) { private fun > processMembers( @@ -150,7 +150,7 @@ class MemberScopeTowerLevel( class ScopeTowerLevel( session: FirSession, val scope: FirScope, - val implicitExtensionReceiver: ImplicitReceiverValue? = null + val implicitExtensionReceiver: ImplicitReceiverValue<*>? = null ) : SessionBasedTowerLevel(session) { private fun FirCallableSymbol<*>.hasConsistentReceivers(extensionReceiver: ReceiverValue?): Boolean = hasConsistentExtensionReceiver(extensionReceiver) && (scope is FirAbstractImportingScope || dispatchReceiverValue() == null) diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirBodyResolveTransformer.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirBodyResolveTransformer.kt index 517dac8088c..e0752682818 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirBodyResolveTransformer.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirBodyResolveTransformer.kt @@ -12,6 +12,7 @@ import org.jetbrains.kotlin.fir.declarations.* import org.jetbrains.kotlin.fir.declarations.impl.FirDefaultPropertyAccessor import org.jetbrains.kotlin.fir.declarations.impl.FirValueParameterImpl import org.jetbrains.kotlin.fir.expressions.* +import org.jetbrains.kotlin.fir.references.FirExplicitThisReference import org.jetbrains.kotlin.fir.references.FirSimpleNamedReference import org.jetbrains.kotlin.fir.resolve.* import org.jetbrains.kotlin.fir.resolve.calls.* @@ -48,7 +49,6 @@ open class FirBodyResolveTransformer( private set final override val returnTypeCalculator: ReturnTypeCalculator = ReturnTypeCalculatorWithJump(session, scopeSession) - final override val labels: SetMultimap = LinkedHashMultimap.create() final override val noExpectedType = FirImplicitTypeRefImpl(null) private val booleanType = FirImplicitBooleanTypeRef(null) @@ -67,7 +67,8 @@ open class FirBodyResolveTransformer( private val localScopes = mutableListOf() private val topLevelScopes = mutableListOf() - private val implicitReceiverStack = mutableListOf() + final override val implicitReceiverPerLabel: SetMultimap> = LinkedHashMultimap.create() + private val implicitReceiverStack = mutableListOf>() final override val inferenceComponents = inferenceComponents(session, returnTypeCalculator, scopeSession) private var primaryConstructorParametersScope: FirLocalScope? = null @@ -197,11 +198,16 @@ open class FirBodyResolveTransformer( ): CompositeTransformResult { when (val callee = qualifiedAccessExpression.calleeReference) { - is FirThisReference -> { + is FirExplicitThisReference -> { val labelName = callee.labelName - val types = if (labelName == null) labels.values() else labels[Name.identifier(labelName)] - val type = types.lastOrNull() ?: ConeKotlinErrorType("Unresolved this@$labelName") - qualifiedAccessExpression.resultType = FirResolvedTypeRefImpl(null, type, emptyList()) + val implicitReceivers = + if (labelName == null) implicitReceiverPerLabel.values() else implicitReceiverPerLabel[Name.identifier(labelName)] + val implicitReceiver = implicitReceivers.lastOrNull() + callee.candidateOwner = implicitReceiver?.boundSymbol + qualifiedAccessExpression.resultType = FirResolvedTypeRefImpl( + null, implicitReceiver?.type ?: ConeKotlinErrorType("Unresolved this@$labelName"), + emptyList() + ) return qualifiedAccessExpression.compose() } is FirSuperReference -> { @@ -366,7 +372,9 @@ open class FirBodyResolveTransformer( val label = anonymousFunction.label return if (label != null && receiverTypeRef != null) { - withLabelAndReceiverType(Name.identifier(label.name), anonymousFunction, receiverTypeRef.coneTypeUnsafe()) { transform() } + withLabelAndReceiverType(Name.identifier(label.name), anonymousFunction, receiverTypeRef.coneTypeUnsafe()) { + transform() + } } else { transform() } @@ -768,22 +776,28 @@ open class FirBodyResolveTransformer( // ----------------------- Util functions ----------------------- - private inline fun withLabelAndReceiverType(labelName: Name, owner: FirElement, type: ConeKotlinType, block: () -> T): T { - labels.put(labelName, type) - implicitReceiverStack += when (owner) { + private inline fun withLabelAndReceiverType( + labelName: Name, + owner: FirDeclaration, + type: ConeKotlinType, + block: () -> T + ): T { + val implicitReceiverValue = when (owner) { is FirRegularClass -> { ImplicitDispatchReceiverValue(owner.symbol, type, symbolProvider, session, scopeSession) } is FirFunction<*> -> { - ImplicitExtensionReceiverValue(type, session, scopeSession) + ImplicitExtensionReceiverValue(owner.symbol, type, session, scopeSession) } else -> { throw IllegalArgumentException("Incorrect label & receiver owner: ${owner.javaClass}") } } + implicitReceiverPerLabel.put(labelName, implicitReceiverValue) + implicitReceiverStack += implicitReceiverValue val result = block() implicitReceiverStack.removeAt(implicitReceiverStack.size - 1) - labels.remove(labelName, type) + implicitReceiverPerLabel.remove(labelName, implicitReceiverValue) return result } diff --git a/compiler/fir/resolve/testData/resolve/builtins/lists.kt b/compiler/fir/resolve/testData/resolve/builtins/lists.kt index 7bc9fcf408e..8eb5d168b34 100644 --- a/compiler/fir/resolve/testData/resolve/builtins/lists.kt +++ b/compiler/fir/resolve/testData/resolve/builtins/lists.kt @@ -2,4 +2,4 @@ abstract class MyStringList : List abstract class MyMutableStringList : MutableList fun List.convert(): MyStringList = this as MyStringList -fun ret(l: MutableList): MyMutableStringList = this as MyMutableStringList \ No newline at end of file +fun ret(l: MutableList): MyMutableStringList = l as MyMutableStringList \ No newline at end of file diff --git a/compiler/fir/resolve/testData/resolve/builtins/lists.txt b/compiler/fir/resolve/testData/resolve/builtins/lists.txt index 4fd5e409f23..4862f5e31bd 100644 --- a/compiler/fir/resolve/testData/resolve/builtins/lists.txt +++ b/compiler/fir/resolve/testData/resolve/builtins/lists.txt @@ -12,8 +12,8 @@ FILE: lists.kt } public final fun R|kotlin/collections/List|.convert(): R|MyStringList| { - ^convert (this# as R|MyStringList|) + ^convert (this@R|/convert| as R|MyStringList|) } public final fun ret(l: R|kotlin/collections/MutableList|): R|MyMutableStringList| { - ^ret (this# as R|MyMutableStringList|) + ^ret (R|/l| as R|MyMutableStringList|) } diff --git a/compiler/fir/resolve/testData/resolve/expresssions/access.txt b/compiler/fir/resolve/testData/resolve/expresssions/access.txt index 0c5b26249ec..d65189aa8a5 100644 --- a/compiler/fir/resolve/testData/resolve/expresssions/access.txt +++ b/compiler/fir/resolve/testData/resolve/expresssions/access.txt @@ -29,7 +29,7 @@ FILE: access.kt } public final fun bar(): R|Bar| { - ^bar this# + ^bar this@R|/Bar| } public final operator fun R|kotlin/String|.plus(bar: R|Bar|): R|kotlin/String| { diff --git a/compiler/fir/resolve/testData/resolve/expresssions/invoke/explicitReceiver.txt b/compiler/fir/resolve/testData/resolve/expresssions/invoke/explicitReceiver.txt index e3eb36d1897..25436acc6a9 100644 --- a/compiler/fir/resolve/testData/resolve/expresssions/invoke/explicitReceiver.txt +++ b/compiler/fir/resolve/testData/resolve/expresssions/invoke/explicitReceiver.txt @@ -10,7 +10,7 @@ FILE: explicitReceiver.kt public get(): R|Foo| public final operator fun invoke(): R|Foo| { - ^invoke this# + ^invoke this@R|/Foo| } public final fun bar(): R|Foo| { @@ -30,7 +30,7 @@ FILE: explicitReceiver.kt public get(): R|Bar| public final operator fun invoke(): R|Bar| { - ^invoke this# + ^invoke this@R|/Bar| } public final fun baz(): R|kotlin/Unit| { diff --git a/compiler/fir/resolve/testData/resolve/expresssions/invoke/explicitReceiver2.txt b/compiler/fir/resolve/testData/resolve/expresssions/invoke/explicitReceiver2.txt index 34e929ab808..96b05b6e029 100644 --- a/compiler/fir/resolve/testData/resolve/expresssions/invoke/explicitReceiver2.txt +++ b/compiler/fir/resolve/testData/resolve/expresssions/invoke/explicitReceiver2.txt @@ -5,7 +5,7 @@ FILE: explicitReceiver2.kt } public final operator fun invoke(): R|Foo| { - ^invoke this# + ^invoke this@R|/Bar| } } @@ -17,7 +17,7 @@ FILE: explicitReceiver2.kt } public final operator fun R|Bar|.invoke(): R|Foo| { - ^invoke this# + ^invoke this@R|/Foo.invoke| } public final val x: R|Bar| = R|/Bar.Bar|() diff --git a/compiler/fir/resolve/testData/resolve/expresssions/invoke/extension.txt b/compiler/fir/resolve/testData/resolve/expresssions/invoke/extension.txt index 1d20f8cea49..36aa54f067e 100644 --- a/compiler/fir/resolve/testData/resolve/expresssions/invoke/extension.txt +++ b/compiler/fir/resolve/testData/resolve/expresssions/invoke/extension.txt @@ -7,7 +7,7 @@ FILE: extension.kt } public final operator fun R|kotlin/Int|.invoke(): R|Foo| { - ^invoke this@Foo + ^invoke this@R|/Foo| } public final val x: R|kotlin/Int| = Int(0) diff --git a/compiler/fir/resolve/testData/resolve/expresssions/invoke/farInvokeExtension.txt b/compiler/fir/resolve/testData/resolve/expresssions/invoke/farInvokeExtension.txt index 0526accb5a3..47254f040e5 100644 --- a/compiler/fir/resolve/testData/resolve/expresssions/invoke/farInvokeExtension.txt +++ b/compiler/fir/resolve/testData/resolve/expresssions/invoke/farInvokeExtension.txt @@ -2,7 +2,7 @@ FILE: farInvokeExtension.kt public final fun x(): R|kotlin/Unit| { } public final operator fun R|kotlin/Int|.invoke(): R|Foo| { - ^invoke this@Foo + ^invoke this@Foo# } public final class Foo : R|kotlin/Any| { public constructor(): R|Foo| { diff --git a/compiler/fir/resolve/testData/resolve/expresssions/invoke/implicitTypeOrder.txt b/compiler/fir/resolve/testData/resolve/expresssions/invoke/implicitTypeOrder.txt index a9424bd87c9..122a093634f 100644 --- a/compiler/fir/resolve/testData/resolve/expresssions/invoke/implicitTypeOrder.txt +++ b/compiler/fir/resolve/testData/resolve/expresssions/invoke/implicitTypeOrder.txt @@ -9,7 +9,7 @@ FILE: implicitTypeOrder.kt } public final fun invoke(): R|A| { - ^invoke this# + ^invoke this@R|/A| } } diff --git a/compiler/fir/resolve/testData/resolve/expresssions/invoke/threeReceivers.txt b/compiler/fir/resolve/testData/resolve/expresssions/invoke/threeReceivers.txt index 4be02bce53d..8a1be596659 100644 --- a/compiler/fir/resolve/testData/resolve/expresssions/invoke/threeReceivers.txt +++ b/compiler/fir/resolve/testData/resolve/expresssions/invoke/threeReceivers.txt @@ -5,7 +5,7 @@ FILE: threeReceivers.kt } public final fun R|FooBar|.invoke(): R|Bar| { - ^invoke this# + ^invoke this@R|/Bar.invoke| } } diff --git a/compiler/fir/resolve/testData/resolve/expresssions/objects.txt b/compiler/fir/resolve/testData/resolve/expresssions/objects.txt index 3db15fcf254..850e089eafe 100644 --- a/compiler/fir/resolve/testData/resolve/expresssions/objects.txt +++ b/compiler/fir/resolve/testData/resolve/expresssions/objects.txt @@ -5,7 +5,7 @@ FILE: objects.kt } public final fun foo(): R|A| { - ^foo this# + ^foo this@R|/A| } } diff --git a/compiler/fir/resolve/testData/resolve/expresssions/this.txt b/compiler/fir/resolve/testData/resolve/expresssions/this.txt index 6ce5edc9e83..ce30d0254c1 100644 --- a/compiler/fir/resolve/testData/resolve/expresssions/this.txt +++ b/compiler/fir/resolve/testData/resolve/expresssions/this.txt @@ -11,19 +11,19 @@ FILE: this.kt } public final fun bar(): R|Foo| { - ^bar this# + ^bar this@R|/Foo| } public final fun R|Bar|.buz(): R|Bar| { - ^buz this# + ^buz this@R|/Foo.buz| } public final fun R|Bar|.foo(): R|Foo| { - ^foo this@Foo + ^foo this@R|/Foo| } public final fun R|Bar|.foobar(): R|Bar| { - ^foobar this@foobar + ^foobar this@R|/Foo.foobar| } } diff --git a/compiler/fir/resolve/testData/resolve/fromBuilder/noPrimaryConstructor.txt b/compiler/fir/resolve/testData/resolve/fromBuilder/noPrimaryConstructor.txt index 1d8de32469f..20a04461b55 100644 --- a/compiler/fir/resolve/testData/resolve/fromBuilder/noPrimaryConstructor.txt +++ b/compiler/fir/resolve/testData/resolve/fromBuilder/noPrimaryConstructor.txt @@ -5,7 +5,7 @@ FILE: noPrimaryConstructor.kt public constructor(x: R|kotlin/String|): R|NoPrimary| { super() - this#.R|/NoPrimary.x| = R|/x| + this@R|/NoPrimary|.R|/NoPrimary.x| = R|/x| } public constructor(): R|NoPrimary| { diff --git a/compiler/fir/resolve/testData/resolve/fromBuilder/typeParameters.txt b/compiler/fir/resolve/testData/resolve/fromBuilder/typeParameters.txt index ff0c71974fb..c34614874a2 100644 --- a/compiler/fir/resolve/testData/resolve/fromBuilder/typeParameters.txt +++ b/compiler/fir/resolve/testData/resolve/fromBuilder/typeParameters.txt @@ -23,7 +23,7 @@ FILE: typeParameters.kt } public final override fun concat(other: R|List|): R|List| { - ^concat this# + ^concat this@R|/SomeList| } } diff --git a/compiler/fir/resolve/testData/resolve/genericFunctions.txt b/compiler/fir/resolve/testData/resolve/genericFunctions.txt index 086b8248783..f183883c3db 100644 --- a/compiler/fir/resolve/testData/resolve/genericFunctions.txt +++ b/compiler/fir/resolve/testData/resolve/genericFunctions.txt @@ -2,7 +2,7 @@ FILE: genericFunctions.kt public abstract interface Any : R|kotlin/Any| { } public final inline fun R|Any|.safeAs(): R|T?| { - ^safeAs (this# as? R|T|) + ^safeAs (this@R|/safeAs| as? R|T|) } public abstract class Summator : R|kotlin/Any| { public constructor(): R|Summator| { diff --git a/compiler/fir/resolve/testData/resolve/nested/inner.txt b/compiler/fir/resolve/testData/resolve/nested/inner.txt index 5acaceb8493..6a814c72516 100644 --- a/compiler/fir/resolve/testData/resolve/nested/inner.txt +++ b/compiler/fir/resolve/testData/resolve/nested/inner.txt @@ -6,7 +6,7 @@ FILE: inner.kt public final fun foo(): R|kotlin/Unit| { R|/Owner.bar|() - this#.R|/Owner.bar|() + this@R|/Owner|.R|/Owner.bar|() } public final fun bar(): R|kotlin/Unit| { @@ -24,15 +24,15 @@ FILE: inner.kt public final fun baz(): R|kotlin/Unit| { R|/Owner.Inner.gau|() - this#.R|/Owner.Inner.gau|() + this@R|/Owner.Inner|.R|/Owner.Inner.gau|() } public final fun gau(): R|kotlin/Unit| { lval o: R|Owner| = R|/Owner.Owner|() R|/o|.R|/Owner.foo|() R|/Owner.foo|() - this@Owner.R|/Owner.foo|() - this#.#() + this@R|/Owner|.R|/Owner.foo|() + this@R|/Owner.Inner|.#() } } diff --git a/compiler/fir/resolve/testData/resolve/nested/simple.txt b/compiler/fir/resolve/testData/resolve/nested/simple.txt index 8a045b7ab61..d098af2b959 100644 --- a/compiler/fir/resolve/testData/resolve/nested/simple.txt +++ b/compiler/fir/resolve/testData/resolve/nested/simple.txt @@ -6,7 +6,7 @@ FILE: simple.kt public final fun foo(): R|kotlin/Unit| { R|/Owner.bar|() - this#.R|/Owner.bar|() + this@R|/Owner|.R|/Owner.bar|() } public final fun bar(): R|kotlin/Unit| { @@ -21,7 +21,7 @@ FILE: simple.kt public final fun baz(): R|kotlin/Unit| { R|/Owner.Nested.gau|() - this#.R|/Owner.Nested.gau|() + this@R|/Owner.Nested|.R|/Owner.Nested.gau|() } public final fun gau(): R|kotlin/Unit| { @@ -31,7 +31,7 @@ FILE: simple.kt public final fun err(): R|kotlin/Unit| { #() - this#.#() + this@R|/Owner.Nested|.#() } } diff --git a/compiler/fir/resolve/testData/resolve/overrides/simple.txt b/compiler/fir/resolve/testData/resolve/overrides/simple.txt index 98f1502ce1e..381dab00501 100644 --- a/compiler/fir/resolve/testData/resolve/overrides/simple.txt +++ b/compiler/fir/resolve/testData/resolve/overrides/simple.txt @@ -5,15 +5,15 @@ FILE: simple.kt } public open fun foo(): R|A| { - ^foo this# + ^foo this@R|/A| } public open fun bar(): R|A| { - ^bar this# + ^bar this@R|/A| } public open fun buz(p: R|A|): R|A| { - ^buz this# + ^buz this@R|/A| } } @@ -23,15 +23,15 @@ FILE: simple.kt } public final override fun foo(): R|B| { - ^foo this# + ^foo this@R|/B| } public final fun bar(): R|B| { - ^bar this# + ^bar this@R|/B| } public final override fun buz(p: R|B|): R|B| { - ^buz this# + ^buz this@R|/B| } public final fun test(): R|kotlin/Unit| { diff --git a/compiler/fir/resolve/testData/resolve/recursiveCallOnWhenWithSealedClass.txt b/compiler/fir/resolve/testData/resolve/recursiveCallOnWhenWithSealedClass.txt index 8045f6676a5..acb722ad5fb 100644 --- a/compiler/fir/resolve/testData/resolve/recursiveCallOnWhenWithSealedClass.txt +++ b/compiler/fir/resolve/testData/resolve/recursiveCallOnWhenWithSealedClass.txt @@ -28,7 +28,7 @@ FILE: recursiveCallOnWhenWithSealedClass.kt } public final fun unwrap(): { - ^unwrap when (this#) { + ^unwrap when (this@R|/Maybe|) { ($subj$ is R|Maybe.Nope|) -> { throw R|java/lang/Exception.Exception|(String()) } diff --git a/compiler/fir/resolve/testData/resolve/stdlib/arrayFirstOrNull.txt b/compiler/fir/resolve/testData/resolve/stdlib/arrayFirstOrNull.txt index 4511de8fe52..13538e9090e 100644 --- a/compiler/fir/resolve/testData/resolve/stdlib/arrayFirstOrNull.txt +++ b/compiler/fir/resolve/testData/resolve/stdlib/arrayFirstOrNull.txt @@ -13,7 +13,7 @@ FILE: arrayFirstOrNull.kt Null(null) } else -> { - this#.R|FakeOverride|(Int(0)) + this@R|/firstOrNullX|.R|FakeOverride|(Int(0)) } } diff --git a/compiler/fir/resolve/testData/resolve/stdlib/mapList.txt b/compiler/fir/resolve/testData/resolve/stdlib/mapList.txt index 0f58d36bd23..f13425a12bd 100644 --- a/compiler/fir/resolve/testData/resolve/stdlib/mapList.txt +++ b/compiler/fir/resolve/testData/resolve/stdlib/mapList.txt @@ -6,7 +6,7 @@ FILE: mapList.kt } ) R|/u|.R|/applyX||>( = applyX@fun R|kotlin/collections/List|.(it: R|kotlin/collections/List|): R|kotlin/Unit| { - this#.R|FakeOverride|(Int(1)) + this@R|special/anonymous|.R|FakeOverride|(Int(1)) R|FakeOverride|(Int(1)) } ) diff --git a/compiler/fir/resolve/testData/resolve/stdlib/simpleDelegatedToMap.txt b/compiler/fir/resolve/testData/resolve/stdlib/simpleDelegatedToMap.txt index 7414c3644d6..4f809582e3d 100644 --- a/compiler/fir/resolve/testData/resolve/stdlib/simpleDelegatedToMap.txt +++ b/compiler/fir/resolve/testData/resolve/stdlib/simpleDelegatedToMap.txt @@ -9,10 +9,10 @@ FILE: simpleDelegatedToMap.kt public final var foo: by R|/map| public get(): { - ^ D|/C.foo|.#(this#, ::R|/C.foo|) + ^ D|/C.foo|.#(this@R|/C|, ::R|/C.foo|) } public set(: ): R|kotlin/Unit| { - D|/C.foo|.#(this#, ::R|/C.foo|, R|/|) + D|/C.foo|.#(this@R|/C|, ::R|/C.foo|, R|/|) } } diff --git a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/FirRenderer.kt b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/FirRenderer.kt index a4686da4191..2b76e7855f9 100644 --- a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/FirRenderer.kt +++ b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/FirRenderer.kt @@ -15,10 +15,7 @@ import org.jetbrains.kotlin.fir.expressions.impl.FirExpressionStub import org.jetbrains.kotlin.fir.expressions.impl.FirLoopJump import org.jetbrains.kotlin.fir.expressions.impl.FirUnitExpression import org.jetbrains.kotlin.fir.references.FirErrorNamedReference -import org.jetbrains.kotlin.fir.symbols.ConeCallableSymbol -import org.jetbrains.kotlin.fir.symbols.ConeClassLikeLookupTag -import org.jetbrains.kotlin.fir.symbols.ConeClassLikeSymbol -import org.jetbrains.kotlin.fir.symbols.StandardClassIds +import org.jetbrains.kotlin.fir.symbols.* import org.jetbrains.kotlin.fir.symbols.impl.FirNamedFunctionSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirPropertySymbol import org.jetbrains.kotlin.fir.types.* @@ -755,16 +752,19 @@ class FirRenderer(builder: StringBuilder) : FirVisitorVoid() { print("*") } + private fun ConeSymbol.render(): String { + if (this is ConeCallableSymbol) + return callableId.toString() + else if (this is ConeClassLikeSymbol) + return classId.toString() + return "?" + } + override fun visitNamedReference(namedReference: FirNamedReference) { val symbol = namedReference.candidateSymbol when { symbol != null -> { - print("R?C|") - if (symbol is ConeCallableSymbol) - print(symbol.callableId) - else if (symbol is ConeClassLikeSymbol) - print(symbol.classId) - print("|") + print("R?C|${symbol.render()}|") } namedReference is FirErrorNamedReference -> print("<${namedReference.errorReason}>#") else -> print("${namedReference.name}#") @@ -791,10 +791,7 @@ class FirRenderer(builder: StringBuilder) : FirVisitorVoid() { print("FakeOverride<") } val symbol = resolvedCallableReference.coneSymbol - if (symbol is ConeCallableSymbol) - print(symbol.callableId) - else if (symbol is ConeClassLikeSymbol) - print(symbol.classId) + print(symbol.render()) if (isFakeOverride) { when (symbol) { is FirNamedFunctionSymbol -> { @@ -814,10 +811,11 @@ class FirRenderer(builder: StringBuilder) : FirVisitorVoid() { override fun visitThisReference(thisReference: FirThisReference) { print("this") val labelName = thisReference.labelName - if (labelName != null) { - print("@$labelName") - } else { - print("#") + val symbol = thisReference.candidateOwner + when { + symbol != null -> print("@R|${symbol.render()}|") + labelName != null -> print("@$labelName#") + else -> print("#") } } diff --git a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/FirThisReference.kt b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/FirThisReference.kt index 0abd31dd7b1..774f0881515 100644 --- a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/FirThisReference.kt +++ b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/FirThisReference.kt @@ -5,11 +5,14 @@ package org.jetbrains.kotlin.fir +import org.jetbrains.kotlin.fir.symbols.AbstractFirBasedSymbol import org.jetbrains.kotlin.fir.visitors.FirVisitor interface FirThisReference : FirReference { val labelName: String? + val candidateOwner: AbstractFirBasedSymbol<*>? get() = null + override fun accept(visitor: FirVisitor, data: D): R = visitor.visitThisReference(this, data) } \ No newline at end of file diff --git a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/references/FirExplicitThisReference.kt b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/references/FirExplicitThisReference.kt index 7578ba0cbb7..597f5be3891 100644 --- a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/references/FirExplicitThisReference.kt +++ b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/references/FirExplicitThisReference.kt @@ -8,5 +8,8 @@ package org.jetbrains.kotlin.fir.references import com.intellij.psi.PsiElement import org.jetbrains.kotlin.fir.FirAbstractElement import org.jetbrains.kotlin.fir.FirThisReference +import org.jetbrains.kotlin.fir.symbols.AbstractFirBasedSymbol -class FirExplicitThisReference(psi: PsiElement?, override val labelName: String?) : FirAbstractElement(psi), FirThisReference \ No newline at end of file +class FirExplicitThisReference(psi: PsiElement?, override val labelName: String?) : FirAbstractElement(psi), FirThisReference { + override var candidateOwner: AbstractFirBasedSymbol<*>? = null +} \ No newline at end of file