Make 'when' great again.
This commit is contained in:
committed by
Dmitry Petrov
parent
f787f8ecbf
commit
97593fa19e
+2
-2
@@ -123,9 +123,9 @@ class DeclarationGenerator(override val context: GeneratorContext) : IrGenerator
|
|||||||
|
|
||||||
private fun generateFunctionBody(scopeOwner: CallableDescriptor, ktBody: KtExpression): IrBody =
|
private fun generateFunctionBody(scopeOwner: CallableDescriptor, ktBody: KtExpression): IrBody =
|
||||||
IrExpressionBodyImpl(ktBody.startOffset, ktBody.endOffset,
|
IrExpressionBodyImpl(ktBody.startOffset, ktBody.endOffset,
|
||||||
ExoressionBodyGenerator(scopeOwner, context).generateFunctionBody(ktBody))
|
ExpressionBodyGenerator(scopeOwner, context).generateFunctionBody(ktBody))
|
||||||
|
|
||||||
private fun generateInitializerBody(scopeOwner: CallableDescriptor, ktBody: KtExpression): IrBody =
|
private fun generateInitializerBody(scopeOwner: CallableDescriptor, ktBody: KtExpression): IrBody =
|
||||||
IrExpressionBodyImpl(ktBody.startOffset, ktBody.endOffset,
|
IrExpressionBodyImpl(ktBody.startOffset, ktBody.endOffset,
|
||||||
ExoressionBodyGenerator(scopeOwner, context).generatePropertyInitializerBody(ktBody))
|
ExpressionBodyGenerator(scopeOwner, context).generatePropertyInitializerBody(ktBody))
|
||||||
}
|
}
|
||||||
+1
-1
@@ -25,7 +25,7 @@ import org.jetbrains.kotlin.psi.KtExpression
|
|||||||
import org.jetbrains.kotlin.psi.psiUtil.endOffset
|
import org.jetbrains.kotlin.psi.psiUtil.endOffset
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.startOffset
|
import org.jetbrains.kotlin.psi.psiUtil.startOffset
|
||||||
|
|
||||||
class ExoressionBodyGenerator(val scopeOwner: CallableDescriptor, override val context: GeneratorContext): IrBodyGenerator {
|
class ExpressionBodyGenerator(val scopeOwner: CallableDescriptor, override val context: GeneratorContext): IrBodyGenerator {
|
||||||
override val scope = Scope.rootScope(scopeOwner, this)
|
override val scope = Scope.rootScope(scopeOwner, this)
|
||||||
|
|
||||||
fun generateFunctionBody(ktBody: KtExpression): IrExpression {
|
fun generateFunctionBody(ktBody: KtExpression): IrExpression {
|
||||||
+38
-6
@@ -39,11 +39,12 @@ import org.jetbrains.kotlin.resolve.constants.StringValue
|
|||||||
import org.jetbrains.kotlin.resolve.constants.evaluate.ConstantExpressionEvaluator
|
import org.jetbrains.kotlin.resolve.constants.evaluate.ConstantExpressionEvaluator
|
||||||
import org.jetbrains.kotlin.resolve.descriptorUtil.classValueType
|
import org.jetbrains.kotlin.resolve.descriptorUtil.classValueType
|
||||||
import org.jetbrains.kotlin.types.expressions.ExpressionTypingUtils
|
import org.jetbrains.kotlin.types.expressions.ExpressionTypingUtils
|
||||||
|
import org.jetbrains.kotlin.utils.SmartList
|
||||||
|
|
||||||
class StatementGenerator(
|
class StatementGenerator(
|
||||||
override val context: GeneratorContext,
|
override val context: GeneratorContext,
|
||||||
val scopeOwner: DeclarationDescriptor,
|
val scopeOwner: DeclarationDescriptor,
|
||||||
val declarationBodyGenerator: ExoressionBodyGenerator,
|
val expressionBodyGenerator: ExpressionBodyGenerator,
|
||||||
override val scope: Scope
|
override val scope: Scope
|
||||||
) : KtVisitor<IrStatement, Nothing?>(), IrBodyGenerator {
|
) : KtVisitor<IrStatement, Nothing?>(), IrBodyGenerator {
|
||||||
fun generateExpression(ktExpression: KtExpression): IrExpression =
|
fun generateExpression(ktExpression: KtExpression): IrExpression =
|
||||||
@@ -264,11 +265,42 @@ class StatementGenerator(
|
|||||||
|
|
||||||
override fun visitIfExpression(expression: KtIfExpression, data: Nothing?): IrStatement {
|
override fun visitIfExpression(expression: KtIfExpression, data: Nothing?): IrStatement {
|
||||||
val resultType = getInferredTypeWithSmartcasts(expression)
|
val resultType = getInferredTypeWithSmartcasts(expression)
|
||||||
val irCondition = toExpectedType(expression.condition!!.genExpr(), context.builtIns.booleanType)
|
|
||||||
val irThenBranch = toExpectedType(expression.then!!.genExpr(), resultType)
|
var ktLastIf: KtIfExpression = expression
|
||||||
val irElseBranch = toExpectedTypeOrNull(expression.`else`?.genExpr(), resultType)
|
val irBranches = SmartList<Pair<IrExpression, IrExpression>>()
|
||||||
return IrIfThenElseImpl(expression.startOffset, expression.endOffset, resultType,
|
var irElseBranch: IrExpression? = null
|
||||||
irCondition, irThenBranch, irElseBranch, IrOperator.IF)
|
|
||||||
|
whenBranches@while (true) {
|
||||||
|
val irCondition = generateExpressionWithExpectedType(expression.condition!!, context.builtIns.booleanType)
|
||||||
|
val irThenBranch = generateExpressionWithExpectedType(expression.then!!, resultType)
|
||||||
|
irBranches.add(Pair(irCondition, irThenBranch))
|
||||||
|
|
||||||
|
val ktElse = ktLastIf.`else`?.deparenthesize()
|
||||||
|
when (ktElse) {
|
||||||
|
null -> break@whenBranches
|
||||||
|
is KtIfExpression -> ktLastIf = ktElse
|
||||||
|
is KtExpression -> {
|
||||||
|
irElseBranch = generateExpressionWithExpectedType(ktElse, resultType)
|
||||||
|
break@whenBranches
|
||||||
|
}
|
||||||
|
else -> throw AssertionError("Unexpected else expression: ${ktElse.text}")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return if (irBranches.size == 1) {
|
||||||
|
val (irCondition, irThenBranch) = irBranches[0]
|
||||||
|
IrIfThenElseImpl(expression.startOffset, expression.endOffset, resultType,
|
||||||
|
irCondition, irThenBranch, irElseBranch, IrOperator.IF)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
val irWhen = IrWhenImpl(expression.startOffset, expression.endOffset, resultType, IrOperator.WHEN)
|
||||||
|
for ((irCondition, irThenBranch) in irBranches) {
|
||||||
|
irWhen.addBranch(irCondition, irThenBranch)
|
||||||
|
}
|
||||||
|
irWhen.elseBranch = irElseBranch
|
||||||
|
irWhen
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun visitWhenExpression(expression: KtWhenExpression, data: Nothing?): IrStatement =
|
override fun visitWhenExpression(expression: KtWhenExpression, data: Nothing?): IrStatement =
|
||||||
|
|||||||
+10
-24
@@ -35,12 +35,11 @@ class WhenExpressionGenerator(statementGenerator: StatementGenerator) : IrChildB
|
|||||||
|
|
||||||
val resultType = getInferredTypeWithSmartcasts(expression)
|
val resultType = getInferredTypeWithSmartcasts(expression)
|
||||||
|
|
||||||
val irBranches = ArrayList<Pair<IrExpression, IrExpression>>(expression.entries.size)
|
val irWhen = IrWhenImpl(expression.startOffset, expression.endOffset, resultType, IrOperator.WHEN)
|
||||||
var irElseExpression: IrExpression? = null
|
|
||||||
|
|
||||||
for (ktEntry in expression.entries) {
|
for (ktEntry in expression.entries) {
|
||||||
if (ktEntry.isElse) {
|
if (ktEntry.isElse) {
|
||||||
irElseExpression = parentGenerator.generateExpressionWithExpectedType(ktEntry.expression!!, resultType)
|
irWhen.elseBranch = parentGenerator.generateExpressionWithExpectedType(ktEntry.expression!!, resultType)
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -56,42 +55,29 @@ class WhenExpressionGenerator(statementGenerator: StatementGenerator) : IrChildB
|
|||||||
}
|
}
|
||||||
|
|
||||||
val irBranchResult = parentGenerator.generateExpressionWithExpectedType(ktEntry.expression!!, resultType)
|
val irBranchResult = parentGenerator.generateExpressionWithExpectedType(ktEntry.expression!!, resultType)
|
||||||
irBranches.add(Pair(irBranchCondition!!, irBranchResult))
|
irWhen.addBranch(irBranchCondition!!, irBranchResult)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (irBranches.isEmpty()) return generateWhenBody(expression, irSubject)
|
return generateWhenBody(expression, irSubject, irWhen)
|
||||||
|
|
||||||
irBranches.reverse()
|
|
||||||
|
|
||||||
val (irLastCondition, irLastResult) = irBranches[0]
|
|
||||||
var irTopBranch = IrIfThenElseImpl(irLastCondition.startOffset, irLastCondition.endOffset, resultType,
|
|
||||||
irLastCondition, irLastResult, irElseExpression, IrOperator.WHEN)
|
|
||||||
|
|
||||||
for ((irBranchCondition, irBranchResult) in irBranches.subList(1, irBranches.size)) {
|
|
||||||
irTopBranch = IrIfThenElseImpl(irBranchCondition.startOffset, irBranchCondition.endOffset, resultType,
|
|
||||||
irBranchCondition, irBranchResult, irTopBranch, IrOperator.WHEN)
|
|
||||||
}
|
|
||||||
|
|
||||||
return generateWhenBody(expression, irSubject, irTopBranch)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun generateWhenBody(expression: KtWhenExpression, irSubject: IrVariable?, irTopBranch: IrIfThenElse? = null): IrExpression {
|
private fun generateWhenBody(expression: KtWhenExpression, irSubject: IrVariable?, irWhen: IrWhen): IrExpression {
|
||||||
if (irSubject == null) {
|
if (irSubject == null) {
|
||||||
if (irTopBranch == null)
|
if (irWhen.branchesCount == 0)
|
||||||
return IrBlockImpl(expression.startOffset, expression.endOffset, null, false, IrOperator.WHEN)
|
return IrBlockImpl(expression.startOffset, expression.endOffset, null, false, IrOperator.WHEN)
|
||||||
else
|
else
|
||||||
return irTopBranch
|
return irWhen
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (irTopBranch == null) {
|
if (irWhen.branchesCount == 0) {
|
||||||
val irBlock = IrBlockImpl(expression.startOffset, expression.endOffset, null, false, IrOperator.WHEN)
|
val irBlock = IrBlockImpl(expression.startOffset, expression.endOffset, null, false, IrOperator.WHEN)
|
||||||
irBlock.addStatement(irSubject)
|
irBlock.addStatement(irSubject)
|
||||||
return irBlock
|
return irBlock
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
val irBlock = IrBlockImpl(expression.startOffset, expression.endOffset, irTopBranch.type, true, IrOperator.WHEN)
|
val irBlock = IrBlockImpl(expression.startOffset, expression.endOffset, irWhen.type, true, IrOperator.WHEN)
|
||||||
irBlock.addStatement(irSubject)
|
irBlock.addStatement(irSubject)
|
||||||
irBlock.addStatement(irTopBranch)
|
irBlock.addStatement(irWhen)
|
||||||
return irBlock
|
return irBlock
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,9 +25,9 @@ const val EXTENSION_RECEIVER_SLOT = -2
|
|||||||
const val FUNCTION_BODY_SLOT = 0
|
const val FUNCTION_BODY_SLOT = 0
|
||||||
const val MODULE_SLOT = 0
|
const val MODULE_SLOT = 0
|
||||||
const val INITIALIZER_SLOT = 0
|
const val INITIALIZER_SLOT = 0
|
||||||
const val IF_CONDITION_SLOT = -1
|
const val IF_CONDITION_SLOT = 0
|
||||||
const val IF_THEN_SLOT = -2
|
const val IF_THEN_SLOT = 1
|
||||||
const val IF_ELSE_SLOT = -3
|
const val IF_ELSE_SLOT = -1
|
||||||
const val LOOP_BODY_SLOT = -1
|
const val LOOP_BODY_SLOT = -1
|
||||||
const val LOOP_CONDITION_SLOT = -2
|
const val LOOP_CONDITION_SLOT = -2
|
||||||
const val SETTER_ARGUMENT_INDEX = 0
|
const val SETTER_ARGUMENT_INDEX = 0
|
||||||
+82
-12
@@ -23,19 +23,81 @@ import org.jetbrains.kotlin.types.KotlinType
|
|||||||
import org.jetbrains.kotlin.utils.SmartList
|
import org.jetbrains.kotlin.utils.SmartList
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
interface IrIfThenElse : IrExpression {
|
interface IrWhen : IrExpression {
|
||||||
val operator: IrOperator?
|
val operator: IrOperator?
|
||||||
var condition: IrExpression
|
val branchesCount: Int
|
||||||
var thenBranch: IrExpression
|
fun getNthCondition(n: Int): IrExpression?
|
||||||
|
fun getNthResult(n: Int): IrExpression?
|
||||||
var elseBranch: IrExpression?
|
var elseBranch: IrExpression?
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class IrWhenImpl(
|
||||||
|
startOffset: Int,
|
||||||
|
endOffset: Int,
|
||||||
|
type: KotlinType?,
|
||||||
|
override val operator: IrOperator? = null
|
||||||
|
) : IrExpressionBase(startOffset, endOffset, type), IrWhen {
|
||||||
|
private val branchParts = ArrayList<IrExpression>()
|
||||||
|
|
||||||
|
fun addBranch(condition: IrExpression, result: IrExpression) {
|
||||||
|
condition.assertDetached()
|
||||||
|
result.assertDetached()
|
||||||
|
condition.setTreeLocation(this, branchParts.size)
|
||||||
|
branchParts.add(condition)
|
||||||
|
result.setTreeLocation(this, branchParts.size)
|
||||||
|
branchParts.add(result)
|
||||||
|
}
|
||||||
|
|
||||||
|
override var elseBranch: IrExpression? = null
|
||||||
|
set(value) {
|
||||||
|
value?.assertDetached()
|
||||||
|
value?.detach()
|
||||||
|
field = value
|
||||||
|
value?.setTreeLocation(this, IF_ELSE_SLOT)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getChild(slot: Int): IrElement? {
|
||||||
|
return when (slot) {
|
||||||
|
IF_ELSE_SLOT -> elseBranch
|
||||||
|
else -> branchParts.getOrNull(slot)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun replaceChild(slot: Int, newChild: IrElement) {
|
||||||
|
when (slot) {
|
||||||
|
IF_ELSE_SLOT -> elseBranch = newChild.assertCast()
|
||||||
|
in branchParts.indices -> {
|
||||||
|
newChild.assertDetached()
|
||||||
|
branchParts[slot].detach()
|
||||||
|
branchParts[slot] = newChild.assertCast()
|
||||||
|
newChild.setTreeLocation(this, slot)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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 <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R =
|
||||||
|
visitor.visitWhen(this, data)
|
||||||
|
|
||||||
|
override fun <D> acceptChildren(visitor: IrElementVisitor<Unit, D>, data: D) {
|
||||||
|
branchParts.forEach { it.accept(visitor, data) }
|
||||||
|
elseBranch?.accept(visitor, data)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
class IrIfThenElseImpl(
|
class IrIfThenElseImpl(
|
||||||
startOffset: Int,
|
startOffset: Int,
|
||||||
endOffset: Int,
|
endOffset: Int,
|
||||||
type: KotlinType?,
|
type: KotlinType?,
|
||||||
override val operator: IrOperator? = null
|
override val operator: IrOperator? = null
|
||||||
) : IrExpressionBase(startOffset, endOffset, type), IrIfThenElse {
|
) : IrExpressionBase(startOffset, endOffset, type), IrWhen {
|
||||||
constructor(
|
constructor(
|
||||||
startOffset: Int,
|
startOffset: Int,
|
||||||
endOffset: Int,
|
endOffset: Int,
|
||||||
@@ -50,8 +112,16 @@ class IrIfThenElseImpl(
|
|||||||
this.elseBranch = elseBranch
|
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? =
|
||||||
|
if (n == 0) thenBranch else null
|
||||||
|
|
||||||
private var conditionImpl: IrExpression? = null
|
private var conditionImpl: IrExpression? = null
|
||||||
override var condition: IrExpression
|
var condition: IrExpression
|
||||||
get() = conditionImpl!!
|
get() = conditionImpl!!
|
||||||
set(value) {
|
set(value) {
|
||||||
value.assertDetached()
|
value.assertDetached()
|
||||||
@@ -61,7 +131,7 @@ class IrIfThenElseImpl(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private var thenBranchImpl: IrExpression? = null
|
private var thenBranchImpl: IrExpression? = null
|
||||||
override var thenBranch: IrExpression
|
var thenBranch: IrExpression
|
||||||
get() = thenBranchImpl!!
|
get() = thenBranchImpl!!
|
||||||
set(value) {
|
set(value) {
|
||||||
value.assertDetached()
|
value.assertDetached()
|
||||||
@@ -99,7 +169,7 @@ class IrIfThenElseImpl(
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R =
|
override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R =
|
||||||
visitor.visitIf(this, data)
|
visitor.visitWhen(this, data)
|
||||||
|
|
||||||
override fun <D> acceptChildren(visitor: IrElementVisitor<Unit, D>, data: D) {
|
override fun <D> acceptChildren(visitor: IrElementVisitor<Unit, D>, data: D) {
|
||||||
condition.accept(visitor, data)
|
condition.accept(visitor, data)
|
||||||
@@ -109,24 +179,24 @@ class IrIfThenElseImpl(
|
|||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
// a || b == if (a) true else b
|
// a || b == if (a) true else b
|
||||||
fun oror(startOffset: Int, endOffset: Int, a: IrExpression, b: IrExpression, operator: IrOperator = IrOperator.OROR): IrIfThenElse =
|
fun oror(startOffset: Int, endOffset: Int, a: IrExpression, b: IrExpression, operator: IrOperator = IrOperator.OROR): IrWhen =
|
||||||
IrIfThenElseImpl(startOffset, endOffset, b.type!!,
|
IrIfThenElseImpl(startOffset, endOffset, b.type!!,
|
||||||
a, IrConstImpl.constTrue(b.startOffset, b.endOffset, b.type!!), b,
|
a, IrConstImpl.constTrue(b.startOffset, b.endOffset, b.type!!), b,
|
||||||
operator)
|
operator)
|
||||||
|
|
||||||
fun oror(a: IrExpression, b: IrExpression, operator: IrOperator = IrOperator.OROR): IrIfThenElse =
|
fun oror(a: IrExpression, b: IrExpression, operator: IrOperator = IrOperator.OROR): IrWhen =
|
||||||
oror(b.startOffset, b.endOffset, a, b, operator)
|
oror(b.startOffset, b.endOffset, a, b, operator)
|
||||||
|
|
||||||
fun whenComma(a: IrExpression, b: IrExpression): IrIfThenElse =
|
fun whenComma(a: IrExpression, b: IrExpression): IrWhen =
|
||||||
oror(a, b, IrOperator.WHEN_COMMA)
|
oror(a, b, IrOperator.WHEN_COMMA)
|
||||||
|
|
||||||
// a && b == if (a) b else false
|
// a && b == if (a) b else false
|
||||||
fun andand(startOffset: Int, endOffset: Int, a: IrExpression, b: IrExpression, operator: IrOperator = IrOperator.ANDAND): IrIfThenElse =
|
fun andand(startOffset: Int, endOffset: Int, a: IrExpression, b: IrExpression, operator: IrOperator = IrOperator.ANDAND): IrWhen =
|
||||||
IrIfThenElseImpl(startOffset, endOffset, b.type!!,
|
IrIfThenElseImpl(startOffset, endOffset, b.type!!,
|
||||||
a, b, IrConstImpl.constFalse(b.startOffset, b.endOffset, b.type!!),
|
a, b, IrConstImpl.constFalse(b.startOffset, b.endOffset, b.type!!),
|
||||||
operator)
|
operator)
|
||||||
|
|
||||||
fun andand(a: IrExpression, b: IrExpression, operator: IrOperator = IrOperator.ANDAND): IrIfThenElse =
|
fun andand(a: IrExpression, b: IrExpression, operator: IrOperator = IrOperator.ANDAND): IrWhen =
|
||||||
andand(b.startOffset, b.endOffset, a, b, operator)
|
andand(b.startOffset, b.endOffset, a, b, operator)
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -20,7 +20,7 @@ import org.jetbrains.kotlin.ir.IrElement
|
|||||||
import org.jetbrains.kotlin.ir.SourceLocationManager
|
import org.jetbrains.kotlin.ir.SourceLocationManager
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrFile
|
import org.jetbrains.kotlin.ir.declarations.IrFile
|
||||||
import org.jetbrains.kotlin.ir.expressions.IrCall
|
import org.jetbrains.kotlin.ir.expressions.IrCall
|
||||||
import org.jetbrains.kotlin.ir.expressions.IrIfThenElse
|
import org.jetbrains.kotlin.ir.expressions.IrWhen
|
||||||
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
|
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
|
||||||
import org.jetbrains.kotlin.utils.Printer
|
import org.jetbrains.kotlin.utils.Printer
|
||||||
|
|
||||||
@@ -54,10 +54,12 @@ class DumpIrTreeVisitor(out: Appendable): IrElementVisitor<Unit, String> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun visitIf(expression: IrIfThenElse, data: String) {
|
override fun visitWhen(expression: IrWhen, data: String) {
|
||||||
expression.dumpLabeledElementWith(data) {
|
expression.dumpLabeledElementWith(data) {
|
||||||
expression.condition.accept(this, "if")
|
for (i in 0 .. expression.branchesCount - 1) {
|
||||||
expression.thenBranch.accept(this, "then")
|
expression.getNthCondition(i)!!.accept(this, "if")
|
||||||
|
expression.getNthResult(i)!!.accept(this, "then")
|
||||||
|
}
|
||||||
expression.elseBranch?.accept(this, "else")
|
expression.elseBranch?.accept(this, "else")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -97,8 +97,8 @@ class RenderIrElementVisitor : IrElementVisitor<String, Nothing?> {
|
|||||||
override fun visitTypeOperator(expression: IrTypeOperatorCall, data: Nothing?): String =
|
override fun visitTypeOperator(expression: IrTypeOperatorCall, data: Nothing?): String =
|
||||||
"TYPE_OP operator=${expression.operator} typeOperand=${expression.typeOperand.render()}"
|
"TYPE_OP operator=${expression.operator} typeOperand=${expression.typeOperand.render()}"
|
||||||
|
|
||||||
override fun visitIf(expression: IrIfThenElse, data: Nothing?): String =
|
override fun visitWhen(expression: IrWhen, data: Nothing?): String =
|
||||||
"IF type=${expression.type.render()} operator=${expression.operator}"
|
"WHEN type=${expression.type.render()} operator=${expression.operator}"
|
||||||
|
|
||||||
override fun visitDummyDeclaration(declaration: IrDummyDeclaration, data: Nothing?): String =
|
override fun visitDummyDeclaration(declaration: IrDummyDeclaration, data: Nothing?): String =
|
||||||
"DUMMY ${declaration.descriptor.name}"
|
"DUMMY ${declaration.descriptor.name}"
|
||||||
|
|||||||
@@ -56,7 +56,7 @@ interface IrElementVisitor<out R, in D> {
|
|||||||
|
|
||||||
fun visitTypeOperator(expression: IrTypeOperatorCall, data: D) = visitExpression(expression, data)
|
fun visitTypeOperator(expression: IrTypeOperatorCall, data: D) = visitExpression(expression, data)
|
||||||
|
|
||||||
fun visitIf(expression: IrIfThenElse, data: D) = visitExpression(expression, data)
|
fun visitWhen(expression: IrWhen, data: D) = visitExpression(expression, data)
|
||||||
fun visitLoop(loop: IrLoop, data: D) = visitExpression(loop, data)
|
fun visitLoop(loop: IrLoop, data: D) = visitExpression(loop, data)
|
||||||
fun visitWhileLoop(loop: IrWhileLoop, data: D) = visitLoop(loop, data)
|
fun visitWhileLoop(loop: IrWhileLoop, data: D) = visitLoop(loop, data)
|
||||||
fun visitDoWhileLoop(loop: IrDoWhileLoop, data: D) = visitLoop(loop, data)
|
fun visitDoWhileLoop(loop: IrDoWhileLoop, data: D) = visitLoop(loop, data)
|
||||||
|
|||||||
+2
-2
@@ -3,7 +3,7 @@ IrFile /booleanOperators.kt
|
|||||||
IrExpressionBody
|
IrExpressionBody
|
||||||
BLOCK type=<no-type> hasResult=false operator=null
|
BLOCK type=<no-type> hasResult=false operator=null
|
||||||
RETURN type=<no-type>
|
RETURN type=<no-type>
|
||||||
IF type=kotlin.Boolean operator=ANDAND
|
WHEN type=kotlin.Boolean operator=ANDAND
|
||||||
if: GET_VAR a type=kotlin.Boolean operator=null
|
if: GET_VAR a type=kotlin.Boolean operator=null
|
||||||
then: GET_VAR b type=kotlin.Boolean operator=null
|
then: GET_VAR b type=kotlin.Boolean operator=null
|
||||||
else: LITERAL Boolean type=kotlin.Boolean value='false'
|
else: LITERAL Boolean type=kotlin.Boolean value='false'
|
||||||
@@ -11,7 +11,7 @@ IrFile /booleanOperators.kt
|
|||||||
IrExpressionBody
|
IrExpressionBody
|
||||||
BLOCK type=<no-type> hasResult=false operator=null
|
BLOCK type=<no-type> hasResult=false operator=null
|
||||||
RETURN type=<no-type>
|
RETURN type=<no-type>
|
||||||
IF type=kotlin.Boolean operator=OROR
|
WHEN type=kotlin.Boolean operator=OROR
|
||||||
if: GET_VAR a type=kotlin.Boolean operator=null
|
if: GET_VAR a type=kotlin.Boolean operator=null
|
||||||
then: LITERAL Boolean type=kotlin.Boolean value='true'
|
then: LITERAL Boolean type=kotlin.Boolean value='true'
|
||||||
else: GET_VAR b type=kotlin.Boolean operator=null
|
else: GET_VAR b type=kotlin.Boolean operator=null
|
||||||
|
|||||||
+2
-2
@@ -12,12 +12,12 @@ IrFile /elvis.kt
|
|||||||
IrFunction public fun test3(/*0*/ a: kotlin.Any?, /*1*/ b: kotlin.Any?): kotlin.String
|
IrFunction public fun test3(/*0*/ a: kotlin.Any?, /*1*/ b: kotlin.Any?): kotlin.String
|
||||||
IrExpressionBody
|
IrExpressionBody
|
||||||
BLOCK type=<no-type> hasResult=false operator=null
|
BLOCK type=<no-type> hasResult=false operator=null
|
||||||
IF type=kotlin.Unit operator=IF
|
WHEN type=kotlin.Unit operator=IF
|
||||||
if: TYPE_OP operator=NOT_INSTANCEOF typeOperand=kotlin.String
|
if: TYPE_OP operator=NOT_INSTANCEOF typeOperand=kotlin.String
|
||||||
GET_VAR b type=kotlin.Any? operator=null
|
GET_VAR b type=kotlin.Any? operator=null
|
||||||
then: RETURN type=<no-type>
|
then: RETURN type=<no-type>
|
||||||
LITERAL String type=kotlin.String value=''
|
LITERAL String type=kotlin.String value=''
|
||||||
IF type=kotlin.Unit operator=IF
|
WHEN type=kotlin.Unit operator=IF
|
||||||
if: TYPE_OP operator=NOT_INSTANCEOF typeOperand=kotlin.String?
|
if: TYPE_OP operator=NOT_INSTANCEOF typeOperand=kotlin.String?
|
||||||
GET_VAR a type=kotlin.Any? operator=null
|
GET_VAR a type=kotlin.Any? operator=null
|
||||||
then: RETURN type=<no-type>
|
then: RETURN type=<no-type>
|
||||||
|
|||||||
+7
-8
@@ -3,16 +3,15 @@ IrFile /ifElseIf.kt
|
|||||||
IrExpressionBody
|
IrExpressionBody
|
||||||
BLOCK type=<no-type> hasResult=false operator=null
|
BLOCK type=<no-type> hasResult=false operator=null
|
||||||
RETURN type=<no-type>
|
RETURN type=<no-type>
|
||||||
IF type=kotlin.Int operator=IF
|
WHEN type=kotlin.Int operator=WHEN
|
||||||
if: CALL .GT0 type=kotlin.Boolean operator=GT
|
if: CALL .GT0 type=kotlin.Boolean operator=GT
|
||||||
arg0: CALL .compareTo type=kotlin.Int operator=GT
|
arg0: CALL .compareTo type=kotlin.Int operator=GT
|
||||||
$this: GET_VAR i type=kotlin.Int operator=null
|
$this: GET_VAR i type=kotlin.Int operator=null
|
||||||
other: LITERAL Int type=kotlin.Int value='0'
|
other: LITERAL Int type=kotlin.Int value='0'
|
||||||
then: LITERAL Int type=kotlin.Int value='1'
|
then: LITERAL Int type=kotlin.Int value='1'
|
||||||
else: IF type=kotlin.Int operator=IF
|
if: CALL .GT0 type=kotlin.Boolean operator=GT
|
||||||
if: CALL .LT0 type=kotlin.Boolean operator=LT
|
arg0: CALL .compareTo type=kotlin.Int operator=GT
|
||||||
arg0: CALL .compareTo type=kotlin.Int operator=LT
|
$this: GET_VAR i type=kotlin.Int operator=null
|
||||||
$this: GET_VAR i type=kotlin.Int operator=null
|
other: LITERAL Int type=kotlin.Int value='0'
|
||||||
other: LITERAL Int type=kotlin.Int value='0'
|
then: LITERAL Int type=kotlin.Int value='1'
|
||||||
then: DUMMY MINUS type=kotlin.Int
|
else: LITERAL Int type=kotlin.Int value='0'
|
||||||
else: LITERAL Int type=kotlin.Int value='0'
|
|
||||||
|
|||||||
+3
-3
@@ -18,7 +18,7 @@ IrFile /smartCasts.kt
|
|||||||
IrFunction public fun test1(/*0*/ x: kotlin.Any): kotlin.Unit
|
IrFunction public fun test1(/*0*/ x: kotlin.Any): kotlin.Unit
|
||||||
IrExpressionBody
|
IrExpressionBody
|
||||||
BLOCK type=<no-type> hasResult=false operator=null
|
BLOCK type=<no-type> hasResult=false operator=null
|
||||||
IF type=kotlin.Unit operator=IF
|
WHEN type=kotlin.Unit operator=IF
|
||||||
if: TYPE_OP operator=NOT_INSTANCEOF typeOperand=kotlin.String
|
if: TYPE_OP operator=NOT_INSTANCEOF typeOperand=kotlin.String
|
||||||
GET_VAR x type=kotlin.Any operator=null
|
GET_VAR x type=kotlin.Any operator=null
|
||||||
then: RETURN type=<no-type>
|
then: RETURN type=<no-type>
|
||||||
@@ -40,7 +40,7 @@ IrFile /smartCasts.kt
|
|||||||
IrFunction public fun test2(/*0*/ x: kotlin.Any): kotlin.String
|
IrFunction public fun test2(/*0*/ x: kotlin.Any): kotlin.String
|
||||||
IrExpressionBody
|
IrExpressionBody
|
||||||
BLOCK type=<no-type> hasResult=false operator=null
|
BLOCK type=<no-type> hasResult=false operator=null
|
||||||
IF type=kotlin.Unit operator=IF
|
WHEN type=kotlin.Unit operator=IF
|
||||||
if: TYPE_OP operator=NOT_INSTANCEOF typeOperand=kotlin.String
|
if: TYPE_OP operator=NOT_INSTANCEOF typeOperand=kotlin.String
|
||||||
GET_VAR x type=kotlin.Any operator=null
|
GET_VAR x type=kotlin.Any operator=null
|
||||||
then: RETURN type=<no-type>
|
then: RETURN type=<no-type>
|
||||||
@@ -52,7 +52,7 @@ IrFile /smartCasts.kt
|
|||||||
IrFunction public fun test3(/*0*/ x: kotlin.Any): kotlin.String
|
IrFunction public fun test3(/*0*/ x: kotlin.Any): kotlin.String
|
||||||
IrExpressionBody
|
IrExpressionBody
|
||||||
BLOCK type=<no-type> hasResult=false operator=null
|
BLOCK type=<no-type> hasResult=false operator=null
|
||||||
IF type=kotlin.Unit operator=IF
|
WHEN type=kotlin.Unit operator=IF
|
||||||
if: TYPE_OP operator=NOT_INSTANCEOF typeOperand=kotlin.String
|
if: TYPE_OP operator=NOT_INSTANCEOF typeOperand=kotlin.String
|
||||||
GET_VAR x type=kotlin.Any operator=null
|
GET_VAR x type=kotlin.Any operator=null
|
||||||
then: RETURN type=<no-type>
|
then: RETURN type=<no-type>
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ IrFile /smartCastsWithDestructuring.kt
|
|||||||
IrFunction public fun test(/*0*/ x: I1): kotlin.Unit
|
IrFunction public fun test(/*0*/ x: I1): kotlin.Unit
|
||||||
IrExpressionBody
|
IrExpressionBody
|
||||||
BLOCK type=<no-type> hasResult=false operator=null
|
BLOCK type=<no-type> hasResult=false operator=null
|
||||||
IF type=kotlin.Unit operator=IF
|
WHEN type=kotlin.Unit operator=IF
|
||||||
if: TYPE_OP operator=NOT_INSTANCEOF typeOperand=I2
|
if: TYPE_OP operator=NOT_INSTANCEOF typeOperand=I2
|
||||||
GET_VAR x type=I1 operator=null
|
GET_VAR x type=I1 operator=null
|
||||||
then: RETURN type=<no-type>
|
then: RETURN type=<no-type>
|
||||||
|
|||||||
Vendored
+53
-61
@@ -7,52 +7,46 @@ IrFile /when.kt
|
|||||||
BLOCK type=kotlin.String hasResult=true operator=WHEN
|
BLOCK type=kotlin.String hasResult=true operator=WHEN
|
||||||
VAR val tmp0_subject: kotlin.Any?
|
VAR val tmp0_subject: kotlin.Any?
|
||||||
GET_VAR x type=kotlin.Any? operator=null
|
GET_VAR x type=kotlin.Any? operator=null
|
||||||
IF type=kotlin.String operator=WHEN
|
WHEN type=kotlin.String operator=WHEN
|
||||||
if: CALL .EQEQ type=kotlin.Boolean operator=EQEQ
|
if: CALL .EQEQ type=kotlin.Boolean operator=EQEQ
|
||||||
arg0: GET_VAR tmp0_subject type=kotlin.Any? operator=null
|
arg0: GET_VAR tmp0_subject type=kotlin.Any? operator=null
|
||||||
arg1: LITERAL Null type=kotlin.Nothing? value='null'
|
arg1: LITERAL Null type=kotlin.Nothing? value='null'
|
||||||
then: LITERAL String type=kotlin.String value='null'
|
then: LITERAL String type=kotlin.String value='null'
|
||||||
else: IF type=kotlin.String operator=WHEN
|
if: CALL .EQEQ type=kotlin.Boolean operator=EQEQ
|
||||||
if: CALL .EQEQ type=kotlin.Boolean operator=EQEQ
|
arg0: GET_VAR tmp0_subject type=kotlin.Any? operator=null
|
||||||
arg0: GET_VAR tmp0_subject type=kotlin.Any? operator=null
|
arg1: GET_OBJECT A type=A
|
||||||
arg1: GET_OBJECT A type=A
|
then: LITERAL String type=kotlin.String value='A'
|
||||||
then: LITERAL String type=kotlin.String value='A'
|
if: TYPE_OP operator=INSTANCEOF typeOperand=kotlin.String
|
||||||
else: IF type=kotlin.String operator=WHEN
|
GET_VAR tmp0_subject type=kotlin.Any? operator=null
|
||||||
if: TYPE_OP operator=INSTANCEOF typeOperand=kotlin.String
|
then: LITERAL String type=kotlin.String value='String'
|
||||||
GET_VAR tmp0_subject type=kotlin.Any? operator=null
|
if: CALL .contains type=kotlin.Boolean operator=IN
|
||||||
then: LITERAL String type=kotlin.String value='String'
|
$receiver: CALL .setOf type=kotlin.collections.Set<kotlin.Nothing> operator=null
|
||||||
else: IF type=kotlin.String operator=WHEN
|
element: TYPE_OP operator=IMPLICIT_CAST typeOperand=kotlin.Any
|
||||||
if: CALL .contains type=kotlin.Boolean operator=IN
|
GET_VAR tmp0_subject type=kotlin.Any? operator=null
|
||||||
$receiver: CALL .setOf type=kotlin.collections.Set<kotlin.Nothing> operator=null
|
then: LITERAL String type=kotlin.String value='nothingness?'
|
||||||
element: TYPE_OP operator=IMPLICIT_CAST typeOperand=kotlin.Any
|
else: LITERAL String type=kotlin.String value='something'
|
||||||
GET_VAR tmp0_subject type=kotlin.Any? operator=null
|
|
||||||
then: LITERAL String type=kotlin.String value='nothingness?'
|
|
||||||
else: LITERAL String type=kotlin.String value='something'
|
|
||||||
IrFunction public fun test(/*0*/ x: kotlin.Any?): kotlin.String
|
IrFunction public fun test(/*0*/ x: kotlin.Any?): kotlin.String
|
||||||
IrExpressionBody
|
IrExpressionBody
|
||||||
BLOCK type=<no-type> hasResult=false operator=null
|
BLOCK type=<no-type> hasResult=false operator=null
|
||||||
RETURN type=<no-type>
|
RETURN type=<no-type>
|
||||||
IF type=kotlin.String operator=WHEN
|
WHEN type=kotlin.String operator=WHEN
|
||||||
if: CALL .EQEQ type=kotlin.Boolean operator=EQEQ
|
if: CALL .EQEQ type=kotlin.Boolean operator=EQEQ
|
||||||
arg0: GET_VAR x type=kotlin.Any? operator=null
|
arg0: GET_VAR x type=kotlin.Any? operator=null
|
||||||
arg1: LITERAL Null type=kotlin.Nothing? value='null'
|
arg1: LITERAL Null type=kotlin.Nothing? value='null'
|
||||||
then: LITERAL String type=kotlin.String value='null'
|
then: LITERAL String type=kotlin.String value='null'
|
||||||
else: IF type=kotlin.String operator=WHEN
|
if: CALL .EQEQ type=kotlin.Boolean operator=EQEQ
|
||||||
if: CALL .EQEQ type=kotlin.Boolean operator=EQEQ
|
arg0: GET_VAR x type=kotlin.Any? operator=null
|
||||||
arg0: GET_VAR x type=kotlin.Any? operator=null
|
arg1: GET_OBJECT A type=A
|
||||||
arg1: GET_OBJECT A type=A
|
then: LITERAL String type=kotlin.String value='A'
|
||||||
then: LITERAL String type=kotlin.String value='A'
|
if: TYPE_OP operator=INSTANCEOF typeOperand=kotlin.String
|
||||||
else: IF type=kotlin.String operator=WHEN
|
GET_VAR x type=kotlin.Any? operator=null
|
||||||
if: TYPE_OP operator=INSTANCEOF typeOperand=kotlin.String
|
then: LITERAL String type=kotlin.String value='String'
|
||||||
GET_VAR x type=kotlin.Any? operator=null
|
if: CALL .contains type=kotlin.Boolean operator=IN
|
||||||
then: LITERAL String type=kotlin.String value='String'
|
$receiver: CALL .setOf type=kotlin.collections.Set<kotlin.Nothing> operator=null
|
||||||
else: IF type=kotlin.String operator=WHEN
|
element: TYPE_OP operator=IMPLICIT_CAST typeOperand=kotlin.Any
|
||||||
if: CALL .contains type=kotlin.Boolean operator=IN
|
GET_VAR x type=kotlin.Any? operator=null
|
||||||
$receiver: CALL .setOf type=kotlin.collections.Set<kotlin.Nothing> operator=null
|
then: LITERAL String type=kotlin.String value='nothingness?'
|
||||||
element: TYPE_OP operator=IMPLICIT_CAST typeOperand=kotlin.Any
|
else: LITERAL String type=kotlin.String value='something'
|
||||||
GET_VAR x type=kotlin.Any? operator=null
|
|
||||||
then: LITERAL String type=kotlin.String value='nothingness?'
|
|
||||||
else: LITERAL String type=kotlin.String value='something'
|
|
||||||
IrFunction public fun testComma(/*0*/ x: kotlin.Int): kotlin.String
|
IrFunction public fun testComma(/*0*/ x: kotlin.Int): kotlin.String
|
||||||
IrExpressionBody
|
IrExpressionBody
|
||||||
BLOCK type=<no-type> hasResult=false operator=null
|
BLOCK type=<no-type> hasResult=false operator=null
|
||||||
@@ -60,10 +54,10 @@ IrFile /when.kt
|
|||||||
BLOCK type=kotlin.String hasResult=true operator=WHEN
|
BLOCK type=kotlin.String hasResult=true operator=WHEN
|
||||||
VAR val tmp0_subject: kotlin.Int
|
VAR val tmp0_subject: kotlin.Int
|
||||||
GET_VAR x type=kotlin.Int operator=null
|
GET_VAR x type=kotlin.Int operator=null
|
||||||
IF type=kotlin.String operator=WHEN
|
WHEN type=kotlin.String operator=WHEN
|
||||||
if: IF type=kotlin.Boolean operator=WHEN_COMMA
|
if: WHEN type=kotlin.Boolean operator=WHEN_COMMA
|
||||||
if: IF type=kotlin.Boolean operator=WHEN_COMMA
|
if: WHEN type=kotlin.Boolean operator=WHEN_COMMA
|
||||||
if: IF type=kotlin.Boolean operator=WHEN_COMMA
|
if: WHEN type=kotlin.Boolean operator=WHEN_COMMA
|
||||||
if: CALL .EQEQ type=kotlin.Boolean operator=EQEQ
|
if: CALL .EQEQ type=kotlin.Boolean operator=EQEQ
|
||||||
arg0: GET_VAR tmp0_subject type=kotlin.Int operator=null
|
arg0: GET_VAR tmp0_subject type=kotlin.Int operator=null
|
||||||
arg1: LITERAL Int type=kotlin.Int value='1'
|
arg1: LITERAL Int type=kotlin.Int value='1'
|
||||||
@@ -80,29 +74,27 @@ IrFile /when.kt
|
|||||||
arg0: GET_VAR tmp0_subject type=kotlin.Int operator=null
|
arg0: GET_VAR tmp0_subject type=kotlin.Int operator=null
|
||||||
arg1: LITERAL Int type=kotlin.Int value='4'
|
arg1: LITERAL Int type=kotlin.Int value='4'
|
||||||
then: LITERAL String type=kotlin.String value='1234'
|
then: LITERAL String type=kotlin.String value='1234'
|
||||||
else: IF type=kotlin.String operator=WHEN
|
if: WHEN type=kotlin.Boolean operator=WHEN_COMMA
|
||||||
if: IF type=kotlin.Boolean operator=WHEN_COMMA
|
if: WHEN type=kotlin.Boolean operator=WHEN_COMMA
|
||||||
if: IF type=kotlin.Boolean operator=WHEN_COMMA
|
if: CALL .EQEQ type=kotlin.Boolean operator=EQEQ
|
||||||
if: CALL .EQEQ type=kotlin.Boolean operator=EQEQ
|
arg0: GET_VAR tmp0_subject type=kotlin.Int operator=null
|
||||||
arg0: GET_VAR tmp0_subject type=kotlin.Int operator=null
|
arg1: LITERAL Int type=kotlin.Int value='5'
|
||||||
arg1: LITERAL Int type=kotlin.Int value='5'
|
|
||||||
then: LITERAL Boolean type=kotlin.Boolean value='true'
|
|
||||||
else: CALL .EQEQ type=kotlin.Boolean operator=EQEQ
|
|
||||||
arg0: GET_VAR tmp0_subject type=kotlin.Int operator=null
|
|
||||||
arg1: LITERAL Int type=kotlin.Int value='6'
|
|
||||||
then: LITERAL Boolean type=kotlin.Boolean value='true'
|
then: LITERAL Boolean type=kotlin.Boolean value='true'
|
||||||
else: CALL .EQEQ type=kotlin.Boolean operator=EQEQ
|
else: CALL .EQEQ type=kotlin.Boolean operator=EQEQ
|
||||||
arg0: GET_VAR tmp0_subject type=kotlin.Int operator=null
|
arg0: GET_VAR tmp0_subject type=kotlin.Int operator=null
|
||||||
arg1: LITERAL Int type=kotlin.Int value='7'
|
arg1: LITERAL Int type=kotlin.Int value='6'
|
||||||
then: LITERAL String type=kotlin.String value='567'
|
then: LITERAL Boolean type=kotlin.Boolean value='true'
|
||||||
else: IF type=kotlin.String operator=WHEN
|
else: CALL .EQEQ type=kotlin.Boolean operator=EQEQ
|
||||||
if: IF type=kotlin.Boolean operator=WHEN_COMMA
|
arg0: GET_VAR tmp0_subject type=kotlin.Int operator=null
|
||||||
if: CALL .EQEQ type=kotlin.Boolean operator=EQEQ
|
arg1: LITERAL Int type=kotlin.Int value='7'
|
||||||
arg0: GET_VAR tmp0_subject type=kotlin.Int operator=null
|
then: LITERAL String type=kotlin.String value='567'
|
||||||
arg1: LITERAL Int type=kotlin.Int value='8'
|
if: WHEN type=kotlin.Boolean operator=WHEN_COMMA
|
||||||
then: LITERAL Boolean type=kotlin.Boolean value='true'
|
if: CALL .EQEQ type=kotlin.Boolean operator=EQEQ
|
||||||
else: CALL .EQEQ type=kotlin.Boolean operator=EQEQ
|
arg0: GET_VAR tmp0_subject type=kotlin.Int operator=null
|
||||||
arg0: GET_VAR tmp0_subject type=kotlin.Int operator=null
|
arg1: LITERAL Int type=kotlin.Int value='8'
|
||||||
arg1: LITERAL Int type=kotlin.Int value='9'
|
then: LITERAL Boolean type=kotlin.Boolean value='true'
|
||||||
then: LITERAL String type=kotlin.String value='89'
|
else: CALL .EQEQ type=kotlin.Boolean operator=EQEQ
|
||||||
else: LITERAL String type=kotlin.String value='?'
|
arg0: GET_VAR tmp0_subject type=kotlin.Int operator=null
|
||||||
|
arg1: LITERAL Int type=kotlin.Int value='9'
|
||||||
|
then: LITERAL String type=kotlin.String value='89'
|
||||||
|
else: LITERAL String type=kotlin.String value='?'
|
||||||
|
|||||||
Reference in New Issue
Block a user