FIR: set bound symbol for explicit this references

This commit is contained in:
Mikhail Glukhikh
2019-08-26 18:20:59 +03:00
parent aa79064a96
commit 6604539154
35 changed files with 116 additions and 93 deletions
@@ -14,11 +14,11 @@ FILE: these.kt
public? final? val instance: Some public? final? val instance: Some
public? get(): Some { public? get(): Some {
^ this@Some ^ this@Some#
} }
public? final? fun String.extension(): Int { 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 { public? final? fun test(some: Some): Int {
^test with#(some#, <L> = with@fun <implicit>.<anonymous>(): <implicit> { ^test with#(some#, <L> = with@fun <implicit>.<anonymous>(): <implicit> {
this#.foo#().plus#(this@with.extension#()) this#.foo#().plus#(this@with#.extension#())
} }
) )
} }
@@ -39,7 +39,7 @@ class FirCallResolver(
private val transformer: FirBodyResolveTransformer, private val transformer: FirBodyResolveTransformer,
private val topLevelScopes: List<FirScope>, private val topLevelScopes: List<FirScope>,
private val localScopes: List<FirLocalScope>, private val localScopes: List<FirLocalScope>,
private val implicitReceiverStack: List<ImplicitReceiverValue>, private val implicitReceiverStack: List<ImplicitReceiverValue<*>>,
private val qualifiedResolver: FirQualifiedNameResolver private val qualifiedResolver: FirQualifiedNameResolver
) : BodyResolveComponents by transformer { ) : BodyResolveComponents by transformer {
@@ -274,9 +274,9 @@ fun <T : FirResolvable> BodyResolveComponents.typeFromCallee(access: T): FirReso
} }
is FirThisReference -> { is FirThisReference -> {
val labelName = newCallee.labelName val labelName = newCallee.labelName
val types = if (labelName == null) labels.values() else labels[Name.identifier(labelName)] val implicitReceivers = if (labelName == null) implicitReceiverPerLabel.values() else implicitReceiverPerLabel[Name.identifier(labelName)]
val type = types.lastOrNull() ?: ConeKotlinErrorType("Unresolved this@$labelName") val implicitReceiver = implicitReceivers.lastOrNull()
FirResolvedTypeRefImpl(null, type, emptyList()) FirResolvedTypeRefImpl(null, implicitReceiver?.type ?: ConeKotlinErrorType("Unresolved this@$labelName"), emptyList())
} }
else -> error("Failed to extract type from: $newCallee") else -> error("Failed to extract type from: $newCallee")
} }
@@ -10,6 +10,7 @@ import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.declarations.FirDeclaration import org.jetbrains.kotlin.fir.declarations.FirDeclaration
import org.jetbrains.kotlin.fir.declarations.FirFile import org.jetbrains.kotlin.fir.declarations.FirFile
import org.jetbrains.kotlin.fir.declarations.FirResolvePhase 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.InferenceComponents
import org.jetbrains.kotlin.fir.resolve.calls.ResolutionStageRunner import org.jetbrains.kotlin.fir.resolve.calls.ResolutionStageRunner
import org.jetbrains.kotlin.fir.resolve.transformers.ReturnTypeCalculator import org.jetbrains.kotlin.fir.resolve.transformers.ReturnTypeCalculator
@@ -26,7 +27,7 @@ interface SessionHolder {
interface BodyResolveComponents : SessionHolder { interface BodyResolveComponents : SessionHolder {
val returnTypeCalculator: ReturnTypeCalculator val returnTypeCalculator: ReturnTypeCalculator
val labels: SetMultimap<Name, ConeKotlinType> val implicitReceiverPerLabel: SetMultimap<Name, ImplicitReceiverValue<*>>
val noExpectedType: FirTypeRef val noExpectedType: FirTypeRef
val symbolProvider: FirSymbolProvider val symbolProvider: FirSymbolProvider
val file: FirFile val file: FirFile
@@ -27,7 +27,7 @@ class CallResolver(
private fun processImplicitReceiver( private fun processImplicitReceiver(
towerDataConsumer: TowerDataConsumer, towerDataConsumer: TowerDataConsumer,
implicitReceiverValue: ImplicitReceiverValue, implicitReceiverValue: ImplicitReceiverValue<*>,
oldGroup: Int oldGroup: Int
): Int { ): Int {
var group = oldGroup var group = oldGroup
@@ -147,9 +147,9 @@ class CallResolver(
val collector by lazy { CandidateCollector(components, resolutionStageRunner) } val collector by lazy { CandidateCollector(components, resolutionStageRunner) }
lateinit var towerDataConsumer: TowerDataConsumer lateinit var towerDataConsumer: TowerDataConsumer
private lateinit var implicitReceiverValues: List<ImplicitReceiverValue> private lateinit var implicitReceiverValues: List<ImplicitReceiverValue<*>>
fun runTowerResolver(consumer: TowerDataConsumer, implicitReceiverValues: List<ImplicitReceiverValue>): CandidateCollector { fun runTowerResolver(consumer: TowerDataConsumer, implicitReceiverValues: List<ImplicitReceiverValue<*>>): CandidateCollector {
this.implicitReceiverValues = implicitReceiverValues this.implicitReceiverValues = implicitReceiverValues
towerDataConsumer = consumer towerDataConsumer = consumer
@@ -46,7 +46,7 @@ enum class CandidateApplicability {
class Candidate( class Candidate(
val symbol: AbstractFirBasedSymbol<*>, val symbol: AbstractFirBasedSymbol<*>,
val dispatchReceiverValue: ClassDispatchReceiverValue?, val dispatchReceiverValue: ClassDispatchReceiverValue?,
val implicitExtensionReceiverValue: ImplicitReceiverValue?, val implicitExtensionReceiverValue: ImplicitReceiverValue<*>?,
val explicitReceiverKind: ExplicitReceiverKind, val explicitReceiverKind: ExplicitReceiverKind,
private val inferenceComponents: InferenceComponents, private val inferenceComponents: InferenceComponents,
private val baseSystem: ConstraintStorage, private val baseSystem: ConstraintStorage,
@@ -31,7 +31,7 @@ class CandidateFactory(
fun createCandidate( fun createCandidate(
symbol: AbstractFirBasedSymbol<*>, symbol: AbstractFirBasedSymbol<*>,
dispatchReceiverValue: ClassDispatchReceiverValue?, dispatchReceiverValue: ClassDispatchReceiverValue?,
implicitExtensionReceiverValue: ImplicitReceiverValue?, implicitExtensionReceiverValue: ImplicitReceiverValue<*>?,
explicitReceiverKind: ExplicitReceiverKind explicitReceiverKind: ExplicitReceiverKind
): Candidate { ): Candidate {
return Candidate( return Candidate(
@@ -13,6 +13,8 @@ import org.jetbrains.kotlin.fir.resolve.FirSymbolProvider
import org.jetbrains.kotlin.fir.resolve.ScopeSession import org.jetbrains.kotlin.fir.resolve.ScopeSession
import org.jetbrains.kotlin.fir.resolve.scope import org.jetbrains.kotlin.fir.resolve.scope
import org.jetbrains.kotlin.fir.scopes.FirScope 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.symbols.impl.FirClassSymbol
import org.jetbrains.kotlin.fir.types.* import org.jetbrains.kotlin.fir.types.*
import org.jetbrains.kotlin.fir.types.impl.ConeClassTypeImpl import org.jetbrains.kotlin.fir.types.impl.ConeClassTypeImpl
@@ -41,7 +43,8 @@ class ExpressionReceiverValue(
?: ConeKotlinErrorType("No type calculated for: ${explicitReceiverExpression.renderWithType()}") // TODO: assert here ?: ConeKotlinErrorType("No type calculated for: ${explicitReceiverExpression.renderWithType()}") // TODO: assert here
} }
abstract class ImplicitReceiverValue( abstract class ImplicitReceiverValue<S : AbstractFirBasedSymbol<*>>(
val boundSymbol: S,
final override val type: ConeKotlinType, final override val type: ConeKotlinType,
useSiteSession: FirSession, useSiteSession: FirSession,
scopeSession: ScopeSession scopeSession: ScopeSession
@@ -52,19 +55,20 @@ abstract class ImplicitReceiverValue(
} }
class ImplicitDispatchReceiverValue( class ImplicitDispatchReceiverValue(
val boundSymbol: FirClassSymbol, boundSymbol: FirClassSymbol,
type: ConeKotlinType, type: ConeKotlinType,
symbolProvider: FirSymbolProvider, symbolProvider: FirSymbolProvider,
useSiteSession: FirSession, useSiteSession: FirSession,
scopeSession: ScopeSession scopeSession: ScopeSession
) : ImplicitReceiverValue(type, useSiteSession, scopeSession) { ) : ImplicitReceiverValue<FirClassSymbol>(boundSymbol, type, useSiteSession, scopeSession) {
val implicitCompanionScope: FirScope? = boundSymbol.fir.companionObject?.let { companionObject -> val implicitCompanionScope: FirScope? = boundSymbol.fir.companionObject?.let { companionObject ->
symbolProvider.getClassUseSiteMemberScope(companionObject.classId, useSiteSession, scopeSession) symbolProvider.getClassUseSiteMemberScope(companionObject.classId, useSiteSession, scopeSession)
} }
} }
class ImplicitExtensionReceiverValue( class ImplicitExtensionReceiverValue(
boundSymbol: FirCallableSymbol<*>,
type: ConeKotlinType, type: ConeKotlinType,
useSiteSession: FirSession, useSiteSession: FirSession,
scopeSession: ScopeSession scopeSession: ScopeSession
) : ImplicitReceiverValue(type, useSiteSession, scopeSession) ) : ImplicitReceiverValue<FirCallableSymbol<*>>(boundSymbol, type, useSiteSession, scopeSession)
@@ -64,7 +64,7 @@ class QualifiedReceiverTowerDataConsumer<T : AbstractFirBasedSymbol<*>>(
override fun consumeCandidate( override fun consumeCandidate(
symbol: T, symbol: T,
dispatchReceiverValue: ClassDispatchReceiverValue?, dispatchReceiverValue: ClassDispatchReceiverValue?,
implicitExtensionReceiverValue: ImplicitReceiverValue? implicitExtensionReceiverValue: ImplicitReceiverValue<*>?
): ProcessorAction { ): ProcessorAction {
assert(dispatchReceiverValue == null) assert(dispatchReceiverValue == null)
resultCollector.consumeCandidate( resultCollector.consumeCandidate(
@@ -191,7 +191,7 @@ class ExplicitReceiverTowerDataConsumer<T : AbstractFirBasedSymbol<*>>(
override fun consumeCandidate( override fun consumeCandidate(
symbol: T, symbol: T,
dispatchReceiverValue: ClassDispatchReceiverValue?, dispatchReceiverValue: ClassDispatchReceiverValue?,
implicitExtensionReceiverValue: ImplicitReceiverValue? implicitExtensionReceiverValue: ImplicitReceiverValue<*>?
): ProcessorAction { ): ProcessorAction {
resultCollector.consumeCandidate( resultCollector.consumeCandidate(
group, group,
@@ -210,7 +210,7 @@ class ExplicitReceiverTowerDataConsumer<T : AbstractFirBasedSymbol<*>>(
override fun consumeCandidate( override fun consumeCandidate(
symbol: T, symbol: T,
dispatchReceiverValue: ClassDispatchReceiverValue?, dispatchReceiverValue: ClassDispatchReceiverValue?,
implicitExtensionReceiverValue: ImplicitReceiverValue? implicitExtensionReceiverValue: ImplicitReceiverValue<*>?
): ProcessorAction { ): ProcessorAction {
if (symbol is FirNamedFunctionSymbol && symbol.callableId.packageName.startsWith(defaultPackage)) { if (symbol is FirNamedFunctionSymbol && symbol.callableId.packageName.startsWith(defaultPackage)) {
val explicitReceiverType = explicitReceiver.type val explicitReceiverType = explicitReceiver.type
@@ -280,7 +280,7 @@ class NoExplicitReceiverTowerDataConsumer<T : AbstractFirBasedSymbol<*>>(
override fun consumeCandidate( override fun consumeCandidate(
symbol: T, symbol: T,
dispatchReceiverValue: ClassDispatchReceiverValue?, dispatchReceiverValue: ClassDispatchReceiverValue?,
implicitExtensionReceiverValue: ImplicitReceiverValue? implicitExtensionReceiverValue: ImplicitReceiverValue<*>?
): ProcessorAction { ): ProcessorAction {
resultCollector.consumeCandidate( resultCollector.consumeCandidate(
group, group,
@@ -51,7 +51,7 @@ interface TowerScopeLevel {
fun consumeCandidate( fun consumeCandidate(
symbol: T, symbol: T,
dispatchReceiverValue: ClassDispatchReceiverValue?, dispatchReceiverValue: ClassDispatchReceiverValue?,
implicitExtensionReceiverValue: ImplicitReceiverValue? implicitExtensionReceiverValue: ImplicitReceiverValue<*>?
): ProcessorAction ): ProcessorAction
} }
@@ -90,7 +90,7 @@ abstract class SessionBasedTowerLevel(val session: FirSession) : TowerScopeLevel
class MemberScopeTowerLevel( class MemberScopeTowerLevel(
session: FirSession, session: FirSession,
val dispatchReceiver: ReceiverValue, val dispatchReceiver: ReceiverValue,
val implicitExtensionReceiver: ImplicitReceiverValue? = null, val implicitExtensionReceiver: ImplicitReceiverValue<*>? = null,
val scopeSession: ScopeSession val scopeSession: ScopeSession
) : SessionBasedTowerLevel(session) { ) : SessionBasedTowerLevel(session) {
private fun <T : AbstractFirBasedSymbol<*>> processMembers( private fun <T : AbstractFirBasedSymbol<*>> processMembers(
@@ -150,7 +150,7 @@ class MemberScopeTowerLevel(
class ScopeTowerLevel( class ScopeTowerLevel(
session: FirSession, session: FirSession,
val scope: FirScope, val scope: FirScope,
val implicitExtensionReceiver: ImplicitReceiverValue? = null val implicitExtensionReceiver: ImplicitReceiverValue<*>? = null
) : SessionBasedTowerLevel(session) { ) : SessionBasedTowerLevel(session) {
private fun FirCallableSymbol<*>.hasConsistentReceivers(extensionReceiver: ReceiverValue?): Boolean = private fun FirCallableSymbol<*>.hasConsistentReceivers(extensionReceiver: ReceiverValue?): Boolean =
hasConsistentExtensionReceiver(extensionReceiver) && (scope is FirAbstractImportingScope || dispatchReceiverValue() == null) hasConsistentExtensionReceiver(extensionReceiver) && (scope is FirAbstractImportingScope || dispatchReceiverValue() == null)
@@ -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.FirDefaultPropertyAccessor
import org.jetbrains.kotlin.fir.declarations.impl.FirValueParameterImpl import org.jetbrains.kotlin.fir.declarations.impl.FirValueParameterImpl
import org.jetbrains.kotlin.fir.expressions.* 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.references.FirSimpleNamedReference
import org.jetbrains.kotlin.fir.resolve.* import org.jetbrains.kotlin.fir.resolve.*
import org.jetbrains.kotlin.fir.resolve.calls.* import org.jetbrains.kotlin.fir.resolve.calls.*
@@ -48,7 +49,6 @@ open class FirBodyResolveTransformer(
private set private set
final override val returnTypeCalculator: ReturnTypeCalculator = ReturnTypeCalculatorWithJump(session, scopeSession) final override val returnTypeCalculator: ReturnTypeCalculator = ReturnTypeCalculatorWithJump(session, scopeSession)
final override val labels: SetMultimap<Name, ConeKotlinType> = LinkedHashMultimap.create()
final override val noExpectedType = FirImplicitTypeRefImpl(null) final override val noExpectedType = FirImplicitTypeRefImpl(null)
private val booleanType = FirImplicitBooleanTypeRef(null) private val booleanType = FirImplicitBooleanTypeRef(null)
@@ -67,7 +67,8 @@ open class FirBodyResolveTransformer(
private val localScopes = mutableListOf<FirLocalScope>() private val localScopes = mutableListOf<FirLocalScope>()
private val topLevelScopes = mutableListOf<FirScope>() private val topLevelScopes = mutableListOf<FirScope>()
private val implicitReceiverStack = mutableListOf<ImplicitReceiverValue>() final override val implicitReceiverPerLabel: SetMultimap<Name, ImplicitReceiverValue<*>> = LinkedHashMultimap.create()
private val implicitReceiverStack = mutableListOf<ImplicitReceiverValue<*>>()
final override val inferenceComponents = inferenceComponents(session, returnTypeCalculator, scopeSession) final override val inferenceComponents = inferenceComponents(session, returnTypeCalculator, scopeSession)
private var primaryConstructorParametersScope: FirLocalScope? = null private var primaryConstructorParametersScope: FirLocalScope? = null
@@ -197,11 +198,16 @@ open class FirBodyResolveTransformer(
): CompositeTransformResult<FirStatement> { ): CompositeTransformResult<FirStatement> {
when (val callee = qualifiedAccessExpression.calleeReference) { when (val callee = qualifiedAccessExpression.calleeReference) {
is FirThisReference -> { is FirExplicitThisReference -> {
val labelName = callee.labelName val labelName = callee.labelName
val types = if (labelName == null) labels.values() else labels[Name.identifier(labelName)] val implicitReceivers =
val type = types.lastOrNull() ?: ConeKotlinErrorType("Unresolved this@$labelName") if (labelName == null) implicitReceiverPerLabel.values() else implicitReceiverPerLabel[Name.identifier(labelName)]
qualifiedAccessExpression.resultType = FirResolvedTypeRefImpl(null, type, emptyList()) val implicitReceiver = implicitReceivers.lastOrNull()
callee.candidateOwner = implicitReceiver?.boundSymbol
qualifiedAccessExpression.resultType = FirResolvedTypeRefImpl(
null, implicitReceiver?.type ?: ConeKotlinErrorType("Unresolved this@$labelName"),
emptyList()
)
return qualifiedAccessExpression.compose() return qualifiedAccessExpression.compose()
} }
is FirSuperReference -> { is FirSuperReference -> {
@@ -366,7 +372,9 @@ open class FirBodyResolveTransformer(
val label = anonymousFunction.label val label = anonymousFunction.label
return if (label != null && receiverTypeRef != null) { 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 { } else {
transform() transform()
} }
@@ -768,22 +776,28 @@ open class FirBodyResolveTransformer(
// ----------------------- Util functions ----------------------- // ----------------------- Util functions -----------------------
private inline fun <T> withLabelAndReceiverType(labelName: Name, owner: FirElement, type: ConeKotlinType, block: () -> T): T { private inline fun <T> withLabelAndReceiverType(
labels.put(labelName, type) labelName: Name,
implicitReceiverStack += when (owner) { owner: FirDeclaration,
type: ConeKotlinType,
block: () -> T
): T {
val implicitReceiverValue = when (owner) {
is FirRegularClass -> { is FirRegularClass -> {
ImplicitDispatchReceiverValue(owner.symbol, type, symbolProvider, session, scopeSession) ImplicitDispatchReceiverValue(owner.symbol, type, symbolProvider, session, scopeSession)
} }
is FirFunction<*> -> { is FirFunction<*> -> {
ImplicitExtensionReceiverValue(type, session, scopeSession) ImplicitExtensionReceiverValue(owner.symbol, type, session, scopeSession)
} }
else -> { else -> {
throw IllegalArgumentException("Incorrect label & receiver owner: ${owner.javaClass}") throw IllegalArgumentException("Incorrect label & receiver owner: ${owner.javaClass}")
} }
} }
implicitReceiverPerLabel.put(labelName, implicitReceiverValue)
implicitReceiverStack += implicitReceiverValue
val result = block() val result = block()
implicitReceiverStack.removeAt(implicitReceiverStack.size - 1) implicitReceiverStack.removeAt(implicitReceiverStack.size - 1)
labels.remove(labelName, type) implicitReceiverPerLabel.remove(labelName, implicitReceiverValue)
return result return result
} }
+1 -1
View File
@@ -2,4 +2,4 @@ abstract class MyStringList : List<String>
abstract class MyMutableStringList : MutableList<String> abstract class MyMutableStringList : MutableList<String>
fun List<String>.convert(): MyStringList = this as MyStringList fun List<String>.convert(): MyStringList = this as MyStringList
fun ret(l: MutableList<String>): MyMutableStringList = this as MyMutableStringList fun ret(l: MutableList<String>): MyMutableStringList = l as MyMutableStringList
+2 -2
View File
@@ -12,8 +12,8 @@ FILE: lists.kt
} }
public final fun R|kotlin/collections/List<kotlin/String>|.convert(): R|MyStringList| { public final fun R|kotlin/collections/List<kotlin/String>|.convert(): R|MyStringList| {
^convert (this# as R|MyStringList|) ^convert (this@R|/convert| as R|MyStringList|)
} }
public final fun ret(l: R|kotlin/collections/MutableList<kotlin/String>|): R|MyMutableStringList| { public final fun ret(l: R|kotlin/collections/MutableList<kotlin/String>|): R|MyMutableStringList| {
^ret (this# as R|MyMutableStringList|) ^ret (R|<local>/l| as R|MyMutableStringList|)
} }
@@ -29,7 +29,7 @@ FILE: access.kt
} }
public final fun bar(): R|Bar| { 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| { public final operator fun R|kotlin/String|.plus(bar: R|Bar|): R|kotlin/String| {
@@ -10,7 +10,7 @@ FILE: explicitReceiver.kt
public get(): R|Foo| public get(): R|Foo|
public final operator fun invoke(): R|Foo| { public final operator fun invoke(): R|Foo| {
^invoke this# ^invoke this@R|/Foo|
} }
public final fun bar(): R|Foo| { public final fun bar(): R|Foo| {
@@ -30,7 +30,7 @@ FILE: explicitReceiver.kt
public get(): R|Bar| public get(): R|Bar|
public final operator fun invoke(): R|Bar| { public final operator fun invoke(): R|Bar| {
^invoke this# ^invoke this@R|/Bar|
} }
public final fun baz(): R|kotlin/Unit| { public final fun baz(): R|kotlin/Unit| {
@@ -5,7 +5,7 @@ FILE: explicitReceiver2.kt
} }
public final operator fun invoke(): R|Foo| { 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| { 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|() public final val x: R|Bar| = R|/Bar.Bar|()
@@ -7,7 +7,7 @@ FILE: extension.kt
} }
public final operator fun R|kotlin/Int|.invoke(): R|Foo| { 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) public final val x: R|kotlin/Int| = Int(0)
@@ -2,7 +2,7 @@ FILE: farInvokeExtension.kt
public final fun x(): R|kotlin/Unit| { public final fun x(): R|kotlin/Unit| {
} }
public final operator fun R|kotlin/Int|.invoke(): R|Foo| { public final operator fun R|kotlin/Int|.invoke(): R|Foo| {
^invoke this@Foo ^invoke this@Foo#
} }
public final class Foo : R|kotlin/Any| { public final class Foo : R|kotlin/Any| {
public constructor(): R|Foo| { public constructor(): R|Foo| {
@@ -9,7 +9,7 @@ FILE: implicitTypeOrder.kt
} }
public final fun invoke(): R|A| { public final fun invoke(): R|A| {
^invoke this# ^invoke this@R|/A|
} }
} }
@@ -5,7 +5,7 @@ FILE: threeReceivers.kt
} }
public final fun R|FooBar|.invoke(): R|Bar| { public final fun R|FooBar|.invoke(): R|Bar| {
^invoke this# ^invoke this@R|/Bar.invoke|
} }
} }
@@ -5,7 +5,7 @@ FILE: objects.kt
} }
public final fun foo(): R|A| { public final fun foo(): R|A| {
^foo this# ^foo this@R|/A|
} }
} }
@@ -11,19 +11,19 @@ FILE: this.kt
} }
public final fun bar(): R|Foo| { public final fun bar(): R|Foo| {
^bar this# ^bar this@R|/Foo|
} }
public final fun R|Bar|.buz(): R|Bar| { public final fun R|Bar|.buz(): R|Bar| {
^buz this# ^buz this@R|/Foo.buz|
} }
public final fun R|Bar|.foo(): R|Foo| { public final fun R|Bar|.foo(): R|Foo| {
^foo this@Foo ^foo this@R|/Foo|
} }
public final fun R|Bar|.foobar(): R|Bar| { public final fun R|Bar|.foobar(): R|Bar| {
^foobar this@foobar ^foobar this@R|/Foo.foobar|
} }
} }
@@ -5,7 +5,7 @@ FILE: noPrimaryConstructor.kt
public constructor(x: R|kotlin/String|): R|NoPrimary| { public constructor(x: R|kotlin/String|): R|NoPrimary| {
super<R|kotlin/Any|>() super<R|kotlin/Any|>()
this#.R|/NoPrimary.x| = R|<local>/x| this@R|/NoPrimary|.R|/NoPrimary.x| = R|<local>/x|
} }
public constructor(): R|NoPrimary| { public constructor(): R|NoPrimary| {
@@ -23,7 +23,7 @@ FILE: typeParameters.kt
} }
public final override fun concat(other: R|List<kotlin/Int>|): R|List<kotlin/Int>| { public final override fun concat(other: R|List<kotlin/Int>|): R|List<kotlin/Int>| {
^concat this# ^concat this@R|/SomeList|
} }
} }
+1 -1
View File
@@ -2,7 +2,7 @@ FILE: genericFunctions.kt
public abstract interface Any : R|kotlin/Any| { public abstract interface Any : R|kotlin/Any| {
} }
public final inline fun <reified T : R|Any|> R|Any|.safeAs(): R|T?| { public final inline fun <reified T : R|Any|> 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 abstract class Summator : R|kotlin/Any| {
public constructor(): R|Summator| { public constructor(): R|Summator| {
+4 -4
View File
@@ -6,7 +6,7 @@ FILE: inner.kt
public final fun foo(): R|kotlin/Unit| { public final fun foo(): R|kotlin/Unit| {
R|/Owner.bar|() R|/Owner.bar|()
this#.R|/Owner.bar|() this@R|/Owner|.R|/Owner.bar|()
} }
public final fun bar(): R|kotlin/Unit| { public final fun bar(): R|kotlin/Unit| {
@@ -24,15 +24,15 @@ FILE: inner.kt
public final fun baz(): R|kotlin/Unit| { public final fun baz(): R|kotlin/Unit| {
R|/Owner.Inner.gau|() R|/Owner.Inner.gau|()
this#.R|/Owner.Inner.gau|() this@R|/Owner.Inner|.R|/Owner.Inner.gau|()
} }
public final fun gau(): R|kotlin/Unit| { public final fun gau(): R|kotlin/Unit| {
lval o: R|Owner| = R|/Owner.Owner|() lval o: R|Owner| = R|/Owner.Owner|()
R|<local>/o|.R|/Owner.foo|() R|<local>/o|.R|/Owner.foo|()
R|/Owner.foo|() R|/Owner.foo|()
this@Owner.R|/Owner.foo|() this@R|/Owner|.R|/Owner.foo|()
this#.<Unresolved name: err>#() this@R|/Owner.Inner|.<Unresolved name: err>#()
} }
} }
+3 -3
View File
@@ -6,7 +6,7 @@ FILE: simple.kt
public final fun foo(): R|kotlin/Unit| { public final fun foo(): R|kotlin/Unit| {
R|/Owner.bar|() R|/Owner.bar|()
this#.R|/Owner.bar|() this@R|/Owner|.R|/Owner.bar|()
} }
public final fun bar(): R|kotlin/Unit| { public final fun bar(): R|kotlin/Unit| {
@@ -21,7 +21,7 @@ FILE: simple.kt
public final fun baz(): R|kotlin/Unit| { public final fun baz(): R|kotlin/Unit| {
R|/Owner.Nested.gau|() R|/Owner.Nested.gau|()
this#.R|/Owner.Nested.gau|() this@R|/Owner.Nested|.R|/Owner.Nested.gau|()
} }
public final fun gau(): R|kotlin/Unit| { public final fun gau(): R|kotlin/Unit| {
@@ -31,7 +31,7 @@ FILE: simple.kt
public final fun err(): R|kotlin/Unit| { public final fun err(): R|kotlin/Unit| {
<Unresolved name: foo>#() <Unresolved name: foo>#()
this#.<Unresolved name: foo>#() this@R|/Owner.Nested|.<Unresolved name: foo>#()
} }
} }
+6 -6
View File
@@ -5,15 +5,15 @@ FILE: simple.kt
} }
public open fun foo(): R|A| { public open fun foo(): R|A| {
^foo this# ^foo this@R|/A|
} }
public open fun bar(): R|A| { public open fun bar(): R|A| {
^bar this# ^bar this@R|/A|
} }
public open fun buz(p: R|A|): 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| { public final override fun foo(): R|B| {
^foo this# ^foo this@R|/B|
} }
public final fun bar(): R|B| { public final fun bar(): R|B| {
^bar this# ^bar this@R|/B|
} }
public final override fun buz(p: R|B|): 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| { public final fun test(): R|kotlin/Unit| {
@@ -28,7 +28,7 @@ FILE: recursiveCallOnWhenWithSealedClass.kt
} }
public final fun unwrap(): <ERROR TYPE REF: Inapplicable when expression> { public final fun unwrap(): <ERROR TYPE REF: Inapplicable when expression> {
^unwrap when (this#) { ^unwrap when (this@R|/Maybe|) {
($subj$ is R|Maybe.Nope|) -> { ($subj$ is R|Maybe.Nope|) -> {
throw R|java/lang/Exception.Exception|(String()) throw R|java/lang/Exception.Exception|(String())
} }
@@ -13,7 +13,7 @@ FILE: arrayFirstOrNull.kt
Null(null) Null(null)
} }
else -> { else -> {
this#.R|FakeOverride<kotlin/Array.get: R|T|>|(Int(0)) this@R|/firstOrNullX|.R|FakeOverride<kotlin/Array.get: R|T|>|(Int(0))
} }
} }
+1 -1
View File
@@ -6,7 +6,7 @@ FILE: mapList.kt
} }
) )
R|<local>/u|.R|/applyX|<R|kotlin/collections/List<kotlin/Int>|>(<L> = applyX@fun R|kotlin/collections/List<kotlin/Int>|.<anonymous>(it: R|kotlin/collections/List<kotlin/Int>|): R|kotlin/Unit| { R|<local>/u|.R|/applyX|<R|kotlin/collections/List<kotlin/Int>|>(<L> = applyX@fun R|kotlin/collections/List<kotlin/Int>|.<anonymous>(it: R|kotlin/collections/List<kotlin/Int>|): R|kotlin/Unit| {
this#.R|FakeOverride<kotlin/collections/List.contains: R|kotlin/Boolean|>|(Int(1)) this@R|special/anonymous|.R|FakeOverride<kotlin/collections/List.contains: R|kotlin/Boolean|>|(Int(1))
R|FakeOverride<kotlin/collections/List.contains: R|kotlin/Boolean|>|(Int(1)) R|FakeOverride<kotlin/collections/List.contains: R|kotlin/Boolean|>|(Int(1))
} }
) )
@@ -9,10 +9,10 @@ FILE: simpleDelegatedToMap.kt
public final var foo: <ERROR TYPE REF: Ambiguity: getValue, [kotlin/collections/getValue, kotlin/collections/getValue, kotlin/collections/getValue]>by R|<local>/map| public final var foo: <ERROR TYPE REF: Ambiguity: getValue, [kotlin/collections/getValue, kotlin/collections/getValue, kotlin/collections/getValue]>by R|<local>/map|
public get(): <ERROR TYPE REF: Ambiguity: getValue, [kotlin/collections/getValue, kotlin/collections/getValue, kotlin/collections/getValue]> { public get(): <ERROR TYPE REF: Ambiguity: getValue, [kotlin/collections/getValue, kotlin/collections/getValue, kotlin/collections/getValue]> {
^ D|/C.foo|.<Ambiguity: getValue, [kotlin/collections/getValue, kotlin/collections/getValue, kotlin/collections/getValue]>#(this#, ::R|/C.foo|) ^ D|/C.foo|.<Ambiguity: getValue, [kotlin/collections/getValue, kotlin/collections/getValue, kotlin/collections/getValue]>#(this@R|/C|, ::R|/C.foo|)
} }
public set(<set-?>: <ERROR TYPE REF: Ambiguity: getValue, [kotlin/collections/getValue, kotlin/collections/getValue, kotlin/collections/getValue]>): R|kotlin/Unit| { public set(<set-?>: <ERROR TYPE REF: Ambiguity: getValue, [kotlin/collections/getValue, kotlin/collections/getValue, kotlin/collections/getValue]>): R|kotlin/Unit| {
D|/C.foo|.<Inapplicable(INAPPLICABLE): [kotlin/collections/setValue]>#(this#, ::R|/C.foo|, R|<local>/<set-?>|) D|/C.foo|.<Inapplicable(INAPPLICABLE): [kotlin/collections/setValue]>#(this@R|/C|, ::R|/C.foo|, R|<local>/<set-?>|)
} }
} }
@@ -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.FirLoopJump
import org.jetbrains.kotlin.fir.expressions.impl.FirUnitExpression import org.jetbrains.kotlin.fir.expressions.impl.FirUnitExpression
import org.jetbrains.kotlin.fir.references.FirErrorNamedReference import org.jetbrains.kotlin.fir.references.FirErrorNamedReference
import org.jetbrains.kotlin.fir.symbols.ConeCallableSymbol import org.jetbrains.kotlin.fir.symbols.*
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.impl.FirNamedFunctionSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirNamedFunctionSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirPropertySymbol import org.jetbrains.kotlin.fir.symbols.impl.FirPropertySymbol
import org.jetbrains.kotlin.fir.types.* import org.jetbrains.kotlin.fir.types.*
@@ -755,16 +752,19 @@ class FirRenderer(builder: StringBuilder) : FirVisitorVoid() {
print("*") 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) { override fun visitNamedReference(namedReference: FirNamedReference) {
val symbol = namedReference.candidateSymbol val symbol = namedReference.candidateSymbol
when { when {
symbol != null -> { symbol != null -> {
print("R?C|") print("R?C|${symbol.render()}|")
if (symbol is ConeCallableSymbol)
print(symbol.callableId)
else if (symbol is ConeClassLikeSymbol)
print(symbol.classId)
print("|")
} }
namedReference is FirErrorNamedReference -> print("<${namedReference.errorReason}>#") namedReference is FirErrorNamedReference -> print("<${namedReference.errorReason}>#")
else -> print("${namedReference.name}#") else -> print("${namedReference.name}#")
@@ -791,10 +791,7 @@ class FirRenderer(builder: StringBuilder) : FirVisitorVoid() {
print("FakeOverride<") print("FakeOverride<")
} }
val symbol = resolvedCallableReference.coneSymbol val symbol = resolvedCallableReference.coneSymbol
if (symbol is ConeCallableSymbol) print(symbol.render())
print(symbol.callableId)
else if (symbol is ConeClassLikeSymbol)
print(symbol.classId)
if (isFakeOverride) { if (isFakeOverride) {
when (symbol) { when (symbol) {
is FirNamedFunctionSymbol -> { is FirNamedFunctionSymbol -> {
@@ -814,10 +811,11 @@ class FirRenderer(builder: StringBuilder) : FirVisitorVoid() {
override fun visitThisReference(thisReference: FirThisReference) { override fun visitThisReference(thisReference: FirThisReference) {
print("this") print("this")
val labelName = thisReference.labelName val labelName = thisReference.labelName
if (labelName != null) { val symbol = thisReference.candidateOwner
print("@$labelName") when {
} else { symbol != null -> print("@R|${symbol.render()}|")
print("#") labelName != null -> print("@$labelName#")
else -> print("#")
} }
} }
@@ -5,11 +5,14 @@
package org.jetbrains.kotlin.fir package org.jetbrains.kotlin.fir
import org.jetbrains.kotlin.fir.symbols.AbstractFirBasedSymbol
import org.jetbrains.kotlin.fir.visitors.FirVisitor import org.jetbrains.kotlin.fir.visitors.FirVisitor
interface FirThisReference : FirReference { interface FirThisReference : FirReference {
val labelName: String? val labelName: String?
val candidateOwner: AbstractFirBasedSymbol<*>? get() = null
override fun <R, D> accept(visitor: FirVisitor<R, D>, data: D): R = override fun <R, D> accept(visitor: FirVisitor<R, D>, data: D): R =
visitor.visitThisReference(this, data) visitor.visitThisReference(this, data)
} }
@@ -8,5 +8,8 @@ package org.jetbrains.kotlin.fir.references
import com.intellij.psi.PsiElement import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.fir.FirAbstractElement import org.jetbrains.kotlin.fir.FirAbstractElement
import org.jetbrains.kotlin.fir.FirThisReference import org.jetbrains.kotlin.fir.FirThisReference
import org.jetbrains.kotlin.fir.symbols.AbstractFirBasedSymbol
class FirExplicitThisReference(psi: PsiElement?, override val labelName: String?) : FirAbstractElement(psi), FirThisReference class FirExplicitThisReference(psi: PsiElement?, override val labelName: String?) : FirAbstractElement(psi), FirThisReference {
override var candidateOwner: AbstractFirBasedSymbol<*>? = null
}