Empty loops.
This commit is contained in:
committed by
Dmitry Petrov
parent
179a06672b
commit
d45811a5da
@@ -20,13 +20,14 @@ import org.jetbrains.kotlin.descriptors.CallableDescriptor
|
||||
import org.jetbrains.kotlin.ir.expressions.*
|
||||
import org.jetbrains.kotlin.psi.KtBlockExpression
|
||||
import org.jetbrains.kotlin.psi.KtExpression
|
||||
import org.jetbrains.kotlin.psi.KtLoopExpression
|
||||
import org.jetbrains.kotlin.psi.psiUtil.endOffset
|
||||
import org.jetbrains.kotlin.psi.psiUtil.startOffset
|
||||
import java.util.*
|
||||
|
||||
class BodyGenerator(val scopeOwner: CallableDescriptor, override val context: GeneratorContext): GeneratorWithScope {
|
||||
override val scope = Scope(scopeOwner)
|
||||
private val loopTable = HashMap<KtExpression, IrLoop>()
|
||||
private val loopTable = HashMap<KtLoopExpression, IrLoop>()
|
||||
|
||||
fun generateFunctionBody(ktBody: KtExpression): IrBody {
|
||||
resetInternalContext()
|
||||
@@ -64,7 +65,7 @@ class BodyGenerator(val scopeOwner: CallableDescriptor, override val context: Ge
|
||||
private fun createStatementGenerator() =
|
||||
StatementGenerator(context, scopeOwner, this, scope)
|
||||
|
||||
fun putLoop(expression: KtExpression, irLoop: IrLoop) {
|
||||
fun putLoop(expression: KtLoopExpression, irLoop: IrLoop) {
|
||||
loopTable[expression] = irLoop
|
||||
}
|
||||
|
||||
|
||||
+5
-3
@@ -44,7 +44,7 @@ class LoopExpressionGenerator(val statementGenerator: StatementGenerator) : Gene
|
||||
private fun generateConditionalLoop(ktLoop: KtWhileExpressionBase, irLoop: IrLoopBase): IrLoop {
|
||||
statementGenerator.bodyGenerator.putLoop(ktLoop, irLoop)
|
||||
irLoop.condition = statementGenerator.generateExpression(ktLoop.condition!!)
|
||||
irLoop.body = statementGenerator.generateExpression(ktLoop.body!!)
|
||||
irLoop.body = ktLoop.body?.let { statementGenerator.generateExpression(ktLoop.body!!) }
|
||||
irLoop.label = getLoopLabel(ktLoop)
|
||||
return irLoop
|
||||
}
|
||||
@@ -105,7 +105,7 @@ class LoopExpressionGenerator(val statementGenerator: StatementGenerator) : Gene
|
||||
}
|
||||
|
||||
val ktLoopRange = ktFor.loopRange!!
|
||||
val ktForBody = ktFor.body!!
|
||||
val ktForBody = ktFor.body
|
||||
val iteratorResolvedCall = getOrFail(BindingContext.LOOP_RANGE_ITERATOR_RESOLVED_CALL, ktLoopRange)
|
||||
val hasNextResolvedCall = getOrFail(BindingContext.LOOP_RANGE_HAS_NEXT_RESOLVED_CALL, ktLoopRange)
|
||||
val nextResolvedCall = getOrFail(BindingContext.LOOP_RANGE_NEXT_RESOLVED_CALL, ktLoopRange)
|
||||
@@ -150,7 +150,9 @@ class LoopExpressionGenerator(val statementGenerator: StatementGenerator) : Gene
|
||||
statementGenerator.declareComponentVariablesInBlock(ktLoopDestructuringParameter, irInnerBody, VariableLValue(irLoopParameter))
|
||||
}
|
||||
|
||||
irInnerBody.addStatement(statementGenerator.generateExpression(ktForBody))
|
||||
if (ktForBody != null) {
|
||||
irInnerBody.addStatement(statementGenerator.generateExpression(ktForBody))
|
||||
}
|
||||
|
||||
return irForBlock
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@ import org.jetbrains.kotlin.types.KotlinType
|
||||
|
||||
interface IrLoop : IrExpression {
|
||||
val operator: IrOperator?
|
||||
var body: IrExpression
|
||||
var body: IrExpression?
|
||||
var condition: IrExpression
|
||||
val label: String?
|
||||
}
|
||||
@@ -49,14 +49,12 @@ abstract class IrLoopBase(
|
||||
value.setTreeLocation(this, LOOP_CONDITION_SLOT)
|
||||
}
|
||||
|
||||
private var bodyImpl: IrExpression? = null
|
||||
override var body: IrExpression
|
||||
get() = bodyImpl!!
|
||||
override var body: IrExpression? = null
|
||||
set(value) {
|
||||
value.assertDetached()
|
||||
bodyImpl?.detach()
|
||||
bodyImpl = value
|
||||
value.setTreeLocation(this, LOOP_BODY_SLOT)
|
||||
value?.assertDetached()
|
||||
field?.detach()
|
||||
field = value
|
||||
value?.setTreeLocation(this, LOOP_BODY_SLOT)
|
||||
}
|
||||
|
||||
override fun getChild(slot: Int): IrElement? =
|
||||
@@ -98,7 +96,7 @@ class IrWhileLoopImpl(
|
||||
|
||||
override fun <D> acceptChildren(visitor: IrElementVisitor<Unit, D>, data: D) {
|
||||
condition.accept(visitor, data)
|
||||
body.accept(visitor, data)
|
||||
body?.accept(visitor, data)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -125,7 +123,7 @@ class IrDoWhileLoopImpl(
|
||||
}
|
||||
|
||||
override fun <D> acceptChildren(visitor: IrElementVisitor<Unit, D>, data: D) {
|
||||
body.accept(visitor, data)
|
||||
body?.accept(visitor, data)
|
||||
condition.accept(visitor, data)
|
||||
}
|
||||
}
|
||||
@@ -66,13 +66,13 @@ class DumpIrTreeVisitor(out: Appendable): IrElementVisitor<Unit, String> {
|
||||
override fun visitWhileLoop(loop: IrWhileLoop, data: String) {
|
||||
loop.dumpLabeledElementWith(data) {
|
||||
loop.condition.accept(this, "condition")
|
||||
loop.body.accept(this, "body")
|
||||
loop.body?.accept(this, "body")
|
||||
}
|
||||
}
|
||||
|
||||
override fun visitDoWhileLoop(loop: IrDoWhileLoop, data: String) {
|
||||
loop.dumpLabeledElementWith(data) {
|
||||
loop.body.accept(this, "body")
|
||||
loop.body?.accept(this, "body")
|
||||
loop.condition.accept(this, "condition")
|
||||
}
|
||||
}
|
||||
|
||||
Vendored
+4
@@ -1,3 +1,7 @@
|
||||
fun testEmpty(ss: List<String>) {
|
||||
for (s in ss);
|
||||
}
|
||||
|
||||
fun testIterable(ss: List<String>) {
|
||||
for (s in ss) {
|
||||
println(s)
|
||||
|
||||
Vendored
+13
@@ -1,4 +1,17 @@
|
||||
FILE /for.kt
|
||||
FUN public fun testEmpty(/*0*/ ss: kotlin.collections.List<kotlin.String>): kotlin.Unit
|
||||
BLOCK_BODY
|
||||
BLOCK type=kotlin.Unit operator=FOR_LOOP
|
||||
VAR val tmp0_iterator: kotlin.collections.Iterator<kotlin.String>
|
||||
CALL .iterator type=kotlin.collections.Iterator<kotlin.String> operator=FOR_LOOP_ITERATOR
|
||||
$this: GET_VAR ss type=kotlin.collections.List<kotlin.String> operator=null
|
||||
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<kotlin.String> operator=null
|
||||
body: BLOCK type=kotlin.Unit operator=FOR_LOOP_INNER_WHILE
|
||||
VAR val s: kotlin.String
|
||||
CALL .next type=kotlin.String operator=FOR_LOOP_NEXT
|
||||
$this: GET_VAR tmp0_iterator type=kotlin.collections.Iterator<kotlin.String> operator=null
|
||||
FUN public fun testIterable(/*0*/ ss: kotlin.collections.List<kotlin.String>): kotlin.Unit
|
||||
BLOCK_BODY
|
||||
BLOCK type=kotlin.Unit operator=FOR_LOOP
|
||||
|
||||
+2
@@ -1,7 +1,9 @@
|
||||
fun test() {
|
||||
var x = 0
|
||||
while (x < 0);
|
||||
while (x < 5) x++
|
||||
while (x < 10) { x++ }
|
||||
do while (x < 0)
|
||||
do x++ while (x < 15)
|
||||
do { x ++ } while (x < 20)
|
||||
}
|
||||
|
||||
+10
@@ -3,6 +3,11 @@ FILE /whileDoWhile.kt
|
||||
BLOCK_BODY
|
||||
VAR var x: kotlin.Int
|
||||
CONST Int type=kotlin.Int value='0'
|
||||
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
|
||||
other: CONST Int type=kotlin.Int value='0'
|
||||
WHILE label=null operator=WHILE_LOOP
|
||||
condition: CALL .LT0 type=kotlin.Boolean operator=LT
|
||||
arg0: CALL .compareTo type=kotlin.Int operator=LT
|
||||
@@ -28,6 +33,11 @@ FILE /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 label=null operator=DO_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
|
||||
other: CONST Int type=kotlin.Int value='0'
|
||||
DO_WHILE label=null operator=DO_WHILE_LOOP
|
||||
body: BLOCK type=kotlin.Int operator=POSTFIX_INCR
|
||||
VAR val tmp2: kotlin.Int
|
||||
|
||||
Reference in New Issue
Block a user