IR to CFG: when implementation in function generator, some when tests
This commit is contained in:
committed by
Dmitry Petrov
parent
eaf10a4675
commit
979f2231a1
@@ -102,6 +102,30 @@ class FunctionGenerator(val function: IrFunction) {
|
|||||||
return expression
|
return expression
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun visitWhen(expression: IrWhen, data: Boolean): IrElement? {
|
||||||
|
if (data) {
|
||||||
|
builder.add(expression)
|
||||||
|
}
|
||||||
|
val whenExit = MergeCfgElement(expression, "When exit")
|
||||||
|
val branches = expression.branches
|
||||||
|
for (branch in branches) {
|
||||||
|
val condition = branch.condition
|
||||||
|
condition.process(includeSelf = false)
|
||||||
|
builder.jump(condition)
|
||||||
|
}
|
||||||
|
for (branch in branches) {
|
||||||
|
val result = branch.result
|
||||||
|
builder.move(branch.condition)
|
||||||
|
if (!result.process().isNothing()) {
|
||||||
|
builder.jump(whenExit)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
builder.move(branch.condition)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return whenExit
|
||||||
|
}
|
||||||
|
|
||||||
override fun visitElement(element: IrElement, data: Boolean): IrElement? {
|
override fun visitElement(element: IrElement, data: Boolean): IrElement? {
|
||||||
TODO("not implemented")
|
TODO("not implemented")
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-2
@@ -36,9 +36,9 @@ class GeneralConnectorBuilder(private val element: IrElement) : BlockConnectorBu
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun build() = when {
|
override fun build() = when {
|
||||||
next.size == 1 -> JoinBlockConnector(previous.toReadOnlyList(), element, next.single())
|
next.size <= 1 -> JoinBlockConnector(previous.toReadOnlyList(), element, next.firstOrNull())
|
||||||
previous.size == 1 -> SplitBlockConnector(previous.single(), element, next.toReadOnlyList())
|
previous.size == 1 -> SplitBlockConnector(previous.single(), element, next.toReadOnlyList())
|
||||||
else -> throw AssertionError("Connector should have either exactly one previous block or exactly one next block, " +
|
else -> throw AssertionError("Connector should have either exactly one previous block or no more than one next block, " +
|
||||||
"actual previous = ${previous.size}, next = ${next.size}")
|
"actual previous = ${previous.size}, next = ${next.size}")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+2
-2
@@ -23,8 +23,8 @@ import org.jetbrains.kotlin.ir2cfg.graph.BlockConnector
|
|||||||
class JoinBlockConnector(
|
class JoinBlockConnector(
|
||||||
override val previousBlocks: List<BasicBlock>,
|
override val previousBlocks: List<BasicBlock>,
|
||||||
override val element: IrElement,
|
override val element: IrElement,
|
||||||
next: BasicBlock
|
next: BasicBlock?
|
||||||
) : BlockConnector {
|
) : BlockConnector {
|
||||||
|
|
||||||
override val nextBlocks = listOf(next)
|
override val nextBlocks = listOfNotNull(next)
|
||||||
}
|
}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
fun compare(x: Int, y: Int) = if (x > y) 1 else if (x < y) -1 else 0
|
||||||
+53
@@ -0,0 +1,53 @@
|
|||||||
|
// FILE: /cascadeIf.kt
|
||||||
|
// FUN: compare
|
||||||
|
BB 0
|
||||||
|
CONTENT
|
||||||
|
1 FUN public fun compare(x: kotlin.Int, y: kotlin.Int): kotlin.Int
|
||||||
|
2 WHEN type=kotlin.Int origin=WHEN
|
||||||
|
OUTGOING -> BB 1, 3
|
||||||
|
CALL 'GT0(Int): Boolean' type=kotlin.Boolean origin=GT
|
||||||
|
BB 1
|
||||||
|
INCOMING <- BB 0
|
||||||
|
CALL 'GT0(Int): Boolean' type=kotlin.Boolean origin=GT
|
||||||
|
CONTENT
|
||||||
|
OUTGOING -> BB 2, 4
|
||||||
|
CALL 'LT0(Int): Boolean' type=kotlin.Boolean origin=LT
|
||||||
|
BB 2
|
||||||
|
INCOMING <- BB 1
|
||||||
|
CALL 'LT0(Int): Boolean' type=kotlin.Boolean origin=LT
|
||||||
|
CONTENT
|
||||||
|
OUTGOING -> BB 5
|
||||||
|
CONST Boolean type=kotlin.Boolean value='true'
|
||||||
|
BB 3
|
||||||
|
INCOMING <- BB 0
|
||||||
|
CALL 'GT0(Int): Boolean' type=kotlin.Boolean origin=GT
|
||||||
|
CONTENT
|
||||||
|
1 CONST Int type=kotlin.Int value='1'
|
||||||
|
OUTGOING -> BB 6
|
||||||
|
When exit: WHEN type=kotlin.Int origin=WHEN
|
||||||
|
BB 4
|
||||||
|
INCOMING <- BB 1
|
||||||
|
CALL 'LT0(Int): Boolean' type=kotlin.Boolean origin=LT
|
||||||
|
CONTENT
|
||||||
|
1 CONST Int type=kotlin.Int value='-1'
|
||||||
|
OUTGOING -> BB 6
|
||||||
|
When exit: WHEN type=kotlin.Int origin=WHEN
|
||||||
|
BB 5
|
||||||
|
INCOMING <- BB 2
|
||||||
|
CONST Boolean type=kotlin.Boolean value='true'
|
||||||
|
CONTENT
|
||||||
|
1 CONST Int type=kotlin.Int value='0'
|
||||||
|
OUTGOING -> BB 6
|
||||||
|
When exit: WHEN type=kotlin.Int origin=WHEN
|
||||||
|
BB 6
|
||||||
|
INCOMING <- BB 3, 4, 5
|
||||||
|
When exit: WHEN type=kotlin.Int origin=WHEN
|
||||||
|
CONTENT
|
||||||
|
1 RETURN type=kotlin.Nothing from='compare(Int, Int): Int'
|
||||||
|
OUTGOING -> NONE
|
||||||
|
Function exit: FUN public fun compare(x: kotlin.Int, y: kotlin.Int): kotlin.Int
|
||||||
|
|
||||||
|
// END FUN: compare
|
||||||
|
|
||||||
|
// END FILE: /cascadeIf.kt
|
||||||
|
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
fun empty() = when {
|
||||||
|
else -> 42
|
||||||
|
}
|
||||||
+27
@@ -0,0 +1,27 @@
|
|||||||
|
// FILE: /emptyWhen.kt
|
||||||
|
// FUN: empty
|
||||||
|
BB 0
|
||||||
|
CONTENT
|
||||||
|
1 FUN public fun empty(): kotlin.Int
|
||||||
|
2 WHEN type=kotlin.Int origin=WHEN
|
||||||
|
OUTGOING -> BB 1
|
||||||
|
CONST Boolean type=kotlin.Boolean value='true'
|
||||||
|
BB 1
|
||||||
|
INCOMING <- BB 0
|
||||||
|
CONST Boolean type=kotlin.Boolean value='true'
|
||||||
|
CONTENT
|
||||||
|
1 CONST Int type=kotlin.Int value='42'
|
||||||
|
OUTGOING -> BB 2
|
||||||
|
When exit: WHEN type=kotlin.Int origin=WHEN
|
||||||
|
BB 2
|
||||||
|
INCOMING <- BB 1
|
||||||
|
When exit: WHEN type=kotlin.Int origin=WHEN
|
||||||
|
CONTENT
|
||||||
|
1 RETURN type=kotlin.Nothing from='empty(): Int'
|
||||||
|
OUTGOING -> NONE
|
||||||
|
Function exit: FUN public fun empty(): kotlin.Int
|
||||||
|
|
||||||
|
// END FUN: empty
|
||||||
|
|
||||||
|
// END FILE: /emptyWhen.kt
|
||||||
|
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
fun max(x: Int, y: Int) = if (x > y) x else y
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
// FILE: /expressionIf.kt
|
||||||
|
// FUN: max
|
||||||
|
BB 0
|
||||||
|
CONTENT
|
||||||
|
1 FUN public fun max(x: kotlin.Int, y: kotlin.Int): kotlin.Int
|
||||||
|
2 WHEN type=kotlin.Int origin=null
|
||||||
|
OUTGOING -> BB 1, 2
|
||||||
|
CALL 'GT0(Int): Boolean' type=kotlin.Boolean origin=GT
|
||||||
|
BB 1
|
||||||
|
INCOMING <- BB 0
|
||||||
|
CALL 'GT0(Int): Boolean' type=kotlin.Boolean origin=GT
|
||||||
|
CONTENT
|
||||||
|
OUTGOING -> BB 3
|
||||||
|
CONST Boolean type=kotlin.Boolean value='true'
|
||||||
|
BB 2
|
||||||
|
INCOMING <- BB 0
|
||||||
|
CALL 'GT0(Int): Boolean' type=kotlin.Boolean origin=GT
|
||||||
|
CONTENT
|
||||||
|
1 GET_VAR 'value-parameter x: Int' type=kotlin.Int origin=null
|
||||||
|
OUTGOING -> BB 4
|
||||||
|
When exit: WHEN type=kotlin.Int origin=null
|
||||||
|
BB 3
|
||||||
|
INCOMING <- BB 1
|
||||||
|
CONST Boolean type=kotlin.Boolean value='true'
|
||||||
|
CONTENT
|
||||||
|
1 GET_VAR 'value-parameter y: Int' type=kotlin.Int origin=null
|
||||||
|
OUTGOING -> BB 4
|
||||||
|
When exit: WHEN type=kotlin.Int origin=null
|
||||||
|
BB 4
|
||||||
|
INCOMING <- BB 2, 3
|
||||||
|
When exit: WHEN type=kotlin.Int origin=null
|
||||||
|
CONTENT
|
||||||
|
1 RETURN type=kotlin.Nothing from='max(Int, Int): Int'
|
||||||
|
OUTGOING -> NONE
|
||||||
|
Function exit: FUN public fun max(x: kotlin.Int, y: kotlin.Int): kotlin.Int
|
||||||
|
|
||||||
|
// END FUN: max
|
||||||
|
|
||||||
|
// END FILE: /expressionIf.kt
|
||||||
|
|
||||||
+14
@@ -0,0 +1,14 @@
|
|||||||
|
fun minBiRoot(a: Double, b: Double, c: Double): Double {
|
||||||
|
if (a == 0.0) {
|
||||||
|
if (b == 0.0) return 1.0
|
||||||
|
val bc = -c / b
|
||||||
|
if (bc < 0.0) return 2.0
|
||||||
|
return -bc
|
||||||
|
}
|
||||||
|
val d = b * b - 4 * a * c
|
||||||
|
if (d < 0.0) return 3.0
|
||||||
|
val y1 = (-b + d) / (2 * a)
|
||||||
|
val y2 = (-b - d) / (2 * a)
|
||||||
|
val y3 = if (y1 > y2) y1 else y2
|
||||||
|
return if (y3 < 0.0) 4.0 else -y3
|
||||||
|
}
|
||||||
+136
@@ -0,0 +1,136 @@
|
|||||||
|
// FILE: /ifChain.kt
|
||||||
|
// FUN: minBiRoot
|
||||||
|
BB 0
|
||||||
|
CONTENT
|
||||||
|
1 FUN public fun minBiRoot(a: kotlin.Double, b: kotlin.Double, c: kotlin.Double): kotlin.Double
|
||||||
|
2 WHEN type=kotlin.Unit origin=null
|
||||||
|
OUTGOING -> BB 1, 6
|
||||||
|
CALL 'EQEQ(Any?, Any?): Boolean' type=kotlin.Boolean origin=EQEQ
|
||||||
|
BB 1
|
||||||
|
INCOMING <- BB 0
|
||||||
|
CALL 'EQEQ(Any?, Any?): Boolean' type=kotlin.Boolean origin=EQEQ
|
||||||
|
CONTENT
|
||||||
|
1 WHEN type=kotlin.Unit origin=null
|
||||||
|
OUTGOING -> BB 2, 3
|
||||||
|
CALL 'EQEQ(Any?, Any?): Boolean' type=kotlin.Boolean origin=EQEQ
|
||||||
|
BB 2
|
||||||
|
INCOMING <- BB 1
|
||||||
|
CALL 'EQEQ(Any?, Any?): Boolean' type=kotlin.Boolean origin=EQEQ
|
||||||
|
CONTENT
|
||||||
|
1 CONST Double type=kotlin.Double value='1.0'
|
||||||
|
2 RETURN type=kotlin.Nothing from='minBiRoot(Double, Double, Double): Double'
|
||||||
|
OUTGOING -> NONE
|
||||||
|
Function exit: FUN public fun minBiRoot(a: kotlin.Double, b: kotlin.Double, c: kotlin.Double): kotlin.Double
|
||||||
|
BB 3
|
||||||
|
INCOMING <- BB 1
|
||||||
|
CALL 'EQEQ(Any?, Any?): Boolean' type=kotlin.Boolean origin=EQEQ
|
||||||
|
CONTENT
|
||||||
|
1 CALL 'div(Double): Double' type=kotlin.Double origin=DIV
|
||||||
|
2 VAR val bc: kotlin.Double
|
||||||
|
3 WHEN type=kotlin.Unit origin=null
|
||||||
|
OUTGOING -> BB 4, 5
|
||||||
|
CALL 'LT0(Int): Boolean' type=kotlin.Boolean origin=LT
|
||||||
|
BB 4
|
||||||
|
INCOMING <- BB 3
|
||||||
|
CALL 'LT0(Int): Boolean' type=kotlin.Boolean origin=LT
|
||||||
|
CONTENT
|
||||||
|
1 CONST Double type=kotlin.Double value='2.0'
|
||||||
|
2 RETURN type=kotlin.Nothing from='minBiRoot(Double, Double, Double): Double'
|
||||||
|
OUTGOING -> NONE
|
||||||
|
Function exit: FUN public fun minBiRoot(a: kotlin.Double, b: kotlin.Double, c: kotlin.Double): kotlin.Double
|
||||||
|
BB 5
|
||||||
|
INCOMING <- BB 3
|
||||||
|
CALL 'LT0(Int): Boolean' type=kotlin.Boolean origin=LT
|
||||||
|
CONTENT
|
||||||
|
1 CALL 'unaryMinus(): Double' type=kotlin.Double origin=UMINUS
|
||||||
|
2 RETURN type=kotlin.Nothing from='minBiRoot(Double, Double, Double): Double'
|
||||||
|
OUTGOING -> NONE
|
||||||
|
Function exit: FUN public fun minBiRoot(a: kotlin.Double, b: kotlin.Double, c: kotlin.Double): kotlin.Double
|
||||||
|
BB 6
|
||||||
|
INCOMING <- BB 0
|
||||||
|
CALL 'EQEQ(Any?, Any?): Boolean' type=kotlin.Boolean origin=EQEQ
|
||||||
|
CONTENT
|
||||||
|
1 CALL 'minus(Double): Double' type=kotlin.Double origin=MINUS
|
||||||
|
2 VAR val d: kotlin.Double
|
||||||
|
3 WHEN type=kotlin.Unit origin=null
|
||||||
|
OUTGOING -> BB 7, 8
|
||||||
|
CALL 'LT0(Int): Boolean' type=kotlin.Boolean origin=LT
|
||||||
|
BB 7
|
||||||
|
INCOMING <- BB 6
|
||||||
|
CALL 'LT0(Int): Boolean' type=kotlin.Boolean origin=LT
|
||||||
|
CONTENT
|
||||||
|
1 CONST Double type=kotlin.Double value='3.0'
|
||||||
|
2 RETURN type=kotlin.Nothing from='minBiRoot(Double, Double, Double): Double'
|
||||||
|
OUTGOING -> NONE
|
||||||
|
Function exit: FUN public fun minBiRoot(a: kotlin.Double, b: kotlin.Double, c: kotlin.Double): kotlin.Double
|
||||||
|
BB 8
|
||||||
|
INCOMING <- BB 6
|
||||||
|
CALL 'LT0(Int): Boolean' type=kotlin.Boolean origin=LT
|
||||||
|
CONTENT
|
||||||
|
1 CALL 'div(Double): Double' type=kotlin.Double origin=DIV
|
||||||
|
2 VAR val y1: kotlin.Double
|
||||||
|
3 CALL 'div(Double): Double' type=kotlin.Double origin=DIV
|
||||||
|
4 VAR val y2: kotlin.Double
|
||||||
|
5 WHEN type=kotlin.Double origin=null
|
||||||
|
OUTGOING -> BB 9, 10
|
||||||
|
CALL 'GT0(Int): Boolean' type=kotlin.Boolean origin=GT
|
||||||
|
BB 9
|
||||||
|
INCOMING <- BB 8
|
||||||
|
CALL 'GT0(Int): Boolean' type=kotlin.Boolean origin=GT
|
||||||
|
CONTENT
|
||||||
|
OUTGOING -> BB 11
|
||||||
|
CONST Boolean type=kotlin.Boolean value='true'
|
||||||
|
BB 10
|
||||||
|
INCOMING <- BB 8
|
||||||
|
CALL 'GT0(Int): Boolean' type=kotlin.Boolean origin=GT
|
||||||
|
CONTENT
|
||||||
|
1 GET_VAR 'y1: Double' type=kotlin.Double origin=null
|
||||||
|
OUTGOING -> BB 12
|
||||||
|
When exit: WHEN type=kotlin.Double origin=null
|
||||||
|
BB 11
|
||||||
|
INCOMING <- BB 9
|
||||||
|
CONST Boolean type=kotlin.Boolean value='true'
|
||||||
|
CONTENT
|
||||||
|
1 GET_VAR 'y2: Double' type=kotlin.Double origin=null
|
||||||
|
OUTGOING -> BB 12
|
||||||
|
When exit: WHEN type=kotlin.Double origin=null
|
||||||
|
BB 12
|
||||||
|
INCOMING <- BB 10, 11
|
||||||
|
When exit: WHEN type=kotlin.Double origin=null
|
||||||
|
CONTENT
|
||||||
|
1 VAR val y3: kotlin.Double
|
||||||
|
2 WHEN type=kotlin.Double origin=null
|
||||||
|
OUTGOING -> BB 13, 14
|
||||||
|
CALL 'LT0(Int): Boolean' type=kotlin.Boolean origin=LT
|
||||||
|
BB 13
|
||||||
|
INCOMING <- BB 12
|
||||||
|
CALL 'LT0(Int): Boolean' type=kotlin.Boolean origin=LT
|
||||||
|
CONTENT
|
||||||
|
OUTGOING -> BB 15
|
||||||
|
CONST Boolean type=kotlin.Boolean value='true'
|
||||||
|
BB 14
|
||||||
|
INCOMING <- BB 12
|
||||||
|
CALL 'LT0(Int): Boolean' type=kotlin.Boolean origin=LT
|
||||||
|
CONTENT
|
||||||
|
1 CONST Double type=kotlin.Double value='4.0'
|
||||||
|
OUTGOING -> BB 16
|
||||||
|
When exit: WHEN type=kotlin.Double origin=null
|
||||||
|
BB 15
|
||||||
|
INCOMING <- BB 13
|
||||||
|
CONST Boolean type=kotlin.Boolean value='true'
|
||||||
|
CONTENT
|
||||||
|
1 CALL 'unaryMinus(): Double' type=kotlin.Double origin=UMINUS
|
||||||
|
OUTGOING -> BB 16
|
||||||
|
When exit: WHEN type=kotlin.Double origin=null
|
||||||
|
BB 16
|
||||||
|
INCOMING <- BB 14, 15
|
||||||
|
When exit: WHEN type=kotlin.Double origin=null
|
||||||
|
CONTENT
|
||||||
|
1 RETURN type=kotlin.Nothing from='minBiRoot(Double, Double, Double): Double'
|
||||||
|
OUTGOING -> NONE
|
||||||
|
Function exit: FUN public fun minBiRoot(a: kotlin.Double, b: kotlin.Double, c: kotlin.Double): kotlin.Double
|
||||||
|
|
||||||
|
// END FUN: minBiRoot
|
||||||
|
|
||||||
|
// END FILE: /ifChain.kt
|
||||||
|
|
||||||
+10
@@ -0,0 +1,10 @@
|
|||||||
|
fun toString(grade: String): String {
|
||||||
|
when (grade) {
|
||||||
|
"A" -> return "Excellent"
|
||||||
|
"B" -> return "Good"
|
||||||
|
"C" -> return "Mediocre"
|
||||||
|
"D" -> return "Fair"
|
||||||
|
else -> return "Failure"
|
||||||
|
}
|
||||||
|
return "???"
|
||||||
|
}
|
||||||
+87
@@ -0,0 +1,87 @@
|
|||||||
|
// FILE: /whenReturn.kt
|
||||||
|
// FUN: toString
|
||||||
|
BB 0
|
||||||
|
CONTENT
|
||||||
|
1 FUN public fun toString(grade: kotlin.String): kotlin.String
|
||||||
|
2 GET_VAR 'value-parameter grade: String' type=kotlin.String origin=null
|
||||||
|
3 VAR IR_TEMPORARY_VARIABLE val tmp0_subject: kotlin.String
|
||||||
|
4 WHEN type=kotlin.Nothing origin=WHEN
|
||||||
|
OUTGOING -> BB 1, 5
|
||||||
|
CALL 'EQEQ(Any?, Any?): Boolean' type=kotlin.Boolean origin=EQEQ
|
||||||
|
BB 1
|
||||||
|
INCOMING <- BB 0
|
||||||
|
CALL 'EQEQ(Any?, Any?): Boolean' type=kotlin.Boolean origin=EQEQ
|
||||||
|
CONTENT
|
||||||
|
OUTGOING -> BB 2, 6
|
||||||
|
CALL 'EQEQ(Any?, Any?): Boolean' type=kotlin.Boolean origin=EQEQ
|
||||||
|
BB 2
|
||||||
|
INCOMING <- BB 1
|
||||||
|
CALL 'EQEQ(Any?, Any?): Boolean' type=kotlin.Boolean origin=EQEQ
|
||||||
|
CONTENT
|
||||||
|
OUTGOING -> BB 3, 7
|
||||||
|
CALL 'EQEQ(Any?, Any?): Boolean' type=kotlin.Boolean origin=EQEQ
|
||||||
|
BB 3
|
||||||
|
INCOMING <- BB 2
|
||||||
|
CALL 'EQEQ(Any?, Any?): Boolean' type=kotlin.Boolean origin=EQEQ
|
||||||
|
CONTENT
|
||||||
|
OUTGOING -> BB 4, 8
|
||||||
|
CALL 'EQEQ(Any?, Any?): Boolean' type=kotlin.Boolean origin=EQEQ
|
||||||
|
BB 4
|
||||||
|
INCOMING <- BB 3
|
||||||
|
CALL 'EQEQ(Any?, Any?): Boolean' type=kotlin.Boolean origin=EQEQ
|
||||||
|
CONTENT
|
||||||
|
OUTGOING -> BB 9, 10
|
||||||
|
CONST Boolean type=kotlin.Boolean value='true'
|
||||||
|
BB 5
|
||||||
|
INCOMING <- BB 0
|
||||||
|
CALL 'EQEQ(Any?, Any?): Boolean' type=kotlin.Boolean origin=EQEQ
|
||||||
|
CONTENT
|
||||||
|
1 CONST String type=kotlin.String value='Excellent'
|
||||||
|
2 RETURN type=kotlin.Nothing from='toString(String): String'
|
||||||
|
OUTGOING -> NONE
|
||||||
|
Function exit: FUN public fun toString(grade: kotlin.String): kotlin.String
|
||||||
|
BB 6
|
||||||
|
INCOMING <- BB 1
|
||||||
|
CALL 'EQEQ(Any?, Any?): Boolean' type=kotlin.Boolean origin=EQEQ
|
||||||
|
CONTENT
|
||||||
|
1 CONST String type=kotlin.String value='Good'
|
||||||
|
2 RETURN type=kotlin.Nothing from='toString(String): String'
|
||||||
|
OUTGOING -> NONE
|
||||||
|
Function exit: FUN public fun toString(grade: kotlin.String): kotlin.String
|
||||||
|
BB 7
|
||||||
|
INCOMING <- BB 2
|
||||||
|
CALL 'EQEQ(Any?, Any?): Boolean' type=kotlin.Boolean origin=EQEQ
|
||||||
|
CONTENT
|
||||||
|
1 CONST String type=kotlin.String value='Mediocre'
|
||||||
|
2 RETURN type=kotlin.Nothing from='toString(String): String'
|
||||||
|
OUTGOING -> NONE
|
||||||
|
Function exit: FUN public fun toString(grade: kotlin.String): kotlin.String
|
||||||
|
BB 8
|
||||||
|
INCOMING <- BB 3
|
||||||
|
CALL 'EQEQ(Any?, Any?): Boolean' type=kotlin.Boolean origin=EQEQ
|
||||||
|
CONTENT
|
||||||
|
1 CONST String type=kotlin.String value='Fair'
|
||||||
|
2 RETURN type=kotlin.Nothing from='toString(String): String'
|
||||||
|
OUTGOING -> NONE
|
||||||
|
Function exit: FUN public fun toString(grade: kotlin.String): kotlin.String
|
||||||
|
BB 9
|
||||||
|
INCOMING <- BB 4
|
||||||
|
CONST Boolean type=kotlin.Boolean value='true'
|
||||||
|
CONTENT
|
||||||
|
1 CONST String type=kotlin.String value='Failure'
|
||||||
|
2 RETURN type=kotlin.Nothing from='toString(String): String'
|
||||||
|
OUTGOING -> NONE
|
||||||
|
Function exit: FUN public fun toString(grade: kotlin.String): kotlin.String
|
||||||
|
BB 10
|
||||||
|
INCOMING <- BB 4
|
||||||
|
CONST Boolean type=kotlin.Boolean value='true'
|
||||||
|
CONTENT
|
||||||
|
1 CONST String type=kotlin.String value='???'
|
||||||
|
2 RETURN type=kotlin.Nothing from='toString(String): String'
|
||||||
|
OUTGOING -> NONE
|
||||||
|
Function exit: FUN public fun toString(grade: kotlin.String): kotlin.String
|
||||||
|
|
||||||
|
// END FUN: toString
|
||||||
|
|
||||||
|
// END FILE: /whenReturn.kt
|
||||||
|
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
fun toString(grade: String): String {
|
||||||
|
when (grade) {
|
||||||
|
"A" -> return "Excellent"
|
||||||
|
"B" -> return "Good"
|
||||||
|
"C" -> return "Mediocre"
|
||||||
|
"D" -> return "Fair"
|
||||||
|
else -> return "Failure"
|
||||||
|
}
|
||||||
|
return "???"
|
||||||
|
}
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
FILE /whenReturn.kt
|
||||||
|
FUN public fun toString(grade: kotlin.String): kotlin.String
|
||||||
|
BLOCK_BODY
|
||||||
|
BLOCK type=kotlin.Nothing origin=WHEN
|
||||||
|
VAR IR_TEMPORARY_VARIABLE val tmp0_subject: kotlin.String
|
||||||
|
GET_VAR 'value-parameter grade: String' type=kotlin.String origin=null
|
||||||
|
WHEN type=kotlin.Nothing origin=WHEN
|
||||||
|
BRANCH
|
||||||
|
if: CALL 'EQEQ(Any?, Any?): Boolean' type=kotlin.Boolean origin=EQEQ
|
||||||
|
arg0: GET_VAR 'tmp0_subject: String' type=kotlin.String origin=null
|
||||||
|
arg1: CONST String type=kotlin.String value='A'
|
||||||
|
then: RETURN type=kotlin.Nothing from='toString(String): String'
|
||||||
|
CONST String type=kotlin.String value='Excellent'
|
||||||
|
BRANCH
|
||||||
|
if: CALL 'EQEQ(Any?, Any?): Boolean' type=kotlin.Boolean origin=EQEQ
|
||||||
|
arg0: GET_VAR 'tmp0_subject: String' type=kotlin.String origin=null
|
||||||
|
arg1: CONST String type=kotlin.String value='B'
|
||||||
|
then: RETURN type=kotlin.Nothing from='toString(String): String'
|
||||||
|
CONST String type=kotlin.String value='Good'
|
||||||
|
BRANCH
|
||||||
|
if: CALL 'EQEQ(Any?, Any?): Boolean' type=kotlin.Boolean origin=EQEQ
|
||||||
|
arg0: GET_VAR 'tmp0_subject: String' type=kotlin.String origin=null
|
||||||
|
arg1: CONST String type=kotlin.String value='C'
|
||||||
|
then: RETURN type=kotlin.Nothing from='toString(String): String'
|
||||||
|
CONST String type=kotlin.String value='Mediocre'
|
||||||
|
BRANCH
|
||||||
|
if: CALL 'EQEQ(Any?, Any?): Boolean' type=kotlin.Boolean origin=EQEQ
|
||||||
|
arg0: GET_VAR 'tmp0_subject: String' type=kotlin.String origin=null
|
||||||
|
arg1: CONST String type=kotlin.String value='D'
|
||||||
|
then: RETURN type=kotlin.Nothing from='toString(String): String'
|
||||||
|
CONST String type=kotlin.String value='Fair'
|
||||||
|
BRANCH
|
||||||
|
if: CONST Boolean type=kotlin.Boolean value='true'
|
||||||
|
then: RETURN type=kotlin.Nothing from='toString(String): String'
|
||||||
|
CONST String type=kotlin.String value='Failure'
|
||||||
|
RETURN type=kotlin.Nothing from='toString(String): String'
|
||||||
|
CONST String type=kotlin.String value='???'
|
||||||
@@ -70,4 +70,43 @@ public class IrCfgTestCaseGenerated extends AbstractIrCfgTestCase {
|
|||||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/ir/irCfg/simpleReturn.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/ir/irCfg/simpleReturn.kt");
|
||||||
doTest(fileName);
|
doTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("compiler/testData/ir/irCfg/when")
|
||||||
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
|
public static class When extends AbstractIrCfgTestCase {
|
||||||
|
public void testAllFilesPresentInWhen() throws Exception {
|
||||||
|
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/ir/irCfg/when"), Pattern.compile("^(.+)\\.kt$"), true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("cascadeIf.kt")
|
||||||
|
public void testCascadeIf() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/ir/irCfg/when/cascadeIf.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("emptyWhen.kt")
|
||||||
|
public void testEmptyWhen() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/ir/irCfg/when/emptyWhen.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("expressionIf.kt")
|
||||||
|
public void testExpressionIf() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/ir/irCfg/when/expressionIf.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("ifChain.kt")
|
||||||
|
public void testIfChain() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/ir/irCfg/when/ifChain.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("whenReturn.kt")
|
||||||
|
public void testWhenReturn() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/ir/irCfg/when/whenReturn.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -658,6 +658,12 @@ public class IrTextTestCaseGenerated extends AbstractIrTextTestCase {
|
|||||||
doTest(fileName);
|
doTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("whenReturn.kt")
|
||||||
|
public void testWhenReturn() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/ir/irText/expressions/whenReturn.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("whileDoWhile.kt")
|
@TestMetadata("whileDoWhile.kt")
|
||||||
public void testWhileDoWhile() throws Exception {
|
public void testWhileDoWhile() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/ir/irText/expressions/whileDoWhile.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/ir/irText/expressions/whileDoWhile.kt");
|
||||||
|
|||||||
Reference in New Issue
Block a user