Make sure expression are only called once when building stack
This commit is contained in:
@@ -16,6 +16,7 @@
|
|||||||
|
|
||||||
package com.bnorm.power
|
package com.bnorm.power
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.backend.common.deepCopyWithVariables
|
||||||
import org.jetbrains.kotlin.ir.IrElement
|
import org.jetbrains.kotlin.ir.IrElement
|
||||||
import org.jetbrains.kotlin.ir.expressions.IrCall
|
import org.jetbrains.kotlin.ir.expressions.IrCall
|
||||||
import org.jetbrains.kotlin.ir.expressions.IrConst
|
import org.jetbrains.kotlin.ir.expressions.IrConst
|
||||||
@@ -60,9 +61,20 @@ class ExpressionNode(
|
|||||||
parent.mutableChildren.add(this)
|
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() {
|
class RootNode : Node() {
|
||||||
@@ -84,7 +96,7 @@ fun buildAssertTree(expression: IrExpression): RootNode {
|
|||||||
|
|
||||||
override fun visitExpression(expression: IrExpression, data: Node) {
|
override fun visitExpression(expression: IrExpression, data: Node) {
|
||||||
val node = data as? ExpressionNode ?: ExpressionNode(data)
|
val node = data as? ExpressionNode ?: ExpressionNode(data)
|
||||||
node.expressions += expression
|
node.add(expression)
|
||||||
expression.acceptChildren(this, node)
|
expression.acceptChildren(this, node)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -114,6 +114,7 @@ class PowerAssertCallTransformer(
|
|||||||
return irBlock {
|
return irBlock {
|
||||||
buildAssert(this@PowerAssertCallTransformer.context, file, fileSource, callSource, callIndent, title, root)
|
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,
|
node: ExpressionNode,
|
||||||
thenPart: IrBlockBuilder.(subStack: MutableList<IrStackVariable>) -> IrExpression
|
thenPart: IrBlockBuilder.(subStack: MutableList<IrStackVariable>) -> IrExpression
|
||||||
): IrWhen {
|
): IrWhen {
|
||||||
val stackTransformer = StackBuilder(this, stack, file, fileSource, callIndent, node.expressions)
|
val expressions = node.getExpressionsCopy()
|
||||||
val transformed = node.expressions.first().transform(stackTransformer, null)
|
val stackTransformer = StackBuilder(this, stack, file, fileSource, callIndent, expressions)
|
||||||
|
val transformed = expressions.first().transform(stackTransformer, null)
|
||||||
return irIfThen(irNot(transformed), thenPart(stack.toMutableList()))
|
return irIfThen(irNot(transformed), thenPart(stack.toMutableList()))
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -197,7 +199,11 @@ class StackBuilder(
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun visitExpression(expression: IrExpression): IrExpression {
|
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