Refactor IrWhen.

This commit is contained in:
Dmitry Petrov
2016-09-21 15:32:36 +03:00
parent aca71dea22
commit 8551bcf103
37 changed files with 700 additions and 554 deletions
@@ -16,19 +16,23 @@
package org.jetbrains.kotlin.ir.expressions
import org.jetbrains.kotlin.ir.IrElement
import org.jetbrains.kotlin.ir.visitors.IrElementTransformer
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
interface IrWhen : IrExpression {
val origin: IrStatementOrigin?
val branchesCount: Int
fun getNthCondition(n: Int): IrExpression?
fun getNthResult(n: Int): IrExpression?
fun putNthCondition(n: Int, expression: IrExpression)
fun putNthResult(n: Int, expression: IrExpression)
var elseBranch: IrExpression?
val branches: MutableList<IrBranch>
}
val IrWhen.branchIndices: IntRange get() = 0 ..branchesCount - 1
interface IrBranch : IrElement {
var condition: IrExpression
var result: IrExpression
override fun <D> transform(transformer: IrElementTransformer<D>, data: D): IrBranch =
transformer.visitBranch(this, data)
override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R =
visitor.visitBranch(this, data)
}
@@ -16,17 +16,19 @@
package org.jetbrains.kotlin.ir.expressions.impl
import org.jetbrains.kotlin.ir.expressions.IrBranch
import org.jetbrains.kotlin.ir.expressions.IrExpression
import org.jetbrains.kotlin.ir.expressions.IrStatementOrigin
import org.jetbrains.kotlin.ir.expressions.IrWhen
import org.jetbrains.kotlin.ir.visitors.IrElementTransformer
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.types.typeUtil.builtIns
import org.jetbrains.kotlin.utils.SmartList
class IrIfThenElseImpl(
startOffset: Int, endOffset: Int, type: KotlinType,
override val origin: IrStatementOrigin? = null
) : IrExpressionBase(startOffset, endOffset, type), IrWhen {
) : IrWhenBase(startOffset, endOffset, type) {
override val branches: MutableList<IrBranch> = SmartList()
constructor(
startOffset: Int, endOffset: Int, type: KotlinType,
condition: IrExpression,
@@ -34,56 +36,9 @@ class IrIfThenElseImpl(
elseBranch: IrExpression? = null,
origin: IrStatementOrigin? = null
) : this(startOffset, endOffset, type, origin) {
this.condition = condition
this.thenBranch = thenBranch
this.elseBranch = elseBranch
}
override val branchesCount: Int get() = 1
override fun getNthCondition(n: Int): IrExpression? =
if (n == 0) condition else null
override fun getNthResult(n: Int): IrExpression? =
when (n) {
0 -> {
thenBranch
}
1 -> {
elseBranch
}
else -> null
}
override fun putNthCondition(n: Int, expression: IrExpression) {
if (n == 0) condition = expression
else throw AssertionError("No such branch $n")
}
override fun putNthResult(n: Int, expression: IrExpression) {
if (n == 0) thenBranch = expression
else throw AssertionError("No such branch $n")
}
lateinit var condition: IrExpression
lateinit var thenBranch: IrExpression
override var elseBranch: IrExpression? = null
override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R =
visitor.visitWhen(this, data)
override fun <D> acceptChildren(visitor: IrElementVisitor<Unit, D>, data: D) {
condition.accept(visitor, data)
thenBranch.accept(visitor, data)
elseBranch?.accept(visitor, data)
}
override fun <D> transformChildren(transformer: IrElementTransformer<D>, data: D) {
condition = condition.transform(transformer, data)
thenBranch = thenBranch.transform(transformer, data)
elseBranch = elseBranch?.transform(transformer, data)
branches.add(IrBranchImpl(startOffset, endOffset, condition, thenBranch))
if (elseBranch != null) {
branches.add(IrBranchImpl.elseBranch(elseBranch))
}
}
}
@@ -16,57 +16,58 @@
package org.jetbrains.kotlin.ir.expressions.impl
import org.jetbrains.kotlin.ir.expressions.IrExpression
import org.jetbrains.kotlin.ir.expressions.IrStatementOrigin
import org.jetbrains.kotlin.ir.expressions.IrWhen
import org.jetbrains.kotlin.ir.IrElementBase
import org.jetbrains.kotlin.ir.expressions.*
import org.jetbrains.kotlin.ir.visitors.IrElementTransformer
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.types.typeUtil.builtIns
import java.util.*
abstract class IrWhenBase(startOffset: Int, endOffset: Int, type: KotlinType, override val origin: IrStatementOrigin? = null) :
IrExpressionBase(startOffset, endOffset, type), IrWhen {
override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R =
visitor.visitWhen(this, data)
override fun <D> acceptChildren(visitor: IrElementVisitor<Unit, D>, data: D) {
branches.forEach { it.accept(visitor, data) }
}
override fun <D> transformChildren(transformer: IrElementTransformer<D>, data: D) {
branches.forEachIndexed { i, irBranch ->
branches[i] = irBranch.transform(transformer, data)
}
}
}
class IrWhenImpl(
startOffset: Int,
endOffset: Int,
type: KotlinType,
override val origin: IrStatementOrigin? = null
) : IrExpressionBase(startOffset, endOffset, type), IrWhen {
private val branchParts = ArrayList<IrExpression>()
) : IrWhenBase(startOffset, endOffset, type) {
override val branches: MutableList<IrBranch> = ArrayList()
}
fun addBranch(condition: IrExpression, result: IrExpression) {
branchParts.add(condition)
branchParts.add(result)
}
override var elseBranch: IrExpression? = null
override val branchesCount: Int get() = branchParts.size / 2
override fun getNthCondition(n: Int): IrExpression? =
branchParts.getOrNull(n * 2)
override fun getNthResult(n: Int): IrExpression? =
branchParts.getOrNull(n * 2 + 1)
override fun putNthCondition(n: Int, expression: IrExpression) {
branchParts[n * 2] = expression
}
override fun putNthResult(n: Int, expression: IrExpression) {
branchParts[n * 2 + 1] = expression
}
override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R =
visitor.visitWhen(this, data)
class IrBranchImpl(startOffset: Int, endOffset: Int, override var condition: IrExpression, override var result: IrExpression) :
IrElementBase(startOffset, endOffset), IrBranch {
constructor(condition: IrExpression, result: IrExpression) : this(condition.startOffset, condition.endOffset, condition, result)
override fun <D> acceptChildren(visitor: IrElementVisitor<Unit, D>, data: D) {
branchParts.forEach { it.accept(visitor, data) }
elseBranch?.accept(visitor, data)
condition.accept(visitor, data)
result.accept(visitor, data)
}
override fun <D> transformChildren(transformer: IrElementTransformer<D>, data: D) {
branchParts.forEachIndexed { i, irExpression ->
branchParts[i] = irExpression.transform(transformer, data)
}
elseBranch = elseBranch?.transform(transformer, data)
condition = condition.transform(transformer, data)
result = result.transform(transformer, data)
}
companion object {
fun elseBranch(result: IrExpression) =
IrBranchImpl(
IrConstImpl.boolean(result.startOffset, result.endOffset, result.type.builtIns.booleanType, true),
result
)
}
}
@@ -131,11 +131,16 @@ class DumpIrTreeVisitor(out: Appendable): IrElementVisitor<Unit, String> {
override fun visitWhen(expression: IrWhen, data: String) {
expression.dumpLabeledElementWith(data) {
for (i in 0 .. expression.branchesCount - 1) {
expression.getNthCondition(i)!!.accept(this, "if")
expression.getNthResult(i)!!.accept(this, "then")
expression.branches.forEach {
it.accept(this, "")
}
expression.elseBranch?.accept(this, "else")
}
}
override fun visitBranch(branch: IrBranch, data: String) {
branch.dumpLabeledElementWith(data) {
branch.condition.accept(this, "if")
branch.result.accept(this, "then")
}
}
@@ -155,6 +155,9 @@ class RenderIrElementVisitor : IrElementVisitor<String, Nothing?> {
override fun visitWhen(expression: IrWhen, data: Nothing?): String =
"WHEN type=${expression.type.render()} origin=${expression.origin}"
override fun visitBranch(branch: IrBranch, data: Nothing?): String =
"BRANCH"
override fun visitWhileLoop(loop: IrWhileLoop, data: Nothing?): String =
"WHILE label=${loop.label} origin=${loop.origin}"
@@ -92,6 +92,13 @@ interface IrElementTransformer<in D> : IrElementVisitor<IrElement, D> {
override fun visitTypeOperator(expression: IrTypeOperatorCall, data: D) = visitExpression(expression, data)
override fun visitWhen(expression: IrWhen, data: D) = visitExpression(expression, data)
override fun visitBranch(branch: IrBranch, data: D): IrBranch =
branch.apply {
condition = condition.transform(this@IrElementTransformer, data)
result = result.transform(this@IrElementTransformer, data)
}
override fun visitLoop(loop: IrLoop, data: D) = visitExpression(loop, data)
override fun visitWhileLoop(loop: IrWhileLoop, data: D) = visitLoop(loop, data)
override fun visitDoWhileLoop(loop: IrDoWhileLoop, data: D) = visitLoop(loop, data)
@@ -78,6 +78,7 @@ interface IrElementVisitor<out R, in D> {
fun visitTypeOperator(expression: IrTypeOperatorCall, data: D) = visitExpression(expression, data)
fun visitWhen(expression: IrWhen, data: D) = visitExpression(expression, data)
fun visitBranch(branch: IrBranch, data: D) = visitElement(branch, data)
fun visitLoop(loop: IrLoop, data: D) = visitExpression(loop, data)
fun visitWhileLoop(loop: IrWhileLoop, data: D) = visitLoop(loop, data)
fun visitDoWhileLoop(loop: IrDoWhileLoop, data: D) = visitLoop(loop, data)
@@ -165,6 +165,9 @@ interface IrElementVisitorVoid : IrElementVisitor<Unit, Nothing?> {
fun visitWhen(expression: IrWhen) = visitExpression(expression)
override fun visitWhen(expression: IrWhen, data: Nothing?) = visitWhen(expression)
fun visitBranch(branch: IrBranch) = visitElement(branch)
override fun visitBranch(branch: IrBranch, data: Nothing?) = visitBranch(branch)
fun visitLoop(loop: IrLoop) = visitExpression(loop)
override fun visitLoop(loop: IrLoop, data: Nothing?) = visitLoop(loop)