[tree generator] Add AbstractElement#subElements, drop semantic leaves

The notion of IR element class being 'semantically leaf' is rather hacky.
Instead, now we only distinguish whether an element has its
implementation class, which is what this notion was actually trying to
represent.

^KT-65773 In Progress
This commit is contained in:
Wojciech Litewka
2024-02-21 17:35:35 +01:00
committed by Space Team
parent 7e01fc5906
commit 6d5b07ebe9
13 changed files with 89 additions and 65 deletions
@@ -42,6 +42,11 @@ abstract class AbstractElement<Element, Field, Implementation>(
val isRootElement: Boolean
get() = elementParents.isEmpty()
/**
* A list of [Element]s which are direct subclasses of this element.
*/
lateinit var subElements: Set<Element>
var isSealed: Boolean = false
/**
@@ -69,18 +69,11 @@ abstract class AbstractImplementationConfigurator<Implementation, Element, Imple
}
private fun generateDefaultImplementations(elements: List<Element>) {
collectLeafsWithoutImplementation(elements).forEach {
impl(it)
}
}
private fun collectLeafsWithoutImplementation(elements: List<Element>): Set<Element> {
val leafs = elements.toMutableSet()
elements.forEach { element ->
leafs.removeAll(element.elementParents.map { it.element }.toSet())
}
leafs.removeAll(elementsWithImpl)
return leafs
elements
.filter { it.subElements.isEmpty() && it !in elementsWithImpl && !it.doesNotNeedImplementation }
.forEach {
impl(it)
}
}
/**
@@ -0,0 +1,20 @@
/*
* Copyright 2010-2024 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.generators.tree
internal fun <Element : AbstractElement<Element, *, *>> initializeSubElements(elements: List<Element>){
val elementSubclasses = elements.associateWith { mutableSetOf<Element>() }
for (element in elements) {
for (parent in element.elementParents) {
elementSubclasses.getValue(parent.element) += element
}
}
for ((element, subElements) in elementSubclasses) {
element.subElements = subElements
}
}
@@ -72,8 +72,6 @@ fun printGeneratedType(
* @param builderConfigurator The class for configuring the set of builders, see [Builder] and [AbstractBuilderConfigurator].
* @param createImplementationPrinter Provide the class that prints implementations of elements, see [AbstractImplementationPrinter].
* @param createBuilderPrinter Provide the class that prints the corresponding builder for each element class, see [AbstractBuilderPrinter].
* @param afterConfiguration The routine to run after all implementations and builders were fully configured,
* but before anything was printed to a file.
* @param enableBaseTransformerTypeDetection Whether to use a special algorithm for inferring return types of transformer methods for each
* element, see [detectBaseTransformerTypes].
* @param addFiles Arbitrary files to add to the set of generated files.
@@ -89,7 +87,6 @@ fun <Element, Implementation, ElementField, ImplementationField> generateTree(
builderConfigurator: AbstractBuilderConfigurator<Element, Implementation, ImplementationField, ElementField>? = null,
createImplementationPrinter: ((SmartPrinter) -> AbstractImplementationPrinter<Implementation, Element, ImplementationField>)? = null,
createBuilderPrinter: ((SmartPrinter) -> AbstractBuilderPrinter<Element, Implementation, ImplementationField, ElementField>)? = null,
afterConfiguration: () -> Unit = {},
enableBaseTransformerTypeDetection: Boolean = true,
addFiles: MutableList<GeneratedFile>.() -> Unit = {},
) where Element : AbstractElement<Element, ElementField, Implementation>,
@@ -100,13 +97,13 @@ fun <Element, Implementation, ElementField, ImplementationField> generateTree(
if (enableBaseTransformerTypeDetection) {
detectBaseTransformerTypes(model)
}
initializeSubElements(model.elements)
implementationConfigurator?.configureImplementations(model)
val implementations = model.elements.flatMap { it.implementations }
InterfaceAndAbstractClassConfigurator((model.elements + implementations))
.configureInterfacesAndAbstractClasses()
addPureAbstractElement(model.elements, pureAbstractElement)
builderConfigurator?.configureBuilders()
afterConfiguration()
val generatedFiles = mutableListOf<GeneratedFile>()
model.elements.mapTo(generatedFiles) { element ->