diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/BridgesConstruction.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/BridgesConstruction.kt index ecf0b310afa..edad298cc64 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/BridgesConstruction.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/BridgesConstruction.kt @@ -13,6 +13,7 @@ import org.jetbrains.kotlin.backend.common.lower.* import org.jetbrains.kotlin.descriptors.Modality import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET import org.jetbrains.kotlin.ir.backend.js.JsCommonBackendContext +import org.jetbrains.kotlin.ir.backend.js.JsIrBackendContext import org.jetbrains.kotlin.ir.backend.js.JsLoweredDeclarationOrigin import org.jetbrains.kotlin.ir.backend.js.utils.hasStableJsName import org.jetbrains.kotlin.ir.backend.js.utils.realOverrideTarget @@ -43,7 +44,7 @@ import org.jetbrains.kotlin.ir.util.* // fun foo(t: Any?) = foo(t as Int) // Constructed bridge // } // -abstract class BridgesConstruction(val context: JsCommonBackendContext) : DeclarationTransformer { +abstract class BridgesConstruction(val context: T) : DeclarationTransformer { private val specialBridgeMethods = SpecialBridgeMethods(context) @@ -115,11 +116,7 @@ abstract class BridgesConstruction(val context: JsCommonBackendContext) : Declar specialMethodInfo: SpecialMethodWithDefaultInfo? ): IrFunction { - val origin = - if (bridge.hasStableJsName()) - JsLoweredDeclarationOrigin.BRIDGE_WITH_STABLE_NAME - else - JsLoweredDeclarationOrigin.BRIDGE_WITHOUT_STABLE_NAME + val origin = getBridgeOrigin(bridge) // TODO: Support offsets for debug info val irFunction = context.irFactory.buildFun { @@ -179,6 +176,8 @@ abstract class BridgesConstruction(val context: JsCommonBackendContext) : Declar return irFunction } + abstract fun getBridgeOrigin(bridge: IrSimpleFunction): IrDeclarationOrigin + // TODO: get rid of Unit check private fun IrBlockBodyBuilder.irCastIfNeeded(argument: IrExpression, type: IrType): IrExpression = if (argument.type.classifierOrNull == type.classifierOrNull) argument else irAs(argument, type) @@ -194,7 +193,7 @@ abstract class BridgesConstruction(val context: JsCommonBackendContext) : Declar override fun equals(other: Any?): Boolean { if (this === other) return true - if (other !is BridgesConstruction.FunctionAndSignature) return false + if (other !is BridgesConstruction<*>.FunctionAndSignature) return false return signature == other.signature } diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/ExportedDefaultParameterStub.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/ExportedDefaultParameterStub.kt index 5598756c09c..a991bb954ee 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/ExportedDefaultParameterStub.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/ExportedDefaultParameterStub.kt @@ -87,7 +87,7 @@ class ExportedDefaultParameterStub(val context: JsIrBackendContext) : Declaratio return null } - if (!declaration.hasStableJsName()) { + if (!declaration.hasStableJsName(context)) { return null } diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/JsBridgesConstruction.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/JsBridgesConstruction.kt index 1a59c7aeb7a..1c540748bb9 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/JsBridgesConstruction.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/JsBridgesConstruction.kt @@ -5,12 +5,21 @@ package org.jetbrains.kotlin.ir.backend.js.lower -import org.jetbrains.kotlin.ir.backend.js.JsCommonBackendContext +import org.jetbrains.kotlin.ir.backend.js.JsIrBackendContext +import org.jetbrains.kotlin.ir.backend.js.JsLoweredDeclarationOrigin import org.jetbrains.kotlin.ir.backend.js.utils.Signature +import org.jetbrains.kotlin.ir.backend.js.utils.hasStableJsName import org.jetbrains.kotlin.ir.backend.js.utils.jsFunctionSignature +import org.jetbrains.kotlin.ir.declarations.IrDeclarationOrigin import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction -class JsBridgesConstruction(context: JsCommonBackendContext) : BridgesConstruction(context) { +class JsBridgesConstruction(context: JsIrBackendContext) : BridgesConstruction(context) { override fun getFunctionSignature(function: IrSimpleFunction): Signature = - jsFunctionSignature(function) + jsFunctionSignature(function, context) + + override fun getBridgeOrigin(bridge: IrSimpleFunction): IrDeclarationOrigin = + if (bridge.hasStableJsName(context)) + JsLoweredDeclarationOrigin.BRIDGE_WITH_STABLE_NAME + else + JsLoweredDeclarationOrigin.BRIDGE_WITHOUT_STABLE_NAME } diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/transformers/irToJs/IrModuleToJsTransformer.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/transformers/irToJs/IrModuleToJsTransformer.kt index 828f6b33f93..269a63319ff 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/transformers/irToJs/IrModuleToJsTransformer.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/transformers/irToJs/IrModuleToJsTransformer.kt @@ -27,7 +27,7 @@ class IrModuleToJsTransformer( private val backendContext: JsIrBackendContext, private val mainArguments: List?, private val generateScriptModule: Boolean = false, - var namer: NameTables = NameTables(emptyList()), + var namer: NameTables = NameTables(emptyList(), context = backendContext), private val fullJs: Boolean = true, private val dceJs: Boolean = false, private val multiModule: Boolean = false, @@ -64,7 +64,7 @@ class IrModuleToJsTransformer( eliminateDeadDeclarations(modules, backendContext) // Use a fresh namer for DCE so that we could compare the result with DCE-driven // TODO: is this mode relevant for scripting? If yes, refactor so that the external name tables are used here when needed. - val namer = NameTables(emptyList()) + val namer = NameTables(emptyList(), context = backendContext) namer.merge(modules.flatMap { it.files }, additionalPackages) generateWrappedModuleBody(modules, exportedModule, namer) } else null diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/utils/NameTables.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/utils/NameTables.kt index 3bf7300153e..f5163534a62 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/utils/NameTables.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/utils/NameTables.kt @@ -7,6 +7,7 @@ package org.jetbrains.kotlin.ir.backend.js.utils import org.jetbrains.kotlin.backend.common.ir.isTopLevel import org.jetbrains.kotlin.ir.IrElement +import org.jetbrains.kotlin.ir.backend.js.JsIrBackendContext import org.jetbrains.kotlin.ir.backend.js.lower.serialization.ir.JsManglerIr import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.expressions.IrBreak @@ -105,13 +106,13 @@ fun fieldSignature(field: IrField): Signature { return BackingFieldSignature(field) } -fun jsFunctionSignature(declaration: IrFunction): Signature { +fun jsFunctionSignature(declaration: IrFunction, context: JsIrBackendContext?): Signature { require(!declaration.isStaticMethodOfClass) require(declaration.dispatchReceiverParameter != null) val declarationName = declaration.getJsNameOrKotlinName().asString() - if (declaration.hasStableJsName()) { + if (declaration.hasStableJsName(context)) { return StableNameSignature(declarationName) } @@ -148,7 +149,8 @@ class NameTables( packages: List, reservedForGlobal: MutableSet = mutableSetOf(), reservedForMember: MutableSet = mutableSetOf(), - val mappedNames: MutableMap? = null + val mappedNames: MutableMap? = null, + private val context: JsIrBackendContext? = null ) { val globalNames: NameTable private val memberNames: NameTable @@ -250,7 +252,13 @@ class NameTables( val packages = mutableListOf().also { it.addAll(files) } if (packagesAdded()) packages.addAll(additionalPackages) - val table = NameTables(packages, globalNames.reserved, memberNames.reserved, mappedNames) + val table = NameTables( + packages, + globalNames.reserved, + memberNames.reserved, + mappedNames, + context + ) globalNames.names.addAllIfAbsent(table.globalNames.names) memberNames.names.addAllIfAbsent(table.memberNames.names) @@ -274,7 +282,7 @@ class NameTables( } private fun generateNameForMemberFunction(declaration: IrSimpleFunction) { - when (val signature = jsFunctionSignature(declaration)) { + when (val signature = jsFunctionSignature(declaration, context)) { is StableNameSignature -> memberNames.declareStableName(signature, signature.name) is ParameterTypeBasedSignature -> memberNames.declareFreshName(signature, signature.suggestedName) } @@ -327,7 +335,7 @@ class NameTables( } fun getNameForMemberFunction(function: IrSimpleFunction): String { - val signature = jsFunctionSignature(function) + val signature = jsFunctionSignature(function, context) val name = memberNames.names[signature] ?: mappedNames?.get(mapToKey(signature)) // TODO Add a compiler flag, which enables this behaviour diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/utils/misc.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/utils/misc.kt index 59b186868fa..2f597d3dddc 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/utils/misc.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/utils/misc.kt @@ -24,7 +24,7 @@ import org.jetbrains.kotlin.name.Name fun TODO(element: IrElement): Nothing = TODO(element::class.java.simpleName + " is not supported yet here") -fun IrFunction.hasStableJsName(): Boolean { +fun IrFunction.hasStableJsName(context: JsIrBackendContext?): Boolean { if ( origin == JsLoweredDeclarationOrigin.BRIDGE_WITH_STABLE_NAME || (this as? IrSimpleFunction)?.isMethodOfAny() == true // Handle names for special functions @@ -52,7 +52,7 @@ fun IrFunction.hasStableJsName(): Boolean { else -> true } - return (isEffectivelyExternal() || getJsName() != null || isExported(null)) && namedOrMissingGetter + return (isEffectivelyExternal() || getJsName() != null || isExported(context)) && namedOrMissingGetter } fun IrFunction.isEqualsInheritedFromAny() = diff --git a/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/lower/WasmBridgesConstruction.kt b/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/lower/WasmBridgesConstruction.kt index 4866ee596d2..2a271194e86 100644 --- a/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/lower/WasmBridgesConstruction.kt +++ b/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/lower/WasmBridgesConstruction.kt @@ -9,6 +9,7 @@ import org.jetbrains.kotlin.backend.common.CommonBackendContext import org.jetbrains.kotlin.backend.wasm.ir2wasm.erasedUpperBound import org.jetbrains.kotlin.ir.backend.js.JsCommonBackendContext import org.jetbrains.kotlin.ir.backend.js.lower.BridgesConstruction +import org.jetbrains.kotlin.ir.declarations.IrDeclarationOrigin import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns import org.jetbrains.kotlin.ir.types.IrType @@ -18,12 +19,14 @@ import org.jetbrains.kotlin.ir.util.defaultType import org.jetbrains.kotlin.ir.util.render import org.jetbrains.kotlin.name.Name -class WasmBridgesConstruction(context: JsCommonBackendContext) : BridgesConstruction(context) { +class WasmBridgesConstruction(context: JsCommonBackendContext) : BridgesConstruction(context) { override fun getFunctionSignature(function: IrSimpleFunction): WasmSignature = function.wasmSignature(context.irBuiltIns) // Dispatch receiver type must be casted when types are different. override val shouldCastDispatchReceiver: Boolean = true + override fun getBridgeOrigin(bridge: IrSimpleFunction): IrDeclarationOrigin = + IrDeclarationOrigin.BRIDGE } data class WasmSignature(