[JS IR] Context to NameTables for stable names in additional exported declarations

[JS IR] BridgesConstruction with generic without cast

^KT-44469 fixed
This commit is contained in:
Ilya Goncharov
2021-01-22 18:42:34 +03:00
parent f186047101
commit d88d1d048e
7 changed files with 41 additions and 22 deletions
@@ -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<T : JsCommonBackendContext>(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
}
@@ -87,7 +87,7 @@ class ExportedDefaultParameterStub(val context: JsIrBackendContext) : Declaratio
return null
}
if (!declaration.hasStableJsName()) {
if (!declaration.hasStableJsName(context)) {
return null
}
@@ -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<JsIrBackendContext>(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
}
@@ -27,7 +27,7 @@ class IrModuleToJsTransformer(
private val backendContext: JsIrBackendContext,
private val mainArguments: List<String>?,
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
@@ -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<IrPackageFragment>,
reservedForGlobal: MutableSet<String> = mutableSetOf(),
reservedForMember: MutableSet<String> = mutableSetOf(),
val mappedNames: MutableMap<String, String>? = null
val mappedNames: MutableMap<String, String>? = null,
private val context: JsIrBackendContext? = null
) {
val globalNames: NameTable<IrDeclaration>
private val memberNames: NameTable<Signature>
@@ -250,7 +252,13 @@ class NameTables(
val packages = mutableListOf<IrPackageFragment>().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
@@ -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() =
@@ -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<JsCommonBackendContext>(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(