diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/transformers/irToJs/JsNameLinkingNamer.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/transformers/irToJs/JsNameLinkingNamer.kt index 5ff0ebb3674..6150bc10b87 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/transformers/irToJs/JsNameLinkingNamer.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/transformers/irToJs/JsNameLinkingNamer.kt @@ -11,10 +11,7 @@ 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.types.IrSimpleType -import org.jetbrains.kotlin.ir.util.fqNameWhenAvailable -import org.jetbrains.kotlin.ir.util.isEffectivelyExternal -import org.jetbrains.kotlin.ir.util.isSimpleProperty -import org.jetbrains.kotlin.ir.util.parentAsClass +import org.jetbrains.kotlin.ir.util.* import org.jetbrains.kotlin.js.backend.ast.* import org.jetbrains.kotlin.utils.DFS import org.jetbrains.kotlin.utils.addToStdlib.safeAs @@ -85,11 +82,16 @@ class JsNameLinkingNamer( parent.child(getJsNameOrKotlinName()).asString() } val name = JsName(sanitizeName(nameString), true) + val nameRef = name.makeRef() if (isEsModules) { - imports[this] = JsImport(jsModule, JsImport.Target.Default(name.makeRef())) + val importSubject = when { + this is IrClass && isObject -> JsImport.Target.All(nameRef) + else -> JsImport.Target.Default(nameRef) + } + imports[this] = JsImport(jsModule, importSubject) } else { - importedModules += JsImportedModule(jsModule, name, name.makeRef()) + importedModules += JsImportedModule(jsModule, name, nameRef) } return name } diff --git a/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/lower/ComplexExternalDeclarationsToTopLevelFunctionsLowering.kt b/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/lower/ComplexExternalDeclarationsToTopLevelFunctionsLowering.kt index 7ad55b88c23..8c3781909a2 100644 --- a/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/lower/ComplexExternalDeclarationsToTopLevelFunctionsLowering.kt +++ b/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/lower/ComplexExternalDeclarationsToTopLevelFunctionsLowering.kt @@ -366,22 +366,21 @@ class ComplexExternalDeclarationsToTopLevelFunctionsLowering(val context: WasmBa } private fun referenceTopLevelExternalDeclaration(declaration: IrDeclarationWithName): String { - var name = declaration.getJsNameOrKotlinName().identifier + var name: String? = declaration.getJsNameOrKotlinName().identifier val qualifier = currentFile.getJsQualifier() val module = currentFile.getJsModule() ?: declaration.getJsModule()?.also { - // JsModule on top level declarations imports "default" - name = "default" + name = if (declaration is IrClass && declaration.isObject) null else "default" } if (qualifier == null && module == null) - return name + return name!! val qualifieReference = JsModuleAndQualifierReference(module, qualifier) context.jsModuleAndQualifierReferences += qualifieReference - return qualifieReference.jsVariableName + "." + name + return qualifieReference.jsVariableName + name?.let { ".$it" }.orEmpty() } } diff --git a/compiler/testData/codegen/boxWasmJsInterop/jsModule.kt b/compiler/testData/codegen/boxWasmJsInterop/jsModule.kt index 1f68cb4ce7e..1a8f8097150 100644 --- a/compiler/testData/codegen/boxWasmJsInterop/jsModule.kt +++ b/compiler/testData/codegen/boxWasmJsInterop/jsModule.kt @@ -28,13 +28,23 @@ package default @JsModule("./jsModule.mjs") external object jsModule { - val defaultX: Int - fun defaultF(): Int - class defaultC { + val x: Int + fun f(): Int + class C { constructor(x: String) - val x: String } + + @JsName("default") + object Default { + val defaultX: Int + fun defaultF(): Int + class defaultC { + constructor(x: String) + + val x: String + } + } } @@ -44,9 +54,13 @@ fun box(): String { if (named.f() != 10) return "Fail2" if (named.C("10").x != "10") return "Fail3" - if (default.jsModule.defaultX != 10) return "Fail4" - if (default.jsModule.defaultF() != 10) return "Fail5" - if (default.jsModule.defaultC("10").x != "10") return "Fail6" + if (default.jsModule.Default.defaultX != 10) return "Fail4" + if (default.jsModule.Default.defaultF() != 10) return "Fail5" + if (default.jsModule.Default.defaultC("10").x != "10") return "Fail6" + + if (default.jsModule.x != 10) return "Fail7" + if (default.jsModule.f() != 10) return "Fail8" + if (default.jsModule.C("10").x != "10") return "Fail9" return "OK" } \ No newline at end of file diff --git a/js/js.translator/testData/box/esModules/jsModule/externalObject.kt b/js/js.translator/testData/box/esModules/jsModule/externalObject.kt index 12c5ce444a2..75e6f1c9a63 100644 --- a/js/js.translator/testData/box/esModules/jsModule/externalObject.kt +++ b/js/js.translator/testData/box/esModules/jsModule/externalObject.kt @@ -4,13 +4,16 @@ package foo @JsModule("./externalObject.mjs") external object A { - val x: Int = definedExternally + @JsName("default") + object Default { + val x: Int = definedExternally - fun foo(y: Int): Int = definedExternally + fun foo(y: Int): Int = definedExternally + } } fun box(): String { - assertEquals(23, A.x) - assertEquals(65, A.foo(42)) + assertEquals(23, A.Default.x) + assertEquals(65, A.Default.foo(42)) return "OK" } \ No newline at end of file diff --git a/js/js.translator/testData/box/esModules/jsModule/jsExternalInheritorsOnly.mjs b/js/js.translator/testData/box/esModules/jsModule/jsExternalInheritorsOnly.mjs index 35ccf800f74..aa31102676b 100644 --- a/js/js.translator/testData/box/esModules/jsModule/jsExternalInheritorsOnly.mjs +++ b/js/js.translator/testData/box/esModules/jsModule/jsExternalInheritorsOnly.mjs @@ -1,21 +1,19 @@ -export default { - createX: function () { - return {x: "X1"}; - }, - createXY: function () { - return {x: "X2", y: "Y2"}; - }, - createXYZ: function () { - return {x: "X3", y: "Y3", z: "Z3"}; - }, - createClassXYZ: function () { - return {x: "X4", y: "Y4", z: "Z4"}; - }, - createNestedInterfaceXYZ: function () { - return {x: "X5", y: "Y5", z: "Z5"}; - }, +export function createX () { + return {x: "X1"}; +} +export function createXY () { + return {x: "X2", y: "Y2"}; +} +export function createXYZ() { + return {x: "X3", y: "Y3", z: "Z3"}; +} +export function createClassXYZ() { + return {x: "X4", y: "Y4", z: "Z4"}; +} +export function createNestedInterfaceXYZ() { + return {x: "X5", y: "Y5", z: "Z5"}; +} - x: "X6", - y: "Y6", - z: "Z6" -}; +export const x = "X6" +export const y = "Y6" +export const z = "Z6"