[JS IR] Introduce special setMetadataFor*() for synthetic classes
^KT-63436 Fixed
This commit is contained in:
committed by
Space Team
parent
9af681e234
commit
45c166abf8
@@ -112,7 +112,14 @@ class JsIntrinsics(private val irBuiltIns: IrBuiltIns, val context: JsIrBackendC
|
||||
|
||||
// RTTI:
|
||||
val implementSymbol = getInternalFunction("implement")
|
||||
val setMetadataForSymbol = getInternalFunction("setMetadataFor")
|
||||
val initMetadataForSymbol = getInternalFunction("initMetadataFor")
|
||||
val initMetadataForClassSymbol = getInternalFunction("initMetadataForClass")
|
||||
val initMetadataForObjectSymbol = getInternalFunction("initMetadataForObject")
|
||||
val initMetadataForInterfaceSymbol = getInternalFunction("initMetadataForInterface")
|
||||
val initMetadataForLambdaSymbol = getInternalFunction("initMetadataForLambda")
|
||||
val initMetadataForCoroutineSymbol = getInternalFunction("initMetadataForCoroutine")
|
||||
val initMetadataForFunctionReferenceSymbol = getInternalFunction("initMetadataForFunctionReference")
|
||||
val initMetadataForCompanionSymbol = getInternalFunction("initMetadataForCompanion")
|
||||
|
||||
val isInterfaceSymbol = getInternalFunction("isInterface")
|
||||
val isArraySymbol = getInternalFunction("isArray")
|
||||
@@ -198,10 +205,6 @@ class JsIntrinsics(private val irBuiltIns: IrBuiltIns, val context: JsIrBackendC
|
||||
getInternalClassWithoutPackage("kotlin.js.Promise")
|
||||
}
|
||||
|
||||
val metadataInterfaceConstructorSymbol = getInternalFunction("interfaceMeta")
|
||||
val metadataObjectConstructorSymbol = getInternalFunction("objectMeta")
|
||||
val metadataClassConstructorSymbol = getInternalFunction("classMeta")
|
||||
|
||||
val longToDouble = context.symbolTable.descriptorExtension.referenceSimpleFunction(
|
||||
context.getClass(FqName("kotlin.Long")).unsubstitutedMemberScope.findSingleFunction(
|
||||
Name.identifier("toDouble")
|
||||
|
||||
+12
-4
@@ -154,17 +154,25 @@ internal class JsUsefulDeclarationProcessor(
|
||||
if (!irClass.containsMetadata()) return
|
||||
|
||||
when {
|
||||
irClass.isObject -> context.intrinsics.metadataObjectConstructorSymbol.owner.enqueue(irClass, "object metadata")
|
||||
irClass.isObject -> {
|
||||
context.intrinsics.initMetadataForCompanionSymbol.owner.enqueue(irClass, "object metadata")
|
||||
context.intrinsics.initMetadataForObjectSymbol.owner.enqueue(irClass, "companion object metadata")
|
||||
}
|
||||
|
||||
irClass.isInterface -> {
|
||||
context.intrinsics.implementSymbol.owner.enqueue(irClass, "interface metadata")
|
||||
context.intrinsics.metadataInterfaceConstructorSymbol.owner.enqueue(irClass, "interface metadata")
|
||||
context.intrinsics.initMetadataForInterfaceSymbol.owner.enqueue(irClass, "interface metadata")
|
||||
}
|
||||
|
||||
else -> context.intrinsics.metadataClassConstructorSymbol.owner.enqueue(irClass, "class metadata")
|
||||
else -> {
|
||||
context.intrinsics.initMetadataForClassSymbol.owner.enqueue(irClass, "class metadata")
|
||||
context.intrinsics.initMetadataForLambdaSymbol.owner.enqueue(irClass, "lambda metadata")
|
||||
context.intrinsics.initMetadataForCoroutineSymbol.owner.enqueue(irClass, "coroutine metadata")
|
||||
context.intrinsics.initMetadataForFunctionReferenceSymbol.owner.enqueue(irClass, "function reference metadata")
|
||||
}
|
||||
}
|
||||
|
||||
context.intrinsics.setMetadataForSymbol.owner.enqueue(irClass, "metadata")
|
||||
context.intrinsics.initMetadataForSymbol.owner.enqueue(irClass, "metadata")
|
||||
|
||||
if (irClass.containsInterfaceDefaultImplementation()) {
|
||||
context.intrinsics.jsPrototypeOfSymbol.owner.enqueue(irClass, "interface default implementation")
|
||||
|
||||
+1
-1
@@ -42,7 +42,7 @@ abstract class AbstractSuspendFunctionsLowering<C : CommonBackendContext>(val co
|
||||
|
||||
private var IrFunction.coroutineConstructor by context.mapping.suspendFunctionToCoroutineConstructor
|
||||
|
||||
protected companion object {
|
||||
companion object {
|
||||
val DECLARATION_ORIGIN_COROUTINE_IMPL = IrDeclarationOriginImpl("COROUTINE_IMPL")
|
||||
}
|
||||
|
||||
|
||||
+53
-28
@@ -12,16 +12,20 @@ import org.jetbrains.kotlin.ir.backend.js.JsIrBackendContext
|
||||
import org.jetbrains.kotlin.ir.backend.js.export.isAllowedFakeOverriddenDeclaration
|
||||
import org.jetbrains.kotlin.ir.backend.js.export.isExported
|
||||
import org.jetbrains.kotlin.ir.backend.js.export.isOverriddenExported
|
||||
import org.jetbrains.kotlin.ir.backend.js.lower.CallableReferenceLowering
|
||||
import org.jetbrains.kotlin.ir.backend.js.lower.coroutines.AbstractSuspendFunctionsLowering
|
||||
import org.jetbrains.kotlin.ir.backend.js.lower.isEs6ConstructorReplacement
|
||||
import org.jetbrains.kotlin.ir.backend.js.utils.*
|
||||
import org.jetbrains.kotlin.ir.declarations.*
|
||||
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.IrClassifierSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
|
||||
import org.jetbrains.kotlin.ir.types.*
|
||||
import org.jetbrains.kotlin.ir.util.*
|
||||
import org.jetbrains.kotlin.js.backend.ast.*
|
||||
import org.jetbrains.kotlin.js.backend.ast.JsVars.JsVar
|
||||
import org.jetbrains.kotlin.js.common.isValidES5Identifier
|
||||
import org.jetbrains.kotlin.name.SpecialNames
|
||||
import org.jetbrains.kotlin.utils.addIfNotNull
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.butIf
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.runIf
|
||||
@@ -255,7 +259,7 @@ class JsClassGenerator(private val irClass: IrClass, val context: JsGenerationCo
|
||||
|
||||
val metadataPlace = if (es6mode) classModel.postDeclarationBlock else classModel.preDeclarationBlock
|
||||
|
||||
metadataPlace.statements += generateSetMetadataCall()
|
||||
metadataPlace.statements += generateInitMetadataCall()
|
||||
context.staticContext.classModels[irClass.symbol] = classModel
|
||||
|
||||
return classBlock
|
||||
@@ -371,39 +375,35 @@ class JsClassGenerator(private val irClass: IrClass, val context: JsGenerationCo
|
||||
}
|
||||
}
|
||||
|
||||
private fun generateSetMetadataCall(): JsStatement {
|
||||
val setMetadataFor = backendContext.intrinsics.setMetadataForSymbol.owner
|
||||
|
||||
private fun generateInitMetadataCall(): JsStatement {
|
||||
val ctor = classNameRef
|
||||
val parent = baseClassRef?.takeIf { !es6mode }
|
||||
val name = generateSimpleName()
|
||||
val interfaces = generateInterfacesList()
|
||||
val metadataConstructor = getMetadataConstructor()
|
||||
val defaultConstructor = runIf(irClass.isClass, ::findDefaultConstructor)
|
||||
val associatedObjectKey = generateAssociatedObjectKey()
|
||||
val associatedObjects = generateAssociatedObjects()
|
||||
val suspendArity = generateSuspendArity()
|
||||
|
||||
return JsInvocation(
|
||||
JsNameRef(context.getNameForStaticFunction(setMetadataFor)),
|
||||
listOf(
|
||||
ctor,
|
||||
name,
|
||||
metadataConstructor,
|
||||
parent,
|
||||
interfaces,
|
||||
defaultConstructor,
|
||||
associatedObjectKey,
|
||||
associatedObjects,
|
||||
suspendArity
|
||||
)
|
||||
.dropLastWhile { it == null }
|
||||
.memoryOptimizedMap { it ?: jsUndefined }
|
||||
).makeStmt()
|
||||
if (defaultConstructor == null && associatedObjectKey == null && associatedObjects == null) {
|
||||
val initSpecialMetadata = getSpecialInitMetadata(name)
|
||||
if (initSpecialMetadata != null) {
|
||||
return initSpecialMetadata.invokeWithoutNullArgs(ctor, parent, interfaces, suspendArity)
|
||||
}
|
||||
}
|
||||
|
||||
return getInitMetadata().invokeWithoutNullArgs(
|
||||
ctor,
|
||||
name,
|
||||
defaultConstructor,
|
||||
parent,
|
||||
interfaces,
|
||||
suspendArity,
|
||||
associatedObjectKey,
|
||||
associatedObjects
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
private fun IrType.asConstructorRef(): JsExpression? {
|
||||
val ownerSymbol = classOrNull?.takeIf {
|
||||
!isAny() && !isFunctionType() && !it.owner.isEffectivelyExternal()
|
||||
@@ -418,16 +418,41 @@ class JsClassGenerator(private val irClass: IrClass, val context: JsGenerationCo
|
||||
return irClass.name.takeIf { !it.isSpecial }?.let { JsStringLiteral(it.identifier) }
|
||||
}
|
||||
|
||||
private fun getMetadataConstructor(): JsNameRef {
|
||||
val metadataConstructorSymbol = with(backendContext.intrinsics) {
|
||||
private fun getInitMetadata(): IrSimpleFunctionSymbol {
|
||||
return with(backendContext.intrinsics) {
|
||||
when {
|
||||
irClass.isInterface -> metadataInterfaceConstructorSymbol
|
||||
irClass.isObject -> metadataObjectConstructorSymbol
|
||||
else -> metadataClassConstructorSymbol
|
||||
irClass.isInterface -> initMetadataForInterfaceSymbol
|
||||
irClass.isObject -> initMetadataForObjectSymbol
|
||||
else -> initMetadataForClassSymbol
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return JsNameRef(context.getNameForStaticFunction(metadataConstructorSymbol.owner))
|
||||
private fun getSpecialInitMetadata(name: JsStringLiteral?): IrSimpleFunctionSymbol? {
|
||||
if (irClass.isCompanion && name?.value == SpecialNames.DEFAULT_NAME_FOR_COMPANION_OBJECT.asString()) {
|
||||
return backendContext.intrinsics.initMetadataForCompanionSymbol
|
||||
}
|
||||
if (irClass.isClass) {
|
||||
when (irClass.origin) {
|
||||
CallableReferenceLowering.LAMBDA_IMPL -> {
|
||||
return backendContext.intrinsics.initMetadataForLambdaSymbol
|
||||
}
|
||||
CallableReferenceLowering.FUNCTION_REFERENCE_IMPL -> {
|
||||
return backendContext.intrinsics.initMetadataForFunctionReferenceSymbol
|
||||
}
|
||||
AbstractSuspendFunctionsLowering.DECLARATION_ORIGIN_COROUTINE_IMPL -> {
|
||||
return backendContext.intrinsics.initMetadataForCoroutineSymbol
|
||||
}
|
||||
}
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
private fun IrSimpleFunctionSymbol.invokeWithoutNullArgs(vararg arguments: JsExpression?): JsStatement {
|
||||
return JsInvocation(
|
||||
JsNameRef(context.getNameForStaticFunction(owner)),
|
||||
arguments.dropLastWhile { it == null }.memoryOptimizedMap { it ?: jsUndefined }
|
||||
).makeStmt()
|
||||
}
|
||||
|
||||
private fun generateInterfacesList(): JsArrayLiteral? {
|
||||
|
||||
Reference in New Issue
Block a user