diff --git a/js/js.tests/test/org/jetbrains/kotlin/js/test/ir/semantics/IrBoxJsTestGenerated.java b/js/js.tests/test/org/jetbrains/kotlin/js/test/ir/semantics/IrBoxJsTestGenerated.java index 81608f6ec9f..e38a6cec649 100644 --- a/js/js.tests/test/org/jetbrains/kotlin/js/test/ir/semantics/IrBoxJsTestGenerated.java +++ b/js/js.tests/test/org/jetbrains/kotlin/js/test/ir/semantics/IrBoxJsTestGenerated.java @@ -1370,6 +1370,94 @@ public class IrBoxJsTestGenerated extends AbstractIrBoxJsTest { } } + @TestMetadata("js/js.translator/testData/box/es6classes") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class Es6classes extends AbstractIrBoxJsTest { + private void runTest(String testDataFilePath) throws Exception { + KotlinTestUtils.runTest0(this::doTest, TargetBackend.JS_IR, testDataFilePath); + } + + public void testAllFilesPresentInEs6classes() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("js/js.translator/testData/box/es6classes"), Pattern.compile("^([^_](.+))\\.kt$"), null, TargetBackend.JS_IR, true); + } + + @TestMetadata("builtItTypes.kt") + public void testBuiltItTypes() throws Exception { + runTest("js/js.translator/testData/box/es6classes/builtItTypes.kt"); + } + + @TestMetadata("defaultPrimary.kt") + public void testDefaultPrimary() throws Exception { + runTest("js/js.translator/testData/box/es6classes/defaultPrimary.kt"); + } + + @TestMetadata("defaultPrimaryExtendsAny.kt") + public void testDefaultPrimaryExtendsAny() throws Exception { + runTest("js/js.translator/testData/box/es6classes/defaultPrimaryExtendsAny.kt"); + } + + @TestMetadata("defaultPrimaryExtendsExternal.kt") + public void testDefaultPrimaryExtendsExternal() throws Exception { + runTest("js/js.translator/testData/box/es6classes/defaultPrimaryExtendsExternal.kt"); + } + + @TestMetadata("defaultPrimaryWithSuper.kt") + public void testDefaultPrimaryWithSuper() throws Exception { + runTest("js/js.translator/testData/box/es6classes/defaultPrimaryWithSuper.kt"); + } + + @TestMetadata("delegation.kt") + public void testDelegation() throws Exception { + runTest("js/js.translator/testData/box/es6classes/delegation.kt"); + } + + @TestMetadata("fieldAccess.kt") + public void testFieldAccess() throws Exception { + runTest("js/js.translator/testData/box/es6classes/fieldAccess.kt"); + } + + @TestMetadata("inheritedFromExternalBySecondaryCtor.kt") + public void testInheritedFromExternalBySecondaryCtor() throws Exception { + runTest("js/js.translator/testData/box/es6classes/inheritedFromExternalBySecondaryCtor.kt"); + } + + @TestMetadata("inheritedFromExternalClass.kt") + public void testInheritedFromExternalClass() throws Exception { + runTest("js/js.translator/testData/box/es6classes/inheritedFromExternalClass.kt"); + } + + @TestMetadata("initBlocks.kt") + public void testInitBlocks() throws Exception { + runTest("js/js.translator/testData/box/es6classes/initBlocks.kt"); + } + + @TestMetadata("innerClasses.kt") + public void testInnerClasses() throws Exception { + runTest("js/js.translator/testData/box/es6classes/innerClasses.kt"); + } + + @TestMetadata("isInitializedFieldBeforeObjectCreation.kt") + public void testIsInitializedFieldBeforeObjectCreation() throws Exception { + runTest("js/js.translator/testData/box/es6classes/isInitializedFieldBeforeObjectCreation.kt"); + } + + @TestMetadata("primaryToSecondary.kt") + public void testPrimaryToSecondary() throws Exception { + runTest("js/js.translator/testData/box/es6classes/primaryToSecondary.kt"); + } + + @TestMetadata("typeCorrectness.kt") + public void testTypeCorrectness() throws Exception { + runTest("js/js.translator/testData/box/es6classes/typeCorrectness.kt"); + } + + @TestMetadata("unboxChain.kt") + public void testUnboxChain() throws Exception { + runTest("js/js.translator/testData/box/es6classes/unboxChain.kt"); + } + } + @TestMetadata("js/js.translator/testData/box/examples") @TestDataPath("$PROJECT_ROOT") @RunWith(JUnit3RunnerWithInners.class) diff --git a/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/BoxJsTestGenerated.java b/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/BoxJsTestGenerated.java index d838c628b77..e56c443975c 100644 --- a/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/BoxJsTestGenerated.java +++ b/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/BoxJsTestGenerated.java @@ -1375,6 +1375,94 @@ public class BoxJsTestGenerated extends AbstractBoxJsTest { } } + @TestMetadata("js/js.translator/testData/box/es6classes") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class Es6classes extends AbstractBoxJsTest { + private void runTest(String testDataFilePath) throws Exception { + KotlinTestUtils.runTest0(this::doTest, TargetBackend.JS, testDataFilePath); + } + + public void testAllFilesPresentInEs6classes() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("js/js.translator/testData/box/es6classes"), Pattern.compile("^([^_](.+))\\.kt$"), null, TargetBackend.JS, true); + } + + @TestMetadata("builtItTypes.kt") + public void testBuiltItTypes() throws Exception { + runTest("js/js.translator/testData/box/es6classes/builtItTypes.kt"); + } + + @TestMetadata("defaultPrimary.kt") + public void testDefaultPrimary() throws Exception { + runTest("js/js.translator/testData/box/es6classes/defaultPrimary.kt"); + } + + @TestMetadata("defaultPrimaryExtendsAny.kt") + public void testDefaultPrimaryExtendsAny() throws Exception { + runTest("js/js.translator/testData/box/es6classes/defaultPrimaryExtendsAny.kt"); + } + + @TestMetadata("defaultPrimaryExtendsExternal.kt") + public void testDefaultPrimaryExtendsExternal() throws Exception { + runTest("js/js.translator/testData/box/es6classes/defaultPrimaryExtendsExternal.kt"); + } + + @TestMetadata("defaultPrimaryWithSuper.kt") + public void testDefaultPrimaryWithSuper() throws Exception { + runTest("js/js.translator/testData/box/es6classes/defaultPrimaryWithSuper.kt"); + } + + @TestMetadata("delegation.kt") + public void testDelegation() throws Exception { + runTest("js/js.translator/testData/box/es6classes/delegation.kt"); + } + + @TestMetadata("fieldAccess.kt") + public void testFieldAccess() throws Exception { + runTest("js/js.translator/testData/box/es6classes/fieldAccess.kt"); + } + + @TestMetadata("inheritedFromExternalBySecondaryCtor.kt") + public void testInheritedFromExternalBySecondaryCtor() throws Exception { + runTest("js/js.translator/testData/box/es6classes/inheritedFromExternalBySecondaryCtor.kt"); + } + + @TestMetadata("inheritedFromExternalClass.kt") + public void testInheritedFromExternalClass() throws Exception { + runTest("js/js.translator/testData/box/es6classes/inheritedFromExternalClass.kt"); + } + + @TestMetadata("initBlocks.kt") + public void testInitBlocks() throws Exception { + runTest("js/js.translator/testData/box/es6classes/initBlocks.kt"); + } + + @TestMetadata("innerClasses.kt") + public void testInnerClasses() throws Exception { + runTest("js/js.translator/testData/box/es6classes/innerClasses.kt"); + } + + @TestMetadata("isInitializedFieldBeforeObjectCreation.kt") + public void testIsInitializedFieldBeforeObjectCreation() throws Exception { + runTest("js/js.translator/testData/box/es6classes/isInitializedFieldBeforeObjectCreation.kt"); + } + + @TestMetadata("primaryToSecondary.kt") + public void testPrimaryToSecondary() throws Exception { + runTest("js/js.translator/testData/box/es6classes/primaryToSecondary.kt"); + } + + @TestMetadata("typeCorrectness.kt") + public void testTypeCorrectness() throws Exception { + runTest("js/js.translator/testData/box/es6classes/typeCorrectness.kt"); + } + + @TestMetadata("unboxChain.kt") + public void testUnboxChain() throws Exception { + runTest("js/js.translator/testData/box/es6classes/unboxChain.kt"); + } + } + @TestMetadata("js/js.translator/testData/box/examples") @TestDataPath("$PROJECT_ROOT") @RunWith(JUnit3RunnerWithInners.class) diff --git a/js/js.translator/testData/box/es6classes/builtItTypes.kt b/js/js.translator/testData/box/es6classes/builtItTypes.kt new file mode 100644 index 00000000000..16014901e26 --- /dev/null +++ b/js/js.translator/testData/box/es6classes/builtItTypes.kt @@ -0,0 +1,10 @@ +// EXPECTED_REACHABLE_NODES: 1331 +fun box(): String { + val s = String() + val ints = Array(2) { i -> (i + 2) * 2 } + + assertEquals(4, ints[0]) + assertEquals(6, ints[1]) + + return "OK" + s +} diff --git a/js/js.translator/testData/box/es6classes/defaultPrimary.kt b/js/js.translator/testData/box/es6classes/defaultPrimary.kt new file mode 100644 index 00000000000..5fa9dd8533e --- /dev/null +++ b/js/js.translator/testData/box/es6classes/defaultPrimary.kt @@ -0,0 +1,30 @@ +// EXPECTED_REACHABLE_NODES: 1344 +open class A(var value: Int) { + init { + value *= 2 + } +} + +class B : A { + init { + value /= 6 + } + + constructor(x: Int) : super(x) { + value *= 18 + } + + constructor() : this(18) { + value *= 12 + } +} + +fun box(): String { + val bs1 = B(15) + assertEquals(90, bs1.value) + + val bs2 = B() + assertEquals(72 * 18, bs2.value) + + return "OK" +} diff --git a/js/js.translator/testData/box/es6classes/defaultPrimaryExtendsAny.kt b/js/js.translator/testData/box/es6classes/defaultPrimaryExtendsAny.kt new file mode 100644 index 00000000000..a55d451d58d --- /dev/null +++ b/js/js.translator/testData/box/es6classes/defaultPrimaryExtendsAny.kt @@ -0,0 +1,32 @@ +// EXPECTED_REACHABLE_NODES: 1347 +var sideEffect = "" + +abstract class A { + fun print(a: Any) { sideEffect += "#$a" } + + constructor(x: Int, y: Int) { + print(x + y) + print(foo()) + } + + abstract fun foo(): String + + init { + print("init: " + foo()) + } +} + +class O(val x: String) { + inner class I() : A(13, 37) { + override fun foo() = x + } +} + +fun box(): String { + val o = O("OK") + val i = o.I() + + assertEquals("#init: OK#50#OK", sideEffect) + + return i.foo() +} diff --git a/js/js.translator/testData/box/es6classes/defaultPrimaryExtendsExternal.js b/js/js.translator/testData/box/es6classes/defaultPrimaryExtendsExternal.js new file mode 100644 index 00000000000..b031ccfb7e1 --- /dev/null +++ b/js/js.translator/testData/box/es6classes/defaultPrimaryExtendsExternal.js @@ -0,0 +1,3 @@ +class E { + constructor() { } +} diff --git a/js/js.translator/testData/box/es6classes/defaultPrimaryExtendsExternal.kt b/js/js.translator/testData/box/es6classes/defaultPrimaryExtendsExternal.kt new file mode 100644 index 00000000000..4f1995e1378 --- /dev/null +++ b/js/js.translator/testData/box/es6classes/defaultPrimaryExtendsExternal.kt @@ -0,0 +1,39 @@ +//IGNORE_BACKEND: JS, JS_IR + +var sideEffect = "" + +open external class E() +abstract class A : E { + fun print(a: Any) { sideEffect += "#$a" } + + constructor(x: Int, y: Int) : super() { + print(x + y) + print(foo()) + } + + constructor(x: Int) : super() { + print(x) + print(foo()) + } + + abstract fun foo(): String + + init { + print("init: " + foo()) + } +} + +class O(val x: String) { + inner class I() : A(1337) { + override fun foo() = x + } +} + +fun box(): String { + val o = O("OK") + val i = o.I() + + assertEquals("#init: OK#1337#OK", sideEffect) + + return i.foo() +} diff --git a/js/js.translator/testData/box/es6classes/defaultPrimaryWithSuper.kt b/js/js.translator/testData/box/es6classes/defaultPrimaryWithSuper.kt new file mode 100644 index 00000000000..1bf26b1c766 --- /dev/null +++ b/js/js.translator/testData/box/es6classes/defaultPrimaryWithSuper.kt @@ -0,0 +1,36 @@ +// EXPECTED_REACHABLE_NODES: 1355 +var sideEffect = "" + +open class Summator(x: Int, y: Int) { + val sum = x + y +} + +abstract class A : Summator { + fun print(a: Any) { sideEffect += "#$a" } + + constructor(x: Int, y: Int) : super(x, y) { //try pass `foo()` + print(sum) + print(foo()) + } + + abstract fun foo(): String + + init { + print("init: " + foo()) + } +} + +class O(val x: String) { + inner class I() : A(13, 37) { + override fun foo() = x + } +} + +fun box(): String { + val o = O("OK") + val i = o.I() + + assertEquals("#init: OK#50#OK", sideEffect) + + return i.foo() +} diff --git a/js/js.translator/testData/box/es6classes/delegation.kt b/js/js.translator/testData/box/es6classes/delegation.kt new file mode 100644 index 00000000000..91a14e2c1ae --- /dev/null +++ b/js/js.translator/testData/box/es6classes/delegation.kt @@ -0,0 +1,32 @@ +// EXPECTED_REACHABLE_NODES: 1359 +open class A(val x: Int) { + constructor(): this(100) +} + +class PrimaryToPrimary(val p: Int): A(p * p) +class PrimaryToSecondary(val p: Int): A() + +class SecondaryToPrimary : A { + constructor() : super(8) +} +class SecondaryToSecondary: A { + constructor() : super() +} + +fun box(): String { + val ptp = PrimaryToPrimary(5) + assertEquals(ptp.p, 5) + assertEquals(ptp.x, 25) + + val pts = PrimaryToSecondary(9) + assertEquals(pts.p, 9) + assertEquals(pts.x, 100) + + val stp = SecondaryToPrimary() + assertEquals(stp.x, 8) + + val sts = SecondaryToSecondary() + assertEquals(sts.x, 100) + + return "OK" +} diff --git a/js/js.translator/testData/box/es6classes/fieldAccess.kt b/js/js.translator/testData/box/es6classes/fieldAccess.kt new file mode 100644 index 00000000000..eb3c6b826c7 --- /dev/null +++ b/js/js.translator/testData/box/es6classes/fieldAccess.kt @@ -0,0 +1,13 @@ +// EXPECTED_REACHABLE_NODES: 1340 +open class A(val x: Int) + +class B(val p: Int, val q: Int): A(p + q) + +fun box(): String { + val b = B(2, 3) + assertEquals(b.p, 2) + assertEquals(b.q, 3) + assertEquals(b.x, 5) + + return "OK" +} diff --git a/js/js.translator/testData/box/es6classes/inheritedFromExternalBySecondaryCtor.js b/js/js.translator/testData/box/es6classes/inheritedFromExternalBySecondaryCtor.js new file mode 100644 index 00000000000..18591e90f4f --- /dev/null +++ b/js/js.translator/testData/box/es6classes/inheritedFromExternalBySecondaryCtor.js @@ -0,0 +1,5 @@ +class E { + constructor(x, y) { + this.t = x + y; + } +} diff --git a/js/js.translator/testData/box/es6classes/inheritedFromExternalBySecondaryCtor.kt b/js/js.translator/testData/box/es6classes/inheritedFromExternalBySecondaryCtor.kt new file mode 100644 index 00000000000..90763faf17c --- /dev/null +++ b/js/js.translator/testData/box/es6classes/inheritedFromExternalBySecondaryCtor.kt @@ -0,0 +1,19 @@ +//IGNORE_BACKEND: JS, JS_IR + +open external class E(x: Int, y: Int) { + val t: Int = definedExternally +} + +open class A(i: Int, j: Int) : E(i, j) + +class B : A { + constructor() : super(3, 4) +} + +fun box(): String { + val b = B() + + assertEquals(7, b.t) + + return "OK" +} diff --git a/js/js.translator/testData/box/es6classes/inheritedFromExternalClass.js b/js/js.translator/testData/box/es6classes/inheritedFromExternalClass.js new file mode 100644 index 00000000000..18591e90f4f --- /dev/null +++ b/js/js.translator/testData/box/es6classes/inheritedFromExternalClass.js @@ -0,0 +1,5 @@ +class E { + constructor(x, y) { + this.t = x + y; + } +} diff --git a/js/js.translator/testData/box/es6classes/inheritedFromExternalClass.kt b/js/js.translator/testData/box/es6classes/inheritedFromExternalClass.kt new file mode 100644 index 00000000000..6c8fd07bd9e --- /dev/null +++ b/js/js.translator/testData/box/es6classes/inheritedFromExternalClass.kt @@ -0,0 +1,17 @@ +//IGNORE_BACKEND: JS, JS_IR + +open external class E(x: Int, y: Int) { + val t: Int = definedExternally +} + +open class A(i: Int, j: Int) : E(i, j) + +class B(val ok: String) : A(2, 3) + +fun box(): String { + val b = B("OK") + + assertEquals(5, b.t) + + return b.ok +} diff --git a/js/js.translator/testData/box/es6classes/initBlocks.kt b/js/js.translator/testData/box/es6classes/initBlocks.kt new file mode 100644 index 00000000000..eabb95ce703 --- /dev/null +++ b/js/js.translator/testData/box/es6classes/initBlocks.kt @@ -0,0 +1,42 @@ +// EXPECTED_REACHABLE_NODES: 1345 +var sideEffect = "" + +open class A(var value: Int) { + init { + sideEffect += "init A###" + } +} + +class B : A { + init { + sideEffect += "init " + } + + constructor(x: Int) : super(x) { + sideEffect += "ctor to A###" + } + + init { + sideEffect += "class " + } + + constructor() : this(180) { + sideEffect += "ctor to B###" + } + + init { + sideEffect += "B###" + } +} + +fun box(): String { + val bs1 = B(14) + assertEquals("init A###init class B###ctor to A###", sideEffect) + + sideEffect = "" + + val bs2 = B() + assertEquals("init A###init class B###ctor to A###ctor to B###", sideEffect) + + return "OK" +} diff --git a/js/js.translator/testData/box/es6classes/innerClasses.kt b/js/js.translator/testData/box/es6classes/innerClasses.kt new file mode 100644 index 00000000000..68fd8b8ad3c --- /dev/null +++ b/js/js.translator/testData/box/es6classes/innerClasses.kt @@ -0,0 +1,19 @@ +// EXPECTED_REACHABLE_NODES: 1343 +abstract class A { + abstract fun foo(): String + + val ss = foo() + "K" +} + +class O(val s: String) { + inner class I() : A() { + override fun foo() = s + } + + fun result() = I().ss +} + +fun box(): String { + val o = O("O") + return o.result() +} diff --git a/js/js.translator/testData/box/es6classes/isInitializedFieldBeforeObjectCreation.kt b/js/js.translator/testData/box/es6classes/isInitializedFieldBeforeObjectCreation.kt new file mode 100644 index 00000000000..31564c75f5e --- /dev/null +++ b/js/js.translator/testData/box/es6classes/isInitializedFieldBeforeObjectCreation.kt @@ -0,0 +1,19 @@ +// EXPECTED_REACHABLE_NODES: 1342 +//WITH_RUNTIME + +package test + +import test.A.p + +object A { + lateinit var p: String + var result: String + + init { + result = if (::p.isInitialized) "FAIL" else "OK" + } +} + +fun box(): String { + return A.result +} diff --git a/js/js.translator/testData/box/es6classes/primaryToSecondary.kt b/js/js.translator/testData/box/es6classes/primaryToSecondary.kt new file mode 100644 index 00000000000..50366aa3939 --- /dev/null +++ b/js/js.translator/testData/box/es6classes/primaryToSecondary.kt @@ -0,0 +1,15 @@ +// EXPECTED_REACHABLE_NODES: 1341 +open class A(val x: Int, val y: Int) { + constructor(x: Int) : this(x, x) +} + +class B(x: Int) : A(x) + +fun box(): String { + val b = B(45) + + assertEquals(b.x, 45) + assertEquals(b.y, 45) + + return "OK" +} diff --git a/js/js.translator/testData/box/es6classes/typeCorrectness.kt b/js/js.translator/testData/box/es6classes/typeCorrectness.kt new file mode 100644 index 00000000000..ad06ca9149c --- /dev/null +++ b/js/js.translator/testData/box/es6classes/typeCorrectness.kt @@ -0,0 +1,45 @@ +// EXPECTED_REACHABLE_NODES: 1358 +open class A(var value: Int) + +open class B : A { + constructor(x: Int) : super(x) + + constructor() : this(180) +} + +open class C(val q: Int) : B(q * q) { + constructor() : this(11) +} + +class D : C { + constructor() : super() +} + +class E(e: Int) : C(e) + +fun box(): String { + val ap = A(0) as A + + val bs1 = B(12) as B + bs1 as A + val bs2 = B() as B + bs2 as A + + val cp = C(14) as C + cp as B + cp as A + val cs = C() as C + cs as B + cs as A + + val ds = D() as D + ds as C + ds as B + ds as A + val ep = E(56) as E + ep as C + ep as B + ep as A + + return "OK" +} diff --git a/js/js.translator/testData/box/es6classes/unboxChain.kt b/js/js.translator/testData/box/es6classes/unboxChain.kt new file mode 100644 index 00000000000..c2b7fb6b8c3 --- /dev/null +++ b/js/js.translator/testData/box/es6classes/unboxChain.kt @@ -0,0 +1,24 @@ +// EXPECTED_REACHABLE_NODES: 1371 +inline class I1(val a: Int) +inline class I2(val i: I1) +inline class I3(val i: I2) +inline class I4(val i: I3) +inline class I5(val i: I4) + +class TestDefault(val def: I5 = I5(I4(I3(I2(I1(999)))))) + +class TestGen(val gen: T) + +fun box(): String { + val x = I5(I4(I3(I2(I1(1337))))) + assertEquals(1337, x.i.i.i.i.a) + + val testDefault = TestDefault() + assertEquals(999, testDefault.def.i.i.i.i.a) + + val testDefaultGen = TestGen(I5(I4(I3(I2(I1(1953)))))) + assertTrue(testDefault.def.i.i.i.i.a is Int) + assertEquals(1953, testDefaultGen.gen.i.i.i.i.a) + + return "OK" +}