Refactor IrWhen.
This commit is contained in:
@@ -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)
|
||||
}
|
||||
|
||||
+10
-55
@@ -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)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user