[JS IR] Export name and ordinal for enum classes
^KT-37916 fixed ^KT-44494 fixed
This commit is contained in:
+18
-5
@@ -108,7 +108,7 @@ class ExportModelGenerator(
|
|||||||
// TODO: Report a frontend error
|
// TODO: Report a frontend error
|
||||||
if (accessor.extensionReceiverParameter != null)
|
if (accessor.extensionReceiverParameter != null)
|
||||||
return null
|
return null
|
||||||
if (accessor.isFakeOverride) {
|
if (accessor.isFakeOverride && !accessor.isEnumFakeOverriddenDeclaration(context)) {
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -446,14 +446,15 @@ private fun shouldDeclarationBeExported(declaration: IrDeclarationWithName, cont
|
|||||||
if (context?.additionalExportedDeclarations?.contains(declaration) == true)
|
if (context?.additionalExportedDeclarations?.contains(declaration) == true)
|
||||||
return true
|
return true
|
||||||
|
|
||||||
if (declaration is IrSimpleFunction) {
|
if (declaration is IrOverridableDeclaration<*>) {
|
||||||
val overriddenNonEmpty = declaration
|
val overriddenNonEmpty = declaration
|
||||||
.overriddenSymbols
|
.overriddenSymbols
|
||||||
.isNotEmpty()
|
.isNotEmpty()
|
||||||
|
|
||||||
if (overriddenNonEmpty) {
|
if (overriddenNonEmpty) {
|
||||||
return declaration.isOverriddenExported(context) ||
|
return declaration.isOverriddenExported(context) ||
|
||||||
declaration.isMethodOfAny() // Handle names for special functions
|
(declaration as? IrSimpleFunction)?.isMethodOfAny() == true // Handle names for special functions
|
||||||
|
|| declaration.isEnumFakeOverriddenDeclaration(context)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -467,9 +468,21 @@ private fun shouldDeclarationBeExported(declaration: IrDeclarationWithName, cont
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun IrSimpleFunction.isOverriddenExported(context: JsIrBackendContext?): Boolean =
|
fun IrOverridableDeclaration<*>.isEnumFakeOverriddenDeclaration(context: JsIrBackendContext?): Boolean {
|
||||||
|
return context?.irBuiltIns?.enumClass?.let { enumClass ->
|
||||||
|
overriddenSymbols
|
||||||
|
.asSequence()
|
||||||
|
.map { it.owner }
|
||||||
|
.filterIsInstance<IrDeclaration>()
|
||||||
|
.mapNotNull { it.parentClassOrNull }
|
||||||
|
.map { it.symbol }
|
||||||
|
.any { it == enumClass }
|
||||||
|
} == true
|
||||||
|
}
|
||||||
|
|
||||||
|
fun IrOverridableDeclaration<*>.isOverriddenExported(context: JsIrBackendContext?): Boolean =
|
||||||
overriddenSymbols
|
overriddenSymbols
|
||||||
.any { shouldDeclarationBeExported(it.owner, context) }
|
.any { shouldDeclarationBeExported(it.owner as IrDeclarationWithName, context) }
|
||||||
|
|
||||||
fun IrDeclaration.isExported(context: JsIrBackendContext?): Boolean {
|
fun IrDeclaration.isExported(context: JsIrBackendContext?): Boolean {
|
||||||
val candidate = getExportCandidate(this) ?: return false
|
val candidate = getExportCandidate(this) ?: return false
|
||||||
|
|||||||
+7
-5
@@ -7,6 +7,7 @@ package org.jetbrains.kotlin.ir.backend.js.transformers.irToJs
|
|||||||
|
|
||||||
import org.jetbrains.kotlin.descriptors.DescriptorVisibilities
|
import org.jetbrains.kotlin.descriptors.DescriptorVisibilities
|
||||||
import org.jetbrains.kotlin.descriptors.Modality
|
import org.jetbrains.kotlin.descriptors.Modality
|
||||||
|
import org.jetbrains.kotlin.ir.backend.js.export.isEnumFakeOverriddenDeclaration
|
||||||
import org.jetbrains.kotlin.ir.backend.js.export.isExported
|
import org.jetbrains.kotlin.ir.backend.js.export.isExported
|
||||||
import org.jetbrains.kotlin.ir.backend.js.export.isOverriddenExported
|
import org.jetbrains.kotlin.ir.backend.js.export.isOverriddenExported
|
||||||
import org.jetbrains.kotlin.ir.backend.js.utils.*
|
import org.jetbrains.kotlin.ir.backend.js.utils.*
|
||||||
@@ -108,7 +109,7 @@ class JsClassGenerator(private val irClass: IrClass, val context: JsGenerationCo
|
|||||||
if (!property.visibility.isPublicAPI)
|
if (!property.visibility.isPublicAPI)
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if (property.isFakeOverride)
|
if (property.isFakeOverride && !property.isEnumFakeOverriddenDeclaration(context.staticContext.backendContext))
|
||||||
continue
|
continue
|
||||||
|
|
||||||
fun IrSimpleFunction.propertyAccessorForwarder(
|
fun IrSimpleFunction.propertyAccessorForwarder(
|
||||||
@@ -140,15 +141,16 @@ class JsClassGenerator(private val irClass: IrClass, val context: JsGenerationCo
|
|||||||
// so we need regenerate `defineProperty` with setter.
|
// so we need regenerate `defineProperty` with setter.
|
||||||
val noOverriddenGetter = property.getter?.overriddenSymbols?.isEmpty() == true
|
val noOverriddenGetter = property.getter?.overriddenSymbols?.isEmpty() == true
|
||||||
|
|
||||||
val overriddenExportedGetter = property.getter?.overriddenSymbols?.isNotEmpty() == true &&
|
val overriddenExportedGetter = (property.getter?.overriddenSymbols?.isNotEmpty() == true &&
|
||||||
property.getter?.isOverriddenExported(context.staticContext.backendContext) == true
|
property.getter?.isOverriddenExported(context.staticContext.backendContext) == true)
|
||||||
|
|
||||||
val noOverriddenExportedSetter = property.setter?.isOverriddenExported(context.staticContext.backendContext) == false
|
val noOverriddenExportedSetter = property.setter?.isOverriddenExported(context.staticContext.backendContext) == false
|
||||||
|
|
||||||
val needOverrideBySetter = overriddenExportedGetter && noOverriddenExportedSetter
|
val needsOverride = (overriddenExportedGetter && noOverriddenExportedSetter) ||
|
||||||
|
property.isEnumFakeOverriddenDeclaration(context.staticContext.backendContext)
|
||||||
|
|
||||||
if (irClass.isExported(context.staticContext.backendContext) &&
|
if (irClass.isExported(context.staticContext.backendContext) &&
|
||||||
(noOverriddenGetter || needOverrideBySetter) ||
|
(noOverriddenGetter || needsOverride) ||
|
||||||
property.getter?.overridesExternal() == true ||
|
property.getter?.overridesExternal() == true ||
|
||||||
property.getJsName() != null
|
property.getJsName() != null
|
||||||
) {
|
) {
|
||||||
|
|||||||
@@ -74,5 +74,11 @@ function box() {
|
|||||||
if (this["export_enum_class"].Foo.values().indexOf(this["export_enum_class"].Foo.A) === -1) return "fail20"
|
if (this["export_enum_class"].Foo.values().indexOf(this["export_enum_class"].Foo.A) === -1) return "fail20"
|
||||||
if (this["export_enum_class"].Foo.values().indexOf(this["export_enum_class"].Foo.B) === -1) return "fail21"
|
if (this["export_enum_class"].Foo.values().indexOf(this["export_enum_class"].Foo.B) === -1) return "fail21"
|
||||||
|
|
||||||
|
if (this["export_enum_class"].Foo.A.name !== "A") return "fail22"
|
||||||
|
if (this["export_enum_class"].Foo.B.name !== "B") return "fail23"
|
||||||
|
|
||||||
|
if (this["export_enum_class"].Foo.A.ordinal !== 0) return "fail24"
|
||||||
|
if (this["export_enum_class"].Foo.B.ordinal !== 1) return "fail23"
|
||||||
|
|
||||||
return "OK"
|
return "OK"
|
||||||
}
|
}
|
||||||
@@ -108,6 +108,8 @@ declare namespace JS_TESTS {
|
|||||||
bay(): string;
|
bay(): string;
|
||||||
static values(): Array<foo.TestEnumClass>;
|
static values(): Array<foo.TestEnumClass>;
|
||||||
static valueOf(value: string): foo.TestEnumClass;
|
static valueOf(value: string): foo.TestEnumClass;
|
||||||
|
readonly name: string;
|
||||||
|
readonly ordinal: number;
|
||||||
}
|
}
|
||||||
namespace TestEnumClass {
|
namespace TestEnumClass {
|
||||||
class Nested {
|
class Nested {
|
||||||
|
|||||||
+4
@@ -107,6 +107,10 @@ function box() {
|
|||||||
assert(TestEnumClass.valueOf("B") === TestEnumClass.B);
|
assert(TestEnumClass.valueOf("B") === TestEnumClass.B);
|
||||||
assert(TestEnumClass.values().indexOf(TestEnumClass.A) != -1);
|
assert(TestEnumClass.values().indexOf(TestEnumClass.A) != -1);
|
||||||
assert(TestEnumClass.values().indexOf(TestEnumClass.B) != -1);
|
assert(TestEnumClass.values().indexOf(TestEnumClass.B) != -1);
|
||||||
|
assert(TestEnumClass.A.name === "A");
|
||||||
|
assert(TestEnumClass.B.name === "B");
|
||||||
|
assert(TestEnumClass.A.ordinal === 0);
|
||||||
|
assert(TestEnumClass.B.ordinal === 1);
|
||||||
assert(new TestEnumClass.Nested().prop == "hello2");
|
assert(new TestEnumClass.Nested().prop == "hello2");
|
||||||
return "OK";
|
return "OK";
|
||||||
}
|
}
|
||||||
|
|||||||
+5
@@ -126,6 +126,11 @@ function box(): string {
|
|||||||
assert(TestEnumClass.values().indexOf(TestEnumClass.A) != -1)
|
assert(TestEnumClass.values().indexOf(TestEnumClass.A) != -1)
|
||||||
assert(TestEnumClass.values().indexOf(TestEnumClass.B) != -1)
|
assert(TestEnumClass.values().indexOf(TestEnumClass.B) != -1)
|
||||||
|
|
||||||
|
assert(TestEnumClass.A.name === "A")
|
||||||
|
assert(TestEnumClass.B.name === "B")
|
||||||
|
assert(TestEnumClass.A.ordinal === 0)
|
||||||
|
assert(TestEnumClass.B.ordinal === 1)
|
||||||
|
|
||||||
assert(new TestEnumClass.Nested().prop == "hello2")
|
assert(new TestEnumClass.Nested().prop == "hello2")
|
||||||
|
|
||||||
return "OK";
|
return "OK";
|
||||||
|
|||||||
Reference in New Issue
Block a user