'while' and 'do-while' loop generator fixes.
Generate 'do-while' loop body as IrComposite, because variables declared in loop body should be visible in loop condition. Wrap 'do-while' loop in IrBlock so that variables declared in loop body are not visible outside of the loop. Generate 'while' and 'do-while' loops as expressions of type Unit.
This commit is contained in:
+1
-1
@@ -72,7 +72,7 @@ class FunctionGenerator(val function: IrFunction) {
|
||||
return body.process()
|
||||
}
|
||||
|
||||
override fun visitBlock(expression: IrBlock, data: Boolean): IrStatement? {
|
||||
override fun visitContainerExpression(expression: IrContainerExpression, data: Boolean): IrStatement? {
|
||||
return expression.process() ?: expression
|
||||
}
|
||||
|
||||
|
||||
+32
-3
@@ -39,14 +39,43 @@ class LoopExpressionGenerator(statementGenerator: StatementGenerator) : Statemen
|
||||
IrDoWhileLoopImpl(ktDoWhile.startOffset, ktDoWhile.endOffset,
|
||||
context.builtIns.unitType, IrStatementOrigin.DO_WHILE_LOOP))
|
||||
|
||||
private fun generateConditionalLoop(ktLoop: KtWhileExpressionBase, irLoop: IrLoopBase): IrLoop {
|
||||
private fun generateConditionalLoop(ktLoop: KtWhileExpressionBase, irLoop: IrLoopBase): IrExpression {
|
||||
irLoop.condition = statementGenerator.generateExpression(ktLoop.condition!!)
|
||||
statementGenerator.bodyGenerator.putLoop(ktLoop, irLoop)
|
||||
irLoop.body = ktLoop.body?.let { statementGenerator.generateExpression(ktLoop.body!!) }
|
||||
irLoop.body = ktLoop.body?.let { ktLoopBody ->
|
||||
if (ktLoopBody is KtBlockExpression) {
|
||||
if (ktLoop is KtDoWhileExpression)
|
||||
generateDoWhileLoopBody(ktLoopBody)
|
||||
else
|
||||
generateWhileLoopBody(ktLoopBody)
|
||||
}
|
||||
else
|
||||
statementGenerator.generateExpression(ktLoopBody)
|
||||
}
|
||||
irLoop.label = getLoopLabel(ktLoop)
|
||||
return irLoop
|
||||
|
||||
return if (ktLoop is KtDoWhileExpression) {
|
||||
IrBlockImpl(ktLoop.startOffset, ktLoop.endOffset, context.builtIns.unitType).apply {
|
||||
statements.add(irLoop)
|
||||
}
|
||||
}
|
||||
else
|
||||
irLoop
|
||||
}
|
||||
|
||||
private fun generateWhileLoopBody(ktLoopBody: KtBlockExpression): IrExpression =
|
||||
IrBlockImpl(
|
||||
ktLoopBody.startOffset, ktLoopBody.endOffset, context.builtIns.unitType, null,
|
||||
ktLoopBody.statements.map { statementGenerator.generateStatement(it) }
|
||||
)
|
||||
|
||||
|
||||
private fun generateDoWhileLoopBody(ktLoopBody: KtBlockExpression): IrExpression =
|
||||
IrCompositeImpl(
|
||||
ktLoopBody.startOffset, ktLoopBody.endOffset, context.builtIns.unitType, null,
|
||||
ktLoopBody.statements.map { statementGenerator.generateStatement(it) }
|
||||
)
|
||||
|
||||
fun generateBreak(ktBreak: KtBreakExpression): IrExpression {
|
||||
val parentLoop = findParentLoop(ktBreak) ?:
|
||||
return ErrorExpressionGenerator(statementGenerator).generateErrorExpression(
|
||||
|
||||
Reference in New Issue
Block a user