[FIR] fixed overridden symbols of "invoke" in KFunction
IR expects overridden symbols of "invoke" in KFunction to be "invoke" in the corresponding Function classes. Before this commit we don't set overriddenSymbol, now we do.
This commit is contained in:
committed by
Mikhail Glukhikh
parent
e3721ed406
commit
04e8cba857
+10
-9
@@ -16,13 +16,8 @@ import org.jetbrains.kotlin.fir.descriptors.FirModuleDescriptor
|
|||||||
import org.jetbrains.kotlin.fir.descriptors.FirPackageFragmentDescriptor
|
import org.jetbrains.kotlin.fir.descriptors.FirPackageFragmentDescriptor
|
||||||
import org.jetbrains.kotlin.fir.psi
|
import org.jetbrains.kotlin.fir.psi
|
||||||
import org.jetbrains.kotlin.fir.render
|
import org.jetbrains.kotlin.fir.render
|
||||||
import org.jetbrains.kotlin.fir.resolve.firProvider
|
import org.jetbrains.kotlin.fir.resolve.*
|
||||||
import org.jetbrains.kotlin.fir.resolve.firSymbolProvider
|
import org.jetbrains.kotlin.fir.symbols.impl.*
|
||||||
import org.jetbrains.kotlin.fir.resolve.getOrPut
|
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.FirClassSymbol
|
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.FirFunctionSymbol
|
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.FirTypeParameterSymbol
|
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.FirVariableSymbol
|
|
||||||
import org.jetbrains.kotlin.fir.types.ConeKotlinType
|
import org.jetbrains.kotlin.fir.types.ConeKotlinType
|
||||||
import org.jetbrains.kotlin.fir.types.FirTypeRef
|
import org.jetbrains.kotlin.fir.types.FirTypeRef
|
||||||
import org.jetbrains.kotlin.fir.types.arrayElementType
|
import org.jetbrains.kotlin.fir.types.arrayElementType
|
||||||
@@ -421,11 +416,12 @@ class Fir2IrDeclarationStorage(
|
|||||||
fun create(): IrSimpleFunction {
|
fun create(): IrSimpleFunction {
|
||||||
val containerSource = function.containerSource
|
val containerSource = function.containerSource
|
||||||
val descriptor = containerSource?.let { WrappedFunctionDescriptorWithContainerSource(it) } ?: WrappedSimpleFunctionDescriptor()
|
val descriptor = containerSource?.let { WrappedFunctionDescriptorWithContainerSource(it) } ?: WrappedSimpleFunctionDescriptor()
|
||||||
|
val updatedOrigin = if (function.symbol.callableId.isKFunctionInvoke()) IrDeclarationOrigin.FAKE_OVERRIDE else origin
|
||||||
return function.convertWithOffsets { startOffset, endOffset ->
|
return function.convertWithOffsets { startOffset, endOffset ->
|
||||||
enterScope(descriptor)
|
enterScope(descriptor)
|
||||||
val result = irSymbolTable.declareSimpleFunction(startOffset, endOffset, origin, descriptor) { symbol ->
|
val result = irSymbolTable.declareSimpleFunction(startOffset, endOffset, origin, descriptor) { symbol ->
|
||||||
IrFunctionImpl(
|
IrFunctionImpl(
|
||||||
startOffset, endOffset, origin, symbol,
|
startOffset, endOffset, updatedOrigin, symbol,
|
||||||
function.name, function.visibility, function.modality!!,
|
function.name, function.visibility, function.modality!!,
|
||||||
function.returnTypeRef.toIrType(session, this),
|
function.returnTypeRef.toIrType(session, this),
|
||||||
isInline = function.isInline,
|
isInline = function.isInline,
|
||||||
@@ -433,7 +429,7 @@ class Fir2IrDeclarationStorage(
|
|||||||
isTailrec = function.isTailRec,
|
isTailrec = function.isTailRec,
|
||||||
isSuspend = function.isSuspend,
|
isSuspend = function.isSuspend,
|
||||||
isExpect = function.isExpect,
|
isExpect = function.isExpect,
|
||||||
isFakeOverride = origin == IrDeclarationOrigin.FAKE_OVERRIDE,
|
isFakeOverride = updatedOrigin == IrDeclarationOrigin.FAKE_OVERRIDE,
|
||||||
isOperator = function.isOperator
|
isOperator = function.isOperator
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -775,6 +771,11 @@ class Fir2IrDeclarationStorage(
|
|||||||
is FirSimpleFunction -> {
|
is FirSimpleFunction -> {
|
||||||
val irDeclaration = getIrFunction(firDeclaration, irParent, shouldLeaveScope = true).apply {
|
val irDeclaration = getIrFunction(firDeclaration, irParent, shouldLeaveScope = true).apply {
|
||||||
setAndModifyParent(irParent)
|
setAndModifyParent(irParent)
|
||||||
|
} as IrSimpleFunction
|
||||||
|
if (firFunctionSymbol.callableId.isKFunctionInvoke()) {
|
||||||
|
(firFunctionSymbol.overriddenSymbol as? FirNamedFunctionSymbol)?.let {
|
||||||
|
irDeclaration.overriddenSymbols += (it.toFunctionSymbol(this) as IrSimpleFunctionSymbol)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
irSymbolTable.referenceSimpleFunction(irDeclaration.descriptor)
|
irSymbolTable.referenceSimpleFunction(irDeclaration.descriptor)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,7 +13,6 @@ import org.jetbrains.kotlin.fir.diagnostics.DiagnosticKind
|
|||||||
import org.jetbrains.kotlin.fir.diagnostics.FirSimpleDiagnostic
|
import org.jetbrains.kotlin.fir.diagnostics.FirSimpleDiagnostic
|
||||||
import org.jetbrains.kotlin.fir.diagnostics.FirStubDiagnostic
|
import org.jetbrains.kotlin.fir.diagnostics.FirStubDiagnostic
|
||||||
import org.jetbrains.kotlin.fir.expressions.*
|
import org.jetbrains.kotlin.fir.expressions.*
|
||||||
import org.jetbrains.kotlin.fir.expressions.builder.FirResolvedQualifierBuilder
|
|
||||||
import org.jetbrains.kotlin.fir.expressions.builder.FirResolvedReifiedParameterReferenceBuilder
|
import org.jetbrains.kotlin.fir.expressions.builder.FirResolvedReifiedParameterReferenceBuilder
|
||||||
import org.jetbrains.kotlin.fir.expressions.impl.FirExpressionWithSmartcastImpl
|
import org.jetbrains.kotlin.fir.expressions.impl.FirExpressionWithSmartcastImpl
|
||||||
import org.jetbrains.kotlin.fir.references.FirErrorNamedReference
|
import org.jetbrains.kotlin.fir.references.FirErrorNamedReference
|
||||||
@@ -463,6 +462,12 @@ fun BodyResolveComponents.transformQualifiedAccessUsingSmartcastInfo(qualifiedAc
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun CallableId.isInvoke() =
|
fun CallableId.isInvoke() =
|
||||||
packageName == KotlinBuiltIns.BUILT_INS_PACKAGE_FQ_NAME
|
isKFunctionInvoke()
|
||||||
|
|| callableName.asString() == "invoke"
|
||||||
&& className?.asString()?.startsWith("Function") == true
|
&& className?.asString()?.startsWith("Function") == true
|
||||||
&& callableName.asString() == "invoke"
|
&& packageName == KotlinBuiltIns.BUILT_INS_PACKAGE_FQ_NAME
|
||||||
|
|
||||||
|
fun CallableId.isKFunctionInvoke() =
|
||||||
|
callableName.asString() == "invoke"
|
||||||
|
&& className?.asString()?.startsWith("KFunction") == true
|
||||||
|
&& packageName.asString() == "kotlin.reflect"
|
||||||
+40
-28
@@ -7,10 +7,7 @@ package org.jetbrains.kotlin.fir.resolve.impl
|
|||||||
|
|
||||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||||
import org.jetbrains.kotlin.builtins.functions.FunctionClassDescriptor
|
import org.jetbrains.kotlin.builtins.functions.FunctionClassDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.ClassKind
|
import org.jetbrains.kotlin.descriptors.*
|
||||||
import org.jetbrains.kotlin.descriptors.Modality
|
|
||||||
import org.jetbrains.kotlin.descriptors.SourceElement
|
|
||||||
import org.jetbrains.kotlin.descriptors.Visibilities
|
|
||||||
import org.jetbrains.kotlin.fir.FirSession
|
import org.jetbrains.kotlin.fir.FirSession
|
||||||
import org.jetbrains.kotlin.fir.declarations.*
|
import org.jetbrains.kotlin.fir.declarations.*
|
||||||
import org.jetbrains.kotlin.fir.declarations.builder.buildClassImpl
|
import org.jetbrains.kotlin.fir.declarations.builder.buildClassImpl
|
||||||
@@ -209,30 +206,11 @@ class FirBuiltinSymbolProvider(val session: FirSession, val kotlinScopeProvider:
|
|||||||
type = ConeTypeParameterTypeImpl(it.symbol.toLookupTag(), false)
|
type = ConeTypeParameterTypeImpl(it.symbol.toLookupTag(), false)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
val superKind: FunctionClassDescriptor.Kind? = when (kind) {
|
||||||
addDeclaration(
|
FunctionClassDescriptor.Kind.KFunction -> FunctionClassDescriptor.Kind.Function
|
||||||
buildSimpleFunction {
|
FunctionClassDescriptor.Kind.KSuspendFunction -> FunctionClassDescriptor.Kind.SuspendFunction
|
||||||
session = this@FirBuiltinSymbolProvider.session
|
else -> null
|
||||||
returnTypeRef = typeArguments.last()
|
}
|
||||||
this.name = name
|
|
||||||
status = functionStatus
|
|
||||||
symbol = FirNamedFunctionSymbol(CallableId(packageFqName, relativeClassName, name))
|
|
||||||
resolvePhase = FirResolvePhase.ANALYZED_DEPENDENCIES
|
|
||||||
valueParameters += typeArguments.dropLast(1).mapIndexed { index, typeArgument ->
|
|
||||||
val parameterName = Name.identifier("p${index + 1}")
|
|
||||||
buildValueParameter {
|
|
||||||
session = this@FirBuiltinSymbolProvider.session
|
|
||||||
returnTypeRef = typeArgument
|
|
||||||
this.name = parameterName
|
|
||||||
symbol = FirVariableSymbol(parameterName)
|
|
||||||
defaultValue = null
|
|
||||||
isCrossinline = false
|
|
||||||
isNoinline = false
|
|
||||||
isVararg = false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
)
|
|
||||||
|
|
||||||
fun createSuperType(
|
fun createSuperType(
|
||||||
kind: FunctionClassDescriptor.Kind,
|
kind: FunctionClassDescriptor.Kind,
|
||||||
@@ -259,12 +237,46 @@ class FirBuiltinSymbolProvider(val session: FirSession, val kotlinScopeProvider:
|
|||||||
FunctionClassDescriptor.Kind.KSuspendFunction ->
|
FunctionClassDescriptor.Kind.KSuspendFunction ->
|
||||||
createSuperType(FunctionClassDescriptor.Kind.SuspendFunction)
|
createSuperType(FunctionClassDescriptor.Kind.SuspendFunction)
|
||||||
}
|
}
|
||||||
|
addDeclaration(
|
||||||
|
buildSimpleFunction {
|
||||||
|
session = this@FirBuiltinSymbolProvider.session
|
||||||
|
returnTypeRef = typeArguments.last()
|
||||||
|
this.name = name
|
||||||
|
status = functionStatus
|
||||||
|
symbol = FirNamedFunctionSymbol(
|
||||||
|
CallableId(packageFqName, relativeClassName, name),
|
||||||
|
// set overriddenSymbol for "invoke" of KFunction/KSuspendFunction
|
||||||
|
superKind != null, superKind?.getInvoke(arity)
|
||||||
|
)
|
||||||
|
resolvePhase = FirResolvePhase.ANALYZED_DEPENDENCIES
|
||||||
|
valueParameters += typeArguments.dropLast(1).mapIndexed { index, typeArgument ->
|
||||||
|
val parameterName = Name.identifier("p${index + 1}")
|
||||||
|
buildValueParameter {
|
||||||
|
session = this@FirBuiltinSymbolProvider.session
|
||||||
|
returnTypeRef = typeArgument
|
||||||
|
this.name = parameterName
|
||||||
|
symbol = FirVariableSymbol(parameterName)
|
||||||
|
defaultValue = null
|
||||||
|
isCrossinline = false
|
||||||
|
isNoinline = false
|
||||||
|
isVararg = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Find the symbol for "invoke" in the function class
|
||||||
|
private fun FunctionClassDescriptor.Kind.getInvoke(arity: Int): FirNamedFunctionSymbol? {
|
||||||
|
val functionClass = getClassLikeSymbolByFqName(classId(arity)) ?: return null
|
||||||
|
val invoke =
|
||||||
|
functionClass.fir.declarations.find { it is FirSimpleFunction && it.name == OperatorNameConventions.INVOKE } ?: return null
|
||||||
|
return (invoke as FirSimpleFunction).symbol as? FirNamedFunctionSymbol
|
||||||
|
}
|
||||||
|
|
||||||
override fun getClassLikeSymbolByFqName(classId: ClassId): FirRegularClassSymbol? {
|
override fun getClassLikeSymbolByFqName(classId: ClassId): FirRegularClassSymbol? {
|
||||||
return allPackageFragments[classId.packageFqName]?.firstNotNullResult {
|
return allPackageFragments[classId.packageFqName]?.firstNotNullResult {
|
||||||
|
|||||||
-1
@@ -1,4 +1,3 @@
|
|||||||
// IGNORE_BACKEND_FIR: JVM_IR
|
|
||||||
abstract class A {
|
abstract class A {
|
||||||
abstract fun foo(): String
|
abstract fun foo(): String
|
||||||
}
|
}
|
||||||
|
|||||||
-1
@@ -1,4 +1,3 @@
|
|||||||
// IGNORE_BACKEND_FIR: JVM_IR
|
|
||||||
class A {
|
class A {
|
||||||
fun foo(k: Int) = k
|
fun foo(k: Int) = k
|
||||||
|
|
||||||
|
|||||||
-1
@@ -1,4 +1,3 @@
|
|||||||
// IGNORE_BACKEND_FIR: JVM_IR
|
|
||||||
class A {
|
class A {
|
||||||
fun o() = 111
|
fun o() = 111
|
||||||
fun k(k: Int) = k
|
fun k(k: Int) = k
|
||||||
|
|||||||
Vendored
-1
@@ -1,4 +1,3 @@
|
|||||||
// IGNORE_BACKEND_FIR: JVM_IR
|
|
||||||
class A {
|
class A {
|
||||||
fun foo() = "OK"
|
fun foo() = "OK"
|
||||||
}
|
}
|
||||||
|
|||||||
-1
@@ -1,4 +1,3 @@
|
|||||||
// IGNORE_BACKEND_FIR: JVM_IR
|
|
||||||
class A {
|
class A {
|
||||||
fun foo(result: String) = result
|
fun foo(result: String) = result
|
||||||
}
|
}
|
||||||
|
|||||||
Vendored
-1
@@ -1,4 +1,3 @@
|
|||||||
// IGNORE_BACKEND_FIR: JVM_IR
|
|
||||||
class A {
|
class A {
|
||||||
var result = "Fail"
|
var result = "Fail"
|
||||||
|
|
||||||
|
|||||||
Vendored
-1
@@ -1,4 +1,3 @@
|
|||||||
// IGNORE_BACKEND_FIR: JVM_IR
|
|
||||||
class A {
|
class A {
|
||||||
var result = "Fail"
|
var result = "Fail"
|
||||||
|
|
||||||
|
|||||||
-1
@@ -1,4 +1,3 @@
|
|||||||
// IGNORE_BACKEND_FIR: JVM_IR
|
|
||||||
class A {
|
class A {
|
||||||
var result = "OK"
|
var result = "OK"
|
||||||
}
|
}
|
||||||
|
|||||||
Vendored
-1
@@ -1,4 +1,3 @@
|
|||||||
// IGNORE_BACKEND_FIR: JVM_IR
|
|
||||||
class A(val result: String)
|
class A(val result: String)
|
||||||
|
|
||||||
fun box() = (::A)("OK").result
|
fun box() = (::A)("OK").result
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
// IGNORE_BACKEND_FIR: JVM_IR
|
|
||||||
class A
|
class A
|
||||||
|
|
||||||
fun box() = if ((A::equals)(A(), A())) "Fail" else "OK"
|
fun box() = if ((A::equals)(A(), A())) "Fail" else "OK"
|
||||||
|
|||||||
-1
@@ -1,4 +1,3 @@
|
|||||||
// IGNORE_BACKEND_FIR: JVM_IR
|
|
||||||
class A {
|
class A {
|
||||||
fun result() = (A::foo)(this, "OK")
|
fun result() = (A::foo)(this, "OK")
|
||||||
}
|
}
|
||||||
|
|||||||
-1
@@ -1,4 +1,3 @@
|
|||||||
// IGNORE_BACKEND_FIR: JVM_IR
|
|
||||||
class A
|
class A
|
||||||
|
|
||||||
fun A.foo() = (A::bar)(this, "OK")
|
fun A.foo() = (A::bar)(this, "OK")
|
||||||
|
|||||||
Vendored
-1
@@ -1,4 +1,3 @@
|
|||||||
// IGNORE_BACKEND_FIR: JVM_IR
|
|
||||||
fun run(arg1: A, funRef:A.() -> String): String {
|
fun run(arg1: A, funRef:A.() -> String): String {
|
||||||
return arg1.funRef()
|
return arg1.funRef()
|
||||||
}
|
}
|
||||||
|
|||||||
Vendored
-1
@@ -1,4 +1,3 @@
|
|||||||
// IGNORE_BACKEND_FIR: JVM_IR
|
|
||||||
fun run(arg1: A, arg2: String, funRef:A.(String) -> String): String {
|
fun run(arg1: A, arg2: String, funRef:A.(String) -> String): String {
|
||||||
return arg1.funRef(arg2)
|
return arg1.funRef(arg2)
|
||||||
}
|
}
|
||||||
|
|||||||
Vendored
-1
@@ -1,4 +1,3 @@
|
|||||||
// IGNORE_BACKEND_FIR: JVM_IR
|
|
||||||
class A {
|
class A {
|
||||||
var result = "Fail"
|
var result = "Fail"
|
||||||
}
|
}
|
||||||
|
|||||||
Vendored
-1
@@ -1,4 +1,3 @@
|
|||||||
// IGNORE_BACKEND_FIR: JVM_IR
|
|
||||||
fun run(arg1: A, arg2: String, funRef:A.(String) -> Unit): Unit {
|
fun run(arg1: A, arg2: String, funRef:A.(String) -> Unit): Unit {
|
||||||
return arg1.funRef(arg2)
|
return arg1.funRef(arg2)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
// IGNORE_BACKEND_FIR: JVM_IR
|
|
||||||
fun box(): String {
|
fun box(): String {
|
||||||
class A {
|
class A {
|
||||||
val result = "OK"
|
val result = "OK"
|
||||||
|
|||||||
Vendored
-1
@@ -1,4 +1,3 @@
|
|||||||
// IGNORE_BACKEND_FIR: JVM_IR
|
|
||||||
fun box(): String {
|
fun box(): String {
|
||||||
class A {
|
class A {
|
||||||
var result: String = "Fail";
|
var result: String = "Fail";
|
||||||
|
|||||||
Vendored
-1
@@ -1,4 +1,3 @@
|
|||||||
// IGNORE_BACKEND_FIR: JVM_IR
|
|
||||||
class A {
|
class A {
|
||||||
class Nested {
|
class Nested {
|
||||||
val result = "OK"
|
val result = "OK"
|
||||||
|
|||||||
-1
@@ -1,4 +1,3 @@
|
|||||||
// IGNORE_BACKEND_FIR: JVM_IR
|
|
||||||
class A {
|
class A {
|
||||||
class Nested(val result: String)
|
class Nested(val result: String)
|
||||||
}
|
}
|
||||||
|
|||||||
-1
@@ -1,4 +1,3 @@
|
|||||||
// IGNORE_BACKEND_FIR: JVM_IR
|
|
||||||
class A {
|
class A {
|
||||||
private fun foo() = "OK"
|
private fun foo() = "OK"
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
// IGNORE_BACKEND_FIR: JVM_IR
|
|
||||||
fun <T> run(arg1: T, arg2: T, funRef:(T,T) -> T): T {
|
fun <T> run(arg1: T, arg2: T, funRef:(T,T) -> T): T {
|
||||||
return funRef(arg1, arg2)
|
return funRef(arg1, arg2)
|
||||||
}
|
}
|
||||||
|
|||||||
-1
@@ -1,4 +1,3 @@
|
|||||||
// IGNORE_BACKEND_FIR: JVM_IR
|
|
||||||
fun <T> run(arg1: T, arg2: T, funRef:(T,T) -> T): T {
|
fun <T> run(arg1: T, arg2: T, funRef:(T,T) -> T): T {
|
||||||
return funRef(arg1, arg2)
|
return funRef(arg1, arg2)
|
||||||
}
|
}
|
||||||
|
|||||||
Vendored
-1
@@ -1,4 +1,3 @@
|
|||||||
// IGNORE_BACKEND_FIR: JVM_IR
|
|
||||||
fun foo(x: String) = x
|
fun foo(x: String) = x
|
||||||
|
|
||||||
fun box(): String {
|
fun box(): String {
|
||||||
|
|||||||
-1
@@ -1,4 +1,3 @@
|
|||||||
// IGNORE_BACKEND_FIR: JVM_IR
|
|
||||||
var result = "Fail"
|
var result = "Fail"
|
||||||
|
|
||||||
fun foo() {
|
fun foo() {
|
||||||
|
|||||||
Vendored
-1
@@ -1,4 +1,3 @@
|
|||||||
// IGNORE_BACKEND_FIR: JVM_IR
|
|
||||||
var result = "Fail"
|
var result = "Fail"
|
||||||
|
|
||||||
fun foo(newResult: String) {
|
fun foo(newResult: String) {
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
// IGNORE_BACKEND_FIR: JVM_IR
|
|
||||||
interface A {
|
interface A {
|
||||||
fun foo(): String
|
fun foo(): String
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
// IGNORE_BACKEND_FIR: JVM_IR
|
|
||||||
// TARGET_BACKEND: JVM
|
// TARGET_BACKEND: JVM
|
||||||
|
|
||||||
// WITH_RUNTIME
|
// WITH_RUNTIME
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
// IGNORE_BACKEND_FIR: JVM_IR
|
|
||||||
// TARGET_BACKEND: JVM
|
// TARGET_BACKEND: JVM
|
||||||
// IGNORE_LIGHT_ANALYSIS
|
// IGNORE_LIGHT_ANALYSIS
|
||||||
// WITH_RUNTIME
|
// WITH_RUNTIME
|
||||||
|
|||||||
Reference in New Issue
Block a user