diff --git a/.idea/kotlinc.xml b/.idea/kotlinc.xml
index 6a5e9230cd8..c82a5d46e86 100644
--- a/.idea/kotlinc.xml
+++ b/.idea/kotlinc.xml
@@ -8,4 +8,7 @@
+
+
+
\ No newline at end of file
diff --git a/.idea/protoeditor.xml b/.idea/protoeditor.xml
index 036b7cc1fd1..e93fd0b9df2 100644
--- a/.idea/protoeditor.xml
+++ b/.idea/protoeditor.xml
@@ -7,6 +7,9 @@
+
+
+
diff --git a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/IrJsTypeScriptExportTestGenerated.java b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/IrJsTypeScriptExportTestGenerated.java
index 8788be3cfb2..2864a2fd347 100644
--- a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/IrJsTypeScriptExportTestGenerated.java
+++ b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/IrJsTypeScriptExportTestGenerated.java
@@ -26,18 +26,18 @@ public class IrJsTypeScriptExportTestGenerated extends AbstractIrJsTypeScriptExp
}
@Nested
- @TestMetadata("js/js.translator/testData/typescript-export/classes")
+ @TestMetadata("js/js.translator/testData/typescript-export/abstract-classes")
@TestDataPath("$PROJECT_ROOT")
- public class Classes {
+ public class Abstract_classes {
@Test
- public void testAllFilesPresentInClasses() throws Exception {
- KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("js/js.translator/testData/typescript-export/classes"), Pattern.compile("^([^_](.+))\\.kt$"), null, TargetBackend.JS_IR, true);
+ @TestMetadata("abstract-classes.kt")
+ public void testAbstract_classes() throws Exception {
+ runTest("js/js.translator/testData/typescript-export/abstract-classes/abstract-classes.kt");
}
@Test
- @TestMetadata("inner-class.kt")
- public void testInner_class() throws Exception {
- runTest("js/js.translator/testData/typescript-export/classes/inner-class.kt");
+ public void testAllFilesPresentInAbstract_classes() throws Exception {
+ KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("js/js.translator/testData/typescript-export/abstract-classes"), Pattern.compile("^([^_](.+))\\.kt$"), null, TargetBackend.JS_IR, true);
}
}
@@ -58,50 +58,82 @@ public class IrJsTypeScriptExportTestGenerated extends AbstractIrJsTypeScriptExp
}
@Nested
- @TestMetadata("js/js.translator/testData/typescript-export/declarations")
+ @TestMetadata("js/js.translator/testData/typescript-export/data-classes")
@TestDataPath("$PROJECT_ROOT")
- public class Declarations {
+ public class Data_classes {
@Test
- public void testAllFilesPresentInDeclarations() throws Exception {
- KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("js/js.translator/testData/typescript-export/declarations"), Pattern.compile("^([^_](.+))\\.kt$"), null, TargetBackend.JS_IR, true);
+ public void testAllFilesPresentInData_classes() throws Exception {
+ KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("js/js.translator/testData/typescript-export/data-classes"), Pattern.compile("^([^_](.+))\\.kt$"), null, TargetBackend.JS_IR, true);
}
@Test
- @TestMetadata("declarations.kt")
- public void testDeclarations() throws Exception {
- runTest("js/js.translator/testData/typescript-export/declarations/declarations.kt");
+ @TestMetadata("data-classes.kt")
+ public void testData_classes() throws Exception {
+ runTest("js/js.translator/testData/typescript-export/data-classes/data-classes.kt");
}
}
@Nested
- @TestMetadata("js/js.translator/testData/typescript-export/escapedDeclarations")
+ @TestMetadata("js/js.translator/testData/typescript-export/enum-classes")
@TestDataPath("$PROJECT_ROOT")
- public class EscapedDeclarations {
+ public class Enum_classes {
@Test
- public void testAllFilesPresentInEscapedDeclarations() throws Exception {
- KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("js/js.translator/testData/typescript-export/escapedDeclarations"), Pattern.compile("^([^_](.+))\\.kt$"), null, TargetBackend.JS_IR, true);
+ public void testAllFilesPresentInEnum_classes() throws Exception {
+ KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("js/js.translator/testData/typescript-export/enum-classes"), Pattern.compile("^([^_](.+))\\.kt$"), null, TargetBackend.JS_IR, true);
}
@Test
- @TestMetadata("escapedDeclarations.kt")
- public void testEscapedDeclarations() throws Exception {
- runTest("js/js.translator/testData/typescript-export/escapedDeclarations/escapedDeclarations.kt");
+ @TestMetadata("enum-classes.kt")
+ public void testEnum_classes() throws Exception {
+ runTest("js/js.translator/testData/typescript-export/enum-classes/enum-classes.kt");
}
}
@Nested
- @TestMetadata("js/js.translator/testData/typescript-export/implicitExport")
+ @TestMetadata("js/js.translator/testData/typescript-export/escaped-declarations")
@TestDataPath("$PROJECT_ROOT")
- public class ImplicitExport {
+ public class Escaped_declarations {
@Test
- public void testAllFilesPresentInImplicitExport() throws Exception {
- KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("js/js.translator/testData/typescript-export/implicitExport"), Pattern.compile("^([^_](.+))\\.kt$"), null, TargetBackend.JS_IR, true);
+ public void testAllFilesPresentInEscaped_declarations() throws Exception {
+ KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("js/js.translator/testData/typescript-export/escaped-declarations"), Pattern.compile("^([^_](.+))\\.kt$"), null, TargetBackend.JS_IR, true);
}
@Test
- @TestMetadata("declarations.kt")
- public void testDeclarations() throws Exception {
- runTest("js/js.translator/testData/typescript-export/implicitExport/declarations.kt");
+ @TestMetadata("escaped-declarations.kt")
+ public void testEscaped_declarations() throws Exception {
+ runTest("js/js.translator/testData/typescript-export/escaped-declarations/escaped-declarations.kt");
+ }
+ }
+
+ @Nested
+ @TestMetadata("js/js.translator/testData/typescript-export/functions")
+ @TestDataPath("$PROJECT_ROOT")
+ public class Functions {
+ @Test
+ public void testAllFilesPresentInFunctions() throws Exception {
+ KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("js/js.translator/testData/typescript-export/functions"), Pattern.compile("^([^_](.+))\\.kt$"), null, TargetBackend.JS_IR, true);
+ }
+
+ @Test
+ @TestMetadata("functions.kt")
+ public void testFunctions() throws Exception {
+ runTest("js/js.translator/testData/typescript-export/functions/functions.kt");
+ }
+ }
+
+ @Nested
+ @TestMetadata("js/js.translator/testData/typescript-export/implicit-export")
+ @TestDataPath("$PROJECT_ROOT")
+ public class Implicit_export {
+ @Test
+ public void testAllFilesPresentInImplicit_export() throws Exception {
+ KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("js/js.translator/testData/typescript-export/implicit-export"), Pattern.compile("^([^_](.+))\\.kt$"), null, TargetBackend.JS_IR, true);
+ }
+
+ @Test
+ @TestMetadata("implicit-export.kt")
+ public void testImplicit_export() throws Exception {
+ runTest("js/js.translator/testData/typescript-export/implicit-export/implicit-export.kt");
}
}
@@ -122,30 +154,110 @@ public class IrJsTypeScriptExportTestGenerated extends AbstractIrJsTypeScriptExp
}
@Nested
- @TestMetadata("js/js.translator/testData/typescript-export/moduleSystems")
+ @TestMetadata("js/js.translator/testData/typescript-export/inner-classes")
@TestDataPath("$PROJECT_ROOT")
- public class ModuleSystems {
+ public class Inner_classes {
@Test
- public void testAllFilesPresentInModuleSystems() throws Exception {
- KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("js/js.translator/testData/typescript-export/moduleSystems"), Pattern.compile("^([^_](.+))\\.kt$"), null, TargetBackend.JS_IR, true);
+ public void testAllFilesPresentInInner_classes() throws Exception {
+ KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("js/js.translator/testData/typescript-export/inner-classes"), Pattern.compile("^([^_](.+))\\.kt$"), null, TargetBackend.JS_IR, true);
+ }
+
+ @Test
+ @TestMetadata("inner-class.kt")
+ public void testInner_class() throws Exception {
+ runTest("js/js.translator/testData/typescript-export/inner-classes/inner-class.kt");
+ }
+ }
+
+ @Nested
+ @TestMetadata("js/js.translator/testData/typescript-export/interfaces")
+ @TestDataPath("$PROJECT_ROOT")
+ public class Interfaces {
+ @Test
+ public void testAllFilesPresentInInterfaces() throws Exception {
+ KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("js/js.translator/testData/typescript-export/interfaces"), Pattern.compile("^([^_](.+))\\.kt$"), null, TargetBackend.JS_IR, true);
+ }
+
+ @Test
+ @TestMetadata("interfaces.kt")
+ public void testInterfaces() throws Exception {
+ runTest("js/js.translator/testData/typescript-export/interfaces/interfaces.kt");
+ }
+ }
+
+ @Nested
+ @TestMetadata("js/js.translator/testData/typescript-export/js-name")
+ @TestDataPath("$PROJECT_ROOT")
+ public class Js_name {
+ @Test
+ public void testAllFilesPresentInJs_name() throws Exception {
+ KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("js/js.translator/testData/typescript-export/js-name"), Pattern.compile("^([^_](.+))\\.kt$"), null, TargetBackend.JS_IR, true);
+ }
+
+ @Test
+ @TestMetadata("js-name.kt")
+ public void testJs_name() throws Exception {
+ runTest("js/js.translator/testData/typescript-export/js-name/js-name.kt");
+ }
+ }
+
+ @Nested
+ @TestMetadata("js/js.translator/testData/typescript-export/member-properties")
+ @TestDataPath("$PROJECT_ROOT")
+ public class Member_properties {
+ @Test
+ public void testAllFilesPresentInMember_properties() throws Exception {
+ KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("js/js.translator/testData/typescript-export/member-properties"), Pattern.compile("^([^_](.+))\\.kt$"), null, TargetBackend.JS_IR, true);
+ }
+
+ @Test
+ @TestMetadata("member-properties.kt")
+ public void testMember_properties() throws Exception {
+ runTest("js/js.translator/testData/typescript-export/member-properties/member-properties.kt");
+ }
+ }
+
+ @Nested
+ @TestMetadata("js/js.translator/testData/typescript-export/methods")
+ @TestDataPath("$PROJECT_ROOT")
+ public class Methods {
+ @Test
+ public void testAllFilesPresentInMethods() throws Exception {
+ KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("js/js.translator/testData/typescript-export/methods"), Pattern.compile("^([^_](.+))\\.kt$"), null, TargetBackend.JS_IR, true);
+ }
+
+ @Test
+ @TestMetadata("methods.kt")
+ public void testMethods() throws Exception {
+ runTest("js/js.translator/testData/typescript-export/methods/methods.kt");
+ }
+ }
+
+ @Nested
+ @TestMetadata("js/js.translator/testData/typescript-export/module-systems")
+ @TestDataPath("$PROJECT_ROOT")
+ public class Module_systems {
+ @Test
+ public void testAllFilesPresentInModule_systems() throws Exception {
+ KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("js/js.translator/testData/typescript-export/module-systems"), Pattern.compile("^([^_](.+))\\.kt$"), null, TargetBackend.JS_IR, true);
}
@Test
@TestMetadata("commonjs.kt")
public void testCommonjs() throws Exception {
- runTest("js/js.translator/testData/typescript-export/moduleSystems/commonjs.kt");
+ runTest("js/js.translator/testData/typescript-export/module-systems/commonjs.kt");
}
@Test
@TestMetadata("plain.kt")
public void testPlain() throws Exception {
- runTest("js/js.translator/testData/typescript-export/moduleSystems/plain.kt");
+ runTest("js/js.translator/testData/typescript-export/module-systems/plain.kt");
}
@Test
@TestMetadata("umd.kt")
public void testUmd() throws Exception {
- runTest("js/js.translator/testData/typescript-export/moduleSystems/umd.kt");
+ runTest("js/js.translator/testData/typescript-export/module-systems/umd.kt");
}
}
@@ -165,6 +277,22 @@ public class IrJsTypeScriptExportTestGenerated extends AbstractIrJsTypeScriptExp
}
}
+ @Nested
+ @TestMetadata("js/js.translator/testData/typescript-export/objects")
+ @TestDataPath("$PROJECT_ROOT")
+ public class Objects {
+ @Test
+ public void testAllFilesPresentInObjects() throws Exception {
+ KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("js/js.translator/testData/typescript-export/objects"), Pattern.compile("^([^_](.+))\\.kt$"), null, TargetBackend.JS_IR, true);
+ }
+
+ @Test
+ @TestMetadata("objects.kt")
+ public void testObjects() throws Exception {
+ runTest("js/js.translator/testData/typescript-export/objects/objects.kt");
+ }
+ }
+
@Nested
@TestMetadata("js/js.translator/testData/typescript-export/primitives")
@TestDataPath("$PROJECT_ROOT")
@@ -182,18 +310,66 @@ public class IrJsTypeScriptExportTestGenerated extends AbstractIrJsTypeScriptExp
}
@Nested
- @TestMetadata("js/js.translator/testData/typescript-export/selectiveExport")
+ @TestMetadata("js/js.translator/testData/typescript-export/properties")
@TestDataPath("$PROJECT_ROOT")
- public class SelectiveExport {
+ public class Properties {
@Test
- public void testAllFilesPresentInSelectiveExport() throws Exception {
- KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("js/js.translator/testData/typescript-export/selectiveExport"), Pattern.compile("^([^_](.+))\\.kt$"), null, TargetBackend.JS_IR, true);
+ public void testAllFilesPresentInProperties() throws Exception {
+ KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("js/js.translator/testData/typescript-export/properties"), Pattern.compile("^([^_](.+))\\.kt$"), null, TargetBackend.JS_IR, true);
}
@Test
- @TestMetadata("selectiveExport.kt")
- public void testSelectiveExport() throws Exception {
- runTest("js/js.translator/testData/typescript-export/selectiveExport/selectiveExport.kt");
+ @TestMetadata("properties.kt")
+ public void testProperties() throws Exception {
+ runTest("js/js.translator/testData/typescript-export/properties/properties.kt");
+ }
+ }
+
+ @Nested
+ @TestMetadata("js/js.translator/testData/typescript-export/regular-classes")
+ @TestDataPath("$PROJECT_ROOT")
+ public class Regular_classes {
+ @Test
+ public void testAllFilesPresentInRegular_classes() throws Exception {
+ KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("js/js.translator/testData/typescript-export/regular-classes"), Pattern.compile("^([^_](.+))\\.kt$"), null, TargetBackend.JS_IR, true);
+ }
+
+ @Test
+ @TestMetadata("regular-classes.kt")
+ public void testRegular_classes() throws Exception {
+ runTest("js/js.translator/testData/typescript-export/regular-classes/regular-classes.kt");
+ }
+ }
+
+ @Nested
+ @TestMetadata("js/js.translator/testData/typescript-export/sealed-classes")
+ @TestDataPath("$PROJECT_ROOT")
+ public class Sealed_classes {
+ @Test
+ public void testAllFilesPresentInSealed_classes() throws Exception {
+ KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("js/js.translator/testData/typescript-export/sealed-classes"), Pattern.compile("^([^_](.+))\\.kt$"), null, TargetBackend.JS_IR, true);
+ }
+
+ @Test
+ @TestMetadata("sealed-classes.kt")
+ public void testSealed_classes() throws Exception {
+ runTest("js/js.translator/testData/typescript-export/sealed-classes/sealed-classes.kt");
+ }
+ }
+
+ @Nested
+ @TestMetadata("js/js.translator/testData/typescript-export/selective-export")
+ @TestDataPath("$PROJECT_ROOT")
+ public class Selective_export {
+ @Test
+ public void testAllFilesPresentInSelective_export() throws Exception {
+ KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("js/js.translator/testData/typescript-export/selective-export"), Pattern.compile("^([^_](.+))\\.kt$"), null, TargetBackend.JS_IR, true);
+ }
+
+ @Test
+ @TestMetadata("selective-export.kt")
+ public void testSelective_export() throws Exception {
+ runTest("js/js.translator/testData/typescript-export/selective-export/selective-export.kt");
}
}
diff --git a/js/js.translator/testData/typescript-export/abstract-classes/abstract-classes.d.ts b/js/js.translator/testData/typescript-export/abstract-classes/abstract-classes.d.ts
new file mode 100644
index 00000000000..db5b60420c6
--- /dev/null
+++ b/js/js.translator/testData/typescript-export/abstract-classes/abstract-classes.d.ts
@@ -0,0 +1,19 @@
+declare namespace JS_TESTS {
+ type Nullable = T | null | undefined
+ namespace foo {
+ abstract class TestAbstract {
+ constructor(name: string);
+ get name(): string;
+ }
+ namespace TestAbstract {
+ class AA extends foo.TestAbstract {
+ constructor();
+ bar(): string;
+ }
+ class BB extends foo.TestAbstract {
+ constructor();
+ baz(): string;
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/js/js.translator/testData/typescript-export/abstract-classes/abstract-classes.kt b/js/js.translator/testData/typescript-export/abstract-classes/abstract-classes.kt
new file mode 100644
index 00000000000..513f62190b7
--- /dev/null
+++ b/js/js.translator/testData/typescript-export/abstract-classes/abstract-classes.kt
@@ -0,0 +1,20 @@
+// CHECK_TYPESCRIPT_DECLARATIONS
+// RUN_PLAIN_BOX_FUNCTION
+// SKIP_MINIFICATION
+// SKIP_NODE_JS
+// INFER_MAIN_MODULE
+// MODULE: JS_TESTS
+// FILE: abstract-classes.kt
+
+package foo
+
+// See KT-39364
+@JsExport
+abstract class TestAbstract(val name: String) {
+ class AA : TestAbstract("AA") {
+ fun bar(): String = "bar"
+ }
+ class BB : TestAbstract("BB") {
+ fun baz(): String = "baz"
+ }
+}
\ No newline at end of file
diff --git a/js/js.translator/testData/typescript-export/abstract-classes/abstract-classes__main.js b/js/js.translator/testData/typescript-export/abstract-classes/abstract-classes__main.js
new file mode 100644
index 00000000000..a0139b52540
--- /dev/null
+++ b/js/js.translator/testData/typescript-export/abstract-classes/abstract-classes__main.js
@@ -0,0 +1,14 @@
+"use strict";
+var TestAbstract = JS_TESTS.foo.TestAbstract;
+function assert(condition) {
+ if (!condition) {
+ throw "Assertion failed";
+ }
+}
+function box() {
+ assert(new TestAbstract.AA().name == "AA");
+ assert(new TestAbstract.AA().bar() == "bar");
+ assert(new TestAbstract.BB().name == "BB");
+ assert(new TestAbstract.BB().baz() == "baz");
+ return "OK";
+}
diff --git a/js/js.translator/testData/typescript-export/abstract-classes/abstract-classes__main.ts b/js/js.translator/testData/typescript-export/abstract-classes/abstract-classes__main.ts
new file mode 100644
index 00000000000..92c4ff8e223
--- /dev/null
+++ b/js/js.translator/testData/typescript-export/abstract-classes/abstract-classes__main.ts
@@ -0,0 +1,17 @@
+import TestAbstract = JS_TESTS.foo.TestAbstract;
+
+function assert(condition: boolean) {
+ if (!condition) {
+ throw "Assertion failed";
+ }
+}
+
+function box(): string {
+ assert(new TestAbstract.AA().name == "AA");
+ assert(new TestAbstract.AA().bar() == "bar");
+ assert(new TestAbstract.BB().name == "BB");
+ assert(new TestAbstract.BB().baz() == "baz");
+
+
+ return "OK";
+}
\ No newline at end of file
diff --git a/js/js.translator/testData/typescript-export/classes/tsconfig.json b/js/js.translator/testData/typescript-export/abstract-classes/tsconfig.json
similarity index 100%
rename from js/js.translator/testData/typescript-export/classes/tsconfig.json
rename to js/js.translator/testData/typescript-export/abstract-classes/tsconfig.json
diff --git a/js/js.translator/testData/typescript-export/data-classes/data-classes.d.ts b/js/js.translator/testData/typescript-export/data-classes/data-classes.d.ts
new file mode 100644
index 00000000000..dcfc9199c47
--- /dev/null
+++ b/js/js.translator/testData/typescript-export/data-classes/data-classes.d.ts
@@ -0,0 +1,31 @@
+declare namespace JS_TESTS {
+ type Nullable = T | null | undefined
+ namespace foo {
+ class TestDataClass {
+ constructor(name: string);
+ get name(): string;
+ component1(): string;
+ copy(name?: string): foo.TestDataClass;
+ toString(): string;
+ hashCode(): number;
+ equals(other: Nullable): boolean;
+ }
+ namespace TestDataClass {
+ class Nested {
+ constructor();
+ get prop(): string;
+ }
+ }
+ class KT39423 {
+ constructor(a: string, b?: Nullable);
+ get a(): string;
+ get b(): Nullable;
+ component1(): string;
+ component2(): Nullable;
+ copy(a?: string, b?: Nullable): foo.KT39423;
+ toString(): string;
+ hashCode(): number;
+ equals(other: Nullable): boolean;
+ }
+ }
+}
\ No newline at end of file
diff --git a/js/js.translator/testData/typescript-export/data-classes/data-classes.kt b/js/js.translator/testData/typescript-export/data-classes/data-classes.kt
new file mode 100644
index 00000000000..4541626f30f
--- /dev/null
+++ b/js/js.translator/testData/typescript-export/data-classes/data-classes.kt
@@ -0,0 +1,23 @@
+// CHECK_TYPESCRIPT_DECLARATIONS
+// RUN_PLAIN_BOX_FUNCTION
+// SKIP_MINIFICATION
+// SKIP_NODE_JS
+// INFER_MAIN_MODULE
+// MODULE: JS_TESTS
+// FILE: data-classes.kt
+
+package foo
+
+
+@JsExport
+data class TestDataClass(val name: String) {
+ class Nested {
+ val prop: String = "hello"
+ }
+}
+
+@JsExport
+data class KT39423(
+ val a: String,
+ val b: Int? = null
+)
\ No newline at end of file
diff --git a/js/js.translator/testData/typescript-export/data-classes/data-classes__main.js b/js/js.translator/testData/typescript-export/data-classes/data-classes__main.js
new file mode 100644
index 00000000000..898f484c364
--- /dev/null
+++ b/js/js.translator/testData/typescript-export/data-classes/data-classes__main.js
@@ -0,0 +1,35 @@
+"use strict";
+var TestDataClass = JS_TESTS.foo.TestDataClass;
+var KT39423 = JS_TESTS.foo.KT39423;
+function assert(condition) {
+ if (!condition) {
+ throw "Assertion failed";
+ }
+}
+function box() {
+ assert(new TestDataClass("Test").name === "Test");
+ assert(new TestDataClass("Test").component1() === "Test");
+ assert(new TestDataClass("Test").copy("NewTest").name === "NewTest");
+ assert(new TestDataClass("Test").toString() === "TestDataClass(name=Test)");
+ assert(new TestDataClass("Test").hashCode() === new TestDataClass("Test").hashCode());
+ assert(new TestDataClass("Test").hashCode() !== new TestDataClass("AnotherTest").hashCode());
+ assert(new TestDataClass("Test").equals(new TestDataClass("Test")));
+ assert(!new TestDataClass("Test").equals(new TestDataClass("AnotherTest")));
+ assert(new TestDataClass.Nested().prop === "hello");
+ assert(new KT39423("Test").a === "Test");
+ assert(new KT39423("Test").b === null);
+ assert(new KT39423("Test", null).a === "Test");
+ assert(new KT39423("Test", null).b === null);
+ assert(new KT39423("Test", 42).a === "Test");
+ assert(new KT39423("Test", 42).b === 42);
+ assert(new KT39423("Test", 42).component1() === "Test");
+ assert(new KT39423("Test", 42).component2() === 42);
+ assert(new KT39423("Test", 42).copy("NewTest").a === "NewTest");
+ assert(new KT39423("Test", 42).copy("NewTest").b === 42);
+ assert(new KT39423("Test", 42).copy("Test", null).a === "Test");
+ assert(new KT39423("Test", 42).copy("Test", null).b === null);
+ assert(new KT39423("Test").toString() === "KT39423(a=Test, b=null)");
+ assert(new KT39423("Test", null).toString() === "KT39423(a=Test, b=null)");
+ assert(new KT39423("Test", 42).toString() === "KT39423(a=Test, b=42)");
+ return "OK";
+}
diff --git a/js/js.translator/testData/typescript-export/data-classes/data-classes__main.ts b/js/js.translator/testData/typescript-export/data-classes/data-classes__main.ts
new file mode 100644
index 00000000000..4a831cc15ee
--- /dev/null
+++ b/js/js.translator/testData/typescript-export/data-classes/data-classes__main.ts
@@ -0,0 +1,45 @@
+import TestDataClass = JS_TESTS.foo.TestDataClass;
+import KT39423 = JS_TESTS.foo.KT39423;
+
+function assert(condition: boolean) {
+ if (!condition) {
+ throw "Assertion failed";
+ }
+}
+
+function box(): string {
+ assert(new TestDataClass("Test").name === "Test");
+ assert(new TestDataClass("Test").component1() === "Test");
+ assert(new TestDataClass("Test").copy("NewTest").name === "NewTest");
+ assert(new TestDataClass("Test").toString() === "TestDataClass(name=Test)");
+
+ assert(new TestDataClass("Test").hashCode() === new TestDataClass("Test").hashCode());
+ assert(new TestDataClass("Test").hashCode() !== new TestDataClass("AnotherTest").hashCode());
+
+ assert(new TestDataClass("Test").equals(new TestDataClass("Test")));
+ assert(!new TestDataClass("Test").equals(new TestDataClass("AnotherTest")));
+
+ assert(new TestDataClass.Nested().prop === "hello");
+
+ assert(new KT39423("Test").a === "Test")
+ assert(new KT39423("Test").b === null)
+ assert(new KT39423("Test", null).a === "Test")
+ assert(new KT39423("Test", null).b === null)
+
+ assert(new KT39423("Test", 42).a === "Test")
+ assert(new KT39423("Test", 42).b === 42)
+
+ assert(new KT39423("Test", 42).component1() === "Test")
+ assert(new KT39423("Test", 42).component2() === 42)
+
+ assert(new KT39423("Test", 42).copy("NewTest").a === "NewTest")
+ assert(new KT39423("Test", 42).copy("NewTest").b === 42)
+ assert(new KT39423("Test", 42).copy("Test", null).a === "Test")
+ assert(new KT39423("Test", 42).copy("Test", null).b === null)
+
+ assert(new KT39423("Test").toString() === "KT39423(a=Test, b=null)")
+ assert(new KT39423("Test", null).toString() === "KT39423(a=Test, b=null)")
+ assert(new KT39423("Test", 42).toString() === "KT39423(a=Test, b=42)")
+
+ return "OK";
+}
\ No newline at end of file
diff --git a/js/js.translator/testData/typescript-export/declarations/tsconfig.json b/js/js.translator/testData/typescript-export/data-classes/tsconfig.json
similarity index 100%
rename from js/js.translator/testData/typescript-export/declarations/tsconfig.json
rename to js/js.translator/testData/typescript-export/data-classes/tsconfig.json
diff --git a/js/js.translator/testData/typescript-export/declarations/declarations.d.ts b/js/js.translator/testData/typescript-export/declarations/declarations.d.ts
deleted file mode 100644
index b55bf3b0a8d..00000000000
--- a/js/js.translator/testData/typescript-export/declarations/declarations.d.ts
+++ /dev/null
@@ -1,249 +0,0 @@
-declare namespace JS_TESTS {
- type Nullable = T | null | undefined
- namespace foo {
- const _val: number;
- let _var: number;
- const _valCustomWithField: number;
- let _varCustomWithField: number;
- function sum(x: number, y: number): number;
- function varargInt(x: Int32Array): number;
- function varargNullableInt(x: Array>): number;
- function varargWithOtherParameters(x: string, y: Array, z: string): number;
- function varargWithComplexType(x: Array<(p0: Array) => Array>): number;
- function sumNullable(x: Nullable, y: Nullable): number;
- function defaultParameters(a: string, x?: number, y?: string): string;
- function generic1(x: T): T;
- function generic2(x: Nullable): boolean;
- function genericWithConstraint(x: T): T;
- function genericWithMultipleConstraints(x: T): T;
- function generic3(a: A, b: B, c: C, d: D): Nullable;
- function inlineFun(x: number, callback: (p0: number) => void): void;
- const _const_val: number;
- const _valCustom: number;
- let _varCustom: number;
- class A {
- constructor();
- }
- class A1 {
- constructor(x: number);
- get x(): number;
- }
- class A2 {
- constructor(x: string, y: boolean);
- get x(): string;
- get y(): boolean;
- set y(value: boolean);
- }
- class A3 {
- constructor();
- get x(): number;
- }
- class A4 {
- constructor();
- get _valCustom(): number;
- get _valCustomWithField(): number;
- get _varCustom(): number;
- set _varCustom(value: number);
- get _varCustomWithField(): number;
- set _varCustomWithField(value: number);
- }
- class A5 {
- constructor(value: T);
- get value(): T;
- test(): T;
- }
- const O0: {
- };
- const O: {
- get x(): number;
- foo(): number;
- };
- function takesO(o: typeof foo.O): number;
- class KT_37829 {
- constructor();
- static get Companion(): {
- get x(): number;
- };
- }
- abstract class TestSealed {
- protected constructor(name: string);
- get name(): string;
- }
- namespace TestSealed {
- class AA extends foo.TestSealed {
- constructor();
- bar(): string;
- }
- class BB extends foo.TestSealed {
- constructor();
- baz(): string;
- }
- }
- abstract class TestAbstract {
- constructor(name: string);
- get name(): string;
- }
- namespace TestAbstract {
- class AA extends foo.TestAbstract {
- constructor();
- bar(): string;
- }
- class BB extends foo.TestAbstract {
- constructor();
- baz(): string;
- }
- }
- class TestDataClass {
- constructor(name: string);
- get name(): string;
- component1(): string;
- copy(name?: string): foo.TestDataClass;
- toString(): string;
- hashCode(): number;
- equals(other: Nullable): boolean;
- }
- namespace TestDataClass {
- class Nested {
- constructor();
- get prop(): string;
- }
- }
- abstract class TestEnumClass {
- private constructor();
- get constructorParameter(): string;
- static get A(): foo.TestEnumClass & {
- get name(): "A";
- get ordinal(): 0;
- };
- static get B(): foo.TestEnumClass & {
- get name(): "B";
- get ordinal(): 1;
- };
- get foo(): number;
- bar(value: string): string;
- bay(): string;
- static values(): Array;
- static valueOf(value: string): foo.TestEnumClass;
- get name(): "A" | "B";
- get ordinal(): 0 | 1;
- }
- namespace TestEnumClass {
- class Nested {
- constructor();
- get prop(): string;
- }
- }
- interface TestInterface {
- readonly value: string;
- getOwnerName(): string;
- readonly __doNotUseOrImplementIt: {
- readonly "foo.TestInterface": unique symbol;
- };
- }
- interface AnotherExportedInterface {
- readonly __doNotUseOrImplementIt: {
- readonly "foo.AnotherExportedInterface": unique symbol;
- };
- }
- class TestInterfaceImpl implements foo.TestInterface {
- constructor(value: string);
- get value(): string;
- getOwnerName(): string;
- readonly __doNotUseOrImplementIt: foo.TestInterface["__doNotUseOrImplementIt"];
- }
- class ChildTestInterfaceImpl extends foo.TestInterfaceImpl implements foo.AnotherExportedInterface {
- constructor();
- readonly __doNotUseOrImplementIt: foo.TestInterfaceImpl["__doNotUseOrImplementIt"] & foo.AnotherExportedInterface["__doNotUseOrImplementIt"];
- }
- function processInterface(test: foo.TestInterface): string;
- class OuterClass {
- constructor();
- }
- namespace OuterClass {
- abstract class NestedEnum {
- private constructor();
- static get A(): foo.OuterClass.NestedEnum & {
- get name(): "A";
- get ordinal(): 0;
- };
- static get B(): foo.OuterClass.NestedEnum & {
- get name(): "B";
- get ordinal(): 1;
- };
- static values(): Array;
- static valueOf(value: string): foo.OuterClass.NestedEnum;
- get name(): "A" | "B";
- get ordinal(): 0 | 1;
- }
- }
- class KT38262 {
- constructor();
- then(): number;
- catch(): number;
- }
- class JsNameTest {
- private constructor();
- get value(): number;
- runTest(): string;
- static get Companion(): {
- create(): foo.JsNameTest;
- createChild(value: number): foo.JsNameTest.NestedJsName;
- };
- }
- namespace JsNameTest {
- class NestedJsName {
- constructor(__value: number);
- get value(): number;
- }
- }
- class KT39423 {
- constructor(a: string, b?: Nullable);
- get a(): string;
- get b(): Nullable;
- component1(): string;
- component2(): Nullable;
- copy(a?: string, b?: Nullable): foo.KT39423;
- toString(): string;
- hashCode(): number;
- equals(other: Nullable): boolean;
- }
- abstract class Parent {
- private constructor();
- }
- namespace Parent {
- abstract class Nested1 extends _objects_.foo$Parent$Nested1 {
- private constructor();
- }
- namespace Nested1 {
- class Nested2 {
- constructor();
- }
- namespace Nested2 {
- abstract class Companion {
- private constructor();
- }
- namespace Companion {
- class Nested3 {
- constructor();
- }
- }
- }
- }
- }
- function getParent(): typeof foo.Parent;
- function createNested1(): typeof foo.Parent.Nested1;
- function createNested2(): foo.Parent.Nested1.Nested2;
- function createNested3(): foo.Parent.Nested1.Nested2.Companion.Nested3;
- class GenericClassWithConstraint {
- constructor(test: T);
- get test(): T;
- }
- }
- namespace _objects_ {
- const foo$Parent$Nested1: {
- get value(): string;
- } & {
- new(): any;
- };
- }
-}
\ No newline at end of file
diff --git a/js/js.translator/testData/typescript-export/declarations/declarations.kt b/js/js.translator/testData/typescript-export/declarations/declarations.kt
deleted file mode 100644
index 65c894e3c00..00000000000
--- a/js/js.translator/testData/typescript-export/declarations/declarations.kt
+++ /dev/null
@@ -1,300 +0,0 @@
-// CHECK_TYPESCRIPT_DECLARATIONS
-// RUN_PLAIN_BOX_FUNCTION
-// SKIP_MINIFICATION
-// SKIP_NODE_JS
-// INFER_MAIN_MODULE
-// MODULE: JS_TESTS
-// FILE: declarations.kt
-
-package foo
-
-// TODO: Test the same for member functions:
-
-@JsExport
-fun sum(x: Int, y: Int): Int =
- x + y
-
-@JsExport
-fun varargInt(vararg x: Int): Int =
- x.size
-
-@JsExport
-fun varargNullableInt(vararg x: Int?): Int =
- x.size
-
-@JsExport
-fun varargWithOtherParameters(x: String, vararg y: String, z: String): Int =
- x.length + y.size + z.length
-
-@JsExport
-fun varargWithComplexType(vararg x: (Array) -> Array): Int =
- x.size
-
-@JsExport
-fun sumNullable(x: Int?, y: Int?): Int =
- (x ?: 0) + (y ?: 0)
-
-@JsExport
-fun defaultParameters(a: String, x: Int = 10, y: String = "OK"): String =
- a + x.toString() + y
-
-@JsExport
-fun generic1(x: T): T = x
-
-@JsExport
-fun generic2(x: T?): Boolean = (x == null)
-
-@JsExport
-fun genericWithConstraint(x: T): T = x
-
-@JsExport
-fun genericWithMultipleConstraints(x: T): T
- where T : Comparable,
- T : TestInterface,
- T : Throwable = x
-
-@JsExport
-fun generic3(a: A, b: B, c: C, d: D): E? = null
-
-@JsExport
-inline fun inlineFun(x: Int, callback: (Int) -> Unit) {
- callback(x)
-}
-
-// Properties
-
-@JsExport
-const val _const_val: Int = 1
-
-@JsExport
-val _val: Int = 1
-
-@JsExport
-var _var: Int = 1
-
-@JsExport
-val _valCustom: Int
- get() = 1
-
-@JsExport
-val _valCustomWithField: Int = 1
- get() = field + 1
-
-@JsExport
-var _varCustom: Int
- get() = 1
- set(value) {}
-
-@JsExport
-var _varCustomWithField: Int = 1
- get() = field * 10
- set(value) { field = value * 10 }
-
-// Classes
-
-@JsExport
-class A
-
-@JsExport
-class A1(val x: Int)
-
-@JsExport
-class A2(val x: String, var y: Boolean)
-
-@JsExport
-class A3 {
- val x: Int = 100
-}
-
-@JsExport
-class A4 {
- val _valCustom: Int
- get() = 1
-
- val _valCustomWithField: Int = 1
- get() = field + 1
-
- var _varCustom: Int
- get() = 1
- set(value) {}
-
- var _varCustomWithField: Int = 1
- get() = field * 10
- set(value) { field = value * 10 }
-}
-
-@JsExport
-class A5(val value: T) {
- fun test(): T = value
-}
-
-@JsExport
-object O0
-
-@JsExport
-object O {
- val x = 10
- @JsName("foo") // TODO: Should work without JsName
- fun foo() = 20
-}
-
-@JsExport
-fun takesO(o: O): Int =
- O.x + O.foo()
-
-@JsExport
-class KT_37829 {
- companion object {
- val x = 10
- }
-}
-
-// See KT-47376, KT-39364
-@JsExport
-sealed class TestSealed(val name: String) {
- class AA : TestSealed("AA") {
- fun bar(): String = "bar"
- }
- class BB : TestSealed("BB") {
- fun baz(): String = "baz"
- }
-}
-
-// See KT-39364
-@JsExport
-abstract class TestAbstract(val name: String) {
- class AA : TestAbstract("AA") {
- fun bar(): String = "bar"
- }
- class BB : TestAbstract("BB") {
- fun baz(): String = "baz"
- }
-}
-
-@JsExport
-data class TestDataClass(val name: String) {
- class Nested {
- val prop: String = "hello"
- }
-}
-
-@JsExport
-enum class TestEnumClass(val constructorParameter: String) {
- A("aConstructorParameter"),
- B("bConstructorParameter");
-
- val foo = ordinal
-
- fun bar(value: String) = value
-
- fun bay() = name
-
- class Nested {
- val prop: String = "hello2"
- }
-}
-
-
-@JsExport
-interface TestInterface {
- val value: String
- fun getOwnerName(): String
-}
-
-@JsExport
-interface AnotherExportedInterface
-
-@JsExport
-open class TestInterfaceImpl(override val value: String) : TestInterface {
- override fun getOwnerName() = "TestInterfaceImpl"
-}
-
-@JsExport
-class ChildTestInterfaceImpl(): TestInterfaceImpl("Test"), AnotherExportedInterface
-
-@JsExport
-fun processInterface(test: TestInterface): String {
- return "Owner ${test.getOwnerName()} has value '${test.value}'"
-}
-
-@JsExport
-class OuterClass {
- enum class NestedEnum {
- A,
- B
- }
-}
-
-@JsExport
-open class KT38262 {
- fun then(): Int = 42
- fun catch(): Int = 24
-}
-
-@JsExport
-@JsName("JsNameTest")
-class __JsNameTest private constructor() {
- @JsName("value")
- val __value = 4
-
- @JsName("runTest")
- fun __runTest(): String {
- return "JsNameTest"
- }
-
- companion object {
- @JsName("create")
- fun __create(): __JsNameTest {
- return __JsNameTest()
- }
-
- @JsName("createChild")
- fun __createChild(value: Int): __NestJsNameTest {
- return __NestJsNameTest(value)
- }
- }
-
- @JsName("NestedJsName")
- class __NestJsNameTest(@JsName("value") val __value: Int)
-}
-
-@JsExport
-data class KT39423(
- val a: String,
- val b: Int? = null
-)
-
-@JsExport
-object Parent {
- object Nested1 {
- val value: String = "Nested1"
- class Nested2 {
- companion object {
- class Nested3
- }
- }
- }
-}
-
-@JsExport
-fun getParent(): Parent {
- return Parent
-}
-
-@JsExport
-fun createNested1(): Parent.Nested1 {
- return Parent.Nested1
-}
-
-@JsExport
-fun createNested2(): Parent.Nested1.Nested2 {
- return Parent.Nested1.Nested2()
-}
-
-@JsExport
-fun createNested3(): Parent.Nested1.Nested2.Companion.Nested3 {
- return Parent.Nested1.Nested2.Companion.Nested3()
-}
-
-@JsExport
-class GenericClassWithConstraint(val test: T)
\ No newline at end of file
diff --git a/js/js.translator/testData/typescript-export/declarations/declarations__main.js b/js/js.translator/testData/typescript-export/declarations/declarations__main.js
deleted file mode 100644
index e4e24c19f20..00000000000
--- a/js/js.translator/testData/typescript-export/declarations/declarations__main.js
+++ /dev/null
@@ -1,157 +0,0 @@
-"use strict";
-var foo = JS_TESTS.foo;
-var varargInt = JS_TESTS.foo.varargInt;
-var varargNullableInt = JS_TESTS.foo.varargNullableInt;
-var varargWithOtherParameters = JS_TESTS.foo.varargWithOtherParameters;
-var varargWithComplexType = JS_TESTS.foo.varargWithComplexType;
-var sumNullable = JS_TESTS.foo.sumNullable;
-var defaultParameters = JS_TESTS.foo.defaultParameters;
-var generic1 = JS_TESTS.foo.generic1;
-var generic2 = JS_TESTS.foo.generic2;
-var generic3 = JS_TESTS.foo.generic3;
-var inlineFun = JS_TESTS.foo.inlineFun;
-var _const_val = JS_TESTS.foo._const_val;
-var _val = JS_TESTS.foo._val;
-var _var = JS_TESTS.foo._var;
-var A = JS_TESTS.foo.A;
-var A1 = JS_TESTS.foo.A1;
-var A2 = JS_TESTS.foo.A2;
-var A3 = JS_TESTS.foo.A3;
-var _valCustom = JS_TESTS.foo._valCustom;
-var _valCustomWithField = JS_TESTS.foo._valCustomWithField;
-var A4 = JS_TESTS.foo.A4;
-var O = JS_TESTS.foo.O;
-var takesO = JS_TESTS.foo.takesO;
-var KT_37829 = JS_TESTS.foo.KT_37829;
-var TestSealed = JS_TESTS.foo.TestSealed;
-var TestAbstract = JS_TESTS.foo.TestAbstract;
-var TestDataClass = JS_TESTS.foo.TestDataClass;
-var TestEnumClass = JS_TESTS.foo.TestEnumClass;
-var TestInterfaceImpl = JS_TESTS.foo.TestInterfaceImpl;
-var processInterface = JS_TESTS.foo.processInterface;
-var OuterClass = JS_TESTS.foo.OuterClass;
-var KT38262 = JS_TESTS.foo.KT38262;
-var JsNameTest = JS_TESTS.foo.JsNameTest;
-var Parent = JS_TESTS.foo.Parent;
-var getParent = JS_TESTS.foo.getParent;
-var createNested1 = JS_TESTS.foo.createNested1;
-var createNested2 = JS_TESTS.foo.createNested2;
-var createNested3 = JS_TESTS.foo.createNested3;
-var GenericClassWithConstraint = JS_TESTS.foo.GenericClassWithConstraint;
-function assert(condition) {
- if (!condition) {
- throw "Assertion failed";
- }
-}
-function box() {
- assert(foo.sum(10, 20) === 30);
- assert(varargInt(new Int32Array([1, 2, 3])) === 3);
- assert(varargNullableInt([10, 20, 30, null, undefined, 40]) === 6);
- assert(varargWithOtherParameters("1234", ["1", "2", "3"], "12") === 9);
- assert(varargWithComplexType([]) === 0);
- assert(varargWithComplexType([
- function (x) { return x; },
- function (x) { return [new Int32Array([1, 2, 3])]; },
- function (x) { return []; },
- ]) === 3);
- assert(sumNullable(10, null) === 10);
- assert(sumNullable(undefined, 20) === 20);
- assert(sumNullable(1, 2) === 3);
- assert(defaultParameters("", 20, "OK") === "20OK");
- assert(generic1("FOO") === "FOO");
- assert(generic1({ x: 10 }).x === 10);
- assert(generic2(null) === true);
- assert(generic2(undefined) === true);
- assert(generic2(10) === false);
- assert(generic3(10, true, "__", {}) === null);
- var result = 0;
- inlineFun(10, function (x) { result = x; });
- assert(result === 10);
- assert(_const_val === 1);
- assert(_val === 1);
- assert(_var === 1);
- foo._var = 1000;
- assert(foo._var === 1000);
- assert(foo._valCustom === 1);
- assert(foo._valCustomWithField === 2);
- assert(foo._varCustom === 1);
- foo._varCustom = 20;
- assert(foo._varCustom === 1);
- assert(foo._varCustomWithField === 10);
- foo._varCustomWithField = 10;
- assert(foo._varCustomWithField === 1000);
- new A();
- assert(new A1(10).x === 10);
- assert(new A2("10", true).x === "10");
- assert(new A3().x === 100);
- var a4 = new A4();
- assert(a4._valCustom === 1);
- assert(a4._valCustomWithField === 2);
- assert(a4._varCustom === 1);
- a4._varCustom = 20;
- assert(a4._varCustom === 1);
- assert(a4._varCustomWithField === 10);
- a4._varCustomWithField = 10;
- assert(a4._varCustomWithField === 1000);
- assert(O.x === 10);
- assert(O.foo() === 20);
- assert(takesO(O) === 30);
- assert(KT_37829.Companion.x == 10);
- assert(new TestSealed.AA().name == "AA");
- assert(new TestSealed.AA().bar() == "bar");
- assert(new TestSealed.BB().name == "BB");
- assert(new TestSealed.BB().baz() == "baz");
- assert(new TestAbstract.AA().name == "AA");
- assert(new TestAbstract.AA().bar() == "bar");
- assert(new TestAbstract.BB().name == "BB");
- assert(new TestAbstract.BB().baz() == "baz");
- assert(new TestDataClass.Nested().prop == "hello");
- assert(TestEnumClass.A.foo == 0);
- assert(TestEnumClass.B.foo == 1);
- assert(TestEnumClass.A.bar("aBar") == "aBar");
- assert(TestEnumClass.B.bar("bBar") == "bBar");
- assert(TestEnumClass.A.bay() == "A");
- assert(TestEnumClass.B.bay() == "B");
- assert(TestEnumClass.A.constructorParameter == "aConstructorParameter");
- assert(TestEnumClass.B.constructorParameter == "bConstructorParameter");
- assert(TestEnumClass.valueOf("A") === TestEnumClass.A);
- assert(TestEnumClass.valueOf("B") === TestEnumClass.B);
- assert(TestEnumClass.values().indexOf(TestEnumClass.A) != -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(processInterface(new TestInterfaceImpl("bar")) == "Owner TestInterfaceImpl has value 'bar'");
- // @ts-expect-error "Just test that this code will throw compilation error for a user"
- assert(processInterface({ value: "bar", getOwnerName: function () { return "RandomObject"; } }) == "Owner RandomObject has value 'bar'");
- assert(OuterClass.NestedEnum.valueOf("A") === OuterClass.NestedEnum.A);
- assert(OuterClass.NestedEnum.valueOf("B") === OuterClass.NestedEnum.B);
- assert(OuterClass.NestedEnum.values().indexOf(OuterClass.NestedEnum.A) != -1);
- assert(OuterClass.NestedEnum.values().indexOf(OuterClass.NestedEnum.B) != -1);
- assert(OuterClass.NestedEnum.A.name === "A");
- assert(OuterClass.NestedEnum.B.name === "B");
- assert(OuterClass.NestedEnum.A.ordinal === 0);
- assert(OuterClass.NestedEnum.B.ordinal === 1);
- assert(new KT38262().then() == 42);
- assert(new KT38262().catch() == 24);
- var jsNameTest = JsNameTest.Companion.create();
- assert(jsNameTest.value === 4);
- assert(jsNameTest.runTest() === "JsNameTest");
- var jsNameNestedTest = JsNameTest.Companion.createChild(42);
- assert(jsNameNestedTest.value === 42);
- // Do not strip types from those test cases (it is a check of nested objects types usability)
- var parent = Parent;
- var nested1 = Parent.Nested1;
- var nested2 = new Parent.Nested1.Nested2();
- var nested3 = new Parent.Nested1.Nested2.Companion.Nested3();
- assert(nested1.value === "Nested1");
- assert(getParent() === parent);
- assert(createNested1() === nested1);
- assert(createNested2() !== nested2);
- assert(createNested3() !== nested3);
- var genericClassInstance = new GenericClassWithConstraint(new TestInterfaceImpl("test"));
- assert(processInterface(genericClassInstance.test) == "Owner TestInterfaceImpl has value 'test'");
- return "OK";
-}
diff --git a/js/js.translator/testData/typescript-export/declarations/declarations__main.ts b/js/js.translator/testData/typescript-export/declarations/declarations__main.ts
deleted file mode 100644
index 3d60116db47..00000000000
--- a/js/js.translator/testData/typescript-export/declarations/declarations__main.ts
+++ /dev/null
@@ -1,191 +0,0 @@
-
-import foo = JS_TESTS.foo;
-import varargInt = JS_TESTS.foo.varargInt;
-import varargNullableInt = JS_TESTS.foo.varargNullableInt;
-import varargWithOtherParameters = JS_TESTS.foo.varargWithOtherParameters;
-import varargWithComplexType = JS_TESTS.foo.varargWithComplexType;
-import sumNullable = JS_TESTS.foo.sumNullable;
-import defaultParameters = JS_TESTS.foo.defaultParameters;
-import generic1 = JS_TESTS.foo.generic1;
-import generic2 = JS_TESTS.foo.generic2;
-import generic3 = JS_TESTS.foo.generic3;
-import inlineFun = JS_TESTS.foo.inlineFun;
-import _const_val = JS_TESTS.foo._const_val;
-import _val = JS_TESTS.foo._val;
-import _var = JS_TESTS.foo._var;
-import A = JS_TESTS.foo.A;
-import A1 = JS_TESTS.foo.A1;
-import A2 = JS_TESTS.foo.A2;
-import A3 = JS_TESTS.foo.A3;
-import _valCustom = JS_TESTS.foo._valCustom;
-import _valCustomWithField = JS_TESTS.foo._valCustomWithField;
-import A4 = JS_TESTS.foo.A4;
-import O = JS_TESTS.foo.O;
-import takesO = JS_TESTS.foo.takesO;
-import KT_37829 = JS_TESTS.foo.KT_37829;
-import TestSealed = JS_TESTS.foo.TestSealed;
-import TestAbstract = JS_TESTS.foo.TestAbstract;
-import TestDataClass = JS_TESTS.foo.TestDataClass;
-import TestEnumClass = JS_TESTS.foo.TestEnumClass;
-import TestInterfaceImpl = JS_TESTS.foo.TestInterfaceImpl;
-import processInterface = JS_TESTS.foo.processInterface;
-import OuterClass = JS_TESTS.foo.OuterClass;
-import KT38262 = JS_TESTS.foo.KT38262;
-import JsNameTest = JS_TESTS.foo.JsNameTest;
-import Parent = JS_TESTS.foo.Parent;
-import getParent = JS_TESTS.foo.getParent;
-import createNested1 = JS_TESTS.foo.createNested1;
-import createNested2 = JS_TESTS.foo.createNested2;
-import createNested3 = JS_TESTS.foo.createNested3;
-import GenericClassWithConstraint = JS_TESTS.foo.GenericClassWithConstraint;
-
-function assert(condition: boolean) {
- if (!condition) {
- throw "Assertion failed";
- }
-}
-
-function box(): string {
- assert(foo.sum(10, 20) === 30);
- assert(varargInt(new Int32Array([1, 2, 3])) === 3);
- assert(varargNullableInt([10, 20, 30, null, undefined, 40]) === 6);
- assert(varargWithOtherParameters("1234", ["1", "2", "3"], "12") === 9);
- assert(varargWithComplexType([]) === 0);
- assert(varargWithComplexType([
- x => x,
- x => [new Int32Array([1, 2, 3])],
- x => [],
- ]) === 3);
-
- assert(sumNullable(10, null) === 10);
- assert(sumNullable(undefined, 20) === 20);
- assert(sumNullable(1, 2) === 3);
- assert(defaultParameters("", 20, "OK") === "20OK");
- assert(generic1("FOO") === "FOO");
- assert(generic1({x: 10}).x === 10);
- assert(generic2(null) === true);
- assert(generic2(undefined) === true);
- assert(generic2(10) === false);
- assert(generic3(10, true, "__", {}) === null);
-
- let result: number = 0;
- inlineFun(10, x => { result = x; });
- assert(result === 10);
-
- assert(_const_val === 1);
- assert(_val === 1);
- assert(_var === 1);
- foo._var = 1000;
- assert(foo._var === 1000);
-
- assert(foo._valCustom === 1);
- assert(foo._valCustomWithField === 2);
- assert(foo._varCustom === 1);
- foo._varCustom = 20;
- assert(foo._varCustom === 1);
- assert(foo._varCustomWithField === 10);
- foo._varCustomWithField = 10;
- assert(foo._varCustomWithField === 1000);
-
- new A();
- assert(new A1(10).x === 10);
- assert(new A2("10", true).x === "10");
- assert(new A3().x === 100);
-
-
- const a4 = new A4();
-
- assert(a4._valCustom === 1);
- assert(a4._valCustomWithField === 2);
- assert(a4._varCustom === 1);
- a4._varCustom = 20;
- assert(a4._varCustom === 1);
- assert(a4._varCustomWithField === 10);
- a4._varCustomWithField = 10;
- assert(a4._varCustomWithField === 1000);
-
- assert(O.x === 10);
- assert(O.foo() === 20);
- assert(takesO(O) === 30);
-
- assert(KT_37829.Companion.x == 10);
-
- assert(new TestSealed.AA().name == "AA");
- assert(new TestSealed.AA().bar() == "bar");
- assert(new TestSealed.BB().name == "BB");
- assert(new TestSealed.BB().baz() == "baz");
-
- assert(new TestAbstract.AA().name == "AA");
- assert(new TestAbstract.AA().bar() == "bar");
- assert(new TestAbstract.BB().name == "BB");
- assert(new TestAbstract.BB().baz() == "baz");
-
- assert(new TestDataClass.Nested().prop == "hello");
-
- assert(TestEnumClass.A.foo == 0)
- assert(TestEnumClass.B.foo == 1)
- assert(TestEnumClass.A.bar("aBar") == "aBar")
- assert(TestEnumClass.B.bar("bBar") == "bBar")
- assert(TestEnumClass.A.bay() == "A")
- assert(TestEnumClass.B.bay() == "B")
- assert(TestEnumClass.A.constructorParameter == "aConstructorParameter")
- assert(TestEnumClass.B.constructorParameter == "bConstructorParameter")
-
- assert(TestEnumClass.valueOf("A") === TestEnumClass.A)
- assert(TestEnumClass.valueOf("B") === TestEnumClass.B)
-
- assert(TestEnumClass.values().indexOf(TestEnumClass.A) != -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(processInterface(new TestInterfaceImpl("bar")) == "Owner TestInterfaceImpl has value 'bar'")
-
- // @ts-expect-error "Just test that this code will throw compilation error for a user"
- assert(processInterface({ value: "bar", getOwnerName: () => "RandomObject" }) == "Owner RandomObject has value 'bar'")
-
- assert(OuterClass.NestedEnum.valueOf("A") === OuterClass.NestedEnum.A)
- assert(OuterClass.NestedEnum.valueOf("B") === OuterClass.NestedEnum.B)
-
- assert(OuterClass.NestedEnum.values().indexOf(OuterClass.NestedEnum.A) != -1)
- assert(OuterClass.NestedEnum.values().indexOf(OuterClass.NestedEnum.B) != -1)
-
- assert(OuterClass.NestedEnum.A.name === "A")
- assert(OuterClass.NestedEnum.B.name === "B")
- assert(OuterClass.NestedEnum.A.ordinal === 0)
- assert(OuterClass.NestedEnum.B.ordinal === 1)
-
- assert(new KT38262().then() == 42)
- assert(new KT38262().catch() == 24)
-
- const jsNameTest = JsNameTest.Companion.create();
-
- assert(jsNameTest.value === 4)
- assert(jsNameTest.runTest() === "JsNameTest")
-
- const jsNameNestedTest = JsNameTest.Companion.createChild(42);
-
- assert(jsNameNestedTest.value === 42)
-
- // Do not strip types from those test cases (it is a check of nested objects types usability)
- const parent: typeof Parent = Parent
- const nested1: typeof Parent.Nested1 = Parent.Nested1
- const nested2: Parent.Nested1.Nested2 = new Parent.Nested1.Nested2()
- const nested3: Parent.Nested1.Nested2.Companion.Nested3 = new Parent.Nested1.Nested2.Companion.Nested3()
-
- assert(nested1.value === "Nested1")
- assert(getParent() === parent)
- assert(createNested1() === nested1)
- assert(createNested2() !== nested2)
- assert(createNested3() !== nested3)
-
- const genericClassInstance = new GenericClassWithConstraint(new TestInterfaceImpl("test"))
- assert(processInterface(genericClassInstance.test) == "Owner TestInterfaceImpl has value 'test'")
-
- return "OK";
-}
\ No newline at end of file
diff --git a/js/js.translator/testData/typescript-export/enum-classes/enum-classes.d.ts b/js/js.translator/testData/typescript-export/enum-classes/enum-classes.d.ts
new file mode 100644
index 00000000000..b5bb99419d0
--- /dev/null
+++ b/js/js.translator/testData/typescript-export/enum-classes/enum-classes.d.ts
@@ -0,0 +1,50 @@
+declare namespace JS_TESTS {
+ type Nullable = T | null | undefined
+ namespace foo {
+ abstract class TestEnumClass {
+ private constructor();
+ get constructorParameter(): string;
+ static get A(): foo.TestEnumClass & {
+ get name(): "A";
+ get ordinal(): 0;
+ };
+ static get B(): foo.TestEnumClass & {
+ get name(): "B";
+ get ordinal(): 1;
+ };
+ get foo(): number;
+ bar(value: string): string;
+ bay(): string;
+ static values(): Array;
+ static valueOf(value: string): foo.TestEnumClass;
+ get name(): "A" | "B";
+ get ordinal(): 0 | 1;
+ }
+ namespace TestEnumClass {
+ class Nested {
+ constructor();
+ get prop(): string;
+ }
+ }
+ class OuterClass {
+ constructor();
+ }
+ namespace OuterClass {
+ abstract class NestedEnum {
+ private constructor();
+ static get A(): foo.OuterClass.NestedEnum & {
+ get name(): "A";
+ get ordinal(): 0;
+ };
+ static get B(): foo.OuterClass.NestedEnum & {
+ get name(): "B";
+ get ordinal(): 1;
+ };
+ static values(): Array;
+ static valueOf(value: string): foo.OuterClass.NestedEnum;
+ get name(): "A" | "B";
+ get ordinal(): 0 | 1;
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/js/js.translator/testData/typescript-export/enum-classes/enum-classes.kt b/js/js.translator/testData/typescript-export/enum-classes/enum-classes.kt
new file mode 100644
index 00000000000..6a9a69d91df
--- /dev/null
+++ b/js/js.translator/testData/typescript-export/enum-classes/enum-classes.kt
@@ -0,0 +1,34 @@
+// CHECK_TYPESCRIPT_DECLARATIONS
+// RUN_PLAIN_BOX_FUNCTION
+// SKIP_MINIFICATION
+// SKIP_NODE_JS
+// INFER_MAIN_MODULE
+// MODULE: JS_TESTS
+// FILE: enum-classes.kt
+
+package foo
+
+@JsExport
+enum class TestEnumClass(val constructorParameter: String) {
+ A("aConstructorParameter"),
+ B("bConstructorParameter");
+
+ val foo = ordinal
+
+ fun bar(value: String) = value
+
+ fun bay() = name
+
+ class Nested {
+ val prop: String = "hello2"
+ }
+}
+
+@JsExport
+class OuterClass {
+ enum class NestedEnum {
+ A,
+ B
+ }
+}
+
diff --git a/js/js.translator/testData/typescript-export/enum-classes/enum-classes__main.js b/js/js.translator/testData/typescript-export/enum-classes/enum-classes__main.js
new file mode 100644
index 00000000000..a7e4d36f0c7
--- /dev/null
+++ b/js/js.translator/testData/typescript-export/enum-classes/enum-classes__main.js
@@ -0,0 +1,36 @@
+"use strict";
+var TestEnumClass = JS_TESTS.foo.TestEnumClass;
+var OuterClass = JS_TESTS.foo.OuterClass;
+function assert(condition) {
+ if (!condition) {
+ throw "Assertion failed";
+ }
+}
+function box() {
+ assert(TestEnumClass.A.foo == 0);
+ assert(TestEnumClass.B.foo == 1);
+ assert(TestEnumClass.A.bar("aBar") == "aBar");
+ assert(TestEnumClass.B.bar("bBar") == "bBar");
+ assert(TestEnumClass.A.bay() == "A");
+ assert(TestEnumClass.B.bay() == "B");
+ assert(TestEnumClass.A.constructorParameter == "aConstructorParameter");
+ assert(TestEnumClass.B.constructorParameter == "bConstructorParameter");
+ assert(TestEnumClass.valueOf("A") === TestEnumClass.A);
+ assert(TestEnumClass.valueOf("B") === TestEnumClass.B);
+ assert(TestEnumClass.values().indexOf(TestEnumClass.A) != -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(OuterClass.NestedEnum.valueOf("A") === OuterClass.NestedEnum.A);
+ assert(OuterClass.NestedEnum.valueOf("B") === OuterClass.NestedEnum.B);
+ assert(OuterClass.NestedEnum.values().indexOf(OuterClass.NestedEnum.A) != -1);
+ assert(OuterClass.NestedEnum.values().indexOf(OuterClass.NestedEnum.B) != -1);
+ assert(OuterClass.NestedEnum.A.name === "A");
+ assert(OuterClass.NestedEnum.B.name === "B");
+ assert(OuterClass.NestedEnum.A.ordinal === 0);
+ assert(OuterClass.NestedEnum.B.ordinal === 1);
+ return "OK";
+}
diff --git a/js/js.translator/testData/typescript-export/enum-classes/enum-classes__main.ts b/js/js.translator/testData/typescript-export/enum-classes/enum-classes__main.ts
new file mode 100644
index 00000000000..7031fba5c9f
--- /dev/null
+++ b/js/js.translator/testData/typescript-export/enum-classes/enum-classes__main.ts
@@ -0,0 +1,45 @@
+import TestEnumClass = JS_TESTS.foo.TestEnumClass;
+import OuterClass = JS_TESTS.foo.OuterClass;
+
+function assert(condition: boolean) {
+ if (!condition) {
+ throw "Assertion failed";
+ }
+}
+
+function box(): string {
+ assert(TestEnumClass.A.foo == 0)
+ assert(TestEnumClass.B.foo == 1)
+ assert(TestEnumClass.A.bar("aBar") == "aBar")
+ assert(TestEnumClass.B.bar("bBar") == "bBar")
+ assert(TestEnumClass.A.bay() == "A")
+ assert(TestEnumClass.B.bay() == "B")
+ assert(TestEnumClass.A.constructorParameter == "aConstructorParameter")
+ assert(TestEnumClass.B.constructorParameter == "bConstructorParameter")
+
+ assert(TestEnumClass.valueOf("A") === TestEnumClass.A)
+ assert(TestEnumClass.valueOf("B") === TestEnumClass.B)
+
+ assert(TestEnumClass.values().indexOf(TestEnumClass.A) != -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(OuterClass.NestedEnum.valueOf("A") === OuterClass.NestedEnum.A)
+ assert(OuterClass.NestedEnum.valueOf("B") === OuterClass.NestedEnum.B)
+
+ assert(OuterClass.NestedEnum.values().indexOf(OuterClass.NestedEnum.A) != -1)
+ assert(OuterClass.NestedEnum.values().indexOf(OuterClass.NestedEnum.B) != -1)
+
+ assert(OuterClass.NestedEnum.A.name === "A")
+ assert(OuterClass.NestedEnum.B.name === "B")
+ assert(OuterClass.NestedEnum.A.ordinal === 0)
+ assert(OuterClass.NestedEnum.B.ordinal === 1)
+
+ return "OK";
+}
\ No newline at end of file
diff --git a/js/js.translator/testData/typescript-export/escapedDeclarations/tsconfig.json b/js/js.translator/testData/typescript-export/enum-classes/tsconfig.json
similarity index 100%
rename from js/js.translator/testData/typescript-export/escapedDeclarations/tsconfig.json
rename to js/js.translator/testData/typescript-export/enum-classes/tsconfig.json
diff --git a/js/js.translator/testData/typescript-export/escapedDeclarations/escapedDeclarations.d.ts b/js/js.translator/testData/typescript-export/escaped-declarations/escaped-declarations.d.ts
similarity index 100%
rename from js/js.translator/testData/typescript-export/escapedDeclarations/escapedDeclarations.d.ts
rename to js/js.translator/testData/typescript-export/escaped-declarations/escaped-declarations.d.ts
diff --git a/js/js.translator/testData/typescript-export/escapedDeclarations/escapedDeclarations.kt b/js/js.translator/testData/typescript-export/escaped-declarations/escaped-declarations.kt
similarity index 96%
rename from js/js.translator/testData/typescript-export/escapedDeclarations/escapedDeclarations.kt
rename to js/js.translator/testData/typescript-export/escaped-declarations/escaped-declarations.kt
index c18754dcc92..6b30617f2c4 100644
--- a/js/js.translator/testData/typescript-export/escapedDeclarations/escapedDeclarations.kt
+++ b/js/js.translator/testData/typescript-export/escaped-declarations/escaped-declarations.kt
@@ -6,7 +6,7 @@
// !LANGUAGE: +JsAllowInvalidCharsIdentifiersEscaping
// INFER_MAIN_MODULE
// MODULE: JS_TESTS
-// FILE: escapedDeclarations.kt
+// FILE: escaped-interfaces.kt
@file:JsExport
diff --git a/js/js.translator/testData/typescript-export/escapedDeclarations/escapedDeclarations__main.js b/js/js.translator/testData/typescript-export/escaped-declarations/escaped-declarations__main.js
similarity index 100%
rename from js/js.translator/testData/typescript-export/escapedDeclarations/escapedDeclarations__main.js
rename to js/js.translator/testData/typescript-export/escaped-declarations/escaped-declarations__main.js
diff --git a/js/js.translator/testData/typescript-export/escapedDeclarations/escapedDeclarations__main.ts b/js/js.translator/testData/typescript-export/escaped-declarations/escaped-declarations__main.ts
similarity index 100%
rename from js/js.translator/testData/typescript-export/escapedDeclarations/escapedDeclarations__main.ts
rename to js/js.translator/testData/typescript-export/escaped-declarations/escaped-declarations__main.ts
diff --git a/js/js.translator/testData/typescript-export/implicitExport/tsconfig.json b/js/js.translator/testData/typescript-export/escaped-declarations/tsconfig.json
similarity index 100%
rename from js/js.translator/testData/typescript-export/implicitExport/tsconfig.json
rename to js/js.translator/testData/typescript-export/escaped-declarations/tsconfig.json
diff --git a/js/js.translator/testData/typescript-export/functions/functions.d.ts b/js/js.translator/testData/typescript-export/functions/functions.d.ts
new file mode 100644
index 00000000000..86d3764e475
--- /dev/null
+++ b/js/js.translator/testData/typescript-export/functions/functions.d.ts
@@ -0,0 +1,18 @@
+declare namespace JS_TESTS {
+ type Nullable = T | null | undefined
+ namespace foo {
+ function sum(x: number, y: number): number;
+ function varargInt(x: Int32Array): number;
+ function varargNullableInt(x: Array>): number;
+ function varargWithOtherParameters(x: string, y: Array, z: string): number;
+ function varargWithComplexType(x: Array<(p0: Array) => Array>): number;
+ function sumNullable(x: Nullable, y: Nullable): number;
+ function defaultParameters(a: string, x?: number, y?: string): string;
+ function generic1(x: T): T;
+ function generic2(x: Nullable): boolean;
+ function genericWithConstraint(x: T): T;
+ function genericWithMultipleConstraints(x: T): T;
+ function generic3(a: A, b: B, c: C, d: D): Nullable;
+ function inlineFun(x: number, callback: (p0: number) => void): void;
+ }
+}
\ No newline at end of file
diff --git a/js/js.translator/testData/typescript-export/functions/functions.kt b/js/js.translator/testData/typescript-export/functions/functions.kt
new file mode 100644
index 00000000000..4cdf003b009
--- /dev/null
+++ b/js/js.translator/testData/typescript-export/functions/functions.kt
@@ -0,0 +1,62 @@
+// CHECK_TYPESCRIPT_DECLARATIONS
+// RUN_PLAIN_BOX_FUNCTION
+// SKIP_MINIFICATION
+// SKIP_NODE_JS
+// INFER_MAIN_MODULE
+// MODULE: JS_TESTS
+// FILE: functions.kt
+
+package foo
+
+external interface RegExpMatchArray
+
+@JsExport
+fun sum(x: Int, y: Int): Int =
+ x + y
+
+@JsExport
+fun varargInt(vararg x: Int): Int =
+ x.size
+
+@JsExport
+fun varargNullableInt(vararg x: Int?): Int =
+ x.size
+
+@JsExport
+fun varargWithOtherParameters(x: String, vararg y: String, z: String): Int =
+ x.length + y.size + z.length
+
+@JsExport
+fun varargWithComplexType(vararg x: (Array) -> Array): Int =
+ x.size
+
+@JsExport
+fun sumNullable(x: Int?, y: Int?): Int =
+ (x ?: 0) + (y ?: 0)
+
+@JsExport
+fun defaultParameters(a: String, x: Int = 10, y: String = "OK"): String =
+ a + x.toString() + y
+
+@JsExport
+fun generic1(x: T): T = x
+
+@JsExport
+fun generic2(x: T?): Boolean = (x == null)
+
+@JsExport
+fun genericWithConstraint(x: T): T = x
+
+@JsExport
+fun genericWithMultipleConstraints(x: T): T
+ where T : Comparable,
+ T : RegExpMatchArray,
+ T : Throwable = x
+
+@JsExport
+fun generic3(a: A, b: B, c: C, d: D): E? = null
+
+@JsExport
+inline fun inlineFun(x: Int, callback: (Int) -> Unit) {
+ callback(x)
+}
\ No newline at end of file
diff --git a/js/js.translator/testData/typescript-export/functions/functions__main.js b/js/js.translator/testData/typescript-export/functions/functions__main.js
new file mode 100644
index 00000000000..a26cd950666
--- /dev/null
+++ b/js/js.translator/testData/typescript-export/functions/functions__main.js
@@ -0,0 +1,59 @@
+"use strict";
+var __assign = (this && this.__assign) || function () {
+ __assign = Object.assign || function(t) {
+ for (var s, i = 1, n = arguments.length; i < n; i++) {
+ s = arguments[i];
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
+ t[p] = s[p];
+ }
+ return t;
+ };
+ return __assign.apply(this, arguments);
+};
+var sum = JS_TESTS.foo.sum;
+var generic1 = JS_TESTS.foo.generic1;
+var generic2 = JS_TESTS.foo.generic2;
+var generic3 = JS_TESTS.foo.generic3;
+var inlineFun = JS_TESTS.foo.inlineFun;
+var varargInt = JS_TESTS.foo.varargInt;
+var sumNullable = JS_TESTS.foo.sumNullable;
+var defaultParameters = JS_TESTS.foo.defaultParameters;
+var varargNullableInt = JS_TESTS.foo.varargNullableInt;
+var varargWithOtherParameters = JS_TESTS.foo.varargWithOtherParameters;
+var varargWithComplexType = JS_TESTS.foo.varargWithComplexType;
+var genericWithConstraint = JS_TESTS.foo.genericWithConstraint;
+var genericWithMultipleConstraints = JS_TESTS.foo.genericWithMultipleConstraints;
+function assert(condition) {
+ if (!condition) {
+ throw "Assertion failed";
+ }
+}
+function box() {
+ assert(sum(10, 20) === 30);
+ assert(varargInt(new Int32Array([1, 2, 3])) === 3);
+ assert(varargNullableInt([10, 20, 30, null, undefined, 40]) === 6);
+ assert(varargWithOtherParameters("1234", ["1", "2", "3"], "12") === 9);
+ assert(varargWithComplexType([]) === 0);
+ assert(varargWithComplexType([
+ function (x) { return x; },
+ function () { return [new Int32Array([1, 2, 3])]; },
+ function () { return []; },
+ ]) === 3);
+ assert(sumNullable(10, null) === 10);
+ assert(sumNullable(undefined, 20) === 20);
+ assert(sumNullable(1, 2) === 3);
+ assert(defaultParameters("", 20, "OK") === "20OK");
+ assert(generic1("FOO") === "FOO");
+ assert(generic1({ x: 10 }).x === 10);
+ assert(generic2(null));
+ assert(generic2(undefined));
+ assert(!generic2(10));
+ assert(generic3(10, true, "__", {}) === null);
+ assert(genericWithConstraint("Test") === "Test");
+ var regExpMatchError = __assign(__assign({}, new Error("Test")), "test test".match(/tes/g));
+ assert(genericWithMultipleConstraints(regExpMatchError) === regExpMatchError);
+ var result = 0;
+ inlineFun(10, function (x) { result = x; });
+ assert(result === 10);
+ return "OK";
+}
diff --git a/js/js.translator/testData/typescript-export/functions/functions__main.ts b/js/js.translator/testData/typescript-export/functions/functions__main.ts
new file mode 100644
index 00000000000..ebaef885299
--- /dev/null
+++ b/js/js.translator/testData/typescript-export/functions/functions__main.ts
@@ -0,0 +1,58 @@
+import sum = JS_TESTS.foo.sum;
+import generic1 = JS_TESTS.foo.generic1;
+import generic2 = JS_TESTS.foo.generic2;
+import generic3 = JS_TESTS.foo.generic3;
+import inlineFun = JS_TESTS.foo.inlineFun;
+import varargInt = JS_TESTS.foo.varargInt;
+import sumNullable = JS_TESTS.foo.sumNullable;
+import defaultParameters = JS_TESTS.foo.defaultParameters;
+import varargNullableInt = JS_TESTS.foo.varargNullableInt;
+import varargWithOtherParameters = JS_TESTS.foo.varargWithOtherParameters;
+import varargWithComplexType = JS_TESTS.foo.varargWithComplexType;
+import genericWithConstraint = JS_TESTS.foo.genericWithConstraint;
+import genericWithMultipleConstraints = JS_TESTS.foo.genericWithMultipleConstraints;
+
+function assert(condition: boolean) {
+ if (!condition) {
+ throw "Assertion failed";
+ }
+}
+
+function box(): string {
+ assert(sum(10, 20) === 30);
+
+ assert(varargInt(new Int32Array([1, 2, 3])) === 3);
+ assert(varargNullableInt([10, 20, 30, null, undefined, 40]) === 6);
+ assert(varargWithOtherParameters("1234", ["1", "2", "3"], "12") === 9);
+ assert(varargWithComplexType([]) === 0);
+ assert(varargWithComplexType([
+ x => x,
+ () => [new Int32Array([1, 2, 3])],
+ () => [],
+ ]) === 3);
+
+ assert(sumNullable(10, null) === 10);
+ assert(sumNullable(undefined, 20) === 20);
+ assert(sumNullable(1, 2) === 3);
+
+ assert(defaultParameters("", 20, "OK") === "20OK");
+
+ assert(generic1("FOO") === "FOO");
+ assert(generic1({x: 10}).x === 10);
+ assert(generic2(null));
+ assert(generic2(undefined));
+ assert(!generic2(10));
+ assert(generic3(10, true, "__", {}) === null);
+
+ assert(genericWithConstraint("Test") === "Test")
+
+ const regExpMatchError: any = { ...new Error("Test"), ..."test test".match(/tes/g) }
+ assert(genericWithMultipleConstraints(regExpMatchError) === regExpMatchError)
+
+
+ let result: number = 0;
+ inlineFun(10, x => { result = x; });
+ assert(result === 10);
+
+ return "OK";
+}
diff --git a/js/js.translator/testData/typescript-export/selectiveExport/tsconfig.json b/js/js.translator/testData/typescript-export/functions/tsconfig.json
similarity index 100%
rename from js/js.translator/testData/typescript-export/selectiveExport/tsconfig.json
rename to js/js.translator/testData/typescript-export/functions/tsconfig.json
diff --git a/js/js.translator/testData/typescript-export/implicitExport/declarations.d.ts b/js/js.translator/testData/typescript-export/implicit-export/implicit-export.d.ts
similarity index 100%
rename from js/js.translator/testData/typescript-export/implicitExport/declarations.d.ts
rename to js/js.translator/testData/typescript-export/implicit-export/implicit-export.d.ts
diff --git a/js/js.translator/testData/typescript-export/implicitExport/declarations.kt b/js/js.translator/testData/typescript-export/implicit-export/implicit-export.kt
similarity index 98%
rename from js/js.translator/testData/typescript-export/implicitExport/declarations.kt
rename to js/js.translator/testData/typescript-export/implicit-export/implicit-export.kt
index f13241efd43..00306ac23fe 100644
--- a/js/js.translator/testData/typescript-export/implicitExport/declarations.kt
+++ b/js/js.translator/testData/typescript-export/implicit-export/implicit-export.kt
@@ -16,7 +16,7 @@ package notQualified
external interface Console
-// FILE: declarations.kt
+// FILE: member-properties.kt
package foo
diff --git a/js/js.translator/testData/typescript-export/implicitExport/declarations__main.js b/js/js.translator/testData/typescript-export/implicit-export/implicit-export__main.js
similarity index 100%
rename from js/js.translator/testData/typescript-export/implicitExport/declarations__main.js
rename to js/js.translator/testData/typescript-export/implicit-export/implicit-export__main.js
diff --git a/js/js.translator/testData/typescript-export/implicitExport/declarations__main.ts b/js/js.translator/testData/typescript-export/implicit-export/implicit-export__main.ts
similarity index 100%
rename from js/js.translator/testData/typescript-export/implicitExport/declarations__main.ts
rename to js/js.translator/testData/typescript-export/implicit-export/implicit-export__main.ts
diff --git a/js/js.translator/testData/typescript-export/implicit-export/tsconfig.json b/js/js.translator/testData/typescript-export/implicit-export/tsconfig.json
new file mode 100644
index 00000000000..17612c56c9d
--- /dev/null
+++ b/js/js.translator/testData/typescript-export/implicit-export/tsconfig.json
@@ -0,0 +1,4 @@
+{
+ "include": [ "./*" ],
+ "extends": "../common.tsconfig.json"
+}
\ No newline at end of file
diff --git a/js/js.translator/testData/typescript-export/classes/inner-class.d.ts b/js/js.translator/testData/typescript-export/inner-classes/inner-class.d.ts
similarity index 100%
rename from js/js.translator/testData/typescript-export/classes/inner-class.d.ts
rename to js/js.translator/testData/typescript-export/inner-classes/inner-class.d.ts
diff --git a/js/js.translator/testData/typescript-export/classes/inner-class.kt b/js/js.translator/testData/typescript-export/inner-classes/inner-class.kt
similarity index 100%
rename from js/js.translator/testData/typescript-export/classes/inner-class.kt
rename to js/js.translator/testData/typescript-export/inner-classes/inner-class.kt
diff --git a/js/js.translator/testData/typescript-export/classes/inner-class__main.js b/js/js.translator/testData/typescript-export/inner-classes/inner-class__main.js
similarity index 100%
rename from js/js.translator/testData/typescript-export/classes/inner-class__main.js
rename to js/js.translator/testData/typescript-export/inner-classes/inner-class__main.js
diff --git a/js/js.translator/testData/typescript-export/classes/inner-class__main.ts b/js/js.translator/testData/typescript-export/inner-classes/inner-class__main.ts
similarity index 100%
rename from js/js.translator/testData/typescript-export/classes/inner-class__main.ts
rename to js/js.translator/testData/typescript-export/inner-classes/inner-class__main.ts
diff --git a/js/js.translator/testData/typescript-export/inner-classes/tsconfig.json b/js/js.translator/testData/typescript-export/inner-classes/tsconfig.json
new file mode 100644
index 00000000000..17612c56c9d
--- /dev/null
+++ b/js/js.translator/testData/typescript-export/inner-classes/tsconfig.json
@@ -0,0 +1,4 @@
+{
+ "include": [ "./*" ],
+ "extends": "../common.tsconfig.json"
+}
\ No newline at end of file
diff --git a/js/js.translator/testData/typescript-export/interfaces/interfaces.d.ts b/js/js.translator/testData/typescript-export/interfaces/interfaces.d.ts
new file mode 100644
index 00000000000..06fd2f146aa
--- /dev/null
+++ b/js/js.translator/testData/typescript-export/interfaces/interfaces.d.ts
@@ -0,0 +1,28 @@
+declare namespace JS_TESTS {
+ type Nullable = T | null | undefined
+ namespace foo {
+ interface TestInterface {
+ readonly value: string;
+ getOwnerName(): string;
+ readonly __doNotUseOrImplementIt: {
+ readonly "foo.TestInterface": unique symbol;
+ };
+ }
+ interface AnotherExportedInterface {
+ readonly __doNotUseOrImplementIt: {
+ readonly "foo.AnotherExportedInterface": unique symbol;
+ };
+ }
+ class TestInterfaceImpl implements foo.TestInterface {
+ constructor(value: string);
+ get value(): string;
+ getOwnerName(): string;
+ readonly __doNotUseOrImplementIt: foo.TestInterface["__doNotUseOrImplementIt"];
+ }
+ class ChildTestInterfaceImpl extends foo.TestInterfaceImpl implements foo.AnotherExportedInterface {
+ constructor();
+ readonly __doNotUseOrImplementIt: foo.TestInterfaceImpl["__doNotUseOrImplementIt"] & foo.AnotherExportedInterface["__doNotUseOrImplementIt"];
+ }
+ function processInterface(test: foo.TestInterface): string;
+ }
+}
\ No newline at end of file
diff --git a/js/js.translator/testData/typescript-export/interfaces/interfaces.kt b/js/js.translator/testData/typescript-export/interfaces/interfaces.kt
new file mode 100644
index 00000000000..c334ef8a706
--- /dev/null
+++ b/js/js.translator/testData/typescript-export/interfaces/interfaces.kt
@@ -0,0 +1,33 @@
+// CHECK_TYPESCRIPT_DECLARATIONS
+// RUN_PLAIN_BOX_FUNCTION
+// SKIP_MINIFICATION
+// SKIP_NODE_JS
+// INFER_MAIN_MODULE
+// MODULE: JS_TESTS
+// FILE: interfaces.kt
+
+package foo
+
+// Classes
+
+@JsExport
+interface TestInterface {
+ val value: String
+ fun getOwnerName(): String
+}
+
+@JsExport
+interface AnotherExportedInterface
+
+@JsExport
+open class TestInterfaceImpl(override val value: String) : TestInterface {
+ override fun getOwnerName() = "TestInterfaceImpl"
+}
+
+@JsExport
+class ChildTestInterfaceImpl(): TestInterfaceImpl("Test"), AnotherExportedInterface
+
+@JsExport
+fun processInterface(test: TestInterface): String {
+ return "Owner ${test.getOwnerName()} has value '${test.value}'"
+}
\ No newline at end of file
diff --git a/js/js.translator/testData/typescript-export/interfaces/interfaces__main.js b/js/js.translator/testData/typescript-export/interfaces/interfaces__main.js
new file mode 100644
index 00000000000..f3aba8a8c27
--- /dev/null
+++ b/js/js.translator/testData/typescript-export/interfaces/interfaces__main.js
@@ -0,0 +1,16 @@
+"use strict";
+var TestInterfaceImpl = JS_TESTS.foo.TestInterfaceImpl;
+var ChildTestInterfaceImpl = JS_TESTS.foo.ChildTestInterfaceImpl;
+var processInterface = JS_TESTS.foo.processInterface;
+function assert(condition) {
+ if (!condition) {
+ throw "Assertion failed";
+ }
+}
+function box() {
+ assert(processInterface(new TestInterfaceImpl("bar")) === "Owner TestInterfaceImpl has value 'bar'");
+ assert(processInterface(new ChildTestInterfaceImpl()) === "Owner TestInterfaceImpl has value 'Test'");
+ // @ts-expect-error "Just test that this code will throw compilation error for a user"
+ assert(processInterface({ value: "bar", getOwnerName: function () { return "RandomObject"; } }) === "Owner RandomObject has value 'bar'");
+ return "OK";
+}
diff --git a/js/js.translator/testData/typescript-export/interfaces/interfaces__main.ts b/js/js.translator/testData/typescript-export/interfaces/interfaces__main.ts
new file mode 100644
index 00000000000..c16a4278309
--- /dev/null
+++ b/js/js.translator/testData/typescript-export/interfaces/interfaces__main.ts
@@ -0,0 +1,19 @@
+import TestInterfaceImpl = JS_TESTS.foo.TestInterfaceImpl;
+import ChildTestInterfaceImpl = JS_TESTS.foo.ChildTestInterfaceImpl;
+import processInterface = JS_TESTS.foo.processInterface;
+
+function assert(condition: boolean) {
+ if (!condition) {
+ throw "Assertion failed";
+ }
+}
+
+function box(): string {
+ assert(processInterface(new TestInterfaceImpl("bar")) === "Owner TestInterfaceImpl has value 'bar'")
+ assert(processInterface(new ChildTestInterfaceImpl()) === "Owner TestInterfaceImpl has value 'Test'")
+
+ // @ts-expect-error "Just test that this code will throw compilation error for a user"
+ assert(processInterface({ value: "bar", getOwnerName: () => "RandomObject" }) === "Owner RandomObject has value 'bar'")
+
+ return "OK";
+}
\ No newline at end of file
diff --git a/js/js.translator/testData/typescript-export/interfaces/tsconfig.json b/js/js.translator/testData/typescript-export/interfaces/tsconfig.json
new file mode 100644
index 00000000000..706556bf1f5
--- /dev/null
+++ b/js/js.translator/testData/typescript-export/interfaces/tsconfig.json
@@ -0,0 +1,3 @@
+{
+ "extends": "../common.tsconfig.json"
+}
\ No newline at end of file
diff --git a/js/js.translator/testData/typescript-export/js-name/js-name.d.ts b/js/js.translator/testData/typescript-export/js-name/js-name.d.ts
new file mode 100644
index 00000000000..68a04698a8f
--- /dev/null
+++ b/js/js.translator/testData/typescript-export/js-name/js-name.d.ts
@@ -0,0 +1,21 @@
+declare namespace JS_TESTS {
+ type Nullable = T | null | undefined
+ namespace foo {
+ class JsNameTest {
+ private constructor();
+ get value(): number;
+ runTest(): string;
+ acceptObject(impl: Object): string;
+ static get NotCompanion(): {
+ create(): foo.JsNameTest;
+ createChild(value: number): foo.JsNameTest.NestedJsName;
+ };
+ }
+ namespace JsNameTest {
+ class NestedJsName {
+ constructor(__value: number);
+ get value(): number;
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/js/js.translator/testData/typescript-export/js-name/js-name.kt b/js/js.translator/testData/typescript-export/js-name/js-name.kt
new file mode 100644
index 00000000000..d6f42c9f6a0
--- /dev/null
+++ b/js/js.translator/testData/typescript-export/js-name/js-name.kt
@@ -0,0 +1,47 @@
+// CHECK_TYPESCRIPT_DECLARATIONS
+// RUN_PLAIN_BOX_FUNCTION
+// SKIP_MINIFICATION
+// SKIP_NODE_JS
+// INFER_MAIN_MODULE
+// MODULE: JS_TESTS
+// FILE: js-name.kt
+
+package foo
+
+@JsName("Object")
+external interface WeirdInterface {
+ val constructor: dynamic
+}
+
+@JsExport
+@JsName("JsNameTest")
+class __JsNameTest private constructor() {
+ @JsName("value")
+ val __value = 4
+
+ @JsName("runTest")
+ fun __runTest(): String {
+ return "JsNameTest"
+ }
+
+ @JsName("acceptObject")
+ fun __acceptWeirdImpl(impl: WeirdInterface): String {
+ return impl.constructor.name
+ }
+
+ @JsName("NotCompanion")
+ companion object {
+ @JsName("create")
+ fun __create(): __JsNameTest {
+ return __JsNameTest()
+ }
+
+ @JsName("createChild")
+ fun __createChild(value: Int): __NestJsNameTest {
+ return __NestJsNameTest(value)
+ }
+ }
+
+ @JsName("NestedJsName")
+ class __NestJsNameTest(@JsName("value") val __value: Int)
+}
\ No newline at end of file
diff --git a/js/js.translator/testData/typescript-export/js-name/js-name__main.js b/js/js.translator/testData/typescript-export/js-name/js-name__main.js
new file mode 100644
index 00000000000..be1a103b50b
--- /dev/null
+++ b/js/js.translator/testData/typescript-export/js-name/js-name__main.js
@@ -0,0 +1,16 @@
+"use strict";
+var JsNameTest = JS_TESTS.foo.JsNameTest;
+function assert(condition) {
+ if (!condition) {
+ throw "Assertion failed";
+ }
+}
+function box() {
+ var jsNameTest = JsNameTest.NotCompanion.create();
+ assert(jsNameTest.value === 4);
+ assert(jsNameTest.runTest() === "JsNameTest");
+ assert(jsNameTest.acceptObject(Object) === "Function");
+ var jsNameNestedTest = JsNameTest.NotCompanion.createChild(42);
+ assert(jsNameNestedTest.value === 42);
+ return "OK";
+}
diff --git a/js/js.translator/testData/typescript-export/js-name/js-name__main.ts b/js/js.translator/testData/typescript-export/js-name/js-name__main.ts
new file mode 100644
index 00000000000..564e7d6d27b
--- /dev/null
+++ b/js/js.translator/testData/typescript-export/js-name/js-name__main.ts
@@ -0,0 +1,21 @@
+import JsNameTest = JS_TESTS.foo.JsNameTest;
+
+function assert(condition: boolean) {
+ if (!condition) {
+ throw "Assertion failed";
+ }
+}
+
+function box(): string {
+ const jsNameTest = JsNameTest.NotCompanion.create();
+
+ assert(jsNameTest.value === 4)
+ assert(jsNameTest.runTest() === "JsNameTest")
+ assert(jsNameTest.acceptObject(Object) === "Function")
+
+ const jsNameNestedTest = JsNameTest.NotCompanion.createChild(42);
+
+ assert(jsNameNestedTest.value === 42)
+
+ return "OK";
+}
\ No newline at end of file
diff --git a/js/js.translator/testData/typescript-export/js-name/tsconfig.json b/js/js.translator/testData/typescript-export/js-name/tsconfig.json
new file mode 100644
index 00000000000..706556bf1f5
--- /dev/null
+++ b/js/js.translator/testData/typescript-export/js-name/tsconfig.json
@@ -0,0 +1,3 @@
+{
+ "extends": "../common.tsconfig.json"
+}
\ No newline at end of file
diff --git a/js/js.translator/testData/typescript-export/member-properties/member-properties.d.ts b/js/js.translator/testData/typescript-export/member-properties/member-properties.d.ts
new file mode 100644
index 00000000000..637e9378b64
--- /dev/null
+++ b/js/js.translator/testData/typescript-export/member-properties/member-properties.d.ts
@@ -0,0 +1,17 @@
+declare namespace JS_TESTS {
+ type Nullable = T | null | undefined
+ namespace foo {
+ class Test {
+ constructor();
+ get _val(): number;
+ get _var(): number;
+ set _var(value: number);
+ get _valCustom(): number;
+ get _valCustomWithField(): number;
+ get _varCustom(): number;
+ set _varCustom(value: number);
+ get _varCustomWithField(): number;
+ set _varCustomWithField(value: number);
+ }
+ }
+}
\ No newline at end of file
diff --git a/js/js.translator/testData/typescript-export/member-properties/member-properties.kt b/js/js.translator/testData/typescript-export/member-properties/member-properties.kt
new file mode 100644
index 00000000000..bdba48b1ce6
--- /dev/null
+++ b/js/js.translator/testData/typescript-export/member-properties/member-properties.kt
@@ -0,0 +1,30 @@
+// CHECK_TYPESCRIPT_DECLARATIONS
+// RUN_PLAIN_BOX_FUNCTION
+// SKIP_MINIFICATION
+// SKIP_NODE_JS
+// INFER_MAIN_MODULE
+// MODULE: JS_TESTS
+// FILE: member-properties.kt
+
+package foo
+
+@JsExport
+class Test {
+ val _val: Int = 1
+
+ var _var: Int = 1
+
+ val _valCustom: Int
+ get() = 1
+
+ val _valCustomWithField: Int = 1
+ get() = field + 1
+
+ var _varCustom: Int
+ get() = 1
+ set(value) {}
+
+ var _varCustomWithField: Int = 1
+ get() = field * 10
+ set(value) { field = value * 10 }
+}
\ No newline at end of file
diff --git a/js/js.translator/testData/typescript-export/member-properties/member-properties__main.js b/js/js.translator/testData/typescript-export/member-properties/member-properties__main.js
new file mode 100644
index 00000000000..3c8760b3878
--- /dev/null
+++ b/js/js.translator/testData/typescript-export/member-properties/member-properties__main.js
@@ -0,0 +1,23 @@
+"use strict";
+var Test = JS_TESTS.foo.Test;
+function assert(condition) {
+ if (!condition) {
+ throw "Assertion failed";
+ }
+}
+function box() {
+ var test = new Test();
+ assert(test._val === 1);
+ assert(test._var === 1);
+ test._var = 1000;
+ assert(test._var === 1000);
+ assert(test._valCustom === 1);
+ assert(test._valCustomWithField === 2);
+ assert(test._varCustom === 1);
+ test._varCustom = 20;
+ assert(test._varCustom === 1);
+ assert(test._varCustomWithField === 10);
+ test._varCustomWithField = 10;
+ assert(test._varCustomWithField === 1000);
+ return "OK";
+}
diff --git a/js/js.translator/testData/typescript-export/member-properties/member-properties__main.ts b/js/js.translator/testData/typescript-export/member-properties/member-properties__main.ts
new file mode 100644
index 00000000000..aaefb1105a3
--- /dev/null
+++ b/js/js.translator/testData/typescript-export/member-properties/member-properties__main.ts
@@ -0,0 +1,27 @@
+import Test = JS_TESTS.foo.Test;
+
+function assert(condition: boolean) {
+ if (!condition) {
+ throw "Assertion failed";
+ }
+}
+
+function box(): string {
+ const test = new Test()
+ assert(test._val === 1);
+ assert(test._var === 1);
+ test._var = 1000;
+ assert(test._var === 1000);
+
+ assert(test._valCustom === 1);
+ assert(test._valCustomWithField === 2);
+ assert(test._varCustom === 1);
+ test._varCustom = 20;
+ assert(test._varCustom === 1);
+ assert(test._varCustomWithField === 10);
+ test._varCustomWithField = 10;
+ assert(test._varCustomWithField === 1000);
+
+
+ return "OK";
+}
\ No newline at end of file
diff --git a/js/js.translator/testData/typescript-export/member-properties/tsconfig.json b/js/js.translator/testData/typescript-export/member-properties/tsconfig.json
new file mode 100644
index 00000000000..17612c56c9d
--- /dev/null
+++ b/js/js.translator/testData/typescript-export/member-properties/tsconfig.json
@@ -0,0 +1,4 @@
+{
+ "include": [ "./*" ],
+ "extends": "../common.tsconfig.json"
+}
\ No newline at end of file
diff --git a/js/js.translator/testData/typescript-export/methods/methods.d.ts b/js/js.translator/testData/typescript-export/methods/methods.d.ts
new file mode 100644
index 00000000000..98791c2670f
--- /dev/null
+++ b/js/js.translator/testData/typescript-export/methods/methods.d.ts
@@ -0,0 +1,21 @@
+declare namespace JS_TESTS {
+ type Nullable = T | null | undefined
+ namespace foo {
+ class Test {
+ constructor();
+ sum(x: number, y: number): number;
+ varargInt(x: Int32Array): number;
+ varargNullableInt(x: Array>): number;
+ varargWithOtherParameters(x: string, y: Array, z: string): number;
+ varargWithComplexType(x: Array<(p0: Array) => Array>): number;
+ sumNullable(x: Nullable, y: Nullable): number;
+ defaultParameters(a: string, x?: number, y?: string): string;
+ generic1(x: T): T;
+ generic2(x: Nullable): boolean;
+ genericWithConstraint(x: T): T;
+ genericWithMultipleConstraints(x: T): T;
+ generic3(a: A, b: B, c: C, d: D): Nullable;
+ inlineFun(x: number, callback: (p0: number) => void): void;
+ }
+ }
+}
\ No newline at end of file
diff --git a/js/js.translator/testData/typescript-export/methods/methods.kt b/js/js.translator/testData/typescript-export/methods/methods.kt
new file mode 100644
index 00000000000..46433ad437a
--- /dev/null
+++ b/js/js.translator/testData/typescript-export/methods/methods.kt
@@ -0,0 +1,52 @@
+// CHECK_TYPESCRIPT_DECLARATIONS
+// RUN_PLAIN_BOX_FUNCTION
+// SKIP_MINIFICATION
+// SKIP_NODE_JS
+// INFER_MAIN_MODULE
+// MODULE: JS_TESTS
+// FILE: member-properties.kt
+
+package foo
+
+external interface RegExpMatchArray
+
+@JsExport
+class Test {
+ fun sum(x: Int, y: Int): Int =
+ x + y
+
+ fun varargInt(vararg x: Int): Int =
+ x.size
+
+ fun varargNullableInt(vararg x: Int?): Int =
+ x.size
+
+ fun varargWithOtherParameters(x: String, vararg y: String, z: String): Int =
+ x.length + y.size + z.length
+
+ fun varargWithComplexType(vararg x: (Array) -> Array): Int =
+ x.size
+
+ fun sumNullable(x: Int?, y: Int?): Int =
+ (x ?: 0) + (y ?: 0)
+
+ fun defaultParameters(a: String, x: Int = 10, y: String = "OK"): String =
+ a + x.toString() + y
+
+ fun generic1(x: T): T = x
+
+ fun generic2(x: T?): Boolean = (x == null)
+
+ fun genericWithConstraint(x: T): T = x
+
+ fun genericWithMultipleConstraints(x: T): T
+ where T : Comparable,
+ T : RegExpMatchArray,
+ T : Throwable = x
+
+ fun generic3(a: A, b: B, c: C, d: D): E? = null
+
+ inline fun inlineFun(x: Int, callback: (Int) -> Unit) {
+ callback(x)
+ }
+}
\ No newline at end of file
diff --git a/js/js.translator/testData/typescript-export/methods/methods__main.js b/js/js.translator/testData/typescript-export/methods/methods__main.js
new file mode 100644
index 00000000000..256edb10814
--- /dev/null
+++ b/js/js.translator/testData/typescript-export/methods/methods__main.js
@@ -0,0 +1,48 @@
+"use strict";
+var __assign = (this && this.__assign) || function () {
+ __assign = Object.assign || function(t) {
+ for (var s, i = 1, n = arguments.length; i < n; i++) {
+ s = arguments[i];
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
+ t[p] = s[p];
+ }
+ return t;
+ };
+ return __assign.apply(this, arguments);
+};
+var Test = JS_TESTS.foo.Test;
+function assert(condition) {
+ if (!condition) {
+ throw "Assertion failed";
+ }
+}
+function box() {
+ var test = new Test();
+ assert(test.sum(10, 20) === 30);
+ assert(test.varargInt(new Int32Array([1, 2, 3])) === 3);
+ assert(test.varargNullableInt([10, 20, 30, null, undefined, 40]) === 6);
+ assert(test.varargWithOtherParameters("1234", ["1", "2", "3"], "12") === 9);
+ assert(test.varargWithComplexType([]) === 0);
+ assert(test.varargWithComplexType([
+ function (x) { return x; },
+ function (x) { return [new Int32Array([1, 2, 3])]; },
+ function (x) { return []; },
+ ]) === 3);
+ assert(test.sumNullable(10, null) === 10);
+ assert(test.sumNullable(undefined, 20) === 20);
+ assert(test.sumNullable(1, 2) === 3);
+ assert(test.defaultParameters("", 20, "OK") === "20OK");
+ assert(test.generic1("FOO") === "FOO");
+ assert(test.generic1({ x: 10 }).x === 10);
+ assert(test.generic2(null) === true);
+ assert(test.generic2(undefined) === true);
+ assert(test.generic2(10) === false);
+ assert(test.generic3(10, true, "__", {}) === null);
+ assert(test.genericWithConstraint("Test") === "Test");
+ var regExpMatchError = __assign(__assign({}, new Error("Test")), "test test".match(/tes/g));
+ assert(test.genericWithMultipleConstraints(regExpMatchError) === regExpMatchError);
+ var result = 0;
+ test.inlineFun(10, function (x) { result = x; });
+ assert(result === 10);
+ return "OK";
+}
diff --git a/js/js.translator/testData/typescript-export/methods/methods__main.ts b/js/js.translator/testData/typescript-export/methods/methods__main.ts
new file mode 100644
index 00000000000..c91e6facd1c
--- /dev/null
+++ b/js/js.translator/testData/typescript-export/methods/methods__main.ts
@@ -0,0 +1,46 @@
+import Test = JS_TESTS.foo.Test;
+
+function assert(condition: boolean) {
+ if (!condition) {
+ throw "Assertion failed";
+ }
+}
+
+function box(): string {
+ const test = new Test()
+ assert(test.sum(10, 20) === 30);
+
+ assert(test.varargInt(new Int32Array([1, 2, 3])) === 3);
+ assert(test.varargNullableInt([10, 20, 30, null, undefined, 40]) === 6);
+ assert(test.varargWithOtherParameters("1234", ["1", "2", "3"], "12") === 9);
+ assert(test.varargWithComplexType([]) === 0);
+ assert(test.varargWithComplexType([
+ x => x,
+ x => [new Int32Array([1, 2, 3])],
+ x => [],
+ ]) === 3);
+
+ assert(test.sumNullable(10, null) === 10);
+ assert(test.sumNullable(undefined, 20) === 20);
+ assert(test.sumNullable(1, 2) === 3);
+
+ assert(test.defaultParameters("", 20, "OK") === "20OK");
+
+ assert(test.generic1("FOO") === "FOO");
+ assert(test.generic1({x: 10}).x === 10);
+ assert(test.generic2(null) === true);
+ assert(test.generic2(undefined) === true);
+ assert(test.generic2(10) === false);
+ assert(test.generic3(10, true, "__", {}) === null);
+
+ assert(test.genericWithConstraint("Test") === "Test")
+
+ const regExpMatchError: any = { ...new Error("Test"), ..."test test".match(/tes/g) }
+ assert(test.genericWithMultipleConstraints(regExpMatchError) === regExpMatchError)
+
+ let result: number = 0;
+ test.inlineFun(10, x => { result = x; });
+ assert(result === 10);
+
+ return "OK";
+}
\ No newline at end of file
diff --git a/js/js.translator/testData/typescript-export/methods/tsconfig.json b/js/js.translator/testData/typescript-export/methods/tsconfig.json
new file mode 100644
index 00000000000..17612c56c9d
--- /dev/null
+++ b/js/js.translator/testData/typescript-export/methods/tsconfig.json
@@ -0,0 +1,4 @@
+{
+ "include": [ "./*" ],
+ "extends": "../common.tsconfig.json"
+}
\ No newline at end of file
diff --git a/js/js.translator/testData/typescript-export/moduleSystems/commonjs.d.ts b/js/js.translator/testData/typescript-export/module-systems/commonjs.d.ts
similarity index 100%
rename from js/js.translator/testData/typescript-export/moduleSystems/commonjs.d.ts
rename to js/js.translator/testData/typescript-export/module-systems/commonjs.d.ts
diff --git a/js/js.translator/testData/typescript-export/moduleSystems/commonjs.kt b/js/js.translator/testData/typescript-export/module-systems/commonjs.kt
similarity index 100%
rename from js/js.translator/testData/typescript-export/moduleSystems/commonjs.kt
rename to js/js.translator/testData/typescript-export/module-systems/commonjs.kt
diff --git a/js/js.translator/testData/typescript-export/moduleSystems/plain.d.ts b/js/js.translator/testData/typescript-export/module-systems/plain.d.ts
similarity index 100%
rename from js/js.translator/testData/typescript-export/moduleSystems/plain.d.ts
rename to js/js.translator/testData/typescript-export/module-systems/plain.d.ts
diff --git a/js/js.translator/testData/typescript-export/moduleSystems/plain.kt b/js/js.translator/testData/typescript-export/module-systems/plain.kt
similarity index 100%
rename from js/js.translator/testData/typescript-export/moduleSystems/plain.kt
rename to js/js.translator/testData/typescript-export/module-systems/plain.kt
diff --git a/js/js.translator/testData/typescript-export/moduleSystems/tsconfig.json b/js/js.translator/testData/typescript-export/module-systems/tsconfig.json
similarity index 100%
rename from js/js.translator/testData/typescript-export/moduleSystems/tsconfig.json
rename to js/js.translator/testData/typescript-export/module-systems/tsconfig.json
diff --git a/js/js.translator/testData/typescript-export/moduleSystems/umd.d.ts b/js/js.translator/testData/typescript-export/module-systems/umd.d.ts
similarity index 100%
rename from js/js.translator/testData/typescript-export/moduleSystems/umd.d.ts
rename to js/js.translator/testData/typescript-export/module-systems/umd.d.ts
diff --git a/js/js.translator/testData/typescript-export/moduleSystems/umd.kt b/js/js.translator/testData/typescript-export/module-systems/umd.kt
similarity index 100%
rename from js/js.translator/testData/typescript-export/moduleSystems/umd.kt
rename to js/js.translator/testData/typescript-export/module-systems/umd.kt
diff --git a/js/js.translator/testData/typescript-export/objects/objects.d.ts b/js/js.translator/testData/typescript-export/objects/objects.d.ts
new file mode 100644
index 00000000000..9de9e3184dc
--- /dev/null
+++ b/js/js.translator/testData/typescript-export/objects/objects.d.ts
@@ -0,0 +1,46 @@
+declare namespace JS_TESTS {
+ type Nullable = T | null | undefined
+ namespace foo {
+ const O0: {
+ };
+ const O: {
+ get x(): number;
+ foo(): number;
+ };
+ function takesO(o: typeof foo.O): number;
+ abstract class Parent {
+ private constructor();
+ }
+ namespace Parent {
+ abstract class Nested1 extends _objects_.foo$Parent$Nested1 {
+ private constructor();
+ }
+ namespace Nested1 {
+ class Nested2 {
+ constructor();
+ }
+ namespace Nested2 {
+ abstract class Companion {
+ private constructor();
+ }
+ namespace Companion {
+ class Nested3 {
+ constructor();
+ }
+ }
+ }
+ }
+ }
+ function getParent(): typeof foo.Parent;
+ function createNested1(): typeof foo.Parent.Nested1;
+ function createNested2(): foo.Parent.Nested1.Nested2;
+ function createNested3(): foo.Parent.Nested1.Nested2.Companion.Nested3;
+ }
+ namespace _objects_ {
+ const foo$Parent$Nested1: {
+ get value(): string;
+ } & {
+ new(): any;
+ };
+ }
+}
\ No newline at end of file
diff --git a/js/js.translator/testData/typescript-export/objects/objects.kt b/js/js.translator/testData/typescript-export/objects/objects.kt
new file mode 100644
index 00000000000..f6da5145a72
--- /dev/null
+++ b/js/js.translator/testData/typescript-export/objects/objects.kt
@@ -0,0 +1,54 @@
+// CHECK_TYPESCRIPT_DECLARATIONS
+// RUN_PLAIN_BOX_FUNCTION
+// SKIP_MINIFICATION
+// SKIP_NODE_JS
+// INFER_MAIN_MODULE
+// MODULE: JS_TESTS
+// FILE: objects.kt
+
+package foo
+
+@JsExport
+object O0
+
+@JsExport
+object O {
+ val x = 10
+ fun foo() = 20
+}
+
+@JsExport
+fun takesO(o: O): Int =
+ O.x + O.foo()
+
+@JsExport
+object Parent {
+ object Nested1 {
+ val value: String = "Nested1"
+ class Nested2 {
+ companion object {
+ class Nested3
+ }
+ }
+ }
+}
+
+@JsExport
+fun getParent(): Parent {
+ return Parent
+}
+
+@JsExport
+fun createNested1(): Parent.Nested1 {
+ return Parent.Nested1
+}
+
+@JsExport
+fun createNested2(): Parent.Nested1.Nested2 {
+ return Parent.Nested1.Nested2()
+}
+
+@JsExport
+fun createNested3(): Parent.Nested1.Nested2.Companion.Nested3 {
+ return Parent.Nested1.Nested2.Companion.Nested3()
+}
\ No newline at end of file
diff --git a/js/js.translator/testData/typescript-export/objects/objects__main.js b/js/js.translator/testData/typescript-export/objects/objects__main.js
new file mode 100644
index 00000000000..4b843859922
--- /dev/null
+++ b/js/js.translator/testData/typescript-export/objects/objects__main.js
@@ -0,0 +1,31 @@
+"use strict";
+var O = JS_TESTS.foo.O;
+var O0 = JS_TESTS.foo.O0;
+var Parent = JS_TESTS.foo.Parent;
+var takesO = JS_TESTS.foo.takesO;
+var getParent = JS_TESTS.foo.getParent;
+var createNested1 = JS_TESTS.foo.createNested1;
+var createNested2 = JS_TESTS.foo.createNested2;
+var createNested3 = JS_TESTS.foo.createNested3;
+function assert(condition) {
+ if (!condition) {
+ throw "Assertion failed";
+ }
+}
+function box() {
+ assert(typeof O0 === "object" && O0 != null);
+ assert(O.x === 10);
+ assert(O.foo() === 20);
+ assert(takesO(O) === 30);
+ // Do not strip types from those test cases (it is a check of nested objects types usability)
+ var parent = Parent;
+ var nested1 = Parent.Nested1;
+ var nested2 = new Parent.Nested1.Nested2();
+ var nested3 = new Parent.Nested1.Nested2.Companion.Nested3();
+ assert(nested1.value === "Nested1");
+ assert(getParent() === parent);
+ assert(createNested1() === nested1);
+ assert(createNested2() !== nested2 && createNested2() instanceof Parent.Nested1.Nested2);
+ assert(createNested3() !== nested3 && createNested3() instanceof Parent.Nested1.Nested2.Companion.Nested3);
+ return "OK";
+}
diff --git a/js/js.translator/testData/typescript-export/objects/objects__main.ts b/js/js.translator/testData/typescript-export/objects/objects__main.ts
new file mode 100644
index 00000000000..4d615540a4e
--- /dev/null
+++ b/js/js.translator/testData/typescript-export/objects/objects__main.ts
@@ -0,0 +1,34 @@
+import O = JS_TESTS.foo.O;
+import O0 = JS_TESTS.foo.O0;
+import Parent = JS_TESTS.foo.Parent;
+import takesO = JS_TESTS.foo.takesO;
+import getParent = JS_TESTS.foo.getParent;
+import createNested1 = JS_TESTS.foo.createNested1;
+import createNested2 = JS_TESTS.foo.createNested2;
+import createNested3 = JS_TESTS.foo.createNested3;
+
+function assert(condition: boolean) {
+ if (!condition) {
+ throw "Assertion failed";
+ }
+}
+
+function box(): string {
+ assert(typeof O0 === "object" && O0 != null);
+ assert(O.x === 10);
+ assert(O.foo() === 20);
+ assert(takesO(O) === 30)
+
+ // Do not strip types from those test cases (it is a check of nested objects types usability)
+ const parent: typeof Parent = Parent
+ const nested1: typeof Parent.Nested1 = Parent.Nested1
+ const nested2: Parent.Nested1.Nested2 = new Parent.Nested1.Nested2()
+ const nested3: Parent.Nested1.Nested2.Companion.Nested3 = new Parent.Nested1.Nested2.Companion.Nested3()
+
+ assert(nested1.value === "Nested1")
+ assert(getParent() === parent)
+ assert(createNested1() === nested1)
+ assert(createNested2() !== nested2 && createNested2() instanceof Parent.Nested1.Nested2)
+ assert(createNested3() !== nested3 && createNested3() instanceof Parent.Nested1.Nested2.Companion.Nested3)
+ return "OK";
+}
\ No newline at end of file
diff --git a/js/js.translator/testData/typescript-export/objects/tsconfig.json b/js/js.translator/testData/typescript-export/objects/tsconfig.json
new file mode 100644
index 00000000000..17612c56c9d
--- /dev/null
+++ b/js/js.translator/testData/typescript-export/objects/tsconfig.json
@@ -0,0 +1,4 @@
+{
+ "include": [ "./*" ],
+ "extends": "../common.tsconfig.json"
+}
\ No newline at end of file
diff --git a/js/js.translator/testData/typescript-export/properties/properties.d.ts b/js/js.translator/testData/typescript-export/properties/properties.d.ts
new file mode 100644
index 00000000000..7e01df49060
--- /dev/null
+++ b/js/js.translator/testData/typescript-export/properties/properties.d.ts
@@ -0,0 +1,12 @@
+declare namespace JS_TESTS {
+ type Nullable = T | null | undefined
+ namespace foo {
+ const _val: number;
+ let _var: number;
+ const _valCustomWithField: number;
+ let _varCustomWithField: number;
+ const _const_val: number;
+ const _valCustom: number;
+ let _varCustom: number;
+ }
+}
\ No newline at end of file
diff --git a/js/js.translator/testData/typescript-export/properties/properties.kt b/js/js.translator/testData/typescript-export/properties/properties.kt
new file mode 100644
index 00000000000..e09f7e10b2a
--- /dev/null
+++ b/js/js.translator/testData/typescript-export/properties/properties.kt
@@ -0,0 +1,36 @@
+// CHECK_TYPESCRIPT_DECLARATIONS
+// RUN_PLAIN_BOX_FUNCTION
+// SKIP_MINIFICATION
+// SKIP_NODE_JS
+// INFER_MAIN_MODULE
+// MODULE: JS_TESTS
+// FILE: properties.kt
+
+package foo
+
+@JsExport
+const val _const_val: Int = 1
+
+@JsExport
+val _val: Int = 1
+
+@JsExport
+var _var: Int = 1
+
+@JsExport
+val _valCustom: Int
+ get() = 1
+
+@JsExport
+val _valCustomWithField: Int = 1
+ get() = field + 1
+
+@JsExport
+var _varCustom: Int
+ get() = 1
+ set(value) {}
+
+@JsExport
+var _varCustomWithField: Int = 1
+ get() = field * 10
+ set(value) { field = value * 10 }
\ No newline at end of file
diff --git a/js/js.translator/testData/typescript-export/properties/properties__main.js b/js/js.translator/testData/typescript-export/properties/properties__main.js
new file mode 100644
index 00000000000..66d306e3883
--- /dev/null
+++ b/js/js.translator/testData/typescript-export/properties/properties__main.js
@@ -0,0 +1,27 @@
+"use strict";
+var _const_val = JS_TESTS.foo._const_val;
+var _val = JS_TESTS.foo._val;
+var _var = JS_TESTS.foo._var;
+var _valCustom = JS_TESTS.foo._valCustom;
+var _valCustomWithField = JS_TESTS.foo._valCustomWithField;
+function assert(condition) {
+ if (!condition) {
+ throw "Assertion failed";
+ }
+}
+function box() {
+ assert(_const_val === 1);
+ assert(_val === 1);
+ assert(_var === 1);
+ JS_TESTS.foo._var = 1000;
+ assert(JS_TESTS.foo._var === 1000);
+ assert(_valCustom === 1);
+ assert(_valCustomWithField === 2);
+ assert(JS_TESTS.foo._varCustom === 1);
+ JS_TESTS.foo._varCustom = 20;
+ assert(JS_TESTS.foo._varCustom === 1);
+ assert(JS_TESTS.foo._varCustomWithField === 10);
+ JS_TESTS.foo._varCustomWithField = 10;
+ assert(JS_TESTS.foo._varCustomWithField === 1000);
+ return "OK";
+}
diff --git a/js/js.translator/testData/typescript-export/properties/properties__main.ts b/js/js.translator/testData/typescript-export/properties/properties__main.ts
new file mode 100644
index 00000000000..69d23c2d87e
--- /dev/null
+++ b/js/js.translator/testData/typescript-export/properties/properties__main.ts
@@ -0,0 +1,33 @@
+import _const_val = JS_TESTS.foo._const_val;
+import _val = JS_TESTS.foo._val;
+import _var = JS_TESTS.foo._var;
+import _valCustom = JS_TESTS.foo._valCustom;
+import _valCustomWithField = JS_TESTS.foo._valCustomWithField;
+
+function assert(condition: boolean) {
+ if (!condition) {
+ throw "Assertion failed";
+ }
+}
+
+function box(): string {
+ assert(_const_val === 1);
+ assert(_val === 1);
+ assert(_var === 1);
+
+ JS_TESTS.foo._var = 1000;
+ assert(JS_TESTS.foo._var === 1000);
+
+ assert(_valCustom === 1);
+ assert(_valCustomWithField === 2);
+
+ assert(JS_TESTS.foo._varCustom === 1);
+ JS_TESTS.foo._varCustom = 20;
+ assert(JS_TESTS.foo._varCustom === 1);
+
+ assert(JS_TESTS.foo._varCustomWithField === 10);
+ JS_TESTS.foo._varCustomWithField = 10;
+ assert(JS_TESTS.foo._varCustomWithField === 1000);
+
+ return "OK";
+}
\ No newline at end of file
diff --git a/js/js.translator/testData/typescript-export/properties/tsconfig.json b/js/js.translator/testData/typescript-export/properties/tsconfig.json
new file mode 100644
index 00000000000..17612c56c9d
--- /dev/null
+++ b/js/js.translator/testData/typescript-export/properties/tsconfig.json
@@ -0,0 +1,4 @@
+{
+ "include": [ "./*" ],
+ "extends": "../common.tsconfig.json"
+}
\ No newline at end of file
diff --git a/js/js.translator/testData/typescript-export/regular-classes/regular-classes.d.ts b/js/js.translator/testData/typescript-export/regular-classes/regular-classes.d.ts
new file mode 100644
index 00000000000..18006f325fc
--- /dev/null
+++ b/js/js.translator/testData/typescript-export/regular-classes/regular-classes.d.ts
@@ -0,0 +1,42 @@
+declare namespace JS_TESTS {
+ type Nullable = T | null | undefined
+ namespace foo {
+ class A {
+ constructor();
+ }
+ class A1 {
+ constructor(x: number);
+ get x(): number;
+ }
+ class A2 {
+ constructor(x: string, y: boolean);
+ get x(): string;
+ get y(): boolean;
+ set y(value: boolean);
+ }
+ class A3 {
+ constructor();
+ get x(): number;
+ }
+ class A4 {
+ constructor(value: T);
+ get value(): T;
+ test(): T;
+ }
+ class A5 {
+ constructor();
+ static get Companion(): {
+ get x(): number;
+ };
+ }
+ class A6 {
+ constructor();
+ then(): number;
+ catch(): number;
+ }
+ class GenericClassWithConstraint {
+ constructor(test: T);
+ get test(): T;
+ }
+ }
+}
diff --git a/js/js.translator/testData/typescript-export/regular-classes/regular-classes.kt b/js/js.translator/testData/typescript-export/regular-classes/regular-classes.kt
new file mode 100644
index 00000000000..17e67b65210
--- /dev/null
+++ b/js/js.translator/testData/typescript-export/regular-classes/regular-classes.kt
@@ -0,0 +1,43 @@
+// CHECK_TYPESCRIPT_DECLARATIONS
+// RUN_PLAIN_BOX_FUNCTION
+// SKIP_MINIFICATION
+// SKIP_NODE_JS
+// INFER_MAIN_MODULE
+// MODULE: JS_TESTS
+// FILE: regular-classes.kt
+
+package foo
+
+@JsExport
+class A
+
+@JsExport
+class A1(val x: Int)
+
+@JsExport
+class A2(val x: String, var y: Boolean)
+
+@JsExport
+class A3 {
+ val x: Int = 100
+}
+
+@JsExport
+class A4(val value: T) {
+ fun test(): T = value
+}
+@JsExport
+class A5 {
+ companion object {
+ val x = 10
+ }
+}
+
+@JsExport
+open class A6 {
+ fun then(): Int = 42
+ fun catch(): Int = 24
+}
+
+@JsExport
+class GenericClassWithConstraint(val test: T)
diff --git a/js/js.translator/testData/typescript-export/regular-classes/regular-classes__main.js b/js/js.translator/testData/typescript-export/regular-classes/regular-classes__main.js
new file mode 100644
index 00000000000..0f6caabe882
--- /dev/null
+++ b/js/js.translator/testData/typescript-export/regular-classes/regular-classes__main.js
@@ -0,0 +1,26 @@
+"use strict";
+var A = JS_TESTS.foo.A;
+var A1 = JS_TESTS.foo.A1;
+var A2 = JS_TESTS.foo.A2;
+var A3 = JS_TESTS.foo.A3;
+var A4 = JS_TESTS.foo.A4;
+var A5 = JS_TESTS.foo.A5;
+var A6 = JS_TESTS.foo.A6;
+var GenericClassWithConstraint = JS_TESTS.foo.GenericClassWithConstraint;
+function assert(condition) {
+ if (!condition) {
+ throw "Assertion failed";
+ }
+}
+function box() {
+ new A();
+ assert(new A1(10).x === 10);
+ assert(new A2("10", true).x === "10");
+ assert(new A3().x === 100);
+ assert(new A4("Hello").test() === "Hello");
+ assert(A5.Companion.x === 10);
+ assert(new A6().then() === 42);
+ assert(new A6().catch() === 24);
+ assert(new GenericClassWithConstraint(new A6()).test.catch() === 24);
+ return "OK";
+}
diff --git a/js/js.translator/testData/typescript-export/regular-classes/regular-classes__main.ts b/js/js.translator/testData/typescript-export/regular-classes/regular-classes__main.ts
new file mode 100644
index 00000000000..8ff265da629
--- /dev/null
+++ b/js/js.translator/testData/typescript-export/regular-classes/regular-classes__main.ts
@@ -0,0 +1,28 @@
+import A = JS_TESTS.foo.A;
+import A1 = JS_TESTS.foo.A1;
+import A2 = JS_TESTS.foo.A2;
+import A3 = JS_TESTS.foo.A3;
+import A4 = JS_TESTS.foo.A4;
+import A5 = JS_TESTS.foo.A5;
+import A6 = JS_TESTS.foo.A6;
+import GenericClassWithConstraint = JS_TESTS.foo.GenericClassWithConstraint;
+
+function assert(condition: boolean) {
+ if (!condition) {
+ throw "Assertion failed";
+ }
+}
+
+function box(): string {
+ new A();
+ assert(new A1(10).x === 10);
+ assert(new A2("10", true).x === "10");
+ assert(new A3().x === 100);
+ assert(new A4("Hello").test() === "Hello");
+ assert(A5.Companion.x === 10);
+ assert(new A6().then() === 42);
+ assert(new A6().catch() === 24);
+ assert(new GenericClassWithConstraint(new A6()).test.catch() === 24)
+
+ return "OK";
+}
\ No newline at end of file
diff --git a/js/js.translator/testData/typescript-export/regular-classes/tsconfig.json b/js/js.translator/testData/typescript-export/regular-classes/tsconfig.json
new file mode 100644
index 00000000000..17612c56c9d
--- /dev/null
+++ b/js/js.translator/testData/typescript-export/regular-classes/tsconfig.json
@@ -0,0 +1,4 @@
+{
+ "include": [ "./*" ],
+ "extends": "../common.tsconfig.json"
+}
\ No newline at end of file
diff --git a/js/js.translator/testData/typescript-export/sealed-classes/sealed-classes.d.ts b/js/js.translator/testData/typescript-export/sealed-classes/sealed-classes.d.ts
new file mode 100644
index 00000000000..c81e17fd2b8
--- /dev/null
+++ b/js/js.translator/testData/typescript-export/sealed-classes/sealed-classes.d.ts
@@ -0,0 +1,19 @@
+declare namespace JS_TESTS {
+ type Nullable = T | null | undefined
+ namespace foo {
+ abstract class TestSealed {
+ protected constructor(name: string);
+ get name(): string;
+ }
+ namespace TestSealed {
+ class AA extends foo.TestSealed {
+ constructor();
+ bar(): string;
+ }
+ class BB extends foo.TestSealed {
+ constructor();
+ baz(): string;
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/js/js.translator/testData/typescript-export/sealed-classes/sealed-classes.kt b/js/js.translator/testData/typescript-export/sealed-classes/sealed-classes.kt
new file mode 100644
index 00000000000..a895a0d7085
--- /dev/null
+++ b/js/js.translator/testData/typescript-export/sealed-classes/sealed-classes.kt
@@ -0,0 +1,20 @@
+// CHECK_TYPESCRIPT_DECLARATIONS
+// RUN_PLAIN_BOX_FUNCTION
+// SKIP_MINIFICATION
+// SKIP_NODE_JS
+// INFER_MAIN_MODULE
+// MODULE: JS_TESTS
+// FILE: sealed-classes.kt
+
+package foo
+
+// See KT-47376, KT-39364
+@JsExport
+sealed class TestSealed(val name: String) {
+ class AA : TestSealed("AA") {
+ fun bar(): String = "bar"
+ }
+ class BB : TestSealed("BB") {
+ fun baz(): String = "baz"
+ }
+}
diff --git a/js/js.translator/testData/typescript-export/sealed-classes/sealed-classes__main.js b/js/js.translator/testData/typescript-export/sealed-classes/sealed-classes__main.js
new file mode 100644
index 00000000000..ac37bc7917d
--- /dev/null
+++ b/js/js.translator/testData/typescript-export/sealed-classes/sealed-classes__main.js
@@ -0,0 +1,14 @@
+"use strict";
+var TestSealed = JS_TESTS.foo.TestSealed;
+function assert(condition) {
+ if (!condition) {
+ throw "Assertion failed";
+ }
+}
+function box() {
+ assert(new TestSealed.AA().name == "AA");
+ assert(new TestSealed.AA().bar() == "bar");
+ assert(new TestSealed.BB().name == "BB");
+ assert(new TestSealed.BB().baz() == "baz");
+ return "OK";
+}
diff --git a/js/js.translator/testData/typescript-export/sealed-classes/sealed-classes__main.ts b/js/js.translator/testData/typescript-export/sealed-classes/sealed-classes__main.ts
new file mode 100644
index 00000000000..7fb339e44d9
--- /dev/null
+++ b/js/js.translator/testData/typescript-export/sealed-classes/sealed-classes__main.ts
@@ -0,0 +1,16 @@
+import TestSealed = JS_TESTS.foo.TestSealed;
+
+function assert(condition: boolean) {
+ if (!condition) {
+ throw "Assertion failed";
+ }
+}
+
+function box(): string {
+ assert(new TestSealed.AA().name == "AA");
+ assert(new TestSealed.AA().bar() == "bar");
+ assert(new TestSealed.BB().name == "BB");
+ assert(new TestSealed.BB().baz() == "baz");
+
+ return "OK";
+}
\ No newline at end of file
diff --git a/js/js.translator/testData/typescript-export/sealed-classes/tsconfig.json b/js/js.translator/testData/typescript-export/sealed-classes/tsconfig.json
new file mode 100644
index 00000000000..17612c56c9d
--- /dev/null
+++ b/js/js.translator/testData/typescript-export/sealed-classes/tsconfig.json
@@ -0,0 +1,4 @@
+{
+ "include": [ "./*" ],
+ "extends": "../common.tsconfig.json"
+}
\ No newline at end of file
diff --git a/js/js.translator/testData/typescript-export/selectiveExport/selectiveExport.d.ts b/js/js.translator/testData/typescript-export/selective-export/selective-export.d.ts
similarity index 100%
rename from js/js.translator/testData/typescript-export/selectiveExport/selectiveExport.d.ts
rename to js/js.translator/testData/typescript-export/selective-export/selective-export.d.ts
diff --git a/js/js.translator/testData/typescript-export/selectiveExport/selectiveExport.kt b/js/js.translator/testData/typescript-export/selective-export/selective-export.kt
similarity index 100%
rename from js/js.translator/testData/typescript-export/selectiveExport/selectiveExport.kt
rename to js/js.translator/testData/typescript-export/selective-export/selective-export.kt
diff --git a/js/js.translator/testData/typescript-export/selectiveExport/selectiveExport__main.js b/js/js.translator/testData/typescript-export/selective-export/selective-export__main.js
similarity index 100%
rename from js/js.translator/testData/typescript-export/selectiveExport/selectiveExport__main.js
rename to js/js.translator/testData/typescript-export/selective-export/selective-export__main.js
diff --git a/js/js.translator/testData/typescript-export/selectiveExport/selectiveExport__main.ts b/js/js.translator/testData/typescript-export/selective-export/selective-export__main.ts
similarity index 100%
rename from js/js.translator/testData/typescript-export/selectiveExport/selectiveExport__main.ts
rename to js/js.translator/testData/typescript-export/selective-export/selective-export__main.ts
diff --git a/js/js.translator/testData/typescript-export/selective-export/tsconfig.json b/js/js.translator/testData/typescript-export/selective-export/tsconfig.json
new file mode 100644
index 00000000000..17612c56c9d
--- /dev/null
+++ b/js/js.translator/testData/typescript-export/selective-export/tsconfig.json
@@ -0,0 +1,4 @@
+{
+ "include": [ "./*" ],
+ "extends": "../common.tsconfig.json"
+}
\ No newline at end of file