Fix hanling module names that require escaping

This commit is contained in:
Svyatoslav Kuzmich
2019-04-23 23:25:12 +03:00
parent c3a439a829
commit e30bdb8dc9
7 changed files with 102 additions and 7 deletions
@@ -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(
@@ -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",
@@ -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<String>, generatedJsFiles: List<Pair<String, TestModule>>,
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)
@@ -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)
@@ -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)
@@ -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");
}
@@ -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");
}