Fix a few bugs in the temporary variable stack building

This commit is contained in:
Brian Norman
2020-02-08 13:22:17 -06:00
parent 3f9f1faf17
commit 9adb5ba4e8
2 changed files with 56 additions and 11 deletions
@@ -128,13 +128,13 @@ fun IrBlockBuilder.buildAssert(
node: Node,
stack: MutableList<IrStackVariable> = mutableListOf(),
constructor: IrConstructorSymbol = context.ir.symbols.assertionErrorConstructor,
thenPart: IrBlockBuilder.(stack: MutableList<IrStackVariable>) -> IrExpression = { stack -> buildThrow(constructor, buildMessage(title, stack, callSource)) }
thenPart: IrBlockBuilder.(stack: MutableList<IrStackVariable>) -> IrExpression = { subStack -> buildThrow(constructor, buildMessage(title, subStack, callSource)) }
) {
fun IrBlockBuilder.nest(children: List<Node>, index: Int, stack: MutableList<IrStackVariable>) {
val child = children[index]
buildAssert(context, file, fileSource, callSource, callIndent, title, child, stack, constructor) { stack ->
if (index + 1 == children.size) buildThrow(constructor, buildMessage(title, stack, callSource))
else irBlock { nest(children, index + 1, stack) }
buildAssert(context, file, fileSource, callSource, callIndent, title, child, stack, constructor) { subStack ->
if (index + 1 == children.size) buildThrow(constructor, buildMessage(title, subStack, callSource))
else irBlock { nest(children, index + 1, subStack) }
}
}
@@ -159,11 +159,11 @@ private inline fun IrBlockBuilder.irIfNotThan(
fileSource: String,
callIndent: Int,
node: ExpressionNode,
thenPart: IrBlockBuilder.(stack: MutableList<IrStackVariable>) -> IrExpression
thenPart: IrBlockBuilder.(subStack: MutableList<IrStackVariable>) -> IrExpression
): IrWhen {
val stackTransformer = StackBuilder(this, stack, file, fileSource, callIndent, node.expressions)
val transformed = node.expressions.first().transform(stackTransformer, null)
return irIfThen(irNot(transformed), thenPart(stack))
return irIfThen(irNot(transformed), thenPart(stack.toMutableList()))
}
class StackBuilder(
@@ -197,11 +197,7 @@ class StackBuilder(
}
override fun visitExpression(expression: IrExpression): IrExpression {
return if (expression in transform) {
push(super.visitExpression(expression))
} else {
super.visitExpression(expression)
}
return super.visitExpression(expression).also { if (expression in transform) push(it) }
}
}
@@ -175,6 +175,29 @@ assert(text != null && (text.length == 1 || text.toLowerCase() == text))
)
}
@Test
fun booleanMixAndLast() {
assertMessage(
"""
fun main() {
val text = "Hello"
assert((text.length == 1 || text.toLowerCase() == text) && text.length == 1)
}""",
"""
Assertion failed
assert((text.length == 1 || text.toLowerCase() == text) && text.length == 1)
| | | | | | |
| | | | | | Hello
| | | | | false
| | | | hello
| | | Hello
| | false
| 5
Hello
""".trimIndent()
)
}
@Test
fun booleanMixOrFirst() {
assertMessage(
@@ -200,6 +223,32 @@ assert(text == null || (text.length == 5 && text.toLowerCase() == text))
)
}
@Test
fun booleanMixOrLast() {
assertMessage(
"""
fun main() {
val text = "Hello"
assert((text.length == 5 && text.toLowerCase() == text) || text.length == 1)
}""",
"""
Assertion failed
assert((text.length == 5 && text.toLowerCase() == text) || text.length == 1)
| | | | | | | | | |
| | | | | | | | | false
| | | | | | | | 5
| | | | | | | Hello
| | | | | | Hello
| | | | | false
| | | | hello
| | | Hello
| | true
| 5
Hello
""".trimIndent()
)
}
@Test
fun conditionalAccess() {
assertMessage(