[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:
Juan Chen
2020-02-07 13:52:01 -08:00
committed by Mikhail Glukhikh
parent e3721ed406
commit 04e8cba857
32 changed files with 58 additions and 69 deletions
@@ -16,13 +16,8 @@ import org.jetbrains.kotlin.fir.descriptors.FirModuleDescriptor
import org.jetbrains.kotlin.fir.descriptors.FirPackageFragmentDescriptor
import org.jetbrains.kotlin.fir.psi
import org.jetbrains.kotlin.fir.render
import org.jetbrains.kotlin.fir.resolve.firProvider
import org.jetbrains.kotlin.fir.resolve.firSymbolProvider
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.resolve.*
import org.jetbrains.kotlin.fir.symbols.impl.*
import org.jetbrains.kotlin.fir.types.ConeKotlinType
import org.jetbrains.kotlin.fir.types.FirTypeRef
import org.jetbrains.kotlin.fir.types.arrayElementType
@@ -421,11 +416,12 @@ class Fir2IrDeclarationStorage(
fun create(): IrSimpleFunction {
val containerSource = function.containerSource
val descriptor = containerSource?.let { WrappedFunctionDescriptorWithContainerSource(it) } ?: WrappedSimpleFunctionDescriptor()
val updatedOrigin = if (function.symbol.callableId.isKFunctionInvoke()) IrDeclarationOrigin.FAKE_OVERRIDE else origin
return function.convertWithOffsets { startOffset, endOffset ->
enterScope(descriptor)
val result = irSymbolTable.declareSimpleFunction(startOffset, endOffset, origin, descriptor) { symbol ->
IrFunctionImpl(
startOffset, endOffset, origin, symbol,
startOffset, endOffset, updatedOrigin, symbol,
function.name, function.visibility, function.modality!!,
function.returnTypeRef.toIrType(session, this),
isInline = function.isInline,
@@ -433,7 +429,7 @@ class Fir2IrDeclarationStorage(
isTailrec = function.isTailRec,
isSuspend = function.isSuspend,
isExpect = function.isExpect,
isFakeOverride = origin == IrDeclarationOrigin.FAKE_OVERRIDE,
isFakeOverride = updatedOrigin == IrDeclarationOrigin.FAKE_OVERRIDE,
isOperator = function.isOperator
)
}
@@ -775,6 +771,11 @@ class Fir2IrDeclarationStorage(
is FirSimpleFunction -> {
val irDeclaration = getIrFunction(firDeclaration, irParent, shouldLeaveScope = true).apply {
setAndModifyParent(irParent)
} as IrSimpleFunction
if (firFunctionSymbol.callableId.isKFunctionInvoke()) {
(firFunctionSymbol.overriddenSymbol as? FirNamedFunctionSymbol)?.let {
irDeclaration.overriddenSymbols += (it.toFunctionSymbol(this) as IrSimpleFunctionSymbol)
}
}
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.FirStubDiagnostic
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.impl.FirExpressionWithSmartcastImpl
import org.jetbrains.kotlin.fir.references.FirErrorNamedReference
@@ -463,6 +462,12 @@ fun BodyResolveComponents.transformQualifiedAccessUsingSmartcastInfo(qualifiedAc
}
fun CallableId.isInvoke() =
packageName == KotlinBuiltIns.BUILT_INS_PACKAGE_FQ_NAME
isKFunctionInvoke()
|| callableName.asString() == "invoke"
&& 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"
@@ -7,10 +7,7 @@ package org.jetbrains.kotlin.fir.resolve.impl
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.builtins.functions.FunctionClassDescriptor
import org.jetbrains.kotlin.descriptors.ClassKind
import org.jetbrains.kotlin.descriptors.Modality
import org.jetbrains.kotlin.descriptors.SourceElement
import org.jetbrains.kotlin.descriptors.Visibilities
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.declarations.*
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)
}
}
addDeclaration(
buildSimpleFunction {
session = this@FirBuiltinSymbolProvider.session
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
}
}
},
)
val superKind: FunctionClassDescriptor.Kind? = when (kind) {
FunctionClassDescriptor.Kind.KFunction -> FunctionClassDescriptor.Kind.Function
FunctionClassDescriptor.Kind.KSuspendFunction -> FunctionClassDescriptor.Kind.SuspendFunction
else -> null
}
fun createSuperType(
kind: FunctionClassDescriptor.Kind,
@@ -259,12 +237,46 @@ class FirBuiltinSymbolProvider(val session: FirSession, val kotlinScopeProvider:
FunctionClassDescriptor.Kind.KSuspendFunction ->
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? {
return allPackageFragments[classId.packageFqName]?.firstNotNullResult {
@@ -1,4 +1,3 @@
// IGNORE_BACKEND_FIR: JVM_IR
abstract class A {
abstract fun foo(): String
}
@@ -1,4 +1,3 @@
// IGNORE_BACKEND_FIR: JVM_IR
class A {
fun foo(k: Int) = k
@@ -1,4 +1,3 @@
// IGNORE_BACKEND_FIR: JVM_IR
class A {
fun o() = 111
fun k(k: Int) = k
@@ -1,4 +1,3 @@
// IGNORE_BACKEND_FIR: JVM_IR
class A {
fun foo() = "OK"
}
@@ -1,4 +1,3 @@
// IGNORE_BACKEND_FIR: JVM_IR
class A {
fun foo(result: String) = result
}
@@ -1,4 +1,3 @@
// IGNORE_BACKEND_FIR: JVM_IR
class A {
var result = "Fail"
@@ -1,4 +1,3 @@
// IGNORE_BACKEND_FIR: JVM_IR
class A {
var result = "Fail"
@@ -1,4 +1,3 @@
// IGNORE_BACKEND_FIR: JVM_IR
class A {
var result = "OK"
}
@@ -1,4 +1,3 @@
// IGNORE_BACKEND_FIR: JVM_IR
class A(val result: String)
fun box() = (::A)("OK").result
@@ -1,4 +1,3 @@
// IGNORE_BACKEND_FIR: JVM_IR
class A
fun box() = if ((A::equals)(A(), A())) "Fail" else "OK"
@@ -1,4 +1,3 @@
// IGNORE_BACKEND_FIR: JVM_IR
class A {
fun result() = (A::foo)(this, "OK")
}
@@ -1,4 +1,3 @@
// IGNORE_BACKEND_FIR: JVM_IR
class A
fun A.foo() = (A::bar)(this, "OK")
@@ -1,4 +1,3 @@
// IGNORE_BACKEND_FIR: JVM_IR
fun run(arg1: A, funRef:A.() -> String): String {
return arg1.funRef()
}
@@ -1,4 +1,3 @@
// IGNORE_BACKEND_FIR: JVM_IR
fun run(arg1: A, arg2: String, funRef:A.(String) -> String): String {
return arg1.funRef(arg2)
}
@@ -1,4 +1,3 @@
// IGNORE_BACKEND_FIR: JVM_IR
class A {
var result = "Fail"
}
@@ -1,4 +1,3 @@
// IGNORE_BACKEND_FIR: JVM_IR
fun run(arg1: A, arg2: String, funRef:A.(String) -> Unit): Unit {
return arg1.funRef(arg2)
}
@@ -1,4 +1,3 @@
// IGNORE_BACKEND_FIR: JVM_IR
fun box(): String {
class A {
val result = "OK"
@@ -1,4 +1,3 @@
// IGNORE_BACKEND_FIR: JVM_IR
fun box(): String {
class A {
var result: String = "Fail";
@@ -1,4 +1,3 @@
// IGNORE_BACKEND_FIR: JVM_IR
class A {
class Nested {
val result = "OK"
@@ -1,4 +1,3 @@
// IGNORE_BACKEND_FIR: JVM_IR
class A {
class Nested(val result: String)
}
@@ -1,4 +1,3 @@
// IGNORE_BACKEND_FIR: JVM_IR
class A {
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 {
return funRef(arg1, arg2)
}
@@ -1,4 +1,3 @@
// IGNORE_BACKEND_FIR: JVM_IR
fun <T> run(arg1: T, arg2: T, funRef:(T,T) -> T): T {
return funRef(arg1, arg2)
}
@@ -1,4 +1,3 @@
// IGNORE_BACKEND_FIR: JVM_IR
fun foo(x: String) = x
fun box(): String {
@@ -1,4 +1,3 @@
// IGNORE_BACKEND_FIR: JVM_IR
var result = "Fail"
fun foo() {
@@ -1,4 +1,3 @@
// IGNORE_BACKEND_FIR: JVM_IR
var result = "Fail"
fun foo(newResult: String) {
@@ -1,4 +1,3 @@
// IGNORE_BACKEND_FIR: JVM_IR
interface A {
fun foo(): String
}
@@ -1,4 +1,3 @@
// IGNORE_BACKEND_FIR: JVM_IR
// TARGET_BACKEND: JVM
// WITH_RUNTIME
@@ -1,4 +1,3 @@
// IGNORE_BACKEND_FIR: JVM_IR
// TARGET_BACKEND: JVM
// IGNORE_LIGHT_ANALYSIS
// WITH_RUNTIME