diff --git a/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/NodeConfigurator.kt b/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/NodeConfigurator.kt index 1c61f472ef4..a8fcab6d13b 100644 --- a/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/NodeConfigurator.kt +++ b/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/NodeConfigurator.kt @@ -166,11 +166,11 @@ object NodeConfigurator : AbstractFieldConfigurator(FirTreeBuild } loopJump.configure { - parentArg(jump, "E", loop) + parentArgs(jump, "E" to loop) } returnExpression.configure { - parentArg(jump, "E", function) + parentArgs(jump, "E" to function) +field("result", expression).withTransform() needTransformOtherChildren() } diff --git a/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/context/AbstractFieldConfigurator.kt b/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/context/AbstractFieldConfigurator.kt index bb32ae92335..244d5afdfee 100644 --- a/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/context/AbstractFieldConfigurator.kt +++ b/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/context/AbstractFieldConfigurator.kt @@ -34,19 +34,25 @@ abstract class AbstractFieldConfigurator(private val return TypeVariable(name, upperBounds, variance).also(element.params::add) } - fun parentArg(parent: Element, argument: String, type: TypeRef) { - parentArg(parent, NamedTypeParameterRef(argument), type) + fun parentArgs(parent: Element, vararg arguments: Pair) { + parentArgs(parent, listOf(*arguments)) } - fun parentArg(parent: Element, argument: NamedTypeParameterRef, type: TypeRef) { - require(parent in element.parents) { + private fun parentArgs(parent: Element, arguments: List>) { + parentArgs(parent, arguments.map { (name, arg) -> NamedTypeParameterRef(name) to arg }) + } + + @JvmName("parentArgs2") + private fun parentArgs(parent: Element, arguments: List>) { + val parentIndex = element.parentRefs.indexOfFirst { it.element == parent } + require(parentIndex >= 0) { "$parent is not parent of $element" } - val argMap = element.parentsArguments.getOrPut(parent) { mutableMapOf() } - require(argument !in argMap) { - "Argument $argument already defined for parent $parent of $element" + val parentRef = element.parentRefs[parentIndex] + require(parentRef.args.isEmpty()) { + "Parent $parent of element $element already has type arguments: $parentRef" } - argMap[argument] = type + element.parentRefs[parentIndex] = parentRef.copy(arguments.toMap()) } fun needTransformOtherChildren() { diff --git a/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/context/AbstractFirTreeBuilder.kt b/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/context/AbstractFirTreeBuilder.kt index 455a001364c..2dad6ccb248 100644 --- a/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/context/AbstractFirTreeBuilder.kt +++ b/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/context/AbstractFirTreeBuilder.kt @@ -47,9 +47,9 @@ abstract class AbstractFirTreeBuilder { private fun createElement(name: String, kind: Element.Kind, vararg dependencies: Element): Element = Element(name, kind).also { if (dependencies.isEmpty()) { - it.parents.add(baseFirElement) + it.parentRefs.add(baseFirElement) } - it.parents.addAll(dependencies) + it.parentRefs.addAll(dependencies) elements += it } diff --git a/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/context/AbstractFirTreeImplementationConfigurator.kt b/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/context/AbstractFirTreeImplementationConfigurator.kt index 8adbc78f85a..f0f7fb38a76 100644 --- a/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/context/AbstractFirTreeImplementationConfigurator.kt +++ b/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/context/AbstractFirTreeImplementationConfigurator.kt @@ -57,7 +57,7 @@ abstract class AbstractFirTreeImplementationConfigurator { private fun collectLeafsWithoutImplementation(builder: AbstractFirTreeBuilder): Set { val elements = builder.elements.toMutableSet() builder.elements.forEach { - elements.removeAll(it.parents) + elements.removeAll(it.parentRefs.map { it.element }.toSet()) } elements.removeAll(elementsWithImpl) return elements diff --git a/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/model/Element.kt b/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/model/Element.kt index ffd82424fc8..e67d7ca3a86 100644 --- a/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/model/Element.kt +++ b/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/model/Element.kt @@ -8,6 +8,7 @@ package org.jetbrains.kotlin.fir.tree.generator.model import org.jetbrains.kotlin.fir.tree.generator.printer.BASE_PACKAGE import org.jetbrains.kotlin.fir.tree.generator.util.set import org.jetbrains.kotlin.generators.tree.* +import org.jetbrains.kotlin.generators.tree.ElementOrRef import org.jetbrains.kotlin.generators.tree.ElementOrRef as GenericElementOrRef import org.jetbrains.kotlin.generators.tree.ElementRef as GenericElementRef @@ -38,13 +39,12 @@ class Element(override val name: String, kind: Kind) : AbstractElement() + override val parentRefs = mutableListOf>() var defaultImplementation: Implementation? = null val customImplementations = mutableListOf() override val params = mutableListOf() - override val parentsArguments = mutableMapOf>() override var kind: ImplementationKind? = null set(value) { if (value !in allowedKinds) { @@ -61,7 +61,7 @@ class Element(override val name: String, kind: Kind) : AbstractElement> = mutableMapOf() val useNullableForReplace: MutableSet = mutableSetOf() val allImplementations: List by lazy { @@ -105,16 +105,18 @@ class Element(override val name: String, kind: Kind) : AbstractElement by lazy { val result = LinkedHashMap() - parents.forEach { parent -> + parentRefs.forEach { parentRef -> + val parent = parentRef.element val fields = parent.allFields.map { field -> val copy = (field as? SimpleField)?.let { simpleField -> - parentsArguments[parent]?.get(NamedTypeParameterRef(simpleField.type))?.let { + // FIXME: Replace with parentRef.args[simpleField.typeRef] + parentRef.args[NamedTypeParameterRef(simpleField.type)]?.let { simpleField.replaceType(it) } } ?: field.copy() copy.apply { arguments.replaceAll { - parentsArguments[parent]?.get(it) ?: it + parentRef.args[it] ?: it } fromParent = true } diff --git a/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/printer/element.kt b/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/printer/element.kt index 5a14c469792..4efccb092a7 100644 --- a/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/printer/element.kt +++ b/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/printer/element.kt @@ -56,21 +56,22 @@ fun SmartPrinter.printElement(element: Element) { print(typeParameters()) val needPureAbstractElement = !isInterface && !allParents.any { it.kind == ImplementationKind.AbstractClass || it.kind == ImplementationKind.SealedClass } - if (parents.isNotEmpty() || needPureAbstractElement) { + if (parentRefs.isNotEmpty() || needPureAbstractElement) { print(" : ") if (needPureAbstractElement) { print("${pureAbstractElementType.type}()") - if (parents.isNotEmpty()) { + if (parentRefs.isNotEmpty()) { print(", ") } } print( - parents.joinToString(", ") { - var result = it.type - parentsArguments[it]?.let { arguments -> - result += arguments.values.joinToString(", ", "<", ">") { it.typeWithArguments } + parentRefs.joinToString(", ") { + // TODO: Factor out + var result = it.element.type + if (it.args.isNotEmpty()) { + result += it.args.values.joinToString(", ", "<", ">") { it.typeWithArguments } } - result + it.kind.braces() + result + it.element.kind.braces() }, ) } @@ -134,14 +135,16 @@ fun SmartPrinter.printElement(element: Element) { if (needTransformOtherChildren) { println() abstract() - if (element.parents.any { it.needTransformOtherChildren }) { + if (element.parentRefs.any { it.element.needTransformOtherChildren }) { print("override ") } println(transformFunctionDeclaration("OtherChildren", typeWithArguments)) } if (element == AbstractFirTreeBuilder.baseFirElement) { - require(isInterface) + require(isInterface) { + "$element must be an interface" + } println() println("fun accept(visitor: FirVisitorVoid) = accept(visitor, null)") println() diff --git a/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/printer/utils.kt b/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/printer/utils.kt index 4af6919526e..ac97b853e74 100644 --- a/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/printer/utils.kt +++ b/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/printer/utils.kt @@ -61,9 +61,9 @@ fun Implementation.collectImports(base: List = emptyList(), kind: Import } fun Element.collectImports(): List { - val baseTypes = parents.mapTo(mutableListOf()) { it.fullQualifiedName } + val baseTypes = parentRefs.mapTo(mutableListOf()) { it.fullQualifiedName!! } baseTypes += AbstractFirTreeBuilder.baseFirElement.fullQualifiedName - baseTypes += parentsArguments.values.flatMap { it.values }.mapNotNull { it.fullQualifiedName } + baseTypes += parentRefs.flatMap { it.args.values }.mapNotNull { it.fullQualifiedName } // TODO: Use recursive import collection for TypeRefs if (needPureAbstractElement) { baseTypes += pureAbstractElementType.fullQualifiedName } diff --git a/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/printer/visitor.kt b/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/printer/visitor.kt index fc0e6302913..5a1d1e9812f 100644 --- a/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/printer/visitor.kt +++ b/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/printer/visitor.kt @@ -21,12 +21,12 @@ private val elementsWithMultipleSupertypesForDefaultVisitor = mapOf( private fun Element.isAcceptableForDefaultVisiting(): Boolean { if (this == AbstractFirTreeBuilder.baseFirElement) return false - val hasSingleSupertype = parents.size == 1 && parents.single().name != "Element" + val hasSingleSupertype = parentRefs.size == 1 && parentRefs.single().element.name != "Element" return hasSingleSupertype || this in elementsWithMultipleSupertypesForDefaultVisitor } private fun Element.getNameOfSupertypeForDefaultVisiting(): String { - val parentForDefaultVisiting = parents.singleOrNull() ?: elementsWithMultipleSupertypesForDefaultVisitor.getValue(this) + val parentForDefaultVisiting = parentRefs.singleOrNull()?.element ?: elementsWithMultipleSupertypesForDefaultVisitor.getValue(this) return parentForDefaultVisiting.name } diff --git a/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/util/util.kt b/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/util/util.kt index f935db30415..cb73f2d6f9e 100644 --- a/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/util/util.kt +++ b/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/util/util.kt @@ -12,7 +12,7 @@ import java.io.File fun Element.traverseParents(block: (Element) -> Unit) { block(this) - parents.forEach { it.traverseParents(block) } + parentRefs.forEach { it.element.traverseParents(block) } } operator fun MutableMap>.set(k1: K, k2: V, value: U) { diff --git a/generators/tree-generator-common/src/org/jetbrains/kotlin/generators/tree/AbstractElement.kt b/generators/tree-generator-common/src/org/jetbrains/kotlin/generators/tree/AbstractElement.kt index f52b95c7ebb..3123ba9fb93 100644 --- a/generators/tree-generator-common/src/org/jetbrains/kotlin/generators/tree/AbstractElement.kt +++ b/generators/tree-generator-common/src/org/jetbrains/kotlin/generators/tree/AbstractElement.kt @@ -20,9 +20,7 @@ interface AbstractElement : ElementOrRef, FieldC val params: List - val parents: List - - val parentsArguments: Map> + val parentRefs: List> val overridenFields: Map> @@ -30,7 +28,7 @@ interface AbstractElement : ElementOrRef, FieldC get() = false override val allParents: List - get() = parents + get() = parentRefs.map { it.element } override fun getTypeWithArguments(notNull: Boolean): String = type + generics }