[JS IR] Support IR dump in JS tests
This commit is contained in:
@@ -337,6 +337,31 @@ abstract class MyAnotherAbstractTestRunner : MyAbstractTestRunner() {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
# Debugging tests (JS and WASM only):
|
||||||
|
|
||||||
|
Kotlin/JS and Kotlin/WASM tests support the following system properties to make debugging them more convenient:
|
||||||
|
- `kotlin.js.debugMode` for setting a debug mode for Kotlin/JS tests
|
||||||
|
- `kotlin.wasm.debugMode` for setting a debug mode for Kotlin/WASM tests
|
||||||
|
- `org.jetbrains.kotlin.compiler.ir.dump.strategy` for the IR dump strategy to use. Set it to `"KotlinLike"`
|
||||||
|
if you want the IR dump to be more human-readable.
|
||||||
|
|
||||||
|
Note that to pass a system property from gradle task invocation, its name should be prefixed with `fd.`.
|
||||||
|
For example, to debug Kotlin/JS tests, run:
|
||||||
|
|
||||||
|
```
|
||||||
|
./gradlew :js:js.tests:jsIrTest -Pfd.kotlin.js.debugMode=2
|
||||||
|
```
|
||||||
|
|
||||||
|
To debug WASM tests, run:
|
||||||
|
```
|
||||||
|
./gradlew :js:js.tests:wasmTest -Pfd.kotlin.wasm.debugMode=2
|
||||||
|
```
|
||||||
|
|
||||||
|
Values of the debug mode: `0` (or `false`), `1` (or `true`), `2`.
|
||||||
|
|
||||||
|
Debug mode `2` will ensure that IR is dumped to a file after each lowering phase.
|
||||||
|
The IR dumps will appear next to the generated `.js` or `.wat` file.
|
||||||
|
|
||||||
# Code style
|
# Code style
|
||||||
|
|
||||||
Please keep your abstract test runners as simple as possible. Ideally each abstract test runner should contain **only** test configuration with DSL and nothing else. All services implementations should be declared in separate files.
|
Please keep your abstract test runners as simple as possible. Ideally each abstract test runner should contain **only** test configuration with DSL and nothing else. All services implementations should be declared in separate files.
|
||||||
|
|||||||
@@ -0,0 +1,30 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||||
|
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jetbrains.kotlin.test
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents a mode fore debugging tests. Depending on what is tested, can represent different things.
|
||||||
|
* For example, in JS IR and WASM tests the selected mode will determine if the test output should include IR dumps.
|
||||||
|
*/
|
||||||
|
enum class DebugMode {
|
||||||
|
NONE,
|
||||||
|
DEBUG,
|
||||||
|
SUPER_DEBUG;
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Obtains a [DebugMode] from the system property with the given [key].
|
||||||
|
* If the property is not defined, returns [NONE].
|
||||||
|
*/
|
||||||
|
fun fromSystemProperty(key: String): DebugMode = when (System.getProperty(key)) {
|
||||||
|
"2", "super_debug" -> SUPER_DEBUG
|
||||||
|
"1", "true", "debug" -> DEBUG
|
||||||
|
"0", "false", "", null -> NONE
|
||||||
|
else -> NONE
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -6,6 +6,7 @@
|
|||||||
package org.jetbrains.kotlin.js.test.converters
|
package org.jetbrains.kotlin.js.test.converters
|
||||||
|
|
||||||
import org.jetbrains.kotlin.backend.common.phaser.PhaseConfig
|
import org.jetbrains.kotlin.backend.common.phaser.PhaseConfig
|
||||||
|
import org.jetbrains.kotlin.backend.common.phaser.toPhaseMap
|
||||||
import org.jetbrains.kotlin.backend.common.serialization.signature.IdSignatureDescriptor
|
import org.jetbrains.kotlin.backend.common.serialization.signature.IdSignatureDescriptor
|
||||||
import org.jetbrains.kotlin.config.CommonConfigurationKeys
|
import org.jetbrains.kotlin.config.CommonConfigurationKeys
|
||||||
import org.jetbrains.kotlin.config.CompilerConfiguration
|
import org.jetbrains.kotlin.config.CompilerConfiguration
|
||||||
@@ -34,6 +35,7 @@ import org.jetbrains.kotlin.name.FqName
|
|||||||
import org.jetbrains.kotlin.psi2ir.Psi2IrConfiguration
|
import org.jetbrains.kotlin.psi2ir.Psi2IrConfiguration
|
||||||
import org.jetbrains.kotlin.psi2ir.Psi2IrTranslator
|
import org.jetbrains.kotlin.psi2ir.Psi2IrTranslator
|
||||||
import org.jetbrains.kotlin.serialization.js.ModuleKind
|
import org.jetbrains.kotlin.serialization.js.ModuleKind
|
||||||
|
import org.jetbrains.kotlin.test.DebugMode
|
||||||
import org.jetbrains.kotlin.test.directives.JsEnvironmentConfigurationDirectives
|
import org.jetbrains.kotlin.test.directives.JsEnvironmentConfigurationDirectives
|
||||||
import org.jetbrains.kotlin.test.frontend.classic.ClassicFrontendOutputArtifact
|
import org.jetbrains.kotlin.test.frontend.classic.ClassicFrontendOutputArtifact
|
||||||
import org.jetbrains.kotlin.test.frontend.classic.moduleDescriptorProvider
|
import org.jetbrains.kotlin.test.frontend.classic.moduleDescriptorProvider
|
||||||
@@ -105,6 +107,21 @@ class JsIrBackendFacade(
|
|||||||
).dump(module, firstTimeCompilation)
|
).dump(module, firstTimeCompilation)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val debugMode = DebugMode.fromSystemProperty("kotlin.js.debugMode")
|
||||||
|
val phaseConfig = if (debugMode >= DebugMode.SUPER_DEBUG) {
|
||||||
|
val dumpOutputDir = File(
|
||||||
|
JsEnvironmentConfigurator.getJsArtifactsOutputDir(testServices),
|
||||||
|
JsEnvironmentConfigurator.getJsArtifactSimpleName(testServices, module.name) + "-irdump"
|
||||||
|
)
|
||||||
|
PhaseConfig(
|
||||||
|
jsPhases,
|
||||||
|
dumpToDirectory = dumpOutputDir.path,
|
||||||
|
toDumpStateAfter = jsPhases.toPhaseMap().values.toSet()
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
PhaseConfig(jsPhases)
|
||||||
|
}
|
||||||
|
|
||||||
val loweredIr = compileIr(
|
val loweredIr = compileIr(
|
||||||
irModuleFragment,
|
irModuleFragment,
|
||||||
MainModule.Klib(inputArtifact.outputFile.absolutePath),
|
MainModule.Klib(inputArtifact.outputFile.absolutePath),
|
||||||
@@ -113,7 +130,7 @@ class JsIrBackendFacade(
|
|||||||
irModuleFragment.irBuiltins,
|
irModuleFragment.irBuiltins,
|
||||||
symbolTable,
|
symbolTable,
|
||||||
deserializer,
|
deserializer,
|
||||||
PhaseConfig(jsPhases), // TODO debug mode
|
phaseConfig,
|
||||||
exportedDeclarations = setOf(FqName.fromSegments(listOfNotNull(testPackage, TEST_FUNCTION))),
|
exportedDeclarations = setOf(FqName.fromSegments(listOfNotNull(testPackage, TEST_FUNCTION))),
|
||||||
dceDriven = false,
|
dceDriven = false,
|
||||||
dceRuntimeDiagnostic = null,
|
dceRuntimeDiagnostic = null,
|
||||||
@@ -341,4 +358,4 @@ fun String.augmentWithModuleName(moduleName: String): String {
|
|||||||
return removeSuffix("_v5.js") + "-${moduleName}_v5.js"
|
return removeSuffix("_v5.js") + "-${moduleName}_v5.js"
|
||||||
}
|
}
|
||||||
|
|
||||||
fun File.augmentWithModuleName(moduleName: String): File = File(absolutePath.augmentWithModuleName(moduleName))
|
fun File.augmentWithModuleName(moduleName: String): File = File(absolutePath.augmentWithModuleName(moduleName))
|
||||||
|
|||||||
@@ -32,6 +32,7 @@ import org.jetbrains.kotlin.psi.KtFile
|
|||||||
import org.jetbrains.kotlin.psi.KtNamedFunction
|
import org.jetbrains.kotlin.psi.KtNamedFunction
|
||||||
import org.jetbrains.kotlin.psi.KtPsiFactory
|
import org.jetbrains.kotlin.psi.KtPsiFactory
|
||||||
import org.jetbrains.kotlin.resolve.CompilerEnvironment
|
import org.jetbrains.kotlin.resolve.CompilerEnvironment
|
||||||
|
import org.jetbrains.kotlin.test.DebugMode
|
||||||
import org.jetbrains.kotlin.test.Directives
|
import org.jetbrains.kotlin.test.Directives
|
||||||
import org.jetbrains.kotlin.test.KotlinTestWithEnvironment
|
import org.jetbrains.kotlin.test.KotlinTestWithEnvironment
|
||||||
import org.jetbrains.kotlin.test.TestFiles
|
import org.jetbrains.kotlin.test.TestFiles
|
||||||
@@ -147,15 +148,9 @@ abstract class BasicWasmBoxTest(
|
|||||||
testFunction: String
|
testFunction: String
|
||||||
) {
|
) {
|
||||||
val filesToCompile = units.map { (it as TranslationUnit.SourceFile).file }
|
val filesToCompile = units.map { (it as TranslationUnit.SourceFile).file }
|
||||||
val debugMode: Int = when (System.getProperty("kotlin.wasm.debugMode")) {
|
val debugMode = DebugMode.fromSystemProperty("kotlin.wasm.debugMode")
|
||||||
"2", "super_debug" -> 2
|
val phaseConfig = if (debugMode >= DebugMode.DEBUG) {
|
||||||
"1", "true", "debug" -> 1
|
val allPhasesSet = if (debugMode >= DebugMode.SUPER_DEBUG) wasmPhases.toPhaseMap().values.toSet() else emptySet()
|
||||||
"0", "false", "", null -> 0
|
|
||||||
else -> 0
|
|
||||||
}
|
|
||||||
|
|
||||||
val phaseConfig = if (debugMode >= 1) {
|
|
||||||
val allPhasesSet = if (debugMode >= 2) wasmPhases.toPhaseMap().values.toSet() else emptySet()
|
|
||||||
val dumpOutputDir = File(outputWatFile.parent, outputWatFile.nameWithoutExtension + "-irdump")
|
val dumpOutputDir = File(outputWatFile.parent, outputWatFile.nameWithoutExtension + "-irdump")
|
||||||
println("\n ------ Dumping phases to file://$dumpOutputDir")
|
println("\n ------ Dumping phases to file://$dumpOutputDir")
|
||||||
println("\n ------ KT file://${testFile.absolutePath}")
|
println("\n ------ KT file://${testFile.absolutePath}")
|
||||||
@@ -211,7 +206,7 @@ abstract class BasicWasmBoxTest(
|
|||||||
|
|
||||||
outputJsFile.write(compilerResult.js + "\n" + testRunner)
|
outputJsFile.write(compilerResult.js + "\n" + testRunner)
|
||||||
|
|
||||||
if (debugMode >= 2) {
|
if (debugMode >= DebugMode.SUPER_DEBUG) {
|
||||||
createDirectoryToRunInBrowser(outputBrowserDir, compilerResult)
|
createDirectoryToRunInBrowser(outputBrowserDir, compilerResult)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user