diff --git a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/LoopExpressionGenerator.kt b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/LoopExpressionGenerator.kt index 63164b47c73..aeaa8a29ea8 100644 --- a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/LoopExpressionGenerator.kt +++ b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/LoopExpressionGenerator.kt @@ -37,25 +37,33 @@ class LoopExpressionGenerator(val statementGenerator: StatementGenerator) : Gene fun generateDoWhileLoop(ktDoWhile: KtDoWhileExpression): IrExpression = generateConditionalLoop(ktDoWhile, IrDoWhileLoopImpl(ktDoWhile.startOffset, ktDoWhile.endOffset, IrOperator.DO_WHILE_LOOP)) - private fun generateConditionalLoop(ktLoop: KtWhileExpressionBase, irLoop: IrLoop): IrLoop { + private fun generateConditionalLoop(ktLoop: KtWhileExpressionBase, irLoop: IrLoopBase): IrLoop { statementGenerator.expressionBodyGenerator.putLoop(ktLoop, irLoop) irLoop.condition = statementGenerator.generateExpression(ktLoop.condition!!) irLoop.body = statementGenerator.generateExpression(ktLoop.body!!) + irLoop.label = getLoopLabel(ktLoop) return irLoop } fun generateBreak(ktBreak: KtBreakExpression): IrExpression { val parentLoop = findParentLoop(ktBreak) - return IrBreakImpl(ktBreak.startOffset, ktBreak.endOffset, context.builtIns.nothingType, parentLoop) + return IrBreakImpl(ktBreak.startOffset, ktBreak.endOffset, context.builtIns.nothingType, parentLoop).apply { + label = ktBreak.getLabelName() + } } fun generateContinue(ktContinue: KtContinueExpression): IrExpression { val parentLoop = findParentLoop(ktContinue) - return IrContinueImpl(ktContinue.startOffset, ktContinue.endOffset, context.builtIns.nothingType, parentLoop) + return IrContinueImpl(ktContinue.startOffset, ktContinue.endOffset, context.builtIns.nothingType, parentLoop).apply { + label = ktContinue.getLabelName() + } } + private fun getLoopLabel(ktLoop: KtLoopExpression): String? = + (ktLoop.parent as? KtLabeledExpression)?.getLabelName() + private fun findParentLoop(ktWithLabel: KtExpressionWithLabel): IrLoop = - findParentLoop(ktWithLabel, ktWithLabel.getTargetLabel()?.getReferencedName()) + findParentLoop(ktWithLabel, ktWithLabel.getLabelName()) private fun findParentLoop(ktExpression: KtExpression, targetLabel: String?): IrLoop { var finger: KtExpression? = ktExpression @@ -109,6 +117,7 @@ class LoopExpressionGenerator(val statementGenerator: StatementGenerator) : Gene irForBlock.addStatement(irIterator) val irInnerWhile = IrWhileLoopImpl(ktFor.startOffset, ktFor.endOffset, IrOperator.FOR_LOOP_INNER_WHILE) + irInnerWhile.label = getLoopLabel(ktFor) statementGenerator.expressionBodyGenerator.putLoop(ktFor, irInnerWhile) irForBlock.addStatement(irInnerWhile) diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/IrBreakContinue.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/IrBreakContinue.kt index 854b4892530..7c74453ad9a 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/IrBreakContinue.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/IrBreakContinue.kt @@ -24,6 +24,7 @@ import org.jetbrains.kotlin.types.KotlinType interface IrBreakContinue : IrExpression { var loop: IrLoop + val label: String? } interface IrBreak: IrBreakContinue @@ -51,6 +52,7 @@ abstract class IrBreakContinueBase( type: KotlinType, override var loop: IrLoop ) : IrTerminalExpressionBase(startOffset, endOffset, type), IrBreakContinue { + override var label: String? = null } class IrBreakImpl( diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/IrLoop.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/IrLoop.kt index a3a8965a158..e596bba456e 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/IrLoop.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/IrLoop.kt @@ -23,6 +23,7 @@ interface IrLoop : IrExpression { val operator: IrOperator? var body: IrExpression var condition: IrExpression + val label: String? } interface IrWhileLoop : IrLoop @@ -34,6 +35,8 @@ abstract class IrLoopBase( endOffset: Int, override val operator: IrOperator? ) : IrExpressionBase(startOffset, endOffset, null), IrLoop { + override var label: String? = null + private var conditionImpl: IrExpression? = null override var condition: IrExpression get() = conditionImpl!! diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/RenderIrElement.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/RenderIrElement.kt index a5e0ee49d5f..17d50273232 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/RenderIrElement.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/RenderIrElement.kt @@ -101,16 +101,16 @@ class RenderIrElementVisitor : IrElementVisitor { "WHEN type=${expression.type.render()} operator=${expression.operator}" override fun visitWhileLoop(loop: IrWhileLoop, data: Nothing?): String = - "WHILE operator=${loop.operator}" + "WHILE label=${loop.label} operator=${loop.operator}" override fun visitDoWhileLoop(loop: IrDoWhileLoop, data: Nothing?): String = - "DO_WHILE operator=${loop.operator}" + "DO_WHILE label=${loop.label} operator=${loop.operator}" override fun visitBreak(jump: IrBreak, data: Nothing?): String = - "BREAK loop.operator=${jump.loop.operator} depth=${jump.getDepth()}" + "BREAK label=${jump.label} depth=${jump.getDepth()}" override fun visitContinue(jump: IrContinue, data: Nothing?): String = - "CONTINUE loop.operator=${jump.loop.operator} depth=${jump.getDepth()}" + "CONTINUE label=${jump.label} depth=${jump.getDepth()}" override fun visitThrow(expression: IrThrow, data: Nothing?): String = "THROW type=${expression.renderType()}" diff --git a/compiler/testData/ir/irText/breakContinue.txt b/compiler/testData/ir/irText/breakContinue.txt index 14ba2caf2a2..196f9b71e06 100644 --- a/compiler/testData/ir/irText/breakContinue.txt +++ b/compiler/testData/ir/irText/breakContinue.txt @@ -2,59 +2,59 @@ IrFile /breakContinue.kt IrFunction public fun test1(): kotlin.Unit IrExpressionBody BLOCK type= hasResult=false operator=null - WHILE operator=WHILE_LOOP + WHILE label=null operator=WHILE_LOOP condition: CONST Boolean type=kotlin.Boolean value='true' body: BLOCK type= hasResult=false operator=null - BREAK loop.operator=WHILE_LOOP depth=0 - DO_WHILE operator=DO_WHILE_LOOP + BREAK label=null depth=0 + DO_WHILE label=null operator=DO_WHILE_LOOP body: BLOCK type= hasResult=false operator=null - BREAK loop.operator=DO_WHILE_LOOP depth=0 + BREAK label=null depth=0 condition: CONST Boolean type=kotlin.Boolean value='true' - WHILE operator=WHILE_LOOP + WHILE label=null operator=WHILE_LOOP condition: CONST Boolean type=kotlin.Boolean value='true' body: BLOCK type= hasResult=false operator=null - CONTINUE loop.operator=WHILE_LOOP depth=0 - DO_WHILE operator=DO_WHILE_LOOP + CONTINUE label=null depth=0 + DO_WHILE label=null operator=DO_WHILE_LOOP body: BLOCK type= hasResult=false operator=null - CONTINUE loop.operator=DO_WHILE_LOOP depth=0 + CONTINUE label=null depth=0 condition: CONST Boolean type=kotlin.Boolean value='true' IrFunction public fun test2(): kotlin.Unit IrExpressionBody BLOCK type= hasResult=false operator=null - WHILE operator=WHILE_LOOP + WHILE label=OUTER operator=WHILE_LOOP condition: CONST Boolean type=kotlin.Boolean value='true' body: BLOCK type= hasResult=false operator=null - WHILE operator=WHILE_LOOP + WHILE label=INNER operator=WHILE_LOOP condition: CONST Boolean type=kotlin.Boolean value='true' body: BLOCK type= hasResult=false operator=null - BREAK loop.operator=WHILE_LOOP depth=0 - BREAK loop.operator=WHILE_LOOP depth=1 - BREAK loop.operator=WHILE_LOOP depth=0 - WHILE operator=WHILE_LOOP + BREAK label=INNER depth=0 + BREAK label=OUTER depth=1 + BREAK label=OUTER depth=0 + WHILE label=OUTER operator=WHILE_LOOP condition: CONST Boolean type=kotlin.Boolean value='true' body: BLOCK type= hasResult=false operator=null - WHILE operator=WHILE_LOOP + WHILE label=INNER operator=WHILE_LOOP condition: CONST Boolean type=kotlin.Boolean value='true' body: BLOCK type= hasResult=false operator=null - CONTINUE loop.operator=WHILE_LOOP depth=0 - CONTINUE loop.operator=WHILE_LOOP depth=1 - CONTINUE loop.operator=WHILE_LOOP depth=0 + CONTINUE label=INNER depth=0 + CONTINUE label=OUTER depth=1 + CONTINUE label=OUTER depth=0 IrFunction public fun test3(): kotlin.Unit IrExpressionBody BLOCK type= hasResult=false operator=null - WHILE operator=WHILE_LOOP + WHILE label=L operator=WHILE_LOOP condition: CONST Boolean type=kotlin.Boolean value='true' body: BLOCK type= hasResult=false operator=null - WHILE operator=WHILE_LOOP + WHILE label=L operator=WHILE_LOOP condition: CONST Boolean type=kotlin.Boolean value='true' body: BLOCK type= hasResult=false operator=null - BREAK loop.operator=WHILE_LOOP depth=0 - BREAK loop.operator=WHILE_LOOP depth=0 - WHILE operator=WHILE_LOOP + BREAK label=L depth=0 + BREAK label=L depth=0 + WHILE label=L operator=WHILE_LOOP condition: CONST Boolean type=kotlin.Boolean value='true' body: BLOCK type= hasResult=false operator=null - WHILE operator=WHILE_LOOP + WHILE label=L operator=WHILE_LOOP condition: CONST Boolean type=kotlin.Boolean value='true' body: BLOCK type= hasResult=false operator=null - CONTINUE loop.operator=WHILE_LOOP depth=0 - CONTINUE loop.operator=WHILE_LOOP depth=0 + CONTINUE label=L depth=0 + CONTINUE label=L depth=0 diff --git a/compiler/testData/ir/irText/for.txt b/compiler/testData/ir/irText/for.txt index 9fdb1fe8a18..a71fd82df28 100644 --- a/compiler/testData/ir/irText/for.txt +++ b/compiler/testData/ir/irText/for.txt @@ -6,7 +6,7 @@ IrFile /for.kt VAR val tmp0_iterator: kotlin.collections.Iterator CALL .iterator type=kotlin.collections.Iterator operator=FOR_LOOP_ITERATOR $this: GET_VAR ss type=kotlin.collections.List operator=null - WHILE operator=FOR_LOOP_INNER_WHILE + WHILE label=null operator=FOR_LOOP_INNER_WHILE condition: CALL .hasNext type=kotlin.Boolean operator=FOR_LOOP_HAS_NEXT $this: GET_VAR tmp0_iterator type=kotlin.collections.Iterator operator=null body: BLOCK type=kotlin.Unit hasResult=false operator=FOR_LOOP_INNER_WHILE @@ -23,7 +23,7 @@ IrFile /for.kt VAR val tmp0_iterator: kotlin.collections.Iterator> CALL .iterator type=kotlin.collections.Iterator> operator=FOR_LOOP_ITERATOR $this: GET_VAR pp type=kotlin.collections.List> operator=null - WHILE operator=FOR_LOOP_INNER_WHILE + WHILE label=null operator=FOR_LOOP_INNER_WHILE condition: CALL .hasNext type=kotlin.Boolean operator=FOR_LOOP_HAS_NEXT $this: GET_VAR tmp0_iterator type=kotlin.collections.Iterator> operator=null body: BLOCK type=kotlin.Unit hasResult=false operator=FOR_LOOP_INNER_WHILE diff --git a/compiler/testData/ir/irText/forWithBreakContinue.txt b/compiler/testData/ir/irText/forWithBreakContinue.txt index 8a2721b7121..3d7545bf96c 100644 --- a/compiler/testData/ir/irText/forWithBreakContinue.txt +++ b/compiler/testData/ir/irText/forWithBreakContinue.txt @@ -6,7 +6,7 @@ IrFile /forWithBreakContinue.kt VAR val tmp0_iterator: kotlin.collections.Iterator CALL .iterator type=kotlin.collections.Iterator operator=FOR_LOOP_ITERATOR $this: GET_VAR ss type=kotlin.collections.List operator=null - WHILE operator=FOR_LOOP_INNER_WHILE + WHILE label=null operator=FOR_LOOP_INNER_WHILE condition: CALL .hasNext type=kotlin.Boolean operator=FOR_LOOP_HAS_NEXT $this: GET_VAR tmp0_iterator type=kotlin.collections.Iterator operator=null body: BLOCK type=kotlin.Unit hasResult=false operator=FOR_LOOP_INNER_WHILE @@ -14,7 +14,7 @@ IrFile /forWithBreakContinue.kt CALL .next type=kotlin.String operator=FOR_LOOP_NEXT $this: GET_VAR tmp0_iterator type=kotlin.collections.Iterator operator=null BLOCK type= hasResult=false operator=null - BREAK loop.operator=FOR_LOOP_INNER_WHILE depth=0 + BREAK label=null depth=0 IrFunction public fun testForBreak2(/*0*/ ss: kotlin.collections.List): kotlin.Unit IrExpressionBody BLOCK type= hasResult=false operator=null @@ -22,7 +22,7 @@ IrFile /forWithBreakContinue.kt VAR val tmp0_iterator: kotlin.collections.Iterator CALL .iterator type=kotlin.collections.Iterator operator=FOR_LOOP_ITERATOR $this: GET_VAR ss type=kotlin.collections.List operator=null - WHILE operator=FOR_LOOP_INNER_WHILE + WHILE label=OUTER operator=FOR_LOOP_INNER_WHILE condition: CALL .hasNext type=kotlin.Boolean operator=FOR_LOOP_HAS_NEXT $this: GET_VAR tmp0_iterator type=kotlin.collections.Iterator operator=null body: BLOCK type=kotlin.Unit hasResult=false operator=FOR_LOOP_INNER_WHILE @@ -34,7 +34,7 @@ IrFile /forWithBreakContinue.kt VAR val tmp1_iterator: kotlin.collections.Iterator CALL .iterator type=kotlin.collections.Iterator operator=FOR_LOOP_ITERATOR $this: GET_VAR ss type=kotlin.collections.List operator=null - WHILE operator=FOR_LOOP_INNER_WHILE + WHILE label=INNER operator=FOR_LOOP_INNER_WHILE condition: CALL .hasNext type=kotlin.Boolean operator=FOR_LOOP_HAS_NEXT $this: GET_VAR tmp1_iterator type=kotlin.collections.Iterator operator=null body: BLOCK type=kotlin.Unit hasResult=false operator=FOR_LOOP_INNER_WHILE @@ -42,10 +42,10 @@ IrFile /forWithBreakContinue.kt CALL .next type=kotlin.String operator=FOR_LOOP_NEXT $this: GET_VAR tmp1_iterator type=kotlin.collections.Iterator operator=null BLOCK type= hasResult=false operator=null - BREAK loop.operator=FOR_LOOP_INNER_WHILE depth=1 - BREAK loop.operator=FOR_LOOP_INNER_WHILE depth=0 - BREAK loop.operator=FOR_LOOP_INNER_WHILE depth=0 - BREAK loop.operator=FOR_LOOP_INNER_WHILE depth=0 + BREAK label=OUTER depth=1 + BREAK label=INNER depth=0 + BREAK label=null depth=0 + BREAK label=OUTER depth=0 IrFunction public fun testForContinue1(/*0*/ ss: kotlin.collections.List): kotlin.Unit IrExpressionBody BLOCK type= hasResult=false operator=null @@ -53,7 +53,7 @@ IrFile /forWithBreakContinue.kt VAR val tmp0_iterator: kotlin.collections.Iterator CALL .iterator type=kotlin.collections.Iterator operator=FOR_LOOP_ITERATOR $this: GET_VAR ss type=kotlin.collections.List operator=null - WHILE operator=FOR_LOOP_INNER_WHILE + WHILE label=null operator=FOR_LOOP_INNER_WHILE condition: CALL .hasNext type=kotlin.Boolean operator=FOR_LOOP_HAS_NEXT $this: GET_VAR tmp0_iterator type=kotlin.collections.Iterator operator=null body: BLOCK type=kotlin.Unit hasResult=false operator=FOR_LOOP_INNER_WHILE @@ -61,7 +61,7 @@ IrFile /forWithBreakContinue.kt CALL .next type=kotlin.String operator=FOR_LOOP_NEXT $this: GET_VAR tmp0_iterator type=kotlin.collections.Iterator operator=null BLOCK type= hasResult=false operator=null - CONTINUE loop.operator=FOR_LOOP_INNER_WHILE depth=0 + CONTINUE label=null depth=0 IrFunction public fun testForContinue2(/*0*/ ss: kotlin.collections.List): kotlin.Unit IrExpressionBody BLOCK type= hasResult=false operator=null @@ -69,7 +69,7 @@ IrFile /forWithBreakContinue.kt VAR val tmp0_iterator: kotlin.collections.Iterator CALL .iterator type=kotlin.collections.Iterator operator=FOR_LOOP_ITERATOR $this: GET_VAR ss type=kotlin.collections.List operator=null - WHILE operator=FOR_LOOP_INNER_WHILE + WHILE label=OUTER operator=FOR_LOOP_INNER_WHILE condition: CALL .hasNext type=kotlin.Boolean operator=FOR_LOOP_HAS_NEXT $this: GET_VAR tmp0_iterator type=kotlin.collections.Iterator operator=null body: BLOCK type=kotlin.Unit hasResult=false operator=FOR_LOOP_INNER_WHILE @@ -81,7 +81,7 @@ IrFile /forWithBreakContinue.kt VAR val tmp1_iterator: kotlin.collections.Iterator CALL .iterator type=kotlin.collections.Iterator operator=FOR_LOOP_ITERATOR $this: GET_VAR ss type=kotlin.collections.List operator=null - WHILE operator=FOR_LOOP_INNER_WHILE + WHILE label=INNER operator=FOR_LOOP_INNER_WHILE condition: CALL .hasNext type=kotlin.Boolean operator=FOR_LOOP_HAS_NEXT $this: GET_VAR tmp1_iterator type=kotlin.collections.Iterator operator=null body: BLOCK type=kotlin.Unit hasResult=false operator=FOR_LOOP_INNER_WHILE @@ -89,7 +89,7 @@ IrFile /forWithBreakContinue.kt CALL .next type=kotlin.String operator=FOR_LOOP_NEXT $this: GET_VAR tmp1_iterator type=kotlin.collections.Iterator operator=null BLOCK type= hasResult=false operator=null - CONTINUE loop.operator=FOR_LOOP_INNER_WHILE depth=1 - CONTINUE loop.operator=FOR_LOOP_INNER_WHILE depth=0 - CONTINUE loop.operator=FOR_LOOP_INNER_WHILE depth=0 - CONTINUE loop.operator=FOR_LOOP_INNER_WHILE depth=0 + CONTINUE label=OUTER depth=1 + CONTINUE label=INNER depth=0 + CONTINUE label=null depth=0 + CONTINUE label=OUTER depth=0 diff --git a/compiler/testData/ir/irText/forWithImplicitReceivers.txt b/compiler/testData/ir/irText/forWithImplicitReceivers.txt index 777610f5666..8c0024b872a 100644 --- a/compiler/testData/ir/irText/forWithImplicitReceivers.txt +++ b/compiler/testData/ir/irText/forWithImplicitReceivers.txt @@ -10,7 +10,7 @@ IrFile /forWithImplicitReceivers.kt CALL .iterator type=IntCell operator=FOR_LOOP_ITERATOR $this: $RECEIVER of: test type=IReceiver $receiver: GET_OBJECT FiveTimes type=FiveTimes - WHILE operator=FOR_LOOP_INNER_WHILE + WHILE label=null operator=FOR_LOOP_INNER_WHILE condition: CALL .hasNext type=kotlin.Boolean operator=FOR_LOOP_HAS_NEXT $this: $RECEIVER of: test type=IReceiver $receiver: GET_VAR tmp0_iterator type=IntCell operator=null diff --git a/compiler/testData/ir/irText/whileDoWhile.txt b/compiler/testData/ir/irText/whileDoWhile.txt index 6b56816b56f..2ea8fba66c4 100644 --- a/compiler/testData/ir/irText/whileDoWhile.txt +++ b/compiler/testData/ir/irText/whileDoWhile.txt @@ -4,7 +4,7 @@ IrFile /whileDoWhile.kt BLOCK type= hasResult=false operator=null VAR var x: kotlin.Int CONST Int type=kotlin.Int value='0' - WHILE operator=WHILE_LOOP + WHILE label=null operator=WHILE_LOOP condition: CALL .LT0 type=kotlin.Boolean operator=LT arg0: CALL .compareTo type=kotlin.Int operator=LT $this: GET_VAR x type=kotlin.Int operator=null @@ -16,7 +16,7 @@ IrFile /whileDoWhile.kt CALL .inc type=kotlin.Int operator=POSTFIX_INCR $this: GET_VAR tmp0 type=kotlin.Int operator=null GET_VAR tmp0 type=kotlin.Int operator=null - WHILE operator=WHILE_LOOP + WHILE label=null operator=WHILE_LOOP condition: CALL .LT0 type=kotlin.Boolean operator=LT arg0: CALL .compareTo type=kotlin.Int operator=LT $this: GET_VAR x type=kotlin.Int operator=null @@ -29,7 +29,7 @@ IrFile /whileDoWhile.kt CALL .inc type=kotlin.Int operator=POSTFIX_INCR $this: GET_VAR tmp1 type=kotlin.Int operator=null GET_VAR tmp1 type=kotlin.Int operator=null - DO_WHILE operator=DO_WHILE_LOOP + DO_WHILE label=null operator=DO_WHILE_LOOP body: BLOCK type=kotlin.Int hasResult=true operator=POSTFIX_INCR VAR val tmp2: kotlin.Int GET_VAR x type=kotlin.Int operator=POSTFIX_INCR @@ -41,7 +41,7 @@ IrFile /whileDoWhile.kt arg0: CALL .compareTo type=kotlin.Int operator=LT $this: GET_VAR x type=kotlin.Int operator=null other: CONST Int type=kotlin.Int value='15' - DO_WHILE operator=DO_WHILE_LOOP + DO_WHILE label=null operator=DO_WHILE_LOOP body: BLOCK type=kotlin.Int hasResult=true operator=null BLOCK type=kotlin.Int hasResult=true operator=POSTFIX_INCR VAR val tmp3: kotlin.Int @@ -63,11 +63,11 @@ IrFile /whileDoWhile.kt if: TYPE_OP operator=INSTANCEOF typeOperand=kotlin.Boolean GET_VAR a type=kotlin.Any? operator=null then: BLOCK type= hasResult=false operator=null - WHILE operator=WHILE_LOOP + WHILE label=null operator=WHILE_LOOP condition: TYPE_OP operator=IMPLICIT_CAST typeOperand=kotlin.Boolean GET_VAR a type=kotlin.Any? operator=null body: BLOCK type= hasResult=false operator=null - DO_WHILE operator=DO_WHILE_LOOP + DO_WHILE label=null operator=DO_WHILE_LOOP body: BLOCK type= hasResult=false operator=null condition: TYPE_OP operator=IMPLICIT_CAST typeOperand=kotlin.Boolean GET_VAR a type=kotlin.Any? operator=null