IR tree gen: restore IrWhileLoop children visit order

This commit is contained in:
Alexander Udalov
2022-06-10 01:27:41 +02:00
committed by Alexander Udalov
parent bf5ab49342
commit f003f19e1d
5 changed files with 12 additions and 3 deletions
@@ -20,12 +20,12 @@ abstract class IrWhileLoop : IrLoop() {
visitor.visitWhileLoop(this, data)
override fun <D> acceptChildren(visitor: IrElementVisitor<Unit, D>, data: D) {
body?.accept(visitor, data)
condition.accept(visitor, data)
body?.accept(visitor, data)
}
override fun <D> transformChildren(transformer: IrElementTransformer<D>, data: D) {
body = body?.transform(transformer, data)
condition = condition.transform(transformer, data)
body = body?.transform(transformer, data)
}
}
@@ -911,6 +911,7 @@ object IrTree : AbstractTreeBuilder() {
val whileLoop: ElementConfig by element(Expression) {
visitorParent = loop
visitorParam = "loop"
childrenOrderOverride = listOf("condition", "body")
parent(loop)
}
@@ -32,6 +32,7 @@ class ElementConfig(
var transform = false
var transformByChildren = false
var transformerReturnType: ElementConfig? = null
var childrenOrderOverride: List<String>? = null
var ownsChildren = true // If false, acceptChildren/transformChildren will NOT be generated.
@@ -28,6 +28,7 @@ class Element(
val allParents: List<ClassOrElementRef>
get() = elementParents + otherParents
var isLeaf = false
val childrenOrderOverride: List<String>? = config.childrenOrderOverride
var walkableChildren: List<Field> = emptyList()
val transformableChildren get() = walkableChildren.filter { it.transformable }
@@ -223,10 +223,16 @@ private fun addWalkableChildren(elements: List<Element>) {
element.fields.filter { it.isChild }.associateByTo(walkableChildren) { it.name }
element.walkableChildren = walkableChildren.values.toList()
element.walkableChildren = reorderIfNecessary(walkableChildren.values.toList(), element.childrenOrderOverride)
}
}
private fun reorderIfNecessary(fields: List<Field>, order: List<String>?): List<Field> =
if (order == null) fields else fields.sortedBy {
val position = order.indexOf(it.name)
if (position < 0) order.size else position
}
private fun iterateElementsParentFirst(elements: List<Element>) = sequence {
val pending = elements.sortedBy { it.elementParents.size }.toMutableSet()
pendingLoop@ while (pending.isNotEmpty()) {