Skip to content

Commit

Permalink
(fixup) Do not generate acceptChildren/transformChildren for some non…
Browse files Browse the repository at this point in the history
…-leaf elements
  • Loading branch information
udalov committed Jan 19, 2022
1 parent 713bbef commit 1e45101
Show file tree
Hide file tree
Showing 5 changed files with 21 additions and 42 deletions.
Expand Up @@ -183,12 +183,14 @@ object IrTree : AbstractTreeBuilder() {
}
val declarationContainer by element(Declaration) {
parent(declarationParent)
ownsChildren = false

+listField("declarations", declaration, mutability = List, isChild = true)
}
val typeParametersContainer by element(Declaration) {
parent(declaration)
parent(declarationParent)
ownsChildren = false

+listField("typeParameters", typeParameter, mutability = Var, isChild = true)
}
Expand Down Expand Up @@ -447,6 +449,7 @@ object IrTree : AbstractTreeBuilder() {
}
val packageFragment by element(Declaration) {
visitorParent = baseElement
ownsChildren = false

parent(declarationContainer)
parent(symbolOwner)
Expand Down Expand Up @@ -494,6 +497,7 @@ object IrTree : AbstractTreeBuilder() {
}
val statementContainer by element(Expression) {
+listField("statements", statement, mutability = List, isChild = true)
ownsChildren = false
}
val body by element(Expression) {
transform = true
Expand Down Expand Up @@ -832,6 +836,7 @@ object IrTree : AbstractTreeBuilder() {
val fieldAccessExpression by element(Expression) {
visitorParent = declarationReference
visitorName = "fieldAccess"
ownsChildren = false

parent(declarationReference)

Expand Down Expand Up @@ -880,6 +885,7 @@ object IrTree : AbstractTreeBuilder() {
val loop by element(Expression) {
visitorParent = expression
visitorParam = "loop"
ownsChildren = false

parent(expression)

Expand Down
Expand Up @@ -34,6 +34,8 @@ class ElementConfig(
var transformByChildren = false
var transformerReturnType: ElementConfig? = null

var ownsChildren = true // If false, acceptChildren/transformChildren will NOT be generated.

var typeKind: TypeKind? = null

var generationCallback: (TypeSpec.Builder.() -> Unit)? = null
Expand Down
Expand Up @@ -30,15 +30,14 @@ class Element(
var isLeaf = false
var walkableChildren: List<Field> = emptyList()
val transformableChildren get() = walkableChildren.filter { it.transformable }
val acceptChildrenSupers = mutableListOf<Element>()
val transformChildrenSupers = mutableListOf<Element>()

val nameInVisitor = config?.visitorName ?: name
val visitFunName = "visit" + nameInVisitor.replaceFirstChar(Char::uppercaseChar)
val visitorParam = config?.visitorParam ?: config?.category?.defaultVisitorParam ?: "element"
val accept = config?.accept ?: false
val transform = config?.transform ?: false
val transformByChildren = config?.transformByChildren ?: false
val ownsChildren = config?.ownsChildren ?: false

val generationCallback = config?.generationCallback
val suppressPrint = config?.suppressPrint ?: false
Expand Down
Expand Up @@ -231,47 +231,27 @@ private fun processFieldOverrides(elements: List<Element>) {

private fun addWalkableChildren(elements: List<Element>) {
for (element in elements) {
val walkableChildren = element.fields.filter { it.isChild }.associateBy { it.name }.toMutableMap()
val walkableChildren = mutableMapOf<String, Field>()

fun visitParents(visited: Element) {
for (parent in visited.elementParents) {
for (field in parent.element.fields) {
if (field.isChild) {
walkableChildren.remove(field.name)
if (!parent.element.ownsChildren) {
for (field in parent.element.fields) {
if (field.isChild) {
walkableChildren[field.name] = field
}
}
}

visitParents(parent.element)
visitParents(parent.element)
}
}
}

visitParents(element)
element.walkableChildren = walkableChildren.values.toList()
}

for (element in iterateElementsParentFirst(elements)) {
fun visitParentsForAccept(of: Element) {
for (parent in of.elementParents) {
if (parent.element.walkableChildren.isNotEmpty()) {
element.acceptChildrenSupers.add(parent.element)
} else {
visitParentsForAccept(parent.element)
}
}
}
element.fields.filter { it.isChild }.associateByTo(walkableChildren) { it.name }

fun visitParentsForTransform(of: Element) {
for (parent in of.elementParents) {
if (parent.element.transformableChildren.isNotEmpty()) {
element.transformChildrenSupers.add(parent.element)
} else {
visitParentsForTransform(parent.element)
}
}
}

visitParentsForAccept(element)
visitParentsForTransform(element)
element.walkableChildren = walkableChildren.values.toList()
}
}

Expand Down
Expand Up @@ -98,18 +98,14 @@ fun printElements(generationPath: File, model: Model) = sequence {
}.build())
}

if (element.walkableChildren.isNotEmpty() || element.acceptChildrenSupers.size > 1) {
if (element.ownsChildren && element.walkableChildren.isNotEmpty()) {
addFunction(FunSpec.builder("acceptChildren").apply {
addModifiers(KModifier.OVERRIDE)
val d = TypeVariableName("D")
addTypeVariable(d)
addParameter("visitor", elementVisitorType.toPoet().tryParameterizedBy(UNIT, d))
addParameter("data", d)

for (ancestor in element.acceptChildrenSupers) {
addStatement("super<%T>.acceptChildren(visitor, data)", ancestor.toPoet())
}

for (child in element.walkableChildren) {
addStatement(buildString {
append(child.name)
Expand All @@ -123,18 +119,14 @@ fun printElements(generationPath: File, model: Model) = sequence {
}.build())
}

if (element.transformableChildren.isNotEmpty() || element.transformChildrenSupers.size > 1) {
if (element.ownsChildren && element.transformableChildren.isNotEmpty()) {
addFunction(FunSpec.builder("transformChildren").apply {
addModifiers(KModifier.OVERRIDE)
val d = TypeVariableName("D")
addTypeVariable(d)
addParameter("transformer", elementTransformerType.toPoet().tryParameterizedBy(d))
addParameter("data", d)

for (ancestor in element.transformChildrenSupers) {
addStatement("super<%T>.transformChildren(transformer, data)", ancestor.toPoet())
}

for (child in element.transformableChildren) {
val args = mutableListOf<Any>()
val code = buildString {
Expand Down

0 comments on commit 1e45101

Please sign in to comment.