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 1493368ce6e..60b461d8a8d 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 @@ -12,25 +12,36 @@ import org.jetbrains.kotlin.ir.declarations.IrFile import org.jetbrains.kotlin.ir.declarations.IrModuleFragment // Phase composition. +private class CompositePhase( + val phases: List> +) : CompilerPhase { + + override fun invoke(phaseConfig: PhaseConfig, phaserState: PhaserState, context: Context, input: Input): Output { + var currentState = phaserState as PhaserState + var result = phases.first().invoke(phaseConfig, currentState, context, input) + for ((previous, next) in phases.zip(phases.drop(1))) { + if (next !is SameTypeCompilerPhase<*, *>) { + // Discard `stickyPostcoditions`, they are useless since data type is changing. + currentState = currentState.changeType() + } + currentState.stickyPostconditions.addAll(previous.stickyPostconditions) + result = next.invoke(phaseConfig, currentState, context, result) + } + return result as Output + } + + override fun getNamedSubphases(startDepth: Int): List> = + phases.flatMap { it.getNamedSubphases(startDepth) } + + override val stickyPostconditions get() = phases.last().stickyPostconditions +} + infix fun CompilerPhase.then( other: CompilerPhase -) = object : CompilerPhase { - override fun invoke(phaseConfig: PhaseConfig, phaserState: PhaserState, context: Context, input: Input): Output = - this@then.invoke(phaseConfig, phaserState, context, input).let { mid -> - val newPhaserState = if (other is SameTypeCompilerPhase<*, *>) - // Keep `stickyPostconditions`. - phaserState as PhaserState - else - // Discard `stickyPostcoditions`, they are useless since data type is changing. - phaserState.changeType() - newPhaserState.stickyPostconditions.addAll(this@then.stickyPostconditions) - other.invoke(phaseConfig, newPhaserState, context, mid) - } - - override fun getNamedSubphases(startDepth: Int) = - this@then.getNamedSubphases(startDepth) + other.getNamedSubphases(startDepth) - - override val stickyPostconditions get() = other.stickyPostconditions +): CompilerPhase { + val unsafeThis = this as CompilerPhase + val unsafeOther = other as CompilerPhase + return CompositePhase(if (this is CompositePhase) phases + unsafeOther else listOf(unsafeThis, unsafeOther)) } fun namedIrModulePhase(