Make sure expression are only called once when building stack
This commit is contained in:
@@ -16,6 +16,7 @@
|
||||
|
||||
package com.bnorm.power
|
||||
|
||||
import org.jetbrains.kotlin.backend.common.deepCopyWithVariables
|
||||
import org.jetbrains.kotlin.ir.IrElement
|
||||
import org.jetbrains.kotlin.ir.expressions.IrCall
|
||||
import org.jetbrains.kotlin.ir.expressions.IrConst
|
||||
@@ -60,9 +61,20 @@ class ExpressionNode(
|
||||
parent.mutableChildren.add(this)
|
||||
}
|
||||
|
||||
val expressions: MutableList<IrExpression> = mutableListOf()
|
||||
private val _expressions: MutableList<IrExpression> = mutableListOf()
|
||||
|
||||
override fun toString() = "ExpressionNode($expressions)"
|
||||
fun add(expression: IrExpression) {
|
||||
_expressions.add(expression)
|
||||
}
|
||||
|
||||
fun getExpressionsCopy(): List<IrExpression> {
|
||||
// Return a copy of all the expression by creating a deep copy of the head
|
||||
// expression and running back through the assertion tree builder
|
||||
val headCopy = _expressions.first().deepCopyWithVariables()
|
||||
return (buildAssertTree(headCopy).children.single() as ExpressionNode)._expressions
|
||||
}
|
||||
|
||||
override fun toString() = "ExpressionNode($_expressions)"
|
||||
}
|
||||
|
||||
class RootNode : Node() {
|
||||
@@ -84,7 +96,7 @@ fun buildAssertTree(expression: IrExpression): RootNode {
|
||||
|
||||
override fun visitExpression(expression: IrExpression, data: Node) {
|
||||
val node = data as? ExpressionNode ?: ExpressionNode(data)
|
||||
node.expressions += expression
|
||||
node.add(expression)
|
||||
expression.acceptChildren(this, node)
|
||||
}
|
||||
|
||||
|
||||
@@ -114,6 +114,7 @@ class PowerAssertCallTransformer(
|
||||
return irBlock {
|
||||
buildAssert(this@PowerAssertCallTransformer.context, file, fileSource, callSource, callIndent, title, root)
|
||||
}
|
||||
// .also { println(it.dump())}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -161,8 +162,9 @@ private inline fun IrBlockBuilder.irIfNotThan(
|
||||
node: ExpressionNode,
|
||||
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)
|
||||
val expressions = node.getExpressionsCopy()
|
||||
val stackTransformer = StackBuilder(this, stack, file, fileSource, callIndent, expressions)
|
||||
val transformed = expressions.first().transform(stackTransformer, null)
|
||||
return irIfThen(irNot(transformed), thenPart(stack.toMutableList()))
|
||||
}
|
||||
|
||||
@@ -197,7 +199,11 @@ class StackBuilder(
|
||||
}
|
||||
|
||||
override fun visitExpression(expression: IrExpression): IrExpression {
|
||||
return super.visitExpression(expression).also { if (expression in transform) push(it) }
|
||||
return if (expression in transform) {
|
||||
push(super.visitExpression(expression))
|
||||
} else {
|
||||
super.visitExpression(expression)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user