JS_IR: DCE

Could be enabled by toggling `-Xir-dce`

Box test output in js/js.translator/testData/out-min
This commit is contained in:
Anton Bannykh
2019-11-19 15:36:27 +03:00
parent faf4c05fc8
commit 81699299f5
23 changed files with 553 additions and 173 deletions
@@ -87,6 +87,7 @@ abstract class BasicBoxTest(
protected open val runMinifierByDefault: Boolean = false
protected open val skipMinification = getBoolean("kotlin.js.skipMinificationTest")
protected open val runIrDce: Boolean = false
protected open val incrementalCompilationChecksEnabled = true
@@ -103,6 +104,7 @@ abstract class BasicBoxTest(
open fun doTest(filePath: String, expectedResult: String, mainCallParameters: MainCallParameters, coroutinesPackage: String = "") {
val file = File(filePath)
val outputDir = getOutputDir(file)
val dceOutputDir = getOutputDir(file, testGroupOutputDirForMinification)
var fileContent = KotlinTestUtils.doLoadFile(file)
if (coroutinesPackage.isNotEmpty()) {
fileContent = fileContent.replace("COROUTINES_PACKAGE", coroutinesPackage)
@@ -154,10 +156,11 @@ abstract class BasicBoxTest(
val friends = module.friends.map { modules[it]?.outputFileName(outputDir) + ".meta.js" }
val outputFileName = module.outputFileName(outputDir) + ".js"
val dceOutputFileName = module.outputFileName(dceOutputDir) + ".js"
val isMainModule = mainModuleName == module.name
generateJavaScriptFile(
testFactory.tmpDir,
file.parent, module, outputFileName, dependencies, allDependencies, friends, modules.size > 1,
file.parent, module, outputFileName, dceOutputFileName, dependencies, allDependencies, friends, modules.size > 1,
!SKIP_SOURCEMAP_REMAPPING.matcher(fileContent).find(), outputPrefixFile, outputPostfixFile,
actualMainCallParameters, testPackage, testFunction, needsFullIrRuntime, isMainModule
)
@@ -212,6 +215,9 @@ abstract class BasicBoxTest(
val allJsFiles = additionalFiles + inputJsFiles + generatedJsFiles.map { it.first } + globalCommonFiles + localCommonFiles +
additionalCommonFiles + additionalMainFiles
val dceAllJsFiles = additionalFiles + inputJsFiles + generatedJsFiles.map { it.first.replace(outputDir.absolutePath, dceOutputDir.absolutePath) } +
globalCommonFiles + localCommonFiles + additionalCommonFiles + additionalMainFiles
val dontRunGeneratedCode = InTextDirectivesUtils.dontRunGeneratedCode(targetBackend, file)
if (!dontRunGeneratedCode && generateNodeJsRunner && !SKIP_NODE_JS.matcher(fileContent).find()) {
@@ -223,6 +229,10 @@ abstract class BasicBoxTest(
if (!dontRunGeneratedCode) {
runGeneratedCode(allJsFiles, testModuleName, testPackage, testFunction, expectedResult, withModuleSystem)
if (runIrDce) {
runGeneratedCode(dceAllJsFiles, testModuleName, testPackage, testFunction, expectedResult, withModuleSystem)
}
}
performAdditionalChecks(generatedJsFiles.map { it.first }, outputPrefixFile, outputPostfixFile)
@@ -340,6 +350,7 @@ abstract class BasicBoxTest(
directory: String,
module: TestModule,
outputFileName: String,
dceOutputFileName: String,
dependencies: List<String>,
allDependencies: List<String>,
friends: List<String>,
@@ -369,10 +380,11 @@ abstract class BasicBoxTest(
val sourceDirs = (testFiles + additionalFiles).map { File(it).parent }.distinct()
val config = createConfig(sourceDirs, module, dependencies, allDependencies, friends, multiModule, tmpDir, incrementalData = null)
val outputFile = File(outputFileName)
val dceOutputFile = File(dceOutputFileName)
val incrementalData = IncrementalData()
translateFiles(
psiFiles.map(TranslationUnit::SourceFile), outputFile, config, outputPrefixFile, outputPostfixFile,
psiFiles.map(TranslationUnit::SourceFile), outputFile, dceOutputFile, config, outputPrefixFile, outputPostfixFile,
mainCallParameters, incrementalData, remap, testPackage, testFunction, needsFullIrRuntime, isMainModule
)
@@ -423,7 +435,7 @@ abstract class BasicBoxTest(
val recompiledOutputFile = File(outputFile.parentFile, outputFile.nameWithoutExtension + "-recompiled.js")
translateFiles(
translationUnits, recompiledOutputFile, recompiledConfig, outputPrefixFile, outputPostfixFile,
translationUnits, recompiledOutputFile, recompiledOutputFile, recompiledConfig, outputPrefixFile, outputPostfixFile,
mainCallParameters, incrementalData, remap, testPackage, testFunction, needsFullIrRuntime, false
)
@@ -485,6 +497,7 @@ abstract class BasicBoxTest(
protected open fun translateFiles(
units: List<TranslationUnit>,
outputFile: File,
dceOutputFile: File,
config: JsConfig,
outputPrefixFile: File?,
outputPostfixFile: File?,
@@ -46,6 +46,8 @@ abstract class BasicIrBoxTest(
override val skipMinification = true
override val runIrDce: Boolean = true
// TODO Design incremental compilation for IR and add test support
override val incrementalCompilationChecksEnabled = false
@@ -62,6 +64,7 @@ abstract class BasicIrBoxTest(
override fun translateFiles(
units: List<TranslationUnit>,
outputFile: File,
dceOutputFile: File,
config: JsConfig,
outputPrefixFile: File?,
outputPostfixFile: File?,
@@ -118,12 +121,19 @@ abstract class BasicIrBoxTest(
allDependencies = resolvedLibraries,
friendDependencies = emptyList(),
mainArguments = mainCallParameters.run { if (shouldBeGenerated()) arguments() else null },
exportedDeclarations = setOf(FqName.fromSegments(listOfNotNull(testPackage, testFunction)))
exportedDeclarations = setOf(FqName.fromSegments(listOfNotNull(testPackage, testFunction))),
generateFullJs = true,
generateDceJs = runIrDce
)
val wrappedCode = wrapWithModuleEmulationMarkers(compiledModule.jsCode, moduleId = config.moduleId, moduleKind = config.moduleKind)
val wrappedCode = wrapWithModuleEmulationMarkers(compiledModule.jsCode!!, moduleId = config.moduleId, moduleKind = config.moduleKind)
outputFile.write(wrappedCode)
compiledModule.dceJsCode?.let { dceJsCode ->
val dceWrappedCode = wrapWithModuleEmulationMarkers(dceJsCode, moduleId = config.moduleId, moduleKind = config.moduleKind)
dceOutputFile.write(dceWrappedCode)
}
if (generateDts) {
val dtsFile = outputFile.withReplacedExtensionOrNull("_v5.js", ".d.ts")
dtsFile?.write(compiledModule.tsDefinitions ?: error("No ts definitions"))
+1 -1
View File
@@ -3,5 +3,5 @@ package kotlin
// see StdLibTestBase.removeAdHocAssertions
fun fail(message: String? = null): Nothing {
throw Exception(message)
throw Throwable(message)
}
@@ -1,5 +1,7 @@
// EXPECTED_REACHABLE_NODES: 1276
// IGNORE_BACKEND: JS_IR
@JsExport
class A(val x: Char)
fun typeOf(x: dynamic): String = js("typeof x")
@@ -4,6 +4,7 @@ interface I {
val a: Char
}
@JsExport
object X : I {
override var a = '#'
}
@@ -1,5 +1,7 @@
// EXPECTED_REACHABLE_NODES: 1289
// IGNORE_BACKEND: JS_IR
@JsExport
open class A {
val foo: Char
get() = 'X'
@@ -3,6 +3,7 @@ package foo
import kotlin.reflect.KProperty
@JsExport
class A {
@JsName("xx") val x: Int by B(23)
@@ -1,5 +1,6 @@
// EXPECTED_REACHABLE_NODES: 1290
@JsExport
object A {
@JsName("js_method") fun f() = "method"
+1
View File
@@ -1,5 +1,6 @@
// EXPECTED_REACHABLE_NODES: 1291
@JsExport
object A {
@JsName("js_f") fun f(x: Int) = "f($x)"
+1 -1
View File
@@ -13,7 +13,7 @@ fun box(): String {
assertEquals(a.foo, undefined)
assertNotEquals(a.toString, undefined)
val b: dynamic = object {val bar = ""}
val b: dynamic = object {@JsName("bar") val bar = ""}
assertEquals(b.foo, undefined)
assertNotEquals(b.bar, undefined)
@@ -7,6 +7,7 @@ fun deinitialize(foo: dynamic) {
}
class Foo {
@JsName("bar")
lateinit var bar: String
fun test(): String {