FIR: Provide dispatch receiver for 'field' according to property type
This commit is contained in:
committed by
Mikhail Glukhikh
parent
a0978a50e8
commit
078cf02c8a
+4
@@ -51,6 +51,10 @@ class PersistentImplicitReceiverStack private constructor(
|
||||
return stack.filterIsInstance<ImplicitDispatchReceiverValue>().lastOrNull()
|
||||
}
|
||||
|
||||
override fun lastDispatchReceiver(lookupCondition: (ImplicitReceiverValue<*>) -> Boolean): ImplicitDispatchReceiverValue? {
|
||||
return stack.filterIsInstance<ImplicitDispatchReceiverValue>().lastOrNull(lookupCondition)
|
||||
}
|
||||
|
||||
override fun receiversAsReversed(): List<ImplicitReceiverValue<*>> = stack.asReversed()
|
||||
|
||||
override operator fun iterator(): Iterator<ImplicitReceiverValue<*>> {
|
||||
|
||||
@@ -11,9 +11,17 @@ import org.jetbrains.kotlin.name.Name
|
||||
|
||||
// NB: with className == null we are at top level
|
||||
data class CallableId(val packageName: FqName, val className: FqName?, val callableName: Name) {
|
||||
val classId: ClassId? get() = className?.let { ClassId(packageName, it, false) }
|
||||
var classId: ClassId? = null
|
||||
get() {
|
||||
if (field == null && className != null) {
|
||||
field = ClassId(packageName, className, false)
|
||||
}
|
||||
return field
|
||||
}
|
||||
|
||||
constructor(classId: ClassId, callableName: Name) : this(classId.packageFqName, classId.relativeClassName, callableName)
|
||||
constructor(classId: ClassId, callableName: Name) : this(classId.packageFqName, classId.relativeClassName, callableName) {
|
||||
this.classId = classId
|
||||
}
|
||||
|
||||
constructor(packageName: FqName, callableName: Name) : this(packageName, null, callableName)
|
||||
|
||||
|
||||
+2
-1
@@ -338,7 +338,8 @@ internal class CallAndReferenceGenerator(
|
||||
// Object case
|
||||
val callableReference = calleeReference as? FirResolvedNamedReference
|
||||
val ownerClassId = (callableReference?.resolvedSymbol as? FirCallableSymbol<*>)?.callableId?.classId
|
||||
val ownerClassSymbol = ownerClassId?.let { session.firSymbolProvider.getClassLikeSymbolByFqName(it) }
|
||||
val ownerClassSymbol =
|
||||
ownerClassId?.takeUnless { it.isLocal }?.let { session.firSymbolProvider.getClassLikeSymbolByFqName(it) }
|
||||
val firClass = (ownerClassSymbol?.fir as? FirClass)?.takeIf {
|
||||
it is FirAnonymousObject || it is FirRegularClass && it.classKind == ClassKind.OBJECT
|
||||
}
|
||||
|
||||
+2
-3
@@ -21,6 +21,7 @@ import org.jetbrains.kotlin.fir.expressions.impl.buildSingleExpressionBlock
|
||||
import org.jetbrains.kotlin.fir.references.FirReference
|
||||
import org.jetbrains.kotlin.fir.references.builder.*
|
||||
import org.jetbrains.kotlin.fir.symbols.CallableId
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.ANONYMOUS_CLASS_ID
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirErrorFunctionSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirNamedFunctionSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirTypeParameterSymbol
|
||||
@@ -35,8 +36,6 @@ import org.jetbrains.kotlin.lexer.KtTokens.OPEN_QUOTE
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.parsing.*
|
||||
import org.jetbrains.kotlin.psi.KtClassOrObject
|
||||
import org.jetbrains.kotlin.psi.KtUnaryExpression
|
||||
import org.jetbrains.kotlin.util.OperatorNameConventions
|
||||
|
||||
//T can be either PsiElement, or LighterASTNode
|
||||
@@ -73,7 +72,7 @@ abstract class BaseFirBuilder<T>(val baseSession: FirSession, val context: Conte
|
||||
when {
|
||||
local -> CallableId(name)
|
||||
context.className == FqName.ROOT -> CallableId(context.packageFqName, name)
|
||||
context.className.shortName() === ANONYMOUS_OBJECT_NAME -> CallableId(FqName.ROOT, FqName("anonymous"), name)
|
||||
context.className.shortName() === ANONYMOUS_OBJECT_NAME -> CallableId(ANONYMOUS_CLASS_ID, name)
|
||||
else -> CallableId(context.packageFqName, context.className, name)
|
||||
}
|
||||
|
||||
|
||||
@@ -19,6 +19,7 @@ abstract class ImplicitReceiverStack : Iterable<ImplicitReceiverValue<*>> {
|
||||
abstract operator fun get(name: String?): ImplicitReceiverValue<*>?
|
||||
|
||||
abstract fun lastDispatchReceiver(): ImplicitDispatchReceiverValue?
|
||||
abstract fun lastDispatchReceiver(lookupCondition: (ImplicitReceiverValue<*>) -> Boolean): ImplicitDispatchReceiverValue?
|
||||
abstract fun receiversAsReversed(): List<ImplicitReceiverValue<*>>
|
||||
}
|
||||
|
||||
@@ -75,6 +76,10 @@ class ImplicitReceiverStackImpl private constructor(
|
||||
return stack.filterIsInstance<ImplicitDispatchReceiverValue>().lastOrNull()
|
||||
}
|
||||
|
||||
override fun lastDispatchReceiver(lookupCondition: (ImplicitReceiverValue<*>) -> Boolean): ImplicitDispatchReceiverValue? {
|
||||
return stack.filterIsInstance<ImplicitDispatchReceiverValue>().lastOrNull(lookupCondition)
|
||||
}
|
||||
|
||||
override fun receiversAsReversed(): List<ImplicitReceiverValue<*>> = stack.asReversed()
|
||||
|
||||
fun getReceiverIndex(symbol: FirBasedSymbol<*>): Int? = indexesPerSymbol[symbol]
|
||||
|
||||
@@ -15,6 +15,7 @@ import org.jetbrains.kotlin.fir.scopes.ProcessorAction
|
||||
import org.jetbrains.kotlin.fir.scopes.impl.FirAbstractImportingScope
|
||||
import org.jetbrains.kotlin.fir.symbols.AbstractFirBasedSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.*
|
||||
import org.jetbrains.kotlin.fir.types.classId
|
||||
import org.jetbrains.kotlin.fir.types.ConeKotlinType
|
||||
import org.jetbrains.kotlin.fir.types.ConeNullability
|
||||
import org.jetbrains.kotlin.fir.types.withNullability
|
||||
@@ -190,8 +191,18 @@ class ScopeTowerLevel(
|
||||
empty = false
|
||||
if (candidate.hasConsistentReceivers(extensionReceiver)) {
|
||||
val dispatchReceiverValue =
|
||||
if (candidate !is FirBackingFieldSymbol) null
|
||||
else bodyResolveComponents.implicitReceiverStack.lastDispatchReceiver()
|
||||
when {
|
||||
candidate !is FirBackingFieldSymbol -> null
|
||||
candidate.callableId.classId != null -> {
|
||||
val propertyHolderId = candidate.callableId.classId
|
||||
bodyResolveComponents.implicitReceiverStack.lastDispatchReceiver { implicitReceiverValue ->
|
||||
implicitReceiverValue.type.classId == propertyHolderId
|
||||
}
|
||||
}
|
||||
else -> {
|
||||
bodyResolveComponents.implicitReceiverStack.lastDispatchReceiver()
|
||||
}
|
||||
}
|
||||
processor.consumeCandidate(
|
||||
candidate as T, dispatchReceiverValue,
|
||||
implicitExtensionReceiverValue = extensionReceiver as? ImplicitReceiverValue<*>
|
||||
|
||||
@@ -27,7 +27,9 @@ sealed class FirClassSymbol<C : FirClass<C>>(classId: ClassId) : FirClassLikeSym
|
||||
|
||||
class FirRegularClassSymbol(classId: ClassId) : FirClassSymbol<FirRegularClass>(classId)
|
||||
|
||||
class FirAnonymousObjectSymbol : FirClassSymbol<FirAnonymousObject>(ClassId(FqName.ROOT, FqName("anonymous"), true))
|
||||
val ANONYMOUS_CLASS_ID = ClassId(FqName.ROOT, FqName("anonymous"), true)
|
||||
|
||||
class FirAnonymousObjectSymbol : FirClassSymbol<FirAnonymousObject>(ANONYMOUS_CLASS_ID)
|
||||
|
||||
class FirTypeAliasSymbol(classId: ClassId) : FirClassLikeSymbol<FirTypeAlias>(classId) {
|
||||
override fun toLookupTag() = ConeClassLikeLookupTagImpl(classId)
|
||||
|
||||
-1
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND_FIR: JVM_IR
|
||||
class Outer {
|
||||
val result = "OK"
|
||||
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND_FIR: JVM_IR
|
||||
// KJS_WITH_FULL_RUNTIME
|
||||
// WITH_RUNTIME
|
||||
class World() {
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND_FIR: JVM_IR
|
||||
open class A(val value: String) {
|
||||
inner class B(val s: String) {
|
||||
val result = value + "_" + s
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND_FIR: JVM_IR
|
||||
class C(val value: String = "C") {
|
||||
|
||||
inner class B(val s: String) {
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND_FIR: JVM_IR
|
||||
// KJS_WITH_FULL_RUNTIME
|
||||
class Outer(val foo: StringBuilder) {
|
||||
inner class Inner() {
|
||||
|
||||
-1
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND_FIR: JVM_IR
|
||||
open class Foo(val x: () -> String)
|
||||
|
||||
class Outer {
|
||||
|
||||
-1
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND_FIR: JVM_IR
|
||||
open class Base(val callback: () -> String)
|
||||
|
||||
class Outer {
|
||||
|
||||
Vendored
-1
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND_FIR: JVM_IR
|
||||
open class Base(val callback: () -> String)
|
||||
|
||||
class Outer {
|
||||
|
||||
Vendored
-1
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND_FIR: JVM_IR
|
||||
open class Base(val callback: () -> String)
|
||||
|
||||
class Outer {
|
||||
|
||||
-1
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND_FIR: JVM_IR
|
||||
open class Foo(val x: () -> String)
|
||||
open class Foo2(val foo: Foo)
|
||||
|
||||
|
||||
Vendored
-1
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND_FIR: JVM_IR
|
||||
open class Base(val callback: () -> String)
|
||||
|
||||
class Outer {
|
||||
|
||||
Vendored
-1
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND_FIR: JVM_IR
|
||||
interface Callback {
|
||||
fun invoke(): String
|
||||
}
|
||||
|
||||
Vendored
-1
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND_FIR: JVM_IR
|
||||
interface Callback {
|
||||
fun invoke(): String
|
||||
}
|
||||
|
||||
-1
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND_FIR: JVM_IR
|
||||
class A {
|
||||
private fun Int.foo(other: Int = 5): Int = this + other
|
||||
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND_FIR: JVM_IR
|
||||
enum class X {
|
||||
B {
|
||||
|
||||
|
||||
-1
@@ -1,5 +1,4 @@
|
||||
// !LANGUAGE: +InlineClasses
|
||||
// IGNORE_BACKEND_FIR: JVM_IR
|
||||
|
||||
inline class S(val string: String)
|
||||
|
||||
|
||||
-1
@@ -1,5 +1,4 @@
|
||||
// !LANGUAGE: +InlineClasses
|
||||
// IGNORE_BACKEND_FIR: JVM_IR
|
||||
|
||||
inline class S(val string: String)
|
||||
|
||||
|
||||
-1
@@ -1,5 +1,4 @@
|
||||
// !LANGUAGE: +InlineClasses
|
||||
// IGNORE_BACKEND_FIR: JVM_IR
|
||||
|
||||
inline class S(val string: String)
|
||||
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
// !LANGUAGE: +InlineClasses
|
||||
// IGNORE_BACKEND_FIR: JVM_IR
|
||||
// WITH_RUNTIME
|
||||
|
||||
inline class Z(val x: Int) {
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
// !LANGUAGE: +InlineClasses
|
||||
// IGNORE_BACKEND_FIR: JVM_IR
|
||||
// WITH_RUNTIME
|
||||
|
||||
inline class Z(val x: Int) {
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND_FIR: JVM_IR
|
||||
class Outer {
|
||||
val x = "O"
|
||||
inner class Inner {
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND_FIR: JVM_IR
|
||||
class Outer(val x: String) {
|
||||
inner class Inner(val y: String) {
|
||||
val z = x + y
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND_FIR: JVM_IR
|
||||
// TARGET_BACKEND: JVM
|
||||
|
||||
public object SomeObject {
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND_FIR: JVM_IR
|
||||
class My {
|
||||
var my: String = "U"
|
||||
get() = { field }()
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND_FIR: JVM_IR
|
||||
abstract class Your {
|
||||
abstract val your: String
|
||||
|
||||
|
||||
Reference in New Issue
Block a user