interface CommonBackendContext interface PhaserState { var depth: Int } interface PhaseConfig { val needProfiling: Boolean } inline fun PhaserState.downlevel(nlevels: Int, block: () -> R): R { depth += nlevels val result = block() depth -= nlevels return result } interface CompilerPhase { fun invoke(phaseConfig: PhaseConfig, phaserState: PhaserState, context: Context, input: Input): Output } class NamedCompilerPhase( private val lower: CompilerPhase ) : CompilerPhase { override fun invoke(phaseConfig: PhaseConfig, phaserState: PhaserState, context: Context, input: Data): Data { // Expected: output: Data, Actual: output: Data? val output = if (phaseConfig.needProfiling) { runAndProfile(phaseConfig, phaserState, context, input) } else { phaserState.downlevel(1) { lower.invoke(phaseConfig, phaserState, context, input) } } runAfter(phaseConfig, phaserState, context, output) } private fun runAfter(phaseConfig: PhaseConfig, phaserState: PhaserState, context: Context, output: Data) { } private fun runAndProfile(phaseConfig: PhaseConfig, phaserState: PhaserState, context: Context, source: Data): Data { } }