From eb3dbac270925f6a7af8b1c0807629fb3ca961c5 Mon Sep 17 00:00:00 2001 From: Alexander Udalov Date: Tue, 18 Jan 2022 01:23:50 +0100 Subject: [PATCH] (fixup) Do not generate acceptChildren/transformChildren for some non-leaf elements --- .../jetbrains/kotlin/ir/generator/IrTree.kt | 13 ++++++ .../kotlin/ir/generator/config/ConfigModel.kt | 2 + .../kotlin/ir/generator/model/Model.kt | 3 +- .../ir/generator/model/Transformations.kt | 40 +++++-------------- .../kotlin/ir/generator/print/Elements.kt | 12 +----- 5 files changed, 28 insertions(+), 42 deletions(-) diff --git a/compiler/ir/ir.tree/tree-generator/src/org/jetbrains/kotlin/ir/generator/IrTree.kt b/compiler/ir/ir.tree/tree-generator/src/org/jetbrains/kotlin/ir/generator/IrTree.kt index aa57e78b9899b..92cb4d338266a 100644 --- a/compiler/ir/ir.tree/tree-generator/src/org/jetbrains/kotlin/ir/generator/IrTree.kt +++ b/compiler/ir/ir.tree/tree-generator/src/org/jetbrains/kotlin/ir/generator/IrTree.kt @@ -25,6 +25,10 @@ import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedContainerSource import org.jetbrains.kotlin.types.Variance +// Note the style of the DSL to describe IR elements, which is these things in the following order: +// 1) config (see properties of ElementConfig) +// 2) parents +// 3) fields object IrTree : AbstractTreeBuilder() { private fun symbol(type: TypeRef) = field("symbol", type) private fun descriptor(typeName: String) = @@ -183,11 +187,15 @@ object IrTree : AbstractTreeBuilder() { +field("body", blockBody, mutable = true, isChild = true) } val declarationContainer: ElementConfig by element(Declaration) { + ownsChildren = false + parent(declarationParent) +listField("declarations", declaration, mutability = List, isChild = true) } val typeParametersContainer: ElementConfig by element(Declaration) { + ownsChildren = false + parent(declaration) parent(declarationParent) @@ -448,6 +456,7 @@ object IrTree : AbstractTreeBuilder() { } val packageFragment: ElementConfig by element(Declaration) { visitorParent = baseElement + ownsChildren = false parent(declarationContainer) parent(symbolOwner) @@ -494,6 +503,8 @@ object IrTree : AbstractTreeBuilder() { +field("type", irTypeType, mutable = true) } val statementContainer: ElementConfig by element(Expression) { + ownsChildren = false + +listField("statements", statement, mutability = List, isChild = true) } val body: ElementConfig by element(Expression) { @@ -832,6 +843,7 @@ object IrTree : AbstractTreeBuilder() { val fieldAccessExpression: ElementConfig by element(Expression) { visitorParent = declarationReference visitorName = "fieldAccess" + ownsChildren = false parent(declarationReference) @@ -880,6 +892,7 @@ object IrTree : AbstractTreeBuilder() { val loop: ElementConfig by element(Expression) { visitorParent = expression visitorParam = "loop" + ownsChildren = false parent(expression) diff --git a/compiler/ir/ir.tree/tree-generator/src/org/jetbrains/kotlin/ir/generator/config/ConfigModel.kt b/compiler/ir/ir.tree/tree-generator/src/org/jetbrains/kotlin/ir/generator/config/ConfigModel.kt index 929aaca6df74b..ea50e8f827a51 100644 --- a/compiler/ir/ir.tree/tree-generator/src/org/jetbrains/kotlin/ir/generator/config/ConfigModel.kt +++ b/compiler/ir/ir.tree/tree-generator/src/org/jetbrains/kotlin/ir/generator/config/ConfigModel.kt @@ -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 diff --git a/compiler/ir/ir.tree/tree-generator/src/org/jetbrains/kotlin/ir/generator/model/Model.kt b/compiler/ir/ir.tree/tree-generator/src/org/jetbrains/kotlin/ir/generator/model/Model.kt index 47166ee70bca7..2000a95f97c48 100644 --- a/compiler/ir/ir.tree/tree-generator/src/org/jetbrains/kotlin/ir/generator/model/Model.kt +++ b/compiler/ir/ir.tree/tree-generator/src/org/jetbrains/kotlin/ir/generator/model/Model.kt @@ -30,14 +30,13 @@ class Element( var isLeaf = false var walkableChildren: List = emptyList() val transformableChildren get() = walkableChildren.filter { it.transformable } - val acceptChildrenSupers = mutableListOf() - val transformChildrenSupers = mutableListOf() val visitFunName = "visit" + (config.visitorName ?: name).replaceFirstChar(Char::uppercaseChar) val visitorParam = config.visitorParam ?: config.category.defaultVisitorParam var accept = config.accept val transform = config.transform val transformByChildren = config.transformByChildren + val ownsChildren = config.ownsChildren val generationCallback = config.generationCallback val suppressPrint = config.suppressPrint diff --git a/compiler/ir/ir.tree/tree-generator/src/org/jetbrains/kotlin/ir/generator/model/Transformations.kt b/compiler/ir/ir.tree/tree-generator/src/org/jetbrains/kotlin/ir/generator/model/Transformations.kt index 63c874affb3b8..ef4a39343deea 100644 --- a/compiler/ir/ir.tree/tree-generator/src/org/jetbrains/kotlin/ir/generator/model/Transformations.kt +++ b/compiler/ir/ir.tree/tree-generator/src/org/jetbrains/kotlin/ir/generator/model/Transformations.kt @@ -234,47 +234,27 @@ private fun processFieldOverrides(elements: List) { private fun addWalkableChildren(elements: List) { for (element in elements) { - val walkableChildren = element.fields.filter { it.isChild }.associateBy { it.name }.toMutableMap() + val walkableChildren = mutableMapOf() 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() } } diff --git a/compiler/ir/ir.tree/tree-generator/src/org/jetbrains/kotlin/ir/generator/print/Elements.kt b/compiler/ir/ir.tree/tree-generator/src/org/jetbrains/kotlin/ir/generator/print/Elements.kt index 134ee4819c2e1..046ed463141ad 100644 --- a/compiler/ir/ir.tree/tree-generator/src/org/jetbrains/kotlin/ir/generator/print/Elements.kt +++ b/compiler/ir/ir.tree/tree-generator/src/org/jetbrains/kotlin/ir/generator/print/Elements.kt @@ -99,7 +99,7 @@ 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") @@ -107,10 +107,6 @@ fun printElements(generationPath: File, model: Model) = sequence { 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) @@ -124,7 +120,7 @@ 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") @@ -132,10 +128,6 @@ fun printElements(generationPath: File, model: Model) = sequence { 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() val code = buildString {