| // RUN_PIPELINE_TILL: FRONTEND | |
| interface CommonBackendContext | |
| interface PhaserState<Data> { | |
| var depth: Int | |
| } | |
| interface PhaseConfig { | |
| val needProfiling: Boolean | |
| } | |
| inline fun <R, D> PhaserState<D>.downlevel(nlevels: Int, block: () -> R): R { | |
| depth += nlevels | |
| val result = block() | |
| depth -= nlevels | |
| return result | |
| } | |
| interface CompilerPhase<in Context : CommonBackendContext, Input, Output> { | |
| fun invoke(phaseConfig: PhaseConfig, phaserState: PhaserState<Input>, context: Context, input: Input): Output | |
| } | |
| class NamedCompilerPhase<in Context : CommonBackendContext, Data>( | |
| private val lower: CompilerPhase<Context, Data, Data> | |
| ) : CompilerPhase<Context, Data, Data> { | |
| override fun invoke(phaseConfig: PhaseConfig, phaserState: PhaserState<Data>, 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) | |
| <!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!> | |
| private fun runAfter(phaseConfig: PhaseConfig, phaserState: PhaserState<Data>, context: Context, output: Data) { | |
| } | |
| private fun runAndProfile(phaseConfig: PhaseConfig, phaserState: PhaserState<Data>, context: Context, source: Data): Data { | |
| <!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!> | |
| } | |
| /* GENERATED_FIR_TAGS: additiveExpression, assignment, classDeclaration, funWithExtensionReceiver, functionDeclaration, | |
| functionalType, ifExpression, in, inline, integerLiteral, interfaceDeclaration, lambdaLiteral, localProperty, | |
| nullableType, override, primaryConstructor, propertyDeclaration, typeConstraint, typeParameter */ |