From e30bdb8dc933421ee2730a799dba2b0fa1336ce3 Mon Sep 17 00:00:00 2001 From: Svyatoslav Kuzmich Date: Tue, 23 Apr 2019 23:25:12 +0300 Subject: [PATCH] Fix hanling module names that require escaping --- .../irToJs/ModuleWrapperTranslation.kt | 5 +++- .../backend/js/utils/StableNamesCollector.kt | 2 +- .../jetbrains/kotlin/js/test/BasicBoxTest.kt | 26 +++++++++++++++---- .../ir/semantics/IrBoxJsTestGenerated.java | 23 ++++++++++++++++ .../js/test/semantics/BoxJsTestGenerated.java | 23 ++++++++++++++++ .../box/export/nonIndetifierModuleName.kt | 15 +++++++++++ .../testData/box/export/reservedModuleName.kt | 15 +++++++++++ 7 files changed, 102 insertions(+), 7 deletions(-) create mode 100644 js/js.translator/testData/box/export/nonIndetifierModuleName.kt create mode 100644 js/js.translator/testData/box/export/reservedModuleName.kt diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/transformers/irToJs/ModuleWrapperTranslation.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/transformers/irToJs/ModuleWrapperTranslation.kt index 246eb6c9cbc..1d9aace93e2 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/transformers/irToJs/ModuleWrapperTranslation.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/transformers/irToJs/ModuleWrapperTranslation.kt @@ -5,12 +5,15 @@ package org.jetbrains.kotlin.ir.backend.js.transformers.irToJs +import org.jetbrains.kotlin.ir.backend.js.utils.RESERVED_IDENTIFIERS import org.jetbrains.kotlin.js.backend.ast.* +import org.jetbrains.kotlin.js.naming.isValidES5Identifier import org.jetbrains.kotlin.serialization.js.ModuleKind object ModuleWrapperTranslation { object Namer { - fun requiresEscaping(name: String) = false + fun requiresEscaping(name: String) = + !name.isValidES5Identifier() || name in RESERVED_IDENTIFIERS } fun wrap( diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/utils/StableNamesCollector.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/utils/StableNamesCollector.kt index 5821b7fe1ef..dfcee49e80b 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/utils/StableNamesCollector.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/utils/StableNamesCollector.kt @@ -83,7 +83,7 @@ class StableNamesCollector : IrElementVisitorVoid { } } -private val RESERVED_IDENTIFIERS = setOf( +val RESERVED_IDENTIFIERS = setOf( // keywords "await", "break", "case", "catch", "continue", "debugger", "default", "delete", "do", "else", "finally", "for", "function", "if", "in", "instanceof", "new", "return", "switch", "throw", "try", "typeof", "var", "void", "while", "with", diff --git a/js/js.tests/test/org/jetbrains/kotlin/js/test/BasicBoxTest.kt b/js/js.tests/test/org/jetbrains/kotlin/js/test/BasicBoxTest.kt index ff4f20a9675..b43e58086ad 100644 --- a/js/js.tests/test/org/jetbrains/kotlin/js/test/BasicBoxTest.kt +++ b/js/js.tests/test/org/jetbrains/kotlin/js/test/BasicBoxTest.kt @@ -116,6 +116,9 @@ abstract class BasicBoxTest( val outputPrefixFile = getOutputPrefixFile(filePath) val outputPostfixFile = getOutputPostfixFile(filePath) + val runPlainBoxFunction = RUN_PLAIN_BOX_FUNCTION.matcher(fileContent).find() + val inferMainModule = INFER_MAIN_MODULE.matcher(fileContent).find() + TestFileFactoryImpl(coroutinesPackage).use { testFactory -> val inputFiles = KotlinTestUtils.createTestFiles(file.name, fileContent, testFactory, true, coroutinesPackage) val modules = inputFiles @@ -128,10 +131,16 @@ abstract class BasicBoxTest( val orderedModules = DFS.topologicalOrder(modules.values) { module -> module.dependencies.mapNotNull { modules[it] } } - val testPackage = testFactory.testPackage + val testPackage = if (runPlainBoxFunction) null else testFactory.testPackage + val testFunction = TEST_FUNCTION - val mainModuleName = if (TEST_MODULE in modules) TEST_MODULE else DEFAULT_MODULE + val mainModuleName = when { + inferMainModule -> orderedModules.last().name + TEST_MODULE in modules -> TEST_MODULE + else -> DEFAULT_MODULE + } + val testModuleName = if (runPlainBoxFunction) null else mainModuleName val mainModule = modules[mainModuleName] ?: error("No module with name \"$mainModuleName\"") val generatedJsFiles = orderedModules.asReversed().mapNotNull { module -> @@ -202,7 +211,7 @@ abstract class BasicBoxTest( } if (!dontRunGeneratedCode) { - runGeneratedCode(allJsFiles, mainModuleName, testPackage, testFunction, expectedResult, withModuleSystem) + runGeneratedCode(allJsFiles, testModuleName, testPackage, testFunction, expectedResult, withModuleSystem) } performAdditionalChecks(generatedJsFiles.map { it.first }, outputPrefixFile, outputPostfixFile) @@ -244,7 +253,7 @@ abstract class BasicBoxTest( allJsFiles = allJsFiles, generatedJsFiles = generatedJsFiles, expectedResult = expectedResult, - testModuleName = mainModuleName, + testModuleName = testModuleName, testPackage = testPackage, testFunction = testFunction, withModuleSystem = withModuleSystem, @@ -648,7 +657,7 @@ abstract class BasicBoxTest( private fun minifyAndRun( workDir: File, allJsFiles: List, generatedJsFiles: List>, - expectedResult: String, testModuleName: String, testPackage: String?, testFunction: String, withModuleSystem: Boolean, + expectedResult: String, testModuleName: String?, testPackage: String?, testFunction: String, withModuleSystem: Boolean, minificationThresholdChecker: (Int) -> Unit ) { val kotlinJsLib = DIST_DIR_JS_PATH + "kotlin.js" @@ -814,6 +823,13 @@ abstract class BasicBoxTest( private val MODULE_KIND_PATTERN = Pattern.compile("^// *MODULE_KIND: *(.+)$", Pattern.MULTILINE) private val NO_MODULE_SYSTEM_PATTERN = Pattern.compile("^// *NO_JS_MODULE_SYSTEM", Pattern.MULTILINE) + + // Infer main module using dependency graph + private val INFER_MAIN_MODULE = Pattern.compile("^// *INFER_MAIN_MODULE", Pattern.MULTILINE) + + // Run top level box function + private val RUN_PLAIN_BOX_FUNCTION = Pattern.compile("^// *RUN_PLAIN_BOX_FUNCTION", Pattern.MULTILINE) + private val NO_INLINE_PATTERN = Pattern.compile("^// *NO_INLINE *$", Pattern.MULTILINE) private val SKIP_NODE_JS = Pattern.compile("^// *SKIP_NODE_JS *$", Pattern.MULTILINE) private val SKIP_MINIFICATION = Pattern.compile("^// *SKIP_MINIFICATION *$", Pattern.MULTILINE) diff --git a/js/js.tests/test/org/jetbrains/kotlin/js/test/ir/semantics/IrBoxJsTestGenerated.java b/js/js.tests/test/org/jetbrains/kotlin/js/test/ir/semantics/IrBoxJsTestGenerated.java index 34145597590..ab71c5eb4d1 100644 --- a/js/js.tests/test/org/jetbrains/kotlin/js/test/ir/semantics/IrBoxJsTestGenerated.java +++ b/js/js.tests/test/org/jetbrains/kotlin/js/test/ir/semantics/IrBoxJsTestGenerated.java @@ -1398,6 +1398,29 @@ public class IrBoxJsTestGenerated extends AbstractIrBoxJsTest { } } + @TestMetadata("js/js.translator/testData/box/export") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class Export extends AbstractIrBoxJsTest { + private void runTest(String testDataFilePath) throws Exception { + KotlinTestUtils.runTest0(this::doTest, TargetBackend.JS_IR, testDataFilePath); + } + + public void testAllFilesPresentInExport() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("js/js.translator/testData/box/export"), Pattern.compile("^([^_](.+))\\.kt$"), TargetBackend.JS_IR, true); + } + + @TestMetadata("nonIndetifierModuleName.kt") + public void testNonIndetifierModuleName() throws Exception { + runTest("js/js.translator/testData/box/export/nonIndetifierModuleName.kt"); + } + + @TestMetadata("reservedModuleName.kt") + public void testReservedModuleName() throws Exception { + runTest("js/js.translator/testData/box/export/reservedModuleName.kt"); + } + } + @TestMetadata("js/js.translator/testData/box/expression") @TestDataPath("$PROJECT_ROOT") @RunWith(JUnit3RunnerWithInners.class) diff --git a/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/BoxJsTestGenerated.java b/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/BoxJsTestGenerated.java index afbdd7de006..3e16971caca 100644 --- a/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/BoxJsTestGenerated.java +++ b/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/BoxJsTestGenerated.java @@ -1403,6 +1403,29 @@ public class BoxJsTestGenerated extends AbstractBoxJsTest { } } + @TestMetadata("js/js.translator/testData/box/export") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class Export extends AbstractBoxJsTest { + private void runTest(String testDataFilePath) throws Exception { + KotlinTestUtils.runTest0(this::doTest, TargetBackend.JS, testDataFilePath); + } + + public void testAllFilesPresentInExport() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("js/js.translator/testData/box/export"), Pattern.compile("^([^_](.+))\\.kt$"), TargetBackend.JS, true); + } + + @TestMetadata("nonIndetifierModuleName.kt") + public void testNonIndetifierModuleName() throws Exception { + runTest("js/js.translator/testData/box/export/nonIndetifierModuleName.kt"); + } + + @TestMetadata("reservedModuleName.kt") + public void testReservedModuleName() throws Exception { + runTest("js/js.translator/testData/box/export/reservedModuleName.kt"); + } + } + @TestMetadata("js/js.translator/testData/box/expression") @TestDataPath("$PROJECT_ROOT") @RunWith(JUnit3RunnerWithInners.class) diff --git a/js/js.translator/testData/box/export/nonIndetifierModuleName.kt b/js/js.translator/testData/box/export/nonIndetifierModuleName.kt new file mode 100644 index 00000000000..bd4fda03c13 --- /dev/null +++ b/js/js.translator/testData/box/export/nonIndetifierModuleName.kt @@ -0,0 +1,15 @@ +// EXPECTED_REACHABLE_NODES: 1270 +// SKIP_MINIFICATION +// RUN_PLAIN_BOX_FUNCTION +// INFER_MAIN_MODULE +// SKIP_NODE_JS + +// MODULE: non-identifier-module-name +// FILE: lib.kt +@JsName("foo") +public fun foo(k: String): String = "O$k" + +// FILE: test.js +function box() { + return this["non-identifier-module-name"].foo("K"); +} diff --git a/js/js.translator/testData/box/export/reservedModuleName.kt b/js/js.translator/testData/box/export/reservedModuleName.kt new file mode 100644 index 00000000000..e1caac333d6 --- /dev/null +++ b/js/js.translator/testData/box/export/reservedModuleName.kt @@ -0,0 +1,15 @@ +// IGNORE_BACKEND: JS +// EXPECTED_REACHABLE_NODES: 1270 +// SKIP_MINIFICATION +// RUN_PLAIN_BOX_FUNCTION +// INFER_MAIN_MODULE + +// MODULE: if +// FILE: lib.kt +@JsName("foo") +public fun foo(k: String): String = "O$k" + +// FILE: test.js +function box() { + return this["if"].foo("K"); +} \ No newline at end of file