[JS IR] Fix export of constructor with default argument (KT-41275)
This commit is contained in:
@@ -40,7 +40,7 @@ class JsIrBackendContext(
|
||||
override val irBuiltIns: IrBuiltIns,
|
||||
val symbolTable: SymbolTable,
|
||||
irModuleFragment: IrModuleFragment,
|
||||
val additionalExportedDeclarations: Set<FqName>,
|
||||
val additionalExportedDeclarationNames: Set<FqName>,
|
||||
override val configuration: CompilerConfiguration, // TODO: remove configuration from backend context
|
||||
override val scriptMode: Boolean = false,
|
||||
override val es6mode: Boolean = false
|
||||
@@ -65,6 +65,8 @@ class JsIrBackendContext(
|
||||
val externalPackageFragment = mutableMapOf<IrFileSymbol, IrFile>()
|
||||
val externalDeclarations = hashSetOf<IrDeclaration>()
|
||||
|
||||
val additionalExportedDeclarations = mutableSetOf<IrDeclaration>()
|
||||
|
||||
val bodilessBuiltInsPackageFragment: IrPackageFragment = IrExternalPackageFragmentImpl(
|
||||
DescriptorlessExternalPackageFragmentSymbol(),
|
||||
FqName("kotlin")
|
||||
|
||||
+15
-2
@@ -331,9 +331,19 @@ class ExportModelGenerator(val context: JsIrBackendContext) {
|
||||
|
||||
if (function.isFakeOverriddenFromAny())
|
||||
return Exportability.NotNeeded
|
||||
if (function.name.asString().endsWith("-impl"))
|
||||
|
||||
|
||||
val nameString = function.name.asString()
|
||||
if (nameString.endsWith("-impl"))
|
||||
return Exportability.NotNeeded
|
||||
|
||||
|
||||
// Workaround in case IrDeclarationOrigin.FUNCTION_FOR_DEFAULT_PARAMETER is rewritten.
|
||||
// TODO: Properly fix KT-41613
|
||||
if (nameString.endsWith("\$") && function.valueParameters.any { "\$mask" in it.name.asString() }) {
|
||||
return Exportability.NotNeeded
|
||||
}
|
||||
|
||||
val name = function.getExportedIdentifier()
|
||||
// TODO: Use [] syntax instead of prohibiting
|
||||
if (name in allReservedWords)
|
||||
@@ -379,7 +389,10 @@ private fun getExportCandidate(declaration: IrDeclaration): IrDeclarationWithNam
|
||||
}
|
||||
|
||||
private fun shouldDeclarationBeExported(declaration: IrDeclarationWithName, context: JsIrBackendContext): Boolean {
|
||||
if (declaration.fqNameWhenAvailable in context.additionalExportedDeclarations)
|
||||
if (declaration.fqNameWhenAvailable in context.additionalExportedDeclarationNames)
|
||||
return true
|
||||
|
||||
if (declaration in context.additionalExportedDeclarations)
|
||||
return true
|
||||
|
||||
if (declaration.isJsExport())
|
||||
|
||||
+8
-2
@@ -5,14 +5,15 @@
|
||||
|
||||
package org.jetbrains.kotlin.ir.backend.js.lower
|
||||
|
||||
import org.jetbrains.kotlin.backend.common.CommonBackendContext
|
||||
import org.jetbrains.kotlin.backend.common.DeclarationTransformer
|
||||
import org.jetbrains.kotlin.ir.backend.js.JsIrBackendContext
|
||||
import org.jetbrains.kotlin.ir.backend.js.export.isExported
|
||||
import org.jetbrains.kotlin.ir.declarations.*
|
||||
import org.jetbrains.kotlin.ir.util.file
|
||||
import org.jetbrains.kotlin.ir.util.isEffectivelyExternal
|
||||
|
||||
// Move static member declarations from classes to top level
|
||||
class StaticMembersLowering(val context: CommonBackendContext) : DeclarationTransformer {
|
||||
class StaticMembersLowering(val context: JsIrBackendContext) : DeclarationTransformer {
|
||||
override fun transformFlat(declaration: IrDeclaration): List<IrDeclaration>? {
|
||||
(declaration.parent as? IrClass)?.let { irClass ->
|
||||
val isStatic = when (declaration) {
|
||||
@@ -23,6 +24,11 @@ class StaticMembersLowering(val context: CommonBackendContext) : DeclarationTran
|
||||
}
|
||||
|
||||
if (isStatic) {
|
||||
// JsExport might be inherited from parent declaration which would be broken if we move it out of its parent.
|
||||
// Marking declaration as exported explicitly.
|
||||
if (declaration.isExported(context)) {
|
||||
context.additionalExportedDeclarations.add(declaration)
|
||||
}
|
||||
declaration.parent = irClass.file
|
||||
irClass.file.declarations += declaration
|
||||
return listOf()
|
||||
|
||||
@@ -312,7 +312,8 @@ class NameTables(
|
||||
parent = parent.parent
|
||||
}
|
||||
|
||||
return mappedNames[mapToKey(declaration)] ?: error("Can't find name for declaration ${declaration.render()}")
|
||||
return mappedNames[mapToKey(declaration)]
|
||||
?: error("Can't find name for declaration ${declaration.render()}")
|
||||
}
|
||||
|
||||
fun getNameForMemberField(field: IrField): String {
|
||||
|
||||
+6
-6
@@ -316,11 +316,11 @@ private val blockDecomposerLoweringPhase = makeCustomWasmModulePhase(
|
||||
// description = "Generate invocations to kotlin.test suite and test functions"
|
||||
//)
|
||||
//
|
||||
private val staticMembersLoweringPhase = makeWasmModulePhase(
|
||||
::StaticMembersLowering,
|
||||
name = "StaticMembersLowering",
|
||||
description = "Move static member declarations to top-level"
|
||||
)
|
||||
//private val staticMembersLoweringPhase = makeWasmModulePhase(
|
||||
// ::StaticMembersLowering,
|
||||
// name = "StaticMembersLowering",
|
||||
// description = "Move static member declarations to top-level"
|
||||
//)
|
||||
|
||||
private val builtInsLoweringPhase = makeWasmModulePhase(
|
||||
::BuiltInsLowering,
|
||||
@@ -434,7 +434,7 @@ val wasmPhases = NamedCompilerPhase(
|
||||
|
||||
objectDeclarationLoweringPhase then
|
||||
objectUsageLoweringPhase then
|
||||
staticMembersLoweringPhase then
|
||||
// staticMembersLoweringPhase then
|
||||
|
||||
validateIrAfterLowering
|
||||
)
|
||||
|
||||
@@ -30,4 +30,8 @@ declare namespace JS_TESTS {
|
||||
static delegateToPrimary(y: string): DerivedClassWithSecondaryCtor;
|
||||
static delegateToCreateFromInts(y: number, z: number): DerivedClassWithSecondaryCtor;
|
||||
}
|
||||
class KotlinGreeter {
|
||||
constructor(greeting: string);
|
||||
readonly greeting: string;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,6 +8,8 @@
|
||||
// TODO fix statics export in DCE-driven mode
|
||||
// SKIP_DCE_DRIVEN
|
||||
|
||||
// FILE: f1.kt
|
||||
|
||||
@file:JsExport
|
||||
|
||||
class ClassWithDefaultCtor {
|
||||
@@ -54,4 +56,9 @@ class DerivedClassWithSecondaryCtor : OpenClassWithMixedConstructors {
|
||||
|
||||
@JsName("delegateToCreateFromInts")
|
||||
constructor(y: Int, z: Int) : super(y, z)
|
||||
}
|
||||
}
|
||||
|
||||
// FILE: f2.kt
|
||||
|
||||
@JsExport
|
||||
class KotlinGreeter(val greeting: String = "helau")
|
||||
+4
-1
@@ -1,5 +1,5 @@
|
||||
"use strict";
|
||||
var ClassWithDefaultCtor = JS_TESTS.ClassWithDefaultCtor, ClassWithPrimaryCtor = JS_TESTS.ClassWithPrimaryCtor, ClassWithSecondaryCtor = JS_TESTS.ClassWithSecondaryCtor, ClassWithMultipleSecondaryCtors = JS_TESTS.ClassWithMultipleSecondaryCtors, DerivedClassWithSecondaryCtor = JS_TESTS.DerivedClassWithSecondaryCtor, OpenClassWithMixedConstructors = JS_TESTS.OpenClassWithMixedConstructors;
|
||||
var ClassWithDefaultCtor = JS_TESTS.ClassWithDefaultCtor, ClassWithPrimaryCtor = JS_TESTS.ClassWithPrimaryCtor, ClassWithSecondaryCtor = JS_TESTS.ClassWithSecondaryCtor, ClassWithMultipleSecondaryCtors = JS_TESTS.ClassWithMultipleSecondaryCtors, DerivedClassWithSecondaryCtor = JS_TESTS.DerivedClassWithSecondaryCtor, OpenClassWithMixedConstructors = JS_TESTS.OpenClassWithMixedConstructors, KotlinGreeter = JS_TESTS.KotlinGreeter;
|
||||
function box() {
|
||||
var o1 = new ClassWithDefaultCtor();
|
||||
if (o1.x !== "ClassWithDefaultCtor::x")
|
||||
@@ -31,5 +31,8 @@ function box() {
|
||||
var o10 = DerivedClassWithSecondaryCtor.delegateToCreateFromInts(-10, 20);
|
||||
if (o10.x !== "fromStrings:-10:20")
|
||||
return "Fail: DerivedClassWithSecondaryCtor.delegateToCreateFromInts";
|
||||
var kg = new KotlinGreeter("Hi");
|
||||
if (kg.greeting != "Hi")
|
||||
return "Fail: KotlinGreeter";
|
||||
return "OK";
|
||||
}
|
||||
|
||||
+6
-1
@@ -4,7 +4,8 @@ const {
|
||||
ClassWithSecondaryCtor,
|
||||
ClassWithMultipleSecondaryCtors,
|
||||
DerivedClassWithSecondaryCtor,
|
||||
OpenClassWithMixedConstructors
|
||||
OpenClassWithMixedConstructors,
|
||||
KotlinGreeter
|
||||
} = JS_TESTS;
|
||||
|
||||
function box(): string {
|
||||
@@ -43,5 +44,9 @@ function box(): string {
|
||||
const o10 = DerivedClassWithSecondaryCtor.delegateToCreateFromInts(-10, 20);
|
||||
if (o10.x !== "fromStrings:-10:20") return "Fail: DerivedClassWithSecondaryCtor.delegateToCreateFromInts";
|
||||
|
||||
|
||||
const kg = new KotlinGreeter("Hi");
|
||||
if (kg.greeting != "Hi") return "Fail: KotlinGreeter";
|
||||
|
||||
return "OK";
|
||||
}
|
||||
Reference in New Issue
Block a user