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()
|
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 fun receiversAsReversed(): List<ImplicitReceiverValue<*>> = stack.asReversed()
|
||||||
|
|
||||||
override operator fun iterator(): Iterator<ImplicitReceiverValue<*>> {
|
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
|
// NB: with className == null we are at top level
|
||||||
data class CallableId(val packageName: FqName, val className: FqName?, val callableName: Name) {
|
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)
|
constructor(packageName: FqName, callableName: Name) : this(packageName, null, callableName)
|
||||||
|
|
||||||
|
|||||||
+2
-1
@@ -338,7 +338,8 @@ internal class CallAndReferenceGenerator(
|
|||||||
// Object case
|
// Object case
|
||||||
val callableReference = calleeReference as? FirResolvedNamedReference
|
val callableReference = calleeReference as? FirResolvedNamedReference
|
||||||
val ownerClassId = (callableReference?.resolvedSymbol as? FirCallableSymbol<*>)?.callableId?.classId
|
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 {
|
val firClass = (ownerClassSymbol?.fir as? FirClass)?.takeIf {
|
||||||
it is FirAnonymousObject || it is FirRegularClass && it.classKind == ClassKind.OBJECT
|
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.FirReference
|
||||||
import org.jetbrains.kotlin.fir.references.builder.*
|
import org.jetbrains.kotlin.fir.references.builder.*
|
||||||
import org.jetbrains.kotlin.fir.symbols.CallableId
|
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.FirErrorFunctionSymbol
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.FirNamedFunctionSymbol
|
import org.jetbrains.kotlin.fir.symbols.impl.FirNamedFunctionSymbol
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.FirTypeParameterSymbol
|
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.FqName
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
import org.jetbrains.kotlin.parsing.*
|
import org.jetbrains.kotlin.parsing.*
|
||||||
import org.jetbrains.kotlin.psi.KtClassOrObject
|
|
||||||
import org.jetbrains.kotlin.psi.KtUnaryExpression
|
|
||||||
import org.jetbrains.kotlin.util.OperatorNameConventions
|
import org.jetbrains.kotlin.util.OperatorNameConventions
|
||||||
|
|
||||||
//T can be either PsiElement, or LighterASTNode
|
//T can be either PsiElement, or LighterASTNode
|
||||||
@@ -73,7 +72,7 @@ abstract class BaseFirBuilder<T>(val baseSession: FirSession, val context: Conte
|
|||||||
when {
|
when {
|
||||||
local -> CallableId(name)
|
local -> CallableId(name)
|
||||||
context.className == FqName.ROOT -> CallableId(context.packageFqName, 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)
|
else -> CallableId(context.packageFqName, context.className, name)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ abstract class ImplicitReceiverStack : Iterable<ImplicitReceiverValue<*>> {
|
|||||||
abstract operator fun get(name: String?): ImplicitReceiverValue<*>?
|
abstract operator fun get(name: String?): ImplicitReceiverValue<*>?
|
||||||
|
|
||||||
abstract fun lastDispatchReceiver(): ImplicitDispatchReceiverValue?
|
abstract fun lastDispatchReceiver(): ImplicitDispatchReceiverValue?
|
||||||
|
abstract fun lastDispatchReceiver(lookupCondition: (ImplicitReceiverValue<*>) -> Boolean): ImplicitDispatchReceiverValue?
|
||||||
abstract fun receiversAsReversed(): List<ImplicitReceiverValue<*>>
|
abstract fun receiversAsReversed(): List<ImplicitReceiverValue<*>>
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -75,6 +76,10 @@ class ImplicitReceiverStackImpl private constructor(
|
|||||||
return stack.filterIsInstance<ImplicitDispatchReceiverValue>().lastOrNull()
|
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 fun receiversAsReversed(): List<ImplicitReceiverValue<*>> = stack.asReversed()
|
||||||
|
|
||||||
fun getReceiverIndex(symbol: FirBasedSymbol<*>): Int? = indexesPerSymbol[symbol]
|
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.scopes.impl.FirAbstractImportingScope
|
||||||
import org.jetbrains.kotlin.fir.symbols.AbstractFirBasedSymbol
|
import org.jetbrains.kotlin.fir.symbols.AbstractFirBasedSymbol
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.*
|
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.ConeKotlinType
|
||||||
import org.jetbrains.kotlin.fir.types.ConeNullability
|
import org.jetbrains.kotlin.fir.types.ConeNullability
|
||||||
import org.jetbrains.kotlin.fir.types.withNullability
|
import org.jetbrains.kotlin.fir.types.withNullability
|
||||||
@@ -190,8 +191,18 @@ class ScopeTowerLevel(
|
|||||||
empty = false
|
empty = false
|
||||||
if (candidate.hasConsistentReceivers(extensionReceiver)) {
|
if (candidate.hasConsistentReceivers(extensionReceiver)) {
|
||||||
val dispatchReceiverValue =
|
val dispatchReceiverValue =
|
||||||
if (candidate !is FirBackingFieldSymbol) null
|
when {
|
||||||
else bodyResolveComponents.implicitReceiverStack.lastDispatchReceiver()
|
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(
|
processor.consumeCandidate(
|
||||||
candidate as T, dispatchReceiverValue,
|
candidate as T, dispatchReceiverValue,
|
||||||
implicitExtensionReceiverValue = extensionReceiver as? ImplicitReceiverValue<*>
|
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 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) {
|
class FirTypeAliasSymbol(classId: ClassId) : FirClassLikeSymbol<FirTypeAlias>(classId) {
|
||||||
override fun toLookupTag() = ConeClassLikeLookupTagImpl(classId)
|
override fun toLookupTag() = ConeClassLikeLookupTagImpl(classId)
|
||||||
|
|||||||
-1
@@ -1,4 +1,3 @@
|
|||||||
// IGNORE_BACKEND_FIR: JVM_IR
|
|
||||||
class Outer {
|
class Outer {
|
||||||
val result = "OK"
|
val result = "OK"
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
// IGNORE_BACKEND_FIR: JVM_IR
|
|
||||||
// KJS_WITH_FULL_RUNTIME
|
// KJS_WITH_FULL_RUNTIME
|
||||||
// WITH_RUNTIME
|
// WITH_RUNTIME
|
||||||
class World() {
|
class World() {
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
// IGNORE_BACKEND_FIR: JVM_IR
|
|
||||||
open class A(val value: String) {
|
open class A(val value: String) {
|
||||||
inner class B(val s: String) {
|
inner class B(val s: String) {
|
||||||
val result = value + "_" + s
|
val result = value + "_" + s
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
// IGNORE_BACKEND_FIR: JVM_IR
|
|
||||||
class C(val value: String = "C") {
|
class C(val value: String = "C") {
|
||||||
|
|
||||||
inner class B(val s: String) {
|
inner class B(val s: String) {
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
// IGNORE_BACKEND_FIR: JVM_IR
|
|
||||||
// KJS_WITH_FULL_RUNTIME
|
// KJS_WITH_FULL_RUNTIME
|
||||||
class Outer(val foo: StringBuilder) {
|
class Outer(val foo: StringBuilder) {
|
||||||
inner class Inner() {
|
inner class Inner() {
|
||||||
|
|||||||
-1
@@ -1,4 +1,3 @@
|
|||||||
// IGNORE_BACKEND_FIR: JVM_IR
|
|
||||||
open class Foo(val x: () -> String)
|
open class Foo(val x: () -> String)
|
||||||
|
|
||||||
class Outer {
|
class Outer {
|
||||||
|
|||||||
-1
@@ -1,4 +1,3 @@
|
|||||||
// IGNORE_BACKEND_FIR: JVM_IR
|
|
||||||
open class Base(val callback: () -> String)
|
open class Base(val callback: () -> String)
|
||||||
|
|
||||||
class Outer {
|
class Outer {
|
||||||
|
|||||||
Vendored
-1
@@ -1,4 +1,3 @@
|
|||||||
// IGNORE_BACKEND_FIR: JVM_IR
|
|
||||||
open class Base(val callback: () -> String)
|
open class Base(val callback: () -> String)
|
||||||
|
|
||||||
class Outer {
|
class Outer {
|
||||||
|
|||||||
Vendored
-1
@@ -1,4 +1,3 @@
|
|||||||
// IGNORE_BACKEND_FIR: JVM_IR
|
|
||||||
open class Base(val callback: () -> String)
|
open class Base(val callback: () -> String)
|
||||||
|
|
||||||
class Outer {
|
class Outer {
|
||||||
|
|||||||
-1
@@ -1,4 +1,3 @@
|
|||||||
// IGNORE_BACKEND_FIR: JVM_IR
|
|
||||||
open class Foo(val x: () -> String)
|
open class Foo(val x: () -> String)
|
||||||
open class Foo2(val foo: Foo)
|
open class Foo2(val foo: Foo)
|
||||||
|
|
||||||
|
|||||||
Vendored
-1
@@ -1,4 +1,3 @@
|
|||||||
// IGNORE_BACKEND_FIR: JVM_IR
|
|
||||||
open class Base(val callback: () -> String)
|
open class Base(val callback: () -> String)
|
||||||
|
|
||||||
class Outer {
|
class Outer {
|
||||||
|
|||||||
Vendored
-1
@@ -1,4 +1,3 @@
|
|||||||
// IGNORE_BACKEND_FIR: JVM_IR
|
|
||||||
interface Callback {
|
interface Callback {
|
||||||
fun invoke(): String
|
fun invoke(): String
|
||||||
}
|
}
|
||||||
|
|||||||
Vendored
-1
@@ -1,4 +1,3 @@
|
|||||||
// IGNORE_BACKEND_FIR: JVM_IR
|
|
||||||
interface Callback {
|
interface Callback {
|
||||||
fun invoke(): String
|
fun invoke(): String
|
||||||
}
|
}
|
||||||
|
|||||||
-1
@@ -1,4 +1,3 @@
|
|||||||
// IGNORE_BACKEND_FIR: JVM_IR
|
|
||||||
class A {
|
class A {
|
||||||
private fun Int.foo(other: Int = 5): Int = this + other
|
private fun Int.foo(other: Int = 5): Int = this + other
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
// IGNORE_BACKEND_FIR: JVM_IR
|
|
||||||
enum class X {
|
enum class X {
|
||||||
B {
|
B {
|
||||||
|
|
||||||
|
|||||||
-1
@@ -1,5 +1,4 @@
|
|||||||
// !LANGUAGE: +InlineClasses
|
// !LANGUAGE: +InlineClasses
|
||||||
// IGNORE_BACKEND_FIR: JVM_IR
|
|
||||||
|
|
||||||
inline class S(val string: String)
|
inline class S(val string: String)
|
||||||
|
|
||||||
|
|||||||
-1
@@ -1,5 +1,4 @@
|
|||||||
// !LANGUAGE: +InlineClasses
|
// !LANGUAGE: +InlineClasses
|
||||||
// IGNORE_BACKEND_FIR: JVM_IR
|
|
||||||
|
|
||||||
inline class S(val string: String)
|
inline class S(val string: String)
|
||||||
|
|
||||||
|
|||||||
-1
@@ -1,5 +1,4 @@
|
|||||||
// !LANGUAGE: +InlineClasses
|
// !LANGUAGE: +InlineClasses
|
||||||
// IGNORE_BACKEND_FIR: JVM_IR
|
|
||||||
|
|
||||||
inline class S(val string: String)
|
inline class S(val string: String)
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
// !LANGUAGE: +InlineClasses
|
// !LANGUAGE: +InlineClasses
|
||||||
// IGNORE_BACKEND_FIR: JVM_IR
|
|
||||||
// WITH_RUNTIME
|
// WITH_RUNTIME
|
||||||
|
|
||||||
inline class Z(val x: Int) {
|
inline class Z(val x: Int) {
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
// !LANGUAGE: +InlineClasses
|
// !LANGUAGE: +InlineClasses
|
||||||
// IGNORE_BACKEND_FIR: JVM_IR
|
|
||||||
// WITH_RUNTIME
|
// WITH_RUNTIME
|
||||||
|
|
||||||
inline class Z(val x: Int) {
|
inline class Z(val x: Int) {
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
// IGNORE_BACKEND_FIR: JVM_IR
|
|
||||||
class Outer {
|
class Outer {
|
||||||
val x = "O"
|
val x = "O"
|
||||||
inner class Inner {
|
inner class Inner {
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
// IGNORE_BACKEND_FIR: JVM_IR
|
|
||||||
class Outer(val x: String) {
|
class Outer(val x: String) {
|
||||||
inner class Inner(val y: String) {
|
inner class Inner(val y: String) {
|
||||||
val z = x + y
|
val z = x + y
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
// IGNORE_BACKEND_FIR: JVM_IR
|
|
||||||
// TARGET_BACKEND: JVM
|
// TARGET_BACKEND: JVM
|
||||||
|
|
||||||
public object SomeObject {
|
public object SomeObject {
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
// IGNORE_BACKEND_FIR: JVM_IR
|
|
||||||
class My {
|
class My {
|
||||||
var my: String = "U"
|
var my: String = "U"
|
||||||
get() = { field }()
|
get() = { field }()
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
// IGNORE_BACKEND_FIR: JVM_IR
|
|
||||||
abstract class Your {
|
abstract class Your {
|
||||||
abstract val your: String
|
abstract val your: String
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user