rra/ilgonmic/reducing-size

[JS IR] Fix review remarks

- Fix translation mode from flags calculation
- comment why not top level could be safely inlined

[JS IR] Add test on exportness of internal val

Revert "[Gradle, JS] Disable minimizing names in production by default"

This reverts commit 700ff8634a73f155a2f0eaf963778216d6877075.

[JS IR] Adopt reserved names

Revert "[JS IR] Reserve interop names"

This reverts commit 63f30becaf1a45750ff85aea3753aae9a85985f4.

Revert "[JS IR] Clear minimized namer states"

This reverts commit ef7f19fa8a928021e8bdfbee7fbb5285fc74b7ab.

[JS IR] Clear minimized namer states

[JS IR] Reserve interop names

[JS IR] Separate arguments for users

[JS IR] Minimized member names in tests

[Gradle, JS] Disable minimizing names in production by default

[JS IR] Fix extra helps

[JS IR] Move mangling of signatures to linking namer

[JS IR] Add key and minimized name generator

[JS IR] cross module dependencies minimized

[JS IR] Minimize names

[JS IR] Cross module by index

[JS IR] Fix warning

[JS IR] Fix inlining accessors

[JS IR] Bridges for property accessors

[JS IR] Special case of jsFunctionSignature with property accessors

[JS IR] Inline property accessor for non top level properties

[JS IR] Reduce crossModule size

Merge-request: KT-MR-5785
Merged-by: Ilya Goncharov <Ilya.Goncharov@jetbrains.com>

^KT-51735 fixed
^KT-50504 fixed
This commit is contained in:
Ilya Goncharov
2022-03-28 10:39:15 +00:00
committed by Space
parent cf581738c3
commit c67c1a69b9
30 changed files with 292 additions and 132 deletions
@@ -13,6 +13,7 @@ object JsLoweredDeclarationOrigin : IrDeclarationOrigin {
object JS_CLOSURE_BOX_CLASS_DECLARATION : IrDeclarationOriginImpl("JS_CLOSURE_BOX_CLASS_DECLARATION")
object BRIDGE_WITH_STABLE_NAME : IrDeclarationOriginImpl("BRIDGE_WITH_STABLE_NAME")
object BRIDGE_WITHOUT_STABLE_NAME : IrDeclarationOriginImpl("BRIDGE_WITHOUT_STABLE_NAME")
object BRIDGE_PROPERTY_ACCESSOR : IrDeclarationOriginImpl("BRIDGE_PROPERTY_ACCESSOR")
object OBJECT_GET_INSTANCE_FUNCTION : IrDeclarationOriginImpl("OBJECT_GET_INSTANCE_FUNCTION")
object JS_SHADOWED_EXPORT : IrDeclarationOriginImpl("JS_SHADOWED_EXPORT")
object JS_SHADOWED_DEFAULT_PARAMETER : IrDeclarationOriginImpl("JS_SHADOWED_DEFAULT_PARAMETER")
@@ -22,6 +22,7 @@ import org.jetbrains.kotlin.ir.backend.js.ir.JsIrBuilder
import org.jetbrains.kotlin.ir.backend.js.lower.JsInnerClassesSupport
import org.jetbrains.kotlin.ir.backend.js.transformers.irToJs.JsPolyfills
import org.jetbrains.kotlin.ir.backend.js.utils.JsInlineClassesUtils
import org.jetbrains.kotlin.ir.backend.js.utils.MinimizedNameGenerator
import org.jetbrains.kotlin.ir.backend.js.utils.OperatorNames
import org.jetbrains.kotlin.ir.builders.declarations.addFunction
import org.jetbrains.kotlin.ir.declarations.*
@@ -72,6 +73,11 @@ class JsIrBackendContext(
val localClassNames: MutableMap<IrClass, String> = mutableMapOf()
val extractedLocalClasses: MutableSet<IrClass> = hashSetOf()
val minimizedNameGenerator: MinimizedNameGenerator =
MinimizedNameGenerator()
val fieldDataCache = mutableMapOf<IrClass, Map<IrField, String>>()
override val builtIns = module.builtIns
override val typeSystem: IrTypeSystemContext = IrTypeSystemContextImpl(irBuiltIns)
@@ -549,6 +549,7 @@ class ExportModelGenerator(
if (function.isFakeOverride && !function.isAllowedFakeOverriddenDeclaration(context))
return Exportability.NotNeeded
if (function.origin == JsLoweredDeclarationOrigin.BRIDGE_WITHOUT_STABLE_NAME ||
function.origin == JsLoweredDeclarationOrigin.BRIDGE_PROPERTY_ACCESSOR ||
function.origin == JsLoweredDeclarationOrigin.BRIDGE_WITH_STABLE_NAME ||
function.origin == IrDeclarationOrigin.FUNCTION_FOR_DEFAULT_PARAMETER ||
function.origin == JsLoweredDeclarationOrigin.OBJECT_GET_INSTANCE_FUNCTION ||
@@ -52,10 +52,11 @@ class JsBridgesConstruction(context: JsIrBackendContext) : BridgesConstruction<J
}
override fun getBridgeOrigin(bridge: IrSimpleFunction): IrDeclarationOrigin =
if (bridge.hasStableJsName(context))
JsLoweredDeclarationOrigin.BRIDGE_WITH_STABLE_NAME
else
JsLoweredDeclarationOrigin.BRIDGE_WITHOUT_STABLE_NAME
when {
bridge.hasStableJsName(context) -> JsLoweredDeclarationOrigin.BRIDGE_WITH_STABLE_NAME
bridge.correspondingPropertySymbol != null -> JsLoweredDeclarationOrigin.BRIDGE_PROPERTY_ACCESSOR
else -> JsLoweredDeclarationOrigin.BRIDGE_WITHOUT_STABLE_NAME
}
override fun extractValueParameters(
blockBodyBuilder: IrBlockBodyBuilder,
@@ -5,6 +5,7 @@
package org.jetbrains.kotlin.ir.backend.js.lower
import org.jetbrains.kotlin.backend.common.ir.isTopLevel
import org.jetbrains.kotlin.backend.common.lower.optimizations.PropertyAccessorInlineLowering
import org.jetbrains.kotlin.ir.backend.js.JsIrBackendContext
import org.jetbrains.kotlin.ir.backend.js.codegen.JsGenerationGranularity
@@ -19,6 +20,9 @@ class JsPropertyAccessorInlineLowering(
if (!isSafeToInlineInClosedWorld())
return false
// Member properties could be safely inlined, because initialization processed via parent declaration
if (!isTopLevel) return true
// TODO: teach the deserializer to load constant property initializers
if (context.icCompatibleIr2Js) {
val accessFile = accessContainer.fileOrNull ?: return false
@@ -68,7 +68,7 @@ class IrModuleToJsTransformer(
val code = EnumMap<TranslationMode, CompilationOutputs>(TranslationMode::class.java)
if (fullJs) code[TranslationMode.fromFlags(false, multiModule)] = generateWrappedModuleBody(modules, exportedModule, namer)
if (fullJs) code[TranslationMode.fromFlags(false, multiModule, false)] = generateWrappedModuleBody(modules, exportedModule, namer)
if (dceJs) {
eliminateDeadDeclarations(modules, backendContext, removeUnusedAssociatedObjects)
@@ -76,7 +76,7 @@ class IrModuleToJsTransformer(
// 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(), context = backendContext)
namer.merge(modules.flatMap { it.files }, additionalPackages)
code[TranslationMode.fromFlags(true, multiModule)] = generateWrappedModuleBody(modules, exportedModule, namer)
code[TranslationMode.fromFlags(true, multiModule, false)] = generateWrappedModuleBody(modules, exportedModule, namer)
}
return CompilerResult(code, dts)
@@ -33,18 +33,30 @@ import java.io.ByteArrayOutputStream
import java.io.File
import java.util.*
enum class TranslationMode(val dce: Boolean, val perModule: Boolean) {
FULL(dce = false, perModule = false),
FULL_DCE(dce = true, perModule = false),
PER_MODULE(dce = false, perModule = true),
PER_MODULE_DCE(dce = true, perModule = true);
enum class TranslationMode(
val dce: Boolean,
val perModule: Boolean,
val minimizedMemberNames: Boolean,
) {
FULL(dce = false, perModule = false, minimizedMemberNames = false),
FULL_DCE(dce = true, perModule = false, minimizedMemberNames = false),
FULL_DCE_MINIMIZED_NAMES(dce = true, perModule = false, minimizedMemberNames = true),
PER_MODULE(dce = false, perModule = true, minimizedMemberNames = false),
PER_MODULE_DCE(dce = true, perModule = true, minimizedMemberNames = false),
PER_MODULE_DCE_MINIMIZED_NAMES(dce = true, perModule = true, minimizedMemberNames = true);
companion object {
fun fromFlags(dce: Boolean, perModule: Boolean): TranslationMode {
fun fromFlags(dce: Boolean, perModule: Boolean, minimizedMemberNames: Boolean): TranslationMode {
return if (perModule) {
if (dce) PER_MODULE_DCE else PER_MODULE
if (dce) {
if (minimizedMemberNames) PER_MODULE_DCE_MINIMIZED_NAMES
else PER_MODULE_DCE
} else PER_MODULE
} else {
if (dce) FULL_DCE else FULL
if (dce) {
if (minimizedMemberNames) FULL_DCE_MINIMIZED_NAMES
else FULL_DCE
} else FULL
}
}
}
@@ -78,11 +90,11 @@ class IrModuleToJsTransformerTmp(
module.files.forEach { StaticMembersLowering(backendContext).lower(it) }
}
fun compilationOutput(multiModule: Boolean) = generateWrappedModuleBody(
fun compilationOutput(multiModule: Boolean, minimizedMemberNames: Boolean) = generateWrappedModuleBody(
multiModule,
mainModuleName,
moduleKind,
generateProgramFragments(modules, exportData),
generateProgramFragments(modules, exportData, minimizedMemberNames),
SourceMapsInfo.from(backendContext.configuration),
relativeRequirePath,
generateScriptModule,
@@ -91,7 +103,11 @@ class IrModuleToJsTransformerTmp(
val result = EnumMap<TranslationMode, CompilationOutputs>(TranslationMode::class.java)
modes.filter { !it.dce }.forEach {
result[it] = compilationOutput(it.perModule)
if (it.minimizedMemberNames) {
backendContext.fieldDataCache.clear()
backendContext.minimizedNameGenerator.clear()
}
result[it] = compilationOutput(it.perModule, it.minimizedMemberNames)
}
if (modes.any { it.dce }) {
@@ -99,7 +115,11 @@ class IrModuleToJsTransformerTmp(
}
modes.filter { it.dce }.forEach {
result[it] = compilationOutput(it.perModule)
if (it.minimizedMemberNames) {
backendContext.fieldDataCache.clear()
backendContext.minimizedNameGenerator.clear()
}
result[it] = compilationOutput(it.perModule, it.minimizedMemberNames)
}
return CompilerResult(result, dts)
@@ -123,7 +143,7 @@ class IrModuleToJsTransformerTmp(
val result = mutableMapOf<String, ByteArray>()
files.forEach { f ->
val exports = exportData[f]!! // TODO
val fragment = generateProgramFragment(f, exports)
val fragment = generateProgramFragment(f, exports, minimizedMemberNames = false)
val output = ByteArrayOutputStream()
serializer.serialize(fragment, output)
val binaryAst = output.toByteArray()
@@ -146,6 +166,7 @@ class IrModuleToJsTransformerTmp(
private fun generateProgramFragments(
modules: Iterable<IrModuleFragment>,
exportData: Map<IrModuleFragment, Map<IrFile, List<ExportedDeclaration>>>,
minimizedMemberNames: Boolean
): JsIrProgram {
return JsIrProgram(
modules.map { m ->
@@ -154,7 +175,7 @@ class IrModuleToJsTransformerTmp(
m.externalModuleName(),
m.files.map {
val exports = exportData[m]!![it]!!
generateProgramFragment(it, exports)
generateProgramFragment(it, exports, minimizedMemberNames)
},
)
}
@@ -164,8 +185,8 @@ class IrModuleToJsTransformerTmp(
private val generateFilePaths = backendContext.configuration.getBoolean(JSConfigurationKeys.GENERATE_COMMENTS_WITH_FILE_PATH)
private val pathPrefixMap = backendContext.configuration.getMap(JSConfigurationKeys.FILE_PATHS_PREFIX_MAP)
private fun generateProgramFragment(file: IrFile, exports: List<ExportedDeclaration>): JsIrProgramFragment {
val nameGenerator = JsNameLinkingNamer(backendContext)
private fun generateProgramFragment(file: IrFile, exports: List<ExportedDeclaration>, minimizedMemberNames: Boolean): JsIrProgramFragment {
val nameGenerator = JsNameLinkingNamer(backendContext, minimizedMemberNames)
val globalNameScope = NameTable<IrDeclaration>()
@@ -5,7 +5,7 @@
package org.jetbrains.kotlin.ir.backend.js.transformers.irToJs
import org.jetbrains.kotlin.ir.backend.js.utils.sanitizeName
import org.jetbrains.kotlin.ir.backend.js.utils.toJsIdentifier
import org.jetbrains.kotlin.js.backend.ast.*
class JsIrProgramFragment(val packageFqn: String) {
@@ -75,19 +75,15 @@ private class JsIrModuleCrossModuleReferecenceBuilder(val module: JsIrModule, va
val exports = mutableSetOf<String>()
var transitiveJsExportFrom = emptyList<JsIrModule>()
private lateinit var exportNames: Map<String, String> // tag -> name
private lateinit var exportNames: Map<String, String> // tag -> index
private fun buildUniqueNames() {
val names = module.fragments.flatMap { it.nameBindings.entries }.associate { it.key to sanitizeName(it.value.ident) }
val nameToCnt = mutableMapOf<String, Int>()
val result = mutableMapOf<String, String>()
var index = 0
exports.sorted().forEach { tag ->
val suggestedName = names[tag] ?: error("Name not found for tag $tag")
val suffix = nameToCnt[suggestedName]?.let { "_$it" } ?: ""
nameToCnt[suggestedName] = nameToCnt.getOrDefault(suggestedName, 0) + 1
result[tag] = suggestedName + suffix
result[tag] = index++.toJsIdentifier()
}
exportNames = result
@@ -132,7 +128,7 @@ private class JsIrModuleCrossModuleReferecenceBuilder(val module: JsIrModule, va
class CrossModuleReferences(
val importedModules: List<JsImportedModule>, // additional Kotlin imported modules
val imports: Map<String, JsVars.JsVar>, // tag -> import statement
val exports: Map<String, String>, // tag -> name
val exports: Map<String, String>, // tag -> index
val transitiveJsExportFrom: List<JsName> // the list of modules which provide their js exports for transitive export
) {
companion object {
@@ -6,6 +6,7 @@
package org.jetbrains.kotlin.ir.backend.js.transformers.irToJs
import org.jetbrains.kotlin.ir.backend.js.JsIrBackendContext
import org.jetbrains.kotlin.ir.backend.js.export.isExported
import org.jetbrains.kotlin.ir.backend.js.utils.*
import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
@@ -17,13 +18,15 @@ import org.jetbrains.kotlin.js.backend.ast.*
import org.jetbrains.kotlin.utils.DFS
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
class JsNameLinkingNamer(private val context: JsIrBackendContext) : IrNamerBase() {
class JsNameLinkingNamer(private val context: JsIrBackendContext, private val minimizedMemberNames: Boolean) : IrNamerBase() {
val nameMap = mutableMapOf<IrDeclaration, JsName>()
private fun IrDeclarationWithName.getName(prefix: String = ""): JsName {
return nameMap.getOrPut(this) {
val name = (this as? IrClass)?.let { context.localClassNames[this] } ?: getJsNameOrKotlinName().asString()
val name = (this as? IrClass)?.let { context.localClassNames[this] } ?: let {
this.nameIfPropertyAccessor() ?: getJsNameOrKotlinName().asString()
}
JsName(sanitizeName(prefix + name), true)
}
}
@@ -82,7 +85,11 @@ class JsNameLinkingNamer(private val context: JsIrBackendContext) : IrNamerBase(
override fun getNameForMemberFunction(function: IrSimpleFunction): JsName {
require(function.dispatchReceiverParameter != null)
val signature = jsFunctionSignature(function, context)
return signature.toJsName()
val result = if (minimizedMemberNames && !function.hasStableJsName(context)) {
function.parentAsClass.fieldData()
context.minimizedNameGenerator.nameBySignature(signature)
} else signature
return result.toJsName()
}
override fun getNameForMemberField(field: IrField): JsName {
@@ -91,10 +98,8 @@ class JsNameLinkingNamer(private val context: JsIrBackendContext) : IrNamerBase(
return JsName(field.parentAsClass.fieldData()[field]!!, false)
}
private val fieldDataCache = mutableMapOf<IrClass, Map<IrField, String>>()
private fun IrClass.fieldData(): Map<IrField, String> {
return fieldDataCache.getOrPut(this) {
return context.fieldDataCache.getOrPut(this) {
val nameCnt = mutableMapOf<String, Int>()
val allClasses = DFS.topologicalOrder(listOf(this)) { node ->
@@ -105,11 +110,37 @@ class JsNameLinkingNamer(private val context: JsIrBackendContext) : IrNamerBase(
val result = mutableMapOf<IrField, String>()
if (minimizedMemberNames) {
allClasses.reversed().forEach {
it.declarations.forEach { declaration ->
when {
declaration is IrFunction && declaration.dispatchReceiverParameter != null -> {
val property = (declaration as? IrSimpleFunction)?.correspondingPropertySymbol?.owner
if (property?.isExported(context) == true || property?.isEffectivelyExternal() == true) {
context.minimizedNameGenerator.reserveName(property.name.asString())
}
if (declaration.hasStableJsName(context)) {
val signature = jsFunctionSignature(declaration, context)
context.minimizedNameGenerator.reserveName(signature)
}
}
declaration is IrProperty -> {
if (declaration.isExported(context)) {
context.minimizedNameGenerator.reserveName(declaration.name.asString())
}
}
}
}
}
}
allClasses.reversed().forEach {
it.declarations.forEach {
when {
it is IrField -> {
val safeName = it.safeName()
val safeName = if (minimizedMemberNames) {
context.minimizedNameGenerator.generateNextName()
} else it.safeName()
val suffix = nameCnt.getOrDefault(safeName, 0) + 1
nameCnt[safeName] = suffix
result[it] = safeName + "_$suffix"
@@ -121,7 +152,7 @@ class JsNameLinkingNamer(private val context: JsIrBackendContext) : IrNamerBase(
}
}
return result
result
}
}
}
@@ -71,10 +71,10 @@ class Merger(
).makeStmt()
additionalExports += createExportBlock
crossModuleReferences.exports.entries.forEach { (tag, name) ->
crossModuleReferences.exports.entries.forEach { (tag, hash) ->
val internalName = nameMap[tag] ?: error("Missing name for declaration '$tag'")
val crossModuleRef = ReservedJsNames.makeCrossModuleNameRef(ReservedJsNames.makeInternalModuleName())
additionalExports += jsAssignment(JsNameRef(name, crossModuleRef), JsNameRef(internalName)).makeStmt()
additionalExports += jsAssignment(JsNameRef(hash, crossModuleRef), JsNameRef(internalName)).makeStmt()
}
}
}
@@ -12,6 +12,6 @@ class ReservedJsNames {
companion object {
fun makeInternalModuleName() = JsName("_", false)
fun makeJsExporterName() = JsName("\$jsExportAll\$", false)
fun makeCrossModuleNameRef(moduleName: JsName) = JsNameRef("\$crossModule\$", moduleName.makeRef())
fun makeCrossModuleNameRef(moduleName: JsName) = JsNameRef("\$_\$", moduleName.makeRef())
}
}
@@ -0,0 +1,36 @@
/*
* Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.ir.backend.js.utils
class MinimizedNameGenerator {
private var index = 0
private val functionSignatureToName = mutableMapOf<String, String>()
private val reservedNames = mutableSetOf<String>()
fun generateNextName(): String {
var candidate = index++.toJsIdentifier()
while (candidate in reservedNames) {
candidate = index++.toJsIdentifier()
}
return candidate
}
fun nameBySignature(signature: String): String {
return functionSignatureToName.getOrPut(signature) {
generateNextName()
}
}
fun reserveName(signature: String) {
reservedNames.add(signature)
}
fun clear() {
index = 0
functionSignatureToName.clear()
reservedNames.clear()
}
}
@@ -8,6 +8,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.JsLoweredDeclarationOrigin
import org.jetbrains.kotlin.ir.backend.js.lower.serialization.ir.JsManglerIr
import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.expressions.*
@@ -105,11 +106,21 @@ fun NameTable<IrDeclaration>.dump(): String =
private const val RESERVED_MEMBER_NAME_SUFFIX = "_k$"
fun Int.toJsIdentifier(): String {
val first = ('a'.code + (this % 26)).toChar().toString()
val other = this / 26
return if (other == 0) {
first
} else {
first + other.toString(Character.MAX_RADIX)
}
}
fun jsFunctionSignature(declaration: IrFunction, context: JsIrBackendContext): String {
require(!declaration.isStaticMethodOfClass)
require(declaration.dispatchReceiverParameter != null)
val declarationName = declaration.getJsNameOrKotlinName().asString()
var declarationName = declaration.getJsNameOrKotlinName().asString()
if (declaration.hasStableJsName(context)) {
// TODO: Handle reserved suffix in FE
@@ -119,6 +130,10 @@ fun jsFunctionSignature(declaration: IrFunction, context: JsIrBackendContext): S
return declarationName
}
declaration.nameIfPropertyAccessor()?.let {
declarationName = it
}
val nameBuilder = StringBuilder()
nameBuilder.append(declarationName)
@@ -139,7 +154,10 @@ fun jsFunctionSignature(declaration: IrFunction, context: JsIrBackendContext): S
val signature = nameBuilder.toString()
// TODO: Use better hashCode
return sanitizeName(declarationName) + "_" + abs(signature.hashCode()).toString(Character.MAX_RADIX) + RESERVED_MEMBER_NAME_SUFFIX
return sanitizeName(
declarationName,
withHash = false
) + "_" + abs(signature.hashCode()).toString(Character.MAX_RADIX) + RESERVED_MEMBER_NAME_SUFFIX
}
class NameTables(
@@ -295,8 +313,10 @@ class NameTables(
}
}
else ->
globalNames.declareFreshName(declaration, declaration.name.asString())
else -> {
val name = declaration.nameIfPropertyAccessor() ?: declaration.name.asString()
globalNames.declareFreshName(declaration, name)
}
}
}
@@ -393,12 +413,38 @@ fun sanitizeName(name: String, withHash: Boolean = true): String {
}
return if (withHash) {
"${builder}_${name.hashCode().toUInt()}"
"${builder}_${abs(name.hashCode()).toString(Character.MAX_RADIX)}"
} else {
builder.toString()
}
}
fun IrDeclarationWithName.nameIfPropertyAccessor(): String? {
if (this is IrSimpleFunction) {
return when {
this.correspondingPropertySymbol != null -> {
val property = this.correspondingPropertySymbol!!.owner
val name = property.getJsNameOrKotlinName().asString()
val prefix = when (this) {
property.getter -> "get_"
property.setter -> "set_"
else -> error("")
}
prefix + name
}
this.origin == JsLoweredDeclarationOrigin.BRIDGE_PROPERTY_ACCESSOR -> {
this.getJsNameOrKotlinName().asString()
.removePrefix("<")
.removeSuffix(">")
.replaceFirst("get-", "get_")
.replaceFirst("set-", "set_")
}
else -> null
}
}
return null
}
private inline fun Char.mangleIfNot(predicate: Char.() -> Boolean) =
if (predicate()) this else '_'
@@ -157,7 +157,8 @@ class NewNamerImpl(
} else { // Non-external declaration
staticNames.declareFreshName(declaration, declaration.name.asString())
val name = declaration.nameIfPropertyAccessor() ?: declaration.name.asString()
staticNames.declareFreshName(declaration, name)
val unitReference = unit.referenceCodegenUnitOfDeclaration(declaration)
if (unitReference is IrToJs.OtherUnitReference) {
registerImport(unitReference.importPath, exportId(declaration))
@@ -8,17 +8,16 @@ package org.jetbrains.kotlin.ir.backend.js.utils
import org.jetbrains.kotlin.backend.common.ir.isMethodOfAny
import org.jetbrains.kotlin.backend.common.ir.isTopLevel
import org.jetbrains.kotlin.ir.IrElement
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.export.isExported
import org.jetbrains.kotlin.ir.backend.js.ir.JsIrBuilder
import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.expressions.*
import org.jetbrains.kotlin.ir.expressions.impl.IrCallImpl
import org.jetbrains.kotlin.ir.expressions.impl.IrVarargImpl
import org.jetbrains.kotlin.ir.types.IrType
import org.jetbrains.kotlin.ir.expressions.IrBlockBody
import org.jetbrains.kotlin.ir.expressions.IrBody
import org.jetbrains.kotlin.ir.expressions.IrCall
import org.jetbrains.kotlin.ir.expressions.IrExpressionBody
import org.jetbrains.kotlin.ir.types.getClass
import org.jetbrains.kotlin.ir.types.isNullableAny
import org.jetbrains.kotlin.ir.util.isEffectivelyExternal
@@ -38,7 +37,8 @@ fun IrFunction.hasStableJsName(context: JsIrBackendContext): Boolean {
if (
origin == JsLoweredDeclarationOrigin.JS_SHADOWED_EXPORT ||
origin == IrDeclarationOrigin.FUNCTION_FOR_DEFAULT_PARAMETER ||
origin == JsLoweredDeclarationOrigin.BRIDGE_WITHOUT_STABLE_NAME
origin == JsLoweredDeclarationOrigin.BRIDGE_WITHOUT_STABLE_NAME ||
origin == JsLoweredDeclarationOrigin.BRIDGE_PROPERTY_ACCESSOR
) {
return false
}