Enum implementing exported interface
[JS IR] Not export get instance enum function [JS IR] Enum corresponding class is not considered in export [JS IR] All enums are abstract and with private constructor [JS IR] Any methods is left in d.ts [JS IR] Make enum with declarations inside corresponding class [JS IR] Export of interface through fake override [JS IR] Include enum entry corresponding class members into export model Merge-request: KT-MR-5031 ^KT-49779 fixed ^KT-49773 fixed
This commit is contained in:
@@ -405,7 +405,7 @@ fun usefulDeclarations(
|
||||
// https://youtrack.jetbrains.com/issue/KT-46672
|
||||
// TODO: Possibly solution with origin is not so good
|
||||
// There is option with applying this hack to jsGetKClass
|
||||
if (expression.origin == JsLoweredDeclarationOrigin.CLASS_REFERENCE) {
|
||||
if (expression.origin == JsStatementOrigins.CLASS_REFERENCE) {
|
||||
// Maybe we need to filter primary constructor
|
||||
// Although at this time, we should have only primary constructor
|
||||
(ref as IrClass)
|
||||
|
||||
@@ -7,7 +7,6 @@ package org.jetbrains.kotlin.ir.backend.js
|
||||
|
||||
import org.jetbrains.kotlin.ir.declarations.IrDeclarationOrigin
|
||||
import org.jetbrains.kotlin.ir.declarations.IrDeclarationOriginImpl
|
||||
import org.jetbrains.kotlin.ir.expressions.IrStatementOriginImpl
|
||||
|
||||
object JsLoweredDeclarationOrigin : IrDeclarationOrigin {
|
||||
object JS_INTRINSICS_STUB : IrDeclarationOriginImpl("JS_INTRINSICS_STUB")
|
||||
@@ -16,5 +15,5 @@ object JsLoweredDeclarationOrigin : IrDeclarationOrigin {
|
||||
object BRIDGE_WITHOUT_STABLE_NAME : IrDeclarationOriginImpl("BRIDGE_WITHOUT_STABLE_NAME")
|
||||
object OBJECT_GET_INSTANCE_FUNCTION : IrDeclarationOriginImpl("OBJECT_GET_INSTANCE_FUNCTION")
|
||||
object JS_SHADOWED_EXPORT : IrDeclarationOriginImpl("JS_SHADOWED_EXPORT")
|
||||
object CLASS_REFERENCE : IrStatementOriginImpl("CLASS_REFERENCE")
|
||||
object ENUM_GET_INSTANCE_FUNCTION : IrDeclarationOriginImpl("ENUM_GET_INSTANCE_FUNCTION")
|
||||
}
|
||||
|
||||
+10
-1
@@ -37,8 +37,11 @@ data class ExportedFunction(
|
||||
|
||||
data class ExportedConstructor(
|
||||
val parameters: List<ExportedParameter>,
|
||||
val visibility: ExportedVisibility
|
||||
) : ExportedDeclaration() {
|
||||
val isProtected: Boolean
|
||||
) : ExportedDeclaration()
|
||||
get() = visibility == ExportedVisibility.PROTECTED
|
||||
}
|
||||
|
||||
data class ExportedConstructSignature(
|
||||
val parameters: List<ExportedParameter>,
|
||||
@@ -131,3 +134,9 @@ sealed class ExportedType {
|
||||
fun withImplicitlyExported(implicitlyExportedType: Boolean) =
|
||||
if (implicitlyExportedType) ImplicitlyExportedType(this) else this
|
||||
}
|
||||
|
||||
enum class ExportedVisibility(val keyword: String) {
|
||||
DEFAULT(""),
|
||||
PRIVATE("private "),
|
||||
PROTECTED("protected ")
|
||||
}
|
||||
|
||||
+38
-14
@@ -10,12 +10,14 @@ import org.jetbrains.kotlin.backend.common.ir.isMethodOfAny
|
||||
import org.jetbrains.kotlin.config.CommonConfigurationKeys
|
||||
import org.jetbrains.kotlin.descriptors.ClassKind
|
||||
import org.jetbrains.kotlin.descriptors.DescriptorVisibilities
|
||||
import org.jetbrains.kotlin.descriptors.DescriptorVisibility
|
||||
import org.jetbrains.kotlin.descriptors.Modality
|
||||
import org.jetbrains.kotlin.ir.backend.js.JsIrBackendContext
|
||||
import org.jetbrains.kotlin.ir.backend.js.JsLoweredDeclarationOrigin
|
||||
import org.jetbrains.kotlin.ir.backend.js.lower.ES6AddInternalParametersToConstructorPhase.ES6_INIT_BOX_PARAMETER
|
||||
import org.jetbrains.kotlin.ir.backend.js.lower.ES6AddInternalParametersToConstructorPhase.ES6_RESULT_TYPE_PARAMETER
|
||||
import org.jetbrains.kotlin.ir.backend.js.utils.getJsNameOrKotlinName
|
||||
import org.jetbrains.kotlin.ir.backend.js.utils.isExportedInterface
|
||||
import org.jetbrains.kotlin.ir.backend.js.utils.isJsExport
|
||||
import org.jetbrains.kotlin.ir.backend.js.utils.sanitizeName
|
||||
import org.jetbrains.kotlin.ir.declarations.*
|
||||
@@ -71,8 +73,12 @@ class ExportModelGenerator(
|
||||
}
|
||||
}
|
||||
|
||||
private fun exportFunction(function: IrSimpleFunction): ExportedDeclaration? =
|
||||
when (val exportability = functionExportability(function)) {
|
||||
private fun exportFunction(function: IrSimpleFunction): ExportedDeclaration? {
|
||||
if (function.origin == JsLoweredDeclarationOrigin.ENUM_GET_INSTANCE_FUNCTION) {
|
||||
return null
|
||||
}
|
||||
|
||||
return when (val exportability = functionExportability(function)) {
|
||||
is Exportability.NotNeeded -> null
|
||||
is Exportability.Prohibited -> ErrorDeclaration(exportability.reason)
|
||||
is Exportability.Allowed -> {
|
||||
@@ -90,6 +96,7 @@ class ExportModelGenerator(
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun exportConstructor(constructor: IrConstructor): ExportedDeclaration? {
|
||||
if (!constructor.isPrimary) return null
|
||||
@@ -97,7 +104,7 @@ class ExportModelGenerator(
|
||||
constructor.valueParameters.filterNot { it.origin === ES6_RESULT_TYPE_PARAMETER || it.origin === ES6_INIT_BOX_PARAMETER }
|
||||
return ExportedConstructor(
|
||||
parameters = allValueParameters.map { exportParameter(it) },
|
||||
isProtected = constructor.visibility == DescriptorVisibilities.PROTECTED
|
||||
visibility = constructor.visibility.toExportedVisibility()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -115,7 +122,7 @@ class ExportModelGenerator(
|
||||
// TODO: Report a frontend error
|
||||
if (accessor.extensionReceiverParameter != null)
|
||||
return null
|
||||
if (accessor.isFakeOverride && !accessor.isEnumFakeOverriddenDeclaration(context)) {
|
||||
if (accessor.isFakeOverride && !accessor.isAllowedFakeOverriddenDeclaration(context)) {
|
||||
return null
|
||||
}
|
||||
}
|
||||
@@ -254,11 +261,20 @@ class ExportModelGenerator(
|
||||
enumExportedMember
|
||||
}
|
||||
|
||||
val privateConstructor = ExportedConstructor(
|
||||
parameters = emptyList(),
|
||||
visibility = ExportedVisibility.PRIVATE
|
||||
)
|
||||
|
||||
return exportClass(
|
||||
klass,
|
||||
members,
|
||||
listOf(privateConstructor) + members,
|
||||
nestedClasses
|
||||
)
|
||||
).let {
|
||||
(it as ExportedClass).copy(
|
||||
isAbstract = true,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private fun exportClassDeclarations(
|
||||
@@ -382,7 +398,7 @@ class ExportModelGenerator(
|
||||
val enumEntries = enumEntriesToOrdinal.keys
|
||||
return when (candidate) {
|
||||
is IrProperty -> {
|
||||
if (candidate.isEnumFakeOverriddenDeclaration(context)) {
|
||||
if (candidate.isAllowedFakeOverriddenDeclaration(context)) {
|
||||
val type: ExportedType? = when (candidate.getExportedIdentifier()) {
|
||||
"name" -> enumEntries
|
||||
.map { it.getExportedIdentifier() }
|
||||
@@ -507,7 +523,7 @@ class ExportModelGenerator(
|
||||
return Exportability.Prohibited("Inline reified function")
|
||||
if (function.isSuspend)
|
||||
return Exportability.Prohibited("Suspend function")
|
||||
if (function.isFakeOverride)
|
||||
if (function.isFakeOverride && !function.isAllowedFakeOverriddenDeclaration(context))
|
||||
return Exportability.NotNeeded
|
||||
if (function.origin == JsLoweredDeclarationOrigin.BRIDGE_WITHOUT_STABLE_NAME ||
|
||||
function.origin == JsLoweredDeclarationOrigin.BRIDGE_WITH_STABLE_NAME ||
|
||||
@@ -524,9 +540,6 @@ class ExportModelGenerator(
|
||||
return Exportability.NotNeeded
|
||||
}
|
||||
|
||||
if (function.isFakeOverriddenFromAny())
|
||||
return Exportability.NotNeeded
|
||||
|
||||
val nameString = function.name.asString()
|
||||
if (nameString.endsWith("-impl"))
|
||||
return Exportability.NotNeeded
|
||||
@@ -605,7 +618,7 @@ private fun shouldDeclarationBeExported(declaration: IrDeclarationWithName, cont
|
||||
if (overriddenNonEmpty) {
|
||||
return declaration.isOverriddenExported(context) ||
|
||||
(declaration as? IrSimpleFunction)?.isMethodOfAny() == true // Handle names for special functions
|
||||
|| declaration.isEnumFakeOverriddenDeclaration(context)
|
||||
|| declaration.isAllowedFakeOverriddenDeclaration(context)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -619,12 +632,17 @@ private fun shouldDeclarationBeExported(declaration: IrDeclarationWithName, cont
|
||||
}
|
||||
}
|
||||
|
||||
fun IrOverridableDeclaration<*>.isEnumFakeOverriddenDeclaration(context: JsIrBackendContext?): Boolean {
|
||||
fun IrOverridableDeclaration<*>.isAllowedFakeOverriddenDeclaration(context: JsIrBackendContext?): Boolean {
|
||||
if (this.resolveFakeOverride(allowAbstract = true)?.parentClassOrNull.isExportedInterface()) {
|
||||
return true
|
||||
}
|
||||
|
||||
return context?.irBuiltIns?.enumClass?.let { enumClass ->
|
||||
overriddenSymbols
|
||||
.asSequence()
|
||||
.map { it.owner }
|
||||
.filterIsInstance<IrDeclaration>()
|
||||
.filterIsInstance<IrOverridableDeclaration<*>>()
|
||||
.filter { it.overriddenSymbols.isEmpty() }
|
||||
.mapNotNull { it.parentClassOrNull }
|
||||
.map { it.symbol }
|
||||
.any { it == enumClass }
|
||||
@@ -640,6 +658,12 @@ fun IrDeclaration.isExported(context: JsIrBackendContext?): Boolean {
|
||||
return shouldDeclarationBeExported(candidate, context)
|
||||
}
|
||||
|
||||
private fun DescriptorVisibility.toExportedVisibility() =
|
||||
when (this) {
|
||||
DescriptorVisibilities.PROTECTED -> ExportedVisibility.PROTECTED
|
||||
else -> ExportedVisibility.DEFAULT
|
||||
}
|
||||
|
||||
private val reservedWords = setOf(
|
||||
"break",
|
||||
"case",
|
||||
|
||||
+2
-3
@@ -93,9 +93,8 @@ fun ExportedDeclaration.toTypeScript(indent: String, prefix: String = ""): Strin
|
||||
}
|
||||
|
||||
is ExportedConstructor -> {
|
||||
val visibility = if (isProtected) "protected " else ""
|
||||
val renderedParameters = parameters.joinToString(", ") { it.toTypeScript(indent) }
|
||||
"${visibility}constructor($renderedParameters);"
|
||||
"${visibility.keyword}constructor($renderedParameters);"
|
||||
}
|
||||
|
||||
is ExportedConstructSignature -> {
|
||||
@@ -220,7 +219,7 @@ fun ExportedClass.withProtectedConstructors(): ExportedClass {
|
||||
if (it !is ExportedConstructor || it.isProtected) {
|
||||
it
|
||||
} else {
|
||||
it.copy(isProtected = true)
|
||||
it.copy(visibility = ExportedVisibility.PROTECTED)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
+1
-1
@@ -142,7 +142,7 @@ class ClassReferenceLowering(val context: JsCommonBackendContext) : BodyLowering
|
||||
JsIrBuilder.buildCall(
|
||||
reflectionSymbols.getClassData,
|
||||
typeArguments = listOf(type),
|
||||
origin = JsLoweredDeclarationOrigin.CLASS_REFERENCE
|
||||
origin = JsStatementOrigins.CLASS_REFERENCE
|
||||
)
|
||||
|
||||
private fun buildCall(name: IrSimpleFunctionSymbol, vararg args: IrExpression): IrExpression =
|
||||
|
||||
+2
-1
@@ -18,6 +18,7 @@ import org.jetbrains.kotlin.descriptors.ClassKind
|
||||
import org.jetbrains.kotlin.descriptors.DescriptorVisibilities.PRIVATE
|
||||
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
|
||||
import org.jetbrains.kotlin.ir.backend.js.JsCommonBackendContext
|
||||
import org.jetbrains.kotlin.ir.backend.js.JsLoweredDeclarationOrigin
|
||||
import org.jetbrains.kotlin.ir.backend.js.ir.JsIrBuilder
|
||||
import org.jetbrains.kotlin.ir.builders.*
|
||||
import org.jetbrains.kotlin.ir.builders.declarations.buildConstructor
|
||||
@@ -445,7 +446,7 @@ class EnumEntryCreateGetInstancesFunsLowering(val context: JsCommonBackendContex
|
||||
context.irFactory.buildFun {
|
||||
name = Name.identifier(createEntryAccessorName(irClass.name.identifier, enumEntry))
|
||||
returnType = enumEntry.getType(irClass)
|
||||
origin = JsIrBuilder.SYNTHESIZED_DECLARATION
|
||||
origin = JsLoweredDeclarationOrigin.ENUM_GET_INSTANCE_FUNCTION
|
||||
}.apply {
|
||||
parent = irClass
|
||||
}
|
||||
|
||||
+7
-5
@@ -6,9 +6,8 @@
|
||||
package org.jetbrains.kotlin.ir.backend.js.transformers.irToJs
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.DescriptorVisibilities
|
||||
import org.jetbrains.kotlin.descriptors.DescriptorVisibility
|
||||
import org.jetbrains.kotlin.descriptors.Modality
|
||||
import org.jetbrains.kotlin.ir.backend.js.export.isEnumFakeOverriddenDeclaration
|
||||
import org.jetbrains.kotlin.ir.backend.js.export.isAllowedFakeOverriddenDeclaration
|
||||
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.utils.*
|
||||
@@ -102,7 +101,7 @@ class JsClassGenerator(private val irClass: IrClass, val context: JsGenerationCo
|
||||
|
||||
classBlock.statements += generateClassMetadata()
|
||||
|
||||
if (!irClass.isInterface && !irClass.isEnumEntry) {
|
||||
if (!irClass.isInterface) {
|
||||
for (property in properties) {
|
||||
if (property.getter?.extensionReceiverParameter != null || property.setter?.extensionReceiverParameter != null)
|
||||
continue
|
||||
@@ -110,7 +109,10 @@ class JsClassGenerator(private val irClass: IrClass, val context: JsGenerationCo
|
||||
if (!property.visibility.isPublicAPI)
|
||||
continue
|
||||
|
||||
if (property.isFakeOverride && !property.isEnumFakeOverriddenDeclaration(context.staticContext.backendContext))
|
||||
if (
|
||||
property.isFakeOverride &&
|
||||
!property.isAllowedFakeOverriddenDeclaration(context.staticContext.backendContext)
|
||||
)
|
||||
continue
|
||||
|
||||
fun IrSimpleFunction.propertyAccessorForwarder(
|
||||
@@ -145,7 +147,7 @@ class JsClassGenerator(private val irClass: IrClass, val context: JsGenerationCo
|
||||
val noOverriddenExportedSetter = property.setter?.isOverriddenExported(context.staticContext.backendContext) == false
|
||||
|
||||
val needsOverride = (overriddenExportedGetter && noOverriddenExportedSetter) ||
|
||||
property.isEnumFakeOverriddenDeclaration(context.staticContext.backendContext)
|
||||
property.isAllowedFakeOverriddenDeclaration(context.staticContext.backendContext)
|
||||
|
||||
if (irClass.isExported(context.staticContext.backendContext) &&
|
||||
(overriddenSymbols.isEmpty() || needsOverride) ||
|
||||
|
||||
+1
@@ -18,4 +18,5 @@ interface JsStatementOrigins {
|
||||
object FACTORY_ORIGIN : IrDeclarationOriginImpl("FACTORY_ORIGIN")
|
||||
object COROUTINE_ROOT_LOOP : IrStatementOriginImpl("COROUTINE_ROOT_LOOP")
|
||||
object COROUTINE_SWITCH : IrStatementOriginImpl("COROUTINE_SWITCH")
|
||||
object CLASS_REFERENCE : IrStatementOriginImpl("CLASS_REFERENCE")
|
||||
}
|
||||
+11
-9
@@ -29,6 +29,7 @@ enum class Bar {
|
||||
init {
|
||||
d = "d2"
|
||||
}
|
||||
fun huh() = "huh"
|
||||
};
|
||||
|
||||
val foo = ordinal
|
||||
@@ -66,19 +67,20 @@ function box() {
|
||||
if (this["export_enum_class"].Bar.A.bay() !== "A") return "fail15"
|
||||
if (this["export_enum_class"].Bar.B.bay() !== "B") return "fail16"
|
||||
|
||||
if (this["export_enum_class"].Bar.B.constructor.prototype.hasOwnProperty('baz')) return "fail17"
|
||||
if (this["export_enum_class"].Bar.B.constructor.prototype.hasOwnProperty('d')) return "fail17"
|
||||
if (this["export_enum_class"].Bar.B.constructor.prototype.hasOwnProperty('huh')) return "fail18"
|
||||
|
||||
if (this["export_enum_class"].Foo.valueOf("A") !== this["export_enum_class"].Foo.A) return "fail18"
|
||||
if (this["export_enum_class"].Foo.valueOf("B") !== this["export_enum_class"].Foo.B) return "fail19"
|
||||
if (this["export_enum_class"].Foo.valueOf("A") !== this["export_enum_class"].Foo.A) return "fail19"
|
||||
if (this["export_enum_class"].Foo.valueOf("B") !== this["export_enum_class"].Foo.B) 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.A) === -1) return "fail21"
|
||||
if (this["export_enum_class"].Foo.values().indexOf(this["export_enum_class"].Foo.B) === -1) return "fail22"
|
||||
|
||||
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.name !== "A") return "fail23"
|
||||
if (this["export_enum_class"].Foo.B.name !== "B") return "fail24"
|
||||
|
||||
if (this["export_enum_class"].Foo.A.ordinal !== 0) return "fail24"
|
||||
if (this["export_enum_class"].Foo.B.ordinal !== 1) return "fail23"
|
||||
if (this["export_enum_class"].Foo.A.ordinal !== 0) return "fail25"
|
||||
if (this["export_enum_class"].Foo.B.ordinal !== 1) return "fail26"
|
||||
|
||||
return "OK"
|
||||
}
|
||||
@@ -100,7 +100,7 @@ declare namespace JS_TESTS {
|
||||
readonly prop: string;
|
||||
}
|
||||
}
|
||||
class TestEnumClass {
|
||||
abstract class TestEnumClass {
|
||||
private constructor();
|
||||
readonly constructorParameter: string;
|
||||
static readonly A: foo.TestEnumClass & {
|
||||
|
||||
@@ -37,5 +37,62 @@ declare namespace JS_TESTS {
|
||||
const O2: {
|
||||
foo(): number;
|
||||
} & foo.OC;
|
||||
interface I3 {
|
||||
readonly foo: string;
|
||||
bar: string;
|
||||
readonly baz: string;
|
||||
bay(): string;
|
||||
readonly __doNotUseIt: __doNotImplementIt;
|
||||
}
|
||||
function getI3(): foo.I3;
|
||||
function getA(): foo.I3;
|
||||
function getB(): foo.I3;
|
||||
function getC(): foo.I3;
|
||||
abstract class A2 implements foo.I3 {
|
||||
constructor();
|
||||
abstract readonly foo: string;
|
||||
abstract bar: string;
|
||||
abstract readonly baz: string;
|
||||
abstract bay(): string;
|
||||
readonly __doNotUseIt: __doNotImplementIt;
|
||||
}
|
||||
class B2 extends foo.A2 {
|
||||
constructor();
|
||||
readonly foo: string;
|
||||
bar: string;
|
||||
readonly baz: string;
|
||||
bay(): string;
|
||||
}
|
||||
class C2 extends foo.B2 {
|
||||
constructor();
|
||||
readonly foo: string;
|
||||
bar: string;
|
||||
baz: string;
|
||||
bay(): string;
|
||||
}
|
||||
abstract class EC implements foo.I3 {
|
||||
private constructor();
|
||||
static readonly EC1: foo.EC & {
|
||||
readonly name: "EC1";
|
||||
readonly ordinal: 0;
|
||||
};
|
||||
static readonly EC2: foo.EC & {
|
||||
readonly name: "EC2";
|
||||
readonly ordinal: 1;
|
||||
};
|
||||
static readonly EC3: foo.EC & {
|
||||
readonly name: "EC3";
|
||||
readonly ordinal: 2;
|
||||
};
|
||||
readonly foo: string;
|
||||
bar: string;
|
||||
bay(): string;
|
||||
static values(): Array<foo.EC>;
|
||||
static valueOf(value: string): foo.EC;
|
||||
readonly name: "EC1" | "EC2" | "EC3";
|
||||
readonly ordinal: 0 | 1 | 2;
|
||||
abstract readonly baz: string;
|
||||
readonly __doNotUseIt: __doNotImplementIt;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,22 +7,23 @@
|
||||
// MODULE: JS_TESTS
|
||||
// FILE: inheritance.kt
|
||||
|
||||
@file:JsExport
|
||||
|
||||
package foo
|
||||
|
||||
@JsExport
|
||||
external interface I<T, out S, in U> {
|
||||
var x: T
|
||||
val y: S
|
||||
fun z(u: U)
|
||||
}
|
||||
|
||||
@JsExport
|
||||
external interface I2 {
|
||||
var x: String
|
||||
val y: Boolean
|
||||
fun z(z: Int)
|
||||
}
|
||||
|
||||
@JsExport
|
||||
abstract class AC : I2 {
|
||||
override var x = "AC"
|
||||
override abstract val y: Boolean
|
||||
@@ -32,6 +33,7 @@ abstract class AC : I2 {
|
||||
abstract val acAbstractProp: String
|
||||
}
|
||||
|
||||
@JsExport
|
||||
open class OC(
|
||||
override val y: Boolean,
|
||||
override val acAbstractProp: String
|
||||
@@ -43,11 +45,121 @@ open class OC(
|
||||
private fun privateFun(): String = "privateFun"
|
||||
}
|
||||
|
||||
@JsExport
|
||||
final class FC : OC(true, "FC")
|
||||
|
||||
@JsExport
|
||||
object O1 : OC(true, "O1")
|
||||
|
||||
@JsExport
|
||||
object O2 : OC(true, "O2") {
|
||||
@JsName("foo") // TODO: Should work without JsName
|
||||
fun foo(): Int = 10
|
||||
}
|
||||
}
|
||||
|
||||
@JsExport
|
||||
interface I3 {
|
||||
val foo: String
|
||||
var bar: String
|
||||
val baz: String
|
||||
|
||||
fun bay(): String
|
||||
}
|
||||
|
||||
@JsExport
|
||||
fun getI3(): I3 = object : I3 {
|
||||
override val foo: String = "fooI3"
|
||||
|
||||
override var bar: String = "barI3"
|
||||
|
||||
override var baz: String = "bazI3"
|
||||
|
||||
override fun bay(): String = "bayI3"
|
||||
}
|
||||
|
||||
abstract class A : I3
|
||||
|
||||
@JsExport
|
||||
fun getA(): I3 = object : A() {
|
||||
override val foo: String = "fooA"
|
||||
|
||||
override var bar: String = "barA"
|
||||
|
||||
override var baz: String = "bazA"
|
||||
|
||||
override fun bay(): String = "bayA"
|
||||
}
|
||||
|
||||
open class B : A() {
|
||||
override val foo: String = "fooB"
|
||||
|
||||
override var bar: String = "barB"
|
||||
|
||||
override val baz: String = "bazB"
|
||||
|
||||
override fun bay(): String = "bayB"
|
||||
}
|
||||
|
||||
@JsExport
|
||||
fun getB(): I3 = B()
|
||||
|
||||
open class C : B() {
|
||||
override val foo: String = "fooC"
|
||||
|
||||
override var bar: String = "barC"
|
||||
|
||||
override var baz: String = "bazC"
|
||||
|
||||
override fun bay(): String = "bayC"
|
||||
}
|
||||
|
||||
@JsExport
|
||||
fun getC(): I3 = C()
|
||||
|
||||
@JsExport
|
||||
abstract class A2 : I3
|
||||
|
||||
@JsExport
|
||||
open class B2 : A2() {
|
||||
override val foo: String = "fooB2"
|
||||
|
||||
override var bar: String = "barB2"
|
||||
|
||||
override val baz: String = "bazB2"
|
||||
|
||||
override fun bay(): String = "bayB2"
|
||||
}
|
||||
|
||||
@JsExport
|
||||
open class C2 : B2() {
|
||||
override val foo: String = "fooC2"
|
||||
|
||||
override var bar: String = "barC2"
|
||||
|
||||
override var baz: String = "bazC2"
|
||||
|
||||
override fun bay(): String = "bayC2"
|
||||
}
|
||||
|
||||
@JsExport
|
||||
enum class EC : I3 {
|
||||
EC1 {
|
||||
override var baz = "ec1"
|
||||
|
||||
val bah = "bah"
|
||||
|
||||
fun huh() = "huh"
|
||||
},
|
||||
EC2 {
|
||||
override var baz = "ec2"
|
||||
},
|
||||
EC3 {
|
||||
override var baz = "ec3"
|
||||
};
|
||||
|
||||
override val foo: String = "foo"
|
||||
|
||||
override var bar = "bar"
|
||||
|
||||
override fun bay(): String = "bay"
|
||||
}
|
||||
|
||||
@@ -17,6 +17,13 @@ var AC = JS_TESTS.foo.AC;
|
||||
var FC = JS_TESTS.foo.FC;
|
||||
var O1 = JS_TESTS.foo.O1;
|
||||
var O2 = JS_TESTS.foo.O2;
|
||||
var getI3 = JS_TESTS.foo.getI3;
|
||||
var getA = JS_TESTS.foo.getA;
|
||||
var getB = JS_TESTS.foo.getB;
|
||||
var getC = JS_TESTS.foo.getC;
|
||||
var B2 = JS_TESTS.foo.B2;
|
||||
var C2 = JS_TESTS.foo.C2;
|
||||
var EC = JS_TESTS.foo.EC;
|
||||
var Impl = /** @class */ (function (_super) {
|
||||
__extends(Impl, _super);
|
||||
function Impl() {
|
||||
@@ -36,6 +43,16 @@ var Impl = /** @class */ (function (_super) {
|
||||
});
|
||||
return Impl;
|
||||
}(AC));
|
||||
// class A2Impl extends A2 {
|
||||
// bar: string = "barA2"
|
||||
// readonly baz: string = "bazA2"
|
||||
// readonly foo: string = "fooA2"
|
||||
//
|
||||
// bay(): string {
|
||||
// return "bayA2";
|
||||
// }
|
||||
//
|
||||
// }
|
||||
function box() {
|
||||
var impl = new Impl();
|
||||
if (impl.acProp !== "acProp")
|
||||
@@ -66,5 +83,87 @@ function box() {
|
||||
return "Fail 9";
|
||||
if (O2.foo() != 10)
|
||||
return "Fail 10";
|
||||
if (getI3().foo != "fooI3")
|
||||
return "Fail 11";
|
||||
if (getI3().bar != "barI3")
|
||||
return "Fail 12";
|
||||
if (getI3().baz != "bazI3")
|
||||
return "Fail 13";
|
||||
if (getI3().bay() != "bayI3")
|
||||
return "Fail 14";
|
||||
if (getA().foo != "fooA")
|
||||
return "Fail 15";
|
||||
if (getA().bar != "barA")
|
||||
return "Fail 16";
|
||||
if (getA().baz != "bazA")
|
||||
return "Fail 17";
|
||||
if (getA().bay() != "bayA")
|
||||
return "Fail 18";
|
||||
if (getB().foo != "fooB")
|
||||
return "Fail 19";
|
||||
if (getB().bar != "barB")
|
||||
return "Fail 20";
|
||||
if (getB().baz != "bazB")
|
||||
return "Fail 21";
|
||||
if (getB().bay() != "bayB")
|
||||
return "Fail 22";
|
||||
if (getC().foo != "fooC")
|
||||
return "Fail 23";
|
||||
if (getC().bar != "barC")
|
||||
return "Fail 24";
|
||||
if (getC().baz != "bazC")
|
||||
return "Fail 25";
|
||||
if (getC().bay() != "bayC")
|
||||
return "Fail 26";
|
||||
// const a2Impl = new A2Impl()
|
||||
// if (a2Impl.foo != "fooA2") return "Fail 27"
|
||||
// if (a2Impl.bar != "barA2") return "Fail 28"
|
||||
// if (a2Impl.baz != "bazA2") return "Fail 29"
|
||||
// if (a2Impl.bay() != "bayA2") return "Fail 30"
|
||||
var b2 = new B2();
|
||||
if (b2.foo != "fooB2")
|
||||
return "Fail 31";
|
||||
if (b2.bar != "barB2")
|
||||
return "Fail 32";
|
||||
if (b2.baz != "bazB2")
|
||||
return "Fail 33";
|
||||
if (b2.bay() != "bayB2")
|
||||
return "Fail 34";
|
||||
var c2 = new C2();
|
||||
if (c2.foo != "fooC2")
|
||||
return "Fail 35";
|
||||
if (c2.bar != "barC2")
|
||||
return "Fail 36";
|
||||
if (c2.baz != "bazC2")
|
||||
return "Fail 37";
|
||||
c2.baz = "bazC2-2";
|
||||
if (c2.baz != "bazC2-2")
|
||||
return "Fail 38";
|
||||
if (c2.bay() != "bayC2")
|
||||
return "Fail 39";
|
||||
if (EC.EC1.foo != "foo")
|
||||
return "Fail 40";
|
||||
if (EC.EC1.bar != "bar")
|
||||
return "Fail 41";
|
||||
if (EC.EC1.baz != "ec1")
|
||||
return "Fail 42";
|
||||
if (EC.EC1.bay() != "bay")
|
||||
return "Fail 43";
|
||||
if (EC.EC2.foo != "foo")
|
||||
return "Fail 44";
|
||||
if (EC.EC2.bar != "bar")
|
||||
return "Fail 45";
|
||||
if (EC.EC2.baz != "ec2")
|
||||
return "Fail 46";
|
||||
if (EC.EC2.bay() != "bay")
|
||||
return "Fail 47";
|
||||
if (EC.EC3.foo != "foo")
|
||||
return "Fail 48";
|
||||
if (EC.EC3.bar != "bar")
|
||||
return "Fail 49";
|
||||
if (EC.EC3.baz != "ec3")
|
||||
return "Fail 50";
|
||||
if (EC.EC3.bay() != "bay")
|
||||
return "Fail 51";
|
||||
return "OK";
|
||||
}
|
||||
|
||||
@@ -3,6 +3,13 @@ import AC = JS_TESTS.foo.AC;
|
||||
import FC = JS_TESTS.foo.FC;
|
||||
import O1 = JS_TESTS.foo.O1;
|
||||
import O2 = JS_TESTS.foo.O2;
|
||||
import getI3 = JS_TESTS.foo.getI3;
|
||||
import getA = JS_TESTS.foo.getA;
|
||||
import getB = JS_TESTS.foo.getB;
|
||||
import getC = JS_TESTS.foo.getC;
|
||||
import B2 = JS_TESTS.foo.B2;
|
||||
import C2 = JS_TESTS.foo.C2;
|
||||
import EC = JS_TESTS.foo.EC;
|
||||
|
||||
class Impl extends AC {
|
||||
z(z: number): void {
|
||||
@@ -12,6 +19,18 @@ class Impl extends AC {
|
||||
get y(): boolean { return true; }
|
||||
}
|
||||
|
||||
// TODO: Uncomment with fix of export open properties
|
||||
// class A2Impl extends A2 {
|
||||
// bar: string = "barA2"
|
||||
// readonly baz: string = "bazA2"
|
||||
// readonly foo: string = "fooA2"
|
||||
//
|
||||
// bay(): string {
|
||||
// return "bayA2";
|
||||
// }
|
||||
//
|
||||
// }
|
||||
|
||||
function box(): string {
|
||||
const impl = new Impl();
|
||||
if (impl.acProp !== "acProp") return "Fail 1";
|
||||
@@ -36,5 +55,60 @@ function box(): string {
|
||||
if (O2.acAbstractProp != "O2") return "Fail 9";
|
||||
if (O2.foo() != 10) return "Fail 10";
|
||||
|
||||
if (getI3().foo != "fooI3") return "Fail 11"
|
||||
if (getI3().bar != "barI3") return "Fail 12"
|
||||
if (getI3().baz != "bazI3") return "Fail 13"
|
||||
if (getI3().bay() != "bayI3") return "Fail 14"
|
||||
|
||||
if (getA().foo != "fooA") return "Fail 15"
|
||||
if (getA().bar != "barA") return "Fail 16"
|
||||
if (getA().baz != "bazA") return "Fail 17"
|
||||
if (getA().bay() != "bayA") return "Fail 18"
|
||||
|
||||
if (getB().foo != "fooB") return "Fail 19"
|
||||
if (getB().bar != "barB") return "Fail 20"
|
||||
if (getB().baz != "bazB") return "Fail 21"
|
||||
if (getB().bay() != "bayB") return "Fail 22"
|
||||
|
||||
if (getC().foo != "fooC") return "Fail 23"
|
||||
if (getC().bar != "barC") return "Fail 24"
|
||||
if (getC().baz != "bazC") return "Fail 25"
|
||||
if (getC().bay() != "bayC") return "Fail 26"
|
||||
|
||||
// const a2Impl = new A2Impl()
|
||||
// if (a2Impl.foo != "fooA2") return "Fail 27"
|
||||
// if (a2Impl.bar != "barA2") return "Fail 28"
|
||||
// if (a2Impl.baz != "bazA2") return "Fail 29"
|
||||
// if (a2Impl.bay() != "bayA2") return "Fail 30"
|
||||
|
||||
const b2 = new B2()
|
||||
if (b2.foo != "fooB2") return "Fail 31"
|
||||
if (b2.bar != "barB2") return "Fail 32"
|
||||
if (b2.baz != "bazB2") return "Fail 33"
|
||||
if (b2.bay() != "bayB2") return "Fail 34"
|
||||
|
||||
const c2 = new C2()
|
||||
if (c2.foo != "fooC2") return "Fail 35"
|
||||
if (c2.bar != "barC2") return "Fail 36"
|
||||
if (c2.baz != "bazC2") return "Fail 37"
|
||||
c2.baz = "bazC2-2"
|
||||
if (c2.baz != "bazC2-2") return "Fail 38"
|
||||
if (c2.bay() != "bayC2") return "Fail 39"
|
||||
|
||||
if (EC.EC1.foo != "foo") return "Fail 40"
|
||||
if (EC.EC1.bar != "bar") return "Fail 41"
|
||||
if (EC.EC1.baz != "ec1") return "Fail 42"
|
||||
if (EC.EC1.bay() != "bay") return "Fail 43"
|
||||
|
||||
if (EC.EC2.foo != "foo") return "Fail 44"
|
||||
if (EC.EC2.bar != "bar") return "Fail 45"
|
||||
if (EC.EC2.baz != "ec2") return "Fail 46"
|
||||
if (EC.EC2.bay() != "bay") return "Fail 47"
|
||||
|
||||
if (EC.EC3.foo != "foo") return "Fail 48"
|
||||
if (EC.EC3.bar != "bar") return "Fail 49"
|
||||
if (EC.EC3.baz != "ec3") return "Fail 50"
|
||||
if (EC.EC3.bay() != "bay") return "Fail 51"
|
||||
|
||||
return "OK";
|
||||
}
|
||||
@@ -33,4 +33,19 @@ declare namespace JS_TESTS {
|
||||
constructor();
|
||||
}
|
||||
}
|
||||
abstract class EnumClass {
|
||||
private constructor();
|
||||
static readonly EC1: EnumClass & {
|
||||
readonly name: "EC1";
|
||||
readonly ordinal: 0;
|
||||
};
|
||||
static readonly EC2: EnumClass & {
|
||||
readonly name: "EC2";
|
||||
readonly ordinal: 1;
|
||||
};
|
||||
static values(): Array<EnumClass>;
|
||||
static valueOf(value: string): EnumClass;
|
||||
readonly name: "EC1" | "EC2";
|
||||
readonly ordinal: 0 | 1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -54,4 +54,9 @@ open class Class {
|
||||
@JsName("publicFun") // TODO: Should work without JsName
|
||||
public fun publicFun() = 10
|
||||
public class publicClass
|
||||
}
|
||||
|
||||
enum class EnumClass {
|
||||
EC1,
|
||||
EC2
|
||||
}
|
||||
Reference in New Issue
Block a user