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 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.backend.ast.*
import org.jetbrains.kotlin.js.naming.isValidES5Identifier
import org.jetbrains.kotlin.serialization.js.ModuleKind import org.jetbrains.kotlin.serialization.js.ModuleKind
object ModuleWrapperTranslation { object ModuleWrapperTranslation {
object Namer { object Namer {
fun requiresEscaping(name: String) = false fun requiresEscaping(name: String) =
!name.isValidES5Identifier() || name in RESERVED_IDENTIFIERS
} }
fun wrap( fun wrap(
@@ -83,7 +83,7 @@ class StableNamesCollector : IrElementVisitorVoid {
} }
} }
private val RESERVED_IDENTIFIERS = setOf( val RESERVED_IDENTIFIERS = setOf(
// keywords // keywords
"await", "break", "case", "catch", "continue", "debugger", "default", "delete", "do", "else", "finally", "for", "function", "if", "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", "in", "instanceof", "new", "return", "switch", "throw", "try", "typeof", "var", "void", "while", "with",
@@ -116,6 +116,9 @@ abstract class BasicBoxTest(
val outputPrefixFile = getOutputPrefixFile(filePath) val outputPrefixFile = getOutputPrefixFile(filePath)
val outputPostfixFile = getOutputPostfixFile(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 -> TestFileFactoryImpl(coroutinesPackage).use { testFactory ->
val inputFiles = KotlinTestUtils.createTestFiles(file.name, fileContent, testFactory, true, coroutinesPackage) val inputFiles = KotlinTestUtils.createTestFiles(file.name, fileContent, testFactory, true, coroutinesPackage)
val modules = inputFiles val modules = inputFiles
@@ -128,10 +131,16 @@ abstract class BasicBoxTest(
val orderedModules = DFS.topologicalOrder(modules.values) { module -> module.dependencies.mapNotNull { modules[it] } } 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 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 mainModule = modules[mainModuleName] ?: error("No module with name \"$mainModuleName\"")
val generatedJsFiles = orderedModules.asReversed().mapNotNull { module -> val generatedJsFiles = orderedModules.asReversed().mapNotNull { module ->
@@ -202,7 +211,7 @@ abstract class BasicBoxTest(
} }
if (!dontRunGeneratedCode) { if (!dontRunGeneratedCode) {
runGeneratedCode(allJsFiles, mainModuleName, testPackage, testFunction, expectedResult, withModuleSystem) runGeneratedCode(allJsFiles, testModuleName, testPackage, testFunction, expectedResult, withModuleSystem)
} }
performAdditionalChecks(generatedJsFiles.map { it.first }, outputPrefixFile, outputPostfixFile) performAdditionalChecks(generatedJsFiles.map { it.first }, outputPrefixFile, outputPostfixFile)
@@ -244,7 +253,7 @@ abstract class BasicBoxTest(
allJsFiles = allJsFiles, allJsFiles = allJsFiles,
generatedJsFiles = generatedJsFiles, generatedJsFiles = generatedJsFiles,
expectedResult = expectedResult, expectedResult = expectedResult,
testModuleName = mainModuleName, testModuleName = testModuleName,
testPackage = testPackage, testPackage = testPackage,
testFunction = testFunction, testFunction = testFunction,
withModuleSystem = withModuleSystem, withModuleSystem = withModuleSystem,
@@ -648,7 +657,7 @@ abstract class BasicBoxTest(
private fun minifyAndRun( private fun minifyAndRun(
workDir: File, allJsFiles: List<String>, generatedJsFiles: List<Pair<String, TestModule>>, 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 minificationThresholdChecker: (Int) -> Unit
) { ) {
val kotlinJsLib = DIST_DIR_JS_PATH + "kotlin.js" 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 MODULE_KIND_PATTERN = Pattern.compile("^// *MODULE_KIND: *(.+)$", Pattern.MULTILINE)
private val NO_MODULE_SYSTEM_PATTERN = Pattern.compile("^// *NO_JS_MODULE_SYSTEM", 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 NO_INLINE_PATTERN = Pattern.compile("^// *NO_INLINE *$", Pattern.MULTILINE)
private val SKIP_NODE_JS = Pattern.compile("^// *SKIP_NODE_JS *$", Pattern.MULTILINE) private val SKIP_NODE_JS = Pattern.compile("^// *SKIP_NODE_JS *$", Pattern.MULTILINE)
private val SKIP_MINIFICATION = Pattern.compile("^// *SKIP_MINIFICATION *$", 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") @TestMetadata("js/js.translator/testData/box/expression")
@TestDataPath("$PROJECT_ROOT") @TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class) @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") @TestMetadata("js/js.translator/testData/box/expression")
@TestDataPath("$PROJECT_ROOT") @TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class) @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");
}