diff --git a/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/arguments/CommonCompilerArguments.kt b/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/arguments/CommonCompilerArguments.kt index 001ee7175af..e87f878d2e7 100644 --- a/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/arguments/CommonCompilerArguments.kt +++ b/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/arguments/CommonCompilerArguments.kt @@ -238,6 +238,18 @@ abstract class CommonCompilerArguments : CommonToolArguments() { ) var namesExcludedFromDumping: Array? by FreezableVar(null) + @Argument( + value = "-Xdump-directory", + description = "Dump backend state into directory" + ) + var dumpDirectory: String? by FreezableVar(null) + + @Argument( + value = "-Xdump-fqname", + description = "FqName of declaration that should be dumped" + ) + var dumpOnlyFqName: String? by FreezableVar(null) + @Argument( value = "-Xphases-to-validate-before", description = "Validate backend state before these phases" diff --git a/compiler/cli/cli-js/src/org/jetbrains/kotlin/cli/js/K2JsIrCompiler.kt b/compiler/cli/cli-js/src/org/jetbrains/kotlin/cli/js/K2JsIrCompiler.kt index 7a9a4b98742..b960ab370d0 100644 --- a/compiler/cli/cli-js/src/org/jetbrains/kotlin/cli/js/K2JsIrCompiler.kt +++ b/compiler/cli/cli-js/src/org/jetbrains/kotlin/cli/js/K2JsIrCompiler.kt @@ -29,8 +29,9 @@ import org.jetbrains.kotlin.incremental.components.LookupTracker import org.jetbrains.kotlin.incremental.js.IncrementalDataProvider import org.jetbrains.kotlin.incremental.js.IncrementalResultsConsumer import org.jetbrains.kotlin.ir.backend.js.KlibModuleRef -import org.jetbrains.kotlin.ir.backend.js.generateKLib import org.jetbrains.kotlin.ir.backend.js.compile +import org.jetbrains.kotlin.ir.backend.js.generateKLib +import org.jetbrains.kotlin.ir.backend.js.jsPhases import org.jetbrains.kotlin.js.config.EcmaVersion import org.jetbrains.kotlin.js.config.JSConfigurationKeys import org.jetbrains.kotlin.js.config.JsConfig @@ -223,10 +224,13 @@ class K2JsIrCompiler : CLICompiler() { } if (produceKind == ProduceKind.JS || produceKind == ProduceKind.DEFAULT) { + val phaseConfig = createPhaseConfig(jsPhases, arguments, messageCollector) + val compiledModule = compile( project, sourcesFiles, configuration, + phaseConfig, immediateDependencies = dependencies, allDependencies = dependencies, friendDependencies = friendDependencies, diff --git a/compiler/cli/src/org/jetbrains/kotlin/cli/common/createPhaseConfig.kt b/compiler/cli/src/org/jetbrains/kotlin/cli/common/createPhaseConfig.kt index b5efe428a51..df6d01d3947 100644 --- a/compiler/cli/src/org/jetbrains/kotlin/cli/common/createPhaseConfig.kt +++ b/compiler/cli/src/org/jetbrains/kotlin/cli/common/createPhaseConfig.kt @@ -29,6 +29,8 @@ fun createPhaseConfig( val bothDumpSet = phaseSetFromArguments(phases, arguments.phasesToDump, ::report) val toDumpStateBefore = beforeDumpSet + bothDumpSet val toDumpStateAfter = afterDumpSet + bothDumpSet + val dumpDirectory = arguments.dumpDirectory + val dumpOnlyFqName = arguments.dumpOnlyFqName val beforeValidateSet = phaseSetFromArguments(phases, arguments.phasesToValidateBefore, ::report) val afterValidateSet = phaseSetFromArguments(phases, arguments.phasesToValidateAfter, ::report) val bothValidateSet = phaseSetFromArguments(phases, arguments.phasesToValidate, ::report) @@ -42,9 +44,20 @@ fun createPhaseConfig( val checkStickyConditions = arguments.checkStickyPhaseConditions return PhaseConfig( - compoundPhase, phases, enabled, verbose, toDumpStateBefore, toDumpStateAfter, toValidateStateBefore, toValidateStateAfter, + compoundPhase, + phases, + enabled, + verbose, + toDumpStateBefore, + toDumpStateAfter, + dumpDirectory, + dumpOnlyFqName, + toValidateStateBefore, + toValidateStateAfter, namesOfElementsExcludedFromDumping, - needProfiling, checkConditions, checkStickyConditions + needProfiling, + checkConditions, + checkStickyConditions ).also { if (arguments.listPhases) { it.list() diff --git a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/phaser/CompilerPhase.kt b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/phaser/CompilerPhase.kt index c3ac1bb835d..32acb020512 100644 --- a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/phaser/CompilerPhase.kt +++ b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/phaser/CompilerPhase.kt @@ -11,11 +11,12 @@ import kotlin.system.measureTimeMillis class PhaserState( val alreadyDone: MutableSet = mutableSetOf(), var depth: Int = 0, + var phaseCount: Int = 0, val stickyPostconditions: MutableSet> = mutableSetOf() ) // Copy state, forgetting the sticky postconditions (which will not be applicable to the new type) -fun PhaserState.changeType() = PhaserState(alreadyDone, depth, mutableSetOf()) +fun PhaserState.changeType() = PhaserState(alreadyDone, depth, phaseCount, mutableSetOf()) fun PhaserState.downlevel(nlevels: Int = 1, block: () -> R): R { @@ -51,15 +52,27 @@ interface NamedCompilerPhase : val prerequisite: Set get() = emptySet() val preconditions: Set> val postconditions: Set> + val actionsBefore: Set> + val actionsAfter: Set> } typealias AnyNamedPhase = NamedCompilerPhase<*, *, *> enum class BeforeOrAfter { BEFORE, AFTER } -interface PhaseDumperVerifier { - fun dump(phase: AnyNamedPhase, phaseConfig: PhaseConfig, data: Data, beforeOrAfter: BeforeOrAfter) - fun verify(context: Context, data: Data) -} +data class ActionState( + val config: PhaseConfig, + val phase: AnyNamedPhase, + val phaseCount: Int, + val beforeOrAfter: BeforeOrAfter +) + +typealias Action = (ActionState, Data, Context) -> Unit + +infix operator fun Action.plus(other: Action): Action = + { phaseState, data, context -> + this(phaseState, data, context) + other(phaseState, data, context) + } abstract class AbstractNamedPhaseWrapper( override val name: String, @@ -69,10 +82,10 @@ abstract class AbstractNamedPhaseWrapper> = emptySet(), override val postconditions: Set> = emptySet(), override val stickyPostconditions: Set> = emptySet(), + override val actionsBefore: Set> = emptySet(), + override val actionsAfter: Set> = emptySet(), private val nlevels: Int = 0 ) : NamedCompilerPhase { - abstract val inputDumperVerifier: PhaseDumperVerifier - abstract val outputDumperVerifier: PhaseDumperVerifier override fun invoke(phaseConfig: PhaseConfig, phaserState: PhaserState, context: Context, input: Input): Output { if (this is SameTypeCompilerPhase<*, *> && @@ -88,18 +101,20 @@ abstract class AbstractNamedPhaseWrapper, context: Context, input: Input) { + val state = ActionState(phaseConfig, this, phaserState.phaseCount, BeforeOrAfter.BEFORE) + for (action in actionsBefore) action(state, input, context) + if (phaseConfig.checkConditions) { for (pre in preconditions) pre(input) } @@ -116,8 +131,9 @@ abstract class AbstractNamedPhaseWrapper, context: Context, output: Output) { - checkAndRun(phaseConfig.toDumpStateAfter) { outputDumperVerifier.dump(this, phaseConfig, output, BeforeOrAfter.AFTER) } - checkAndRun(phaseConfig.toValidateStateAfter) { outputDumperVerifier.verify(context, output) } + val state = ActionState(phaseConfig, this, phaserState.phaseCount, BeforeOrAfter.AFTER) + for (action in actionsAfter) action(state, output, context) + if (phaseConfig.checkConditions) { for (post in postconditions) post(output) for (post in stickyPostconditions) post(output) @@ -158,11 +174,8 @@ class SameTypeNamedPhaseWrapper( preconditions: Set> = emptySet(), postconditions: Set> = emptySet(), stickyPostconditions: Set> = lower.stickyPostconditions, - nlevels: Int = 0, - val dumperVerifier: PhaseDumperVerifier + actions: Set> = emptySet(), + nlevels: Int = 0 ) : AbstractNamedPhaseWrapper( - name, description, prerequisite, lower, preconditions, postconditions, stickyPostconditions, nlevels -), SameTypeCompilerPhase { - override val inputDumperVerifier get() = dumperVerifier - override val outputDumperVerifier get() = dumperVerifier -} + name, description, prerequisite, lower, preconditions, postconditions, stickyPostconditions, actions, actions, nlevels +), SameTypeCompilerPhase diff --git a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/phaser/DumperVerifier.kt b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/phaser/DumperVerifier.kt index 37d308888f4..ba68f056be7 100644 --- a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/phaser/DumperVerifier.kt +++ b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/phaser/DumperVerifier.kt @@ -5,48 +5,115 @@ package org.jetbrains.kotlin.backend.common.phaser -import org.jetbrains.kotlin.backend.common.CommonBackendContext import org.jetbrains.kotlin.ir.IrElement -import org.jetbrains.kotlin.ir.declarations.IrFile -import org.jetbrains.kotlin.ir.declarations.IrModuleFragment -import org.jetbrains.kotlin.ir.declarations.name +import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.util.dump +import org.jetbrains.kotlin.ir.util.fqNameWhenAvailable +import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid +import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid +import org.jetbrains.kotlin.ir.visitors.acceptVoid +import org.jetbrains.kotlin.name.FqName +import java.io.File -abstract class IrPhaseDumperVerifier( - val verifier: (Context, Data) -> Unit -) : PhaseDumperVerifier { - abstract fun Data.getElementName(): String +private val IrElement.elementName: String + get() = when (this) { + is IrModuleFragment -> + this.name.asString() - // TODO: use a proper logger. - override fun dump(phase: AnyNamedPhase, phaseConfig: PhaseConfig, data: Data, beforeOrAfter: BeforeOrAfter) { - fun separator(title: String) = println("\n\n--- $title ----------------------\n") + is IrFile -> + this.name - if (!shouldBeDumped(phaseConfig, data)) return - - val beforeOrAfterStr = beforeOrAfter.name.toLowerCase() - val title = "IR for ${data.getElementName()} $beforeOrAfterStr ${phase.description}" - separator(title) - println(data.dump()) + else -> + this.toString() } - override fun verify(context: Context, data: Data) = verifier(context, data) +private fun ActionState.isDumpNeeded() = + phase in when (beforeOrAfter) { + BeforeOrAfter.BEFORE -> config.toDumpStateBefore + BeforeOrAfter.AFTER -> config.toDumpStateAfter + } - private fun shouldBeDumped(phaseConfig: PhaseConfig, input: Data) = - input.getElementName() !in phaseConfig.namesOfElementsExcludedFromDumping +private fun ActionState.isValidationNeeded() = + phase in when (beforeOrAfter) { + BeforeOrAfter.BEFORE -> config.toValidateStateBefore + BeforeOrAfter.AFTER -> config.toValidateStateAfter + } + +fun makeDumpAction(dumper: Action): Action = + { phaseState, data, context -> + if (phaseState.isDumpNeeded()) + dumper(phaseState, data, context) + } + +fun makeVerifyAction(verifier: (Context, Data) -> Unit): Action = + { phaseState, data, context -> + if (phaseState.isValidationNeeded()) + verifier(context, data) + } + +fun dumpIrElement(actionState: ActionState, data: IrElement, context: Any?): String { + val beforeOrAfterStr = actionState.beforeOrAfter.name.toLowerCase() + + var dumpText: String = "" + val elementName: String + + val dumpOnlyFqName = actionState.config.dumpOnlyFqName + if (dumpOnlyFqName != null) { + elementName = dumpOnlyFqName + data.acceptVoid(object : IrElementVisitorVoid { + override fun visitElement(element: IrElement) { + element.acceptChildrenVoid(this) + } + + override fun visitDeclaration(declaration: IrDeclaration) { + if (declaration is IrDeclarationWithName && FqName(dumpOnlyFqName) == declaration.fqNameWhenAvailable) { + dumpText += declaration.dump() + } else { + super.visitDeclaration(declaration) + } + } + }) + } else { + elementName = data.elementName + dumpText = data.dump() + } + + val title = "-- IR for $elementName $beforeOrAfterStr ${actionState.phase.description}\n" + return title + dumpText } -class IrFileDumperVerifier(verifier: (Context, IrFile) -> Unit) : - IrPhaseDumperVerifier(verifier) { - override fun IrFile.getElementName() = name -} +typealias Dumper = (ActionState, Data, Context) -> String? -class IrModuleDumperVerifier(verifier: (Context, IrModuleFragment) -> Unit) : - IrPhaseDumperVerifier(verifier) { - override fun IrModuleFragment.getElementName() = name.asString() -} +fun dumpToFile( + fileExtension: String, + dumper: Dumper +): Action = + fun(actionState: ActionState, data: Data, context: Context) { + val directoryPath = actionState.config.dumpToDirectory ?: return + val dumpContent = dumper(actionState, data, context) ?: return -class EmptyDumperVerifier : PhaseDumperVerifier { - override fun dump(phase: AnyNamedPhase, phaseConfig: PhaseConfig, data: Data, beforeOrAfter: BeforeOrAfter) {} - override fun verify(context: Context, data: Data) {} -} + val directoryFile = File(directoryPath) + if (!directoryFile.isDirectory) + if (!directoryFile.mkdirs()) + error("Can't create directory for IR dumps at $directoryPath") + // Make dump files in a directory sorted by ID + val phaseIdFormatted = "%02d".format(actionState.phaseCount) + + val fileName = "${phaseIdFormatted}_${actionState.phase.name}.$fileExtension" + + File(directoryFile, fileName).writeText(dumpContent) + } + +fun dumpToStdout( + dumper: Dumper +): Action = + fun(actionState: ActionState, data: Data, context: Context) { + if (actionState.config.dumpToDirectory != null) return + val dumpContent = dumper(actionState, data, context) ?: return + println("\n\n----------------------------------------------") + println(dumpContent) + println() + } + +val defaultDumper = makeDumpAction(dumpToStdout(::dumpIrElement) + dumpToFile("ir", ::dumpIrElement)) \ No newline at end of file diff --git a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/phaser/PhaseBuilders.kt b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/phaser/PhaseBuilders.kt index 0e3673f39c2..907559eaf7f 100644 --- a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/phaser/PhaseBuilders.kt +++ b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/phaser/PhaseBuilders.kt @@ -54,7 +54,7 @@ fun namedIrModulePhase( preconditions: Set> = emptySet(), postconditions: Set> = emptySet(), stickyPostconditions: Set> = lower.stickyPostconditions, - verify: (Context, IrModuleFragment) -> Unit = { _, _ -> }, + actions: Set> = setOf(defaultDumper), nlevels: Int = 1 ) = SameTypeNamedPhaseWrapper( name, @@ -64,8 +64,8 @@ fun namedIrModulePhase( preconditions, postconditions, stickyPostconditions, - nlevels, - IrModuleDumperVerifier(verify) + actions, + nlevels ) fun namedIrFilePhase( @@ -76,7 +76,7 @@ fun namedIrFilePhase( preconditions: Set> = emptySet(), postconditions: Set> = emptySet(), stickyPostconditions: Set> = lower.stickyPostconditions, - verify: (Context, IrFile) -> Unit = { _, _ -> }, + actions: Set> = setOf(defaultDumper), nlevels: Int = 1 ) = SameTypeNamedPhaseWrapper( name, @@ -86,8 +86,8 @@ fun namedIrFilePhase( preconditions, postconditions, stickyPostconditions, - nlevels, - IrFileDumperVerifier(verify) + actions, + nlevels ) fun namedUnitPhase( @@ -99,8 +99,7 @@ fun namedUnitPhase( ) = SameTypeNamedPhaseWrapper( name, description, prerequisite, lower = lower, - nlevels = nlevels, - dumperVerifier = EmptyDumperVerifier() + nlevels = nlevels ) fun namedOpUnitPhase( @@ -125,14 +124,14 @@ fun performByIrFile( preconditions: Set> = emptySet(), postconditions: Set> = emptySet(), stickyPostconditions: Set> = emptySet(), - verify: (Context, IrModuleFragment) -> Unit = { _, _ -> }, + actions: Set> = setOf(defaultDumper), lower: CompilerPhase ) = namedIrModulePhase( name, description, prerequisite, preconditions = preconditions, postconditions = postconditions, stickyPostconditions = stickyPostconditions, - verify = verify, + actions = actions, nlevels = 1, lower = object : SameTypeCompilerPhase { override fun invoke( @@ -161,13 +160,13 @@ fun makeIrFilePhase( preconditions: Set> = emptySet(), postconditions: Set> = emptySet(), stickyPostconditions: Set> = emptySet(), - verify: (Context, IrFile) -> Unit = { _, _ -> } + actions: Set> = setOf(defaultDumper) ) = namedIrFilePhase( name, description, prerequisite, preconditions = preconditions, postconditions = postconditions, stickyPostconditions = stickyPostconditions, - verify = verify, + actions = actions, nlevels = 0, lower = object : SameTypeCompilerPhase { override fun invoke(phaseConfig: PhaseConfig, phaserState: PhaserState, context: Context, input: IrFile): IrFile { @@ -185,13 +184,13 @@ fun makeIrModulePhase( preconditions: Set> = emptySet(), postconditions: Set> = emptySet(), stickyPostconditions: Set> = emptySet(), - verify: (Context, IrModuleFragment) -> Unit = { _, _ -> } + actions: Set> = setOf(defaultDumper) ) = namedIrModulePhase( name, description, prerequisite, preconditions=preconditions, postconditions = postconditions, stickyPostconditions = stickyPostconditions, - verify = verify, + actions = actions, nlevels = 0, lower = object : SameTypeCompilerPhase { override fun invoke( @@ -222,10 +221,7 @@ fun unitPhase( context.op() } } - ) { - override val inputDumperVerifier = EmptyDumperVerifier() - override val outputDumperVerifier = EmptyDumperVerifier() - } + ) {} fun unitSink() = object : CompilerPhase { override fun invoke(phaseConfig: PhaseConfig, phaserState: PhaserState, context: Context, input: Input) {} diff --git a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/phaser/PhaseConfig.kt b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/phaser/PhaseConfig.kt index 61f314df53a..731bf9eb087 100644 --- a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/phaser/PhaseConfig.kt +++ b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/phaser/PhaseConfig.kt @@ -19,6 +19,8 @@ class PhaseConfig( val verbose: Set = emptySet(), val toDumpStateBefore: Set = emptySet(), val toDumpStateAfter: Set = emptySet(), + val dumpToDirectory: String? = null, + val dumpOnlyFqName: String? = null, val toValidateStateBefore: Set = emptySet(), val toValidateStateAfter: Set = emptySet(), val namesOfElementsExcludedFromDumping: Set = emptySet(), diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/JsLoweringPhases.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/JsLoweringPhases.kt index 5a34a0d4448..0fe0ee8c677 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/JsLoweringPhases.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/JsLoweringPhases.kt @@ -33,12 +33,14 @@ private fun validationCallback(context: JsIrBackendContext, module: IrModuleFrag module.accept(CheckDeclarationParentsVisitor, null) } +val validationAction = makeVerifyAction(::validationCallback) + private fun makeJsModulePhase( lowering: (JsIrBackendContext) -> FileLoweringPass, name: String, description: String, prerequisite: Set = emptySet() -) = makeIrModulePhase(lowering, name, description, prerequisite, verify = ::validationCallback) +) = makeIrModulePhase(lowering, name, description, prerequisite, actions = setOf(validationAction, defaultDumper)) private fun makeCustomJsModulePhase( op: (JsIrBackendContext, IrModuleFragment) -> Unit, @@ -49,7 +51,7 @@ private fun makeCustomJsModulePhase( name, description, prerequisite, - verify = ::validationCallback, + actions = setOf(defaultDumper, validationAction), nlevels = 0, lower = object : SameTypeCompilerPhase { override fun invoke( diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/compiler.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/compiler.kt index fc9a5c87f89..36e91a1017e 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/compiler.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/compiler.kt @@ -19,7 +19,7 @@ fun compile( project: Project, files: List, configuration: CompilerConfiguration, - phaseConfig: PhaseConfig = PhaseConfig(jsPhases), + phaseConfig: PhaseConfig, immediateDependencies: List, allDependencies: List, friendDependencies: List, diff --git a/compiler/testData/cli/js/jsExtraHelp.out b/compiler/testData/cli/js/jsExtraHelp.out index 14cbf7660b6..eee153dcf30 100644 --- a/compiler/testData/cli/js/jsExtraHelp.out +++ b/compiler/testData/cli/js/jsExtraHelp.out @@ -15,6 +15,8 @@ where advanced options include: -Xcoroutines={enable|warn|error} Enable coroutines or report warnings or errors on declarations and use sites of 'suspend' modifier -Xdisable-phases Disable backend phases + -Xdump-directory Dump backend state into directory + -Xdump-fqname FqName of declaration that should be dumped -Xdump-perf= Dump detailed performance statistics to the specified file -Xeffect-system Enable experimental language feature: effect system -Xexperimental= Enable and propagate usages of experimental API for marker annotation with the given fully qualified name diff --git a/compiler/testData/cli/jvm/extraHelp.out b/compiler/testData/cli/jvm/extraHelp.out index 2a21dd8576e..658a60a0ed3 100644 --- a/compiler/testData/cli/jvm/extraHelp.out +++ b/compiler/testData/cli/jvm/extraHelp.out @@ -79,6 +79,8 @@ where advanced options include: -Xcoroutines={enable|warn|error} Enable coroutines or report warnings or errors on declarations and use sites of 'suspend' modifier -Xdisable-phases Disable backend phases + -Xdump-directory Dump backend state into directory + -Xdump-fqname FqName of declaration that should be dumped -Xdump-perf= Dump detailed performance statistics to the specified file -Xeffect-system Enable experimental language feature: effect system -Xexperimental= Enable and propagate usages of experimental API for marker annotation with the given fully qualified name diff --git a/js/js.tests/test/org/jetbrains/kotlin/js/test/BasicIrBoxTest.kt b/js/js.tests/test/org/jetbrains/kotlin/js/test/BasicIrBoxTest.kt index 0d74b49a40b..a8f884af327 100644 --- a/js/js.tests/test/org/jetbrains/kotlin/js/test/BasicIrBoxTest.kt +++ b/js/js.tests/test/org/jetbrains/kotlin/js/test/BasicIrBoxTest.kt @@ -6,7 +6,7 @@ package org.jetbrains.kotlin.js.test import org.jetbrains.kotlin.backend.common.phaser.PhaseConfig -import org.jetbrains.kotlin.cli.common.CLIConfigurationKeys +import org.jetbrains.kotlin.backend.common.phaser.toPhaseMap import org.jetbrains.kotlin.ir.backend.js.KlibModuleRef import org.jetbrains.kotlin.ir.backend.js.compile import org.jetbrains.kotlin.ir.backend.js.generateKLib @@ -90,11 +90,28 @@ abstract class BasicIrBoxTest( } if (isMainModule) { + val debugMode = false + + val phaseConfig = if (debugMode) { + val allPhasesSet = jsPhases.toPhaseMap().values.toSet() + val dumpOutputDir = File(outputFile.parent, outputFile.nameWithoutExtension + "-irdump") + println("\n ------ Dumping phases to file://$dumpOutputDir") + PhaseConfig( + jsPhases, + dumpToDirectory = dumpOutputDir.path, + toDumpStateAfter = allPhasesSet, + toValidateStateAfter = allPhasesSet, + dumpOnlyFqName = null + ) + } else { + PhaseConfig(jsPhases) + } + val jsCode = compile( project = config.project, files = filesToCompile, configuration = config.configuration, - phaseConfig = config.configuration.get(CLIConfigurationKeys.PHASE_CONFIG) ?: PhaseConfig(jsPhases), + phaseConfig = phaseConfig, immediateDependencies = dependencies, allDependencies = allDependencies, friendDependencies = emptyList(),