[FIR/IR generator] Refactor element parents
- Move `elementParents` and `otherParents` properties to `AbstractElement` - Use `elementParents` instead of `parentRefs` where needed
This commit is contained in:
committed by
Space Team
parent
33994d419d
commit
5798021e4b
+1
-1
@@ -707,7 +707,7 @@ object NodeConfigurator : AbstractFieldConfigurator<FirTreeBuilder>(FirTreeBuild
|
||||
resolvedTypeRef.configure {
|
||||
+field("type", coneKotlinTypeType)
|
||||
+field("delegatedTypeRef", typeRef, nullable = true)
|
||||
element.additionalSupertypeInterfaces.add(typeRefMarkerType)
|
||||
element.otherParents.add(typeRefMarkerType)
|
||||
}
|
||||
|
||||
typeRefWithNullability.configure {
|
||||
|
||||
+3
-3
@@ -44,15 +44,15 @@ abstract class AbstractFieldConfigurator<T : AbstractFirTreeBuilder>(private val
|
||||
|
||||
@JvmName("parentArgs2")
|
||||
private fun parentArgs(parent: Element, arguments: List<Pair<NamedTypeParameterRef, TypeRef>>) {
|
||||
val parentIndex = element.parentRefs.indexOfFirst { it.element == parent }
|
||||
val parentIndex = element.elementParents.indexOfFirst { it.element == parent }
|
||||
require(parentIndex >= 0) {
|
||||
"$parent is not parent of $element"
|
||||
}
|
||||
val parentRef = element.parentRefs[parentIndex]
|
||||
val parentRef = element.elementParents[parentIndex]
|
||||
require(parentRef.args.isEmpty()) {
|
||||
"Parent $parent of element $element already has type arguments: $parentRef"
|
||||
}
|
||||
element.parentRefs[parentIndex] = parentRef.copy(arguments.toMap())
|
||||
element.elementParents[parentIndex] = parentRef.copy(arguments.toMap())
|
||||
}
|
||||
|
||||
fun needTransformOtherChildren() {
|
||||
|
||||
+6
-5
@@ -6,15 +6,14 @@
|
||||
package org.jetbrains.kotlin.fir.tree.generator.context
|
||||
|
||||
import org.jetbrains.kotlin.fir.tree.generator.model.Element
|
||||
import org.jetbrains.kotlin.fir.tree.generator.model.ElementRef
|
||||
import org.jetbrains.kotlin.fir.tree.generator.model.IntermediateBuilder
|
||||
import org.jetbrains.kotlin.fir.tree.generator.printer.BASE_PACKAGE
|
||||
import org.jetbrains.kotlin.utils.DummyDelegate
|
||||
import org.jetbrains.kotlin.generators.tree.ClassRef
|
||||
import org.jetbrains.kotlin.generators.tree.PositionTypeParameterRef
|
||||
import org.jetbrains.kotlin.generators.tree.TypeRef
|
||||
import org.jetbrains.kotlin.generators.tree.TypeKind
|
||||
import org.jetbrains.kotlin.utils.DummyDelegate
|
||||
import kotlin.properties.ReadOnlyProperty
|
||||
import kotlin.reflect.KClass
|
||||
import kotlin.reflect.KProperty
|
||||
|
||||
abstract class AbstractFirTreeBuilder {
|
||||
@@ -47,9 +46,11 @@ abstract class AbstractFirTreeBuilder {
|
||||
private fun createElement(name: String, kind: Element.Kind, vararg dependencies: Element): Element =
|
||||
Element(name, kind).also {
|
||||
if (dependencies.isEmpty()) {
|
||||
it.parentRefs.add(baseFirElement)
|
||||
it.elementParents.add(ElementRef(baseFirElement))
|
||||
}
|
||||
for (dependency in dependencies) {
|
||||
it.elementParents.add(ElementRef(dependency))
|
||||
}
|
||||
it.parentRefs.addAll(dependencies)
|
||||
elements += it
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -57,7 +57,7 @@ abstract class AbstractFirTreeImplementationConfigurator {
|
||||
private fun collectLeafsWithoutImplementation(builder: AbstractFirTreeBuilder): Set<Element> {
|
||||
val elements = builder.elements.toMutableSet()
|
||||
builder.elements.forEach {
|
||||
elements.removeAll(it.parentRefs.map { it.element }.toSet())
|
||||
elements.removeAll(it.elementParents.map { it.element }.toSet())
|
||||
}
|
||||
elements.removeAll(elementsWithImpl)
|
||||
return elements
|
||||
|
||||
+7
-5
@@ -8,7 +8,6 @@ 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
|
||||
|
||||
@@ -35,8 +34,11 @@ class Element(override val name: String, kind: Kind) : AbstractElement<Element,
|
||||
override val type: String = "Fir$name"
|
||||
override val packageName: String = BASE_PACKAGE + kind.packageName.let { if (it.isBlank()) it else "." + it }
|
||||
override val fullQualifiedName: String get() = super.fullQualifiedName!!
|
||||
override val parentRefs = mutableListOf<ElementOrRef<Element, Field>>()
|
||||
val additionalSupertypeInterfaces = mutableListOf<TypeRef>()
|
||||
|
||||
override val elementParents = mutableListOf<ElementRef>()
|
||||
|
||||
override val otherParents = mutableListOf<ClassRef<*>>()
|
||||
|
||||
var defaultImplementation: Implementation? = null
|
||||
val customImplementations = mutableListOf<Implementation>()
|
||||
|
||||
@@ -58,7 +60,7 @@ class Element(override val name: String, kind: Kind) : AbstractElement<Element,
|
||||
|
||||
var doesNotNeedImplementation: Boolean = false
|
||||
|
||||
val needTransformOtherChildren: Boolean get() = _needTransformOtherChildren || parentRefs.any { it.element.needTransformOtherChildren }
|
||||
val needTransformOtherChildren: Boolean get() = _needTransformOtherChildren || elementParents.any { it.element.needTransformOtherChildren }
|
||||
val overridenFields: MutableMap<Field, MutableMap<Field, Boolean>> = mutableMapOf()
|
||||
val useNullableForReplace: MutableSet<Field> = mutableSetOf()
|
||||
val allImplementations: List<Implementation> by lazy {
|
||||
@@ -102,7 +104,7 @@ class Element(override val name: String, kind: Kind) : AbstractElement<Element,
|
||||
|
||||
val parentFields: List<Field> by lazy {
|
||||
val result = LinkedHashMap<String, Field>()
|
||||
parentRefs.forEach { parentRef ->
|
||||
elementParents.forEach { parentRef ->
|
||||
val parent = parentRef.element
|
||||
val fields = parent.allFields.map { field ->
|
||||
val copy = (field as? SimpleField)?.let { simpleField ->
|
||||
|
||||
+6
-7
@@ -5,7 +5,6 @@
|
||||
|
||||
package org.jetbrains.kotlin.fir.tree.generator.printer
|
||||
|
||||
import org.jetbrains.kotlin.fir.tree.generator.context.AbstractFirTreeBuilder
|
||||
import org.jetbrains.kotlin.fir.tree.generator.model.Element
|
||||
import org.jetbrains.kotlin.fir.tree.generator.model.Field
|
||||
import org.jetbrains.kotlin.fir.tree.generator.pureAbstractElementType
|
||||
@@ -36,22 +35,22 @@ fun SmartPrinter.printElement(element: Element) {
|
||||
}
|
||||
|
||||
fun override() {
|
||||
if (this != AbstractFirTreeBuilder.baseFirElement) {
|
||||
if (!isRootElement) {
|
||||
print("override ")
|
||||
}
|
||||
}
|
||||
|
||||
print("${kind!!.title} $type")
|
||||
print(typeParameters())
|
||||
val needPureAbstractElement = !isInterface && !allParents.any { it.kind == ImplementationKind.AbstractClass || it.kind == ImplementationKind.SealedClass }
|
||||
val superTypesStrings = parentRefs.map {
|
||||
val needPureAbstractElement = this.needPureAbstractElement
|
||||
val superTypesStrings = elementParents.map {
|
||||
// TODO: Factor out
|
||||
var result = it.element.type
|
||||
if (it.args.isNotEmpty()) {
|
||||
result += it.args.values.joinToString(", ", "<", ">") { it.typeWithArguments }
|
||||
}
|
||||
result + it.element.kind.braces()
|
||||
} + additionalSupertypeInterfaces.map { it.type }
|
||||
} + otherParents.map { it.type }
|
||||
|
||||
if (superTypesStrings.isNotEmpty() || needPureAbstractElement) {
|
||||
print(" : ")
|
||||
@@ -123,13 +122,13 @@ fun SmartPrinter.printElement(element: Element) {
|
||||
if (needTransformOtherChildren) {
|
||||
println()
|
||||
abstract()
|
||||
if (element.parentRefs.any { it.element.needTransformOtherChildren }) {
|
||||
if (element.elementParents.any { it.element.needTransformOtherChildren }) {
|
||||
print("override ")
|
||||
}
|
||||
println(transformFunctionDeclaration("OtherChildren", typeWithArguments))
|
||||
}
|
||||
|
||||
if (element == AbstractFirTreeBuilder.baseFirElement) {
|
||||
if (element.isRootElement) {
|
||||
require(isInterface) {
|
||||
"$element must be an interface"
|
||||
}
|
||||
|
||||
+3
-3
@@ -58,13 +58,13 @@ fun Implementation.collectImports(base: List<String> = emptyList(), kind: Import
|
||||
}
|
||||
|
||||
fun Element.collectImports(): List<String> {
|
||||
val baseTypes = parentRefs.mapTo(mutableListOf()) { it.fullQualifiedName!! }
|
||||
val baseTypes = elementParents.mapTo(mutableListOf()) { it.fullQualifiedName!! }
|
||||
baseTypes += AbstractFirTreeBuilder.baseFirElement.fullQualifiedName
|
||||
baseTypes += parentRefs.flatMap { it.args.values }.mapNotNull { it.fullQualifiedName } // TODO: Use recursive import collection for TypeRefs
|
||||
baseTypes += elementParents.flatMap { it.args.values }.mapNotNull { it.fullQualifiedName } // TODO: Use recursive import collection for TypeRefs
|
||||
if (needPureAbstractElement) {
|
||||
baseTypes += pureAbstractElementType.fullQualifiedName
|
||||
}
|
||||
baseTypes.addAll(additionalSupertypeInterfaces.map { it.fullQualifiedName!! })
|
||||
baseTypes.addAll(otherParents.map { it.fullQualifiedName })
|
||||
return collectImportsInternal(
|
||||
baseTypes,
|
||||
ImportKind.Element,
|
||||
|
||||
+3
-2
@@ -23,12 +23,13 @@ private val elementsWithMultipleSupertypesForDefaultVisitor = mapOf(
|
||||
|
||||
private fun Element.isAcceptableForDefaultVisiting(): Boolean {
|
||||
if (this == AbstractFirTreeBuilder.baseFirElement) return false
|
||||
val hasSingleSupertype = parentRefs.size == 1 && parentRefs.single().element.name != "Element"
|
||||
val hasSingleSupertype = elementParents.size == 1 && !elementParents[0].element.isRootElement
|
||||
return hasSingleSupertype || this in elementsWithMultipleSupertypesForDefaultVisitor
|
||||
}
|
||||
|
||||
private fun Element.getNameOfSupertypeForDefaultVisiting(): String {
|
||||
val parentForDefaultVisiting = parentRefs.singleOrNull()?.element ?: elementsWithMultipleSupertypesForDefaultVisitor.getValue(this)
|
||||
val parentForDefaultVisiting =
|
||||
elementParents.singleOrNull()?.element ?: elementsWithMultipleSupertypesForDefaultVisitor.getValue(this)
|
||||
return parentForDefaultVisiting.name
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -12,7 +12,7 @@ import java.io.File
|
||||
|
||||
fun Element.traverseParents(block: (Element) -> Unit) {
|
||||
block(this)
|
||||
parentRefs.forEach { it.element.traverseParents(block) }
|
||||
elementParents.forEach { it.element.traverseParents(block) }
|
||||
}
|
||||
|
||||
operator fun <K, V, U> MutableMap<K, MutableMap<V, U>>.set(k1: K, k2: V, value: U) {
|
||||
|
||||
+2
-5
@@ -22,11 +22,8 @@ class Element(
|
||||
override val fields: MutableSet<Field>,
|
||||
val additionalFactoryMethodParameters: MutableList<Field>,
|
||||
) : AbstractElement<Element, Field>() {
|
||||
var elementParents: List<ElementRef> = emptyList()
|
||||
var otherParents: List<ClassRef<*>> = emptyList()
|
||||
|
||||
override val parentRefs: List<ElementOrRef>
|
||||
get() = elementParents
|
||||
override var elementParents: List<ElementRef> = emptyList()
|
||||
override var otherParents: List<ClassRef<*>> = emptyList()
|
||||
|
||||
override val allFields: List<Field>
|
||||
get() = fields.toList()
|
||||
|
||||
+2
-2
@@ -40,7 +40,7 @@ fun printElements(generationPath: File, model: Model) = sequence {
|
||||
)
|
||||
addTypeVariables(element.params.map { it.toPoet() })
|
||||
|
||||
val (classes, interfaces) = (element.elementParents + element.otherParents).partition { it.typeKind == TypeKind.Class }
|
||||
val (classes, interfaces) = element.parentRefs.partition { it.typeKind == TypeKind.Class }
|
||||
classes.singleOrNull()?.let {
|
||||
superclass(it.toPoet())
|
||||
}
|
||||
@@ -77,7 +77,7 @@ fun printElements(generationPath: File, model: Model) = sequence {
|
||||
}.build())
|
||||
}
|
||||
|
||||
val isRootElement = element.elementParents.isEmpty()
|
||||
val isRootElement = element.isRootElement
|
||||
val acceptMethodName = "accept"
|
||||
val transformMethodName = "transform"
|
||||
if (element.accept) {
|
||||
|
||||
+2
-2
@@ -13,6 +13,7 @@ import org.jetbrains.kotlin.ir.generator.model.Element.Companion.elementName2typ
|
||||
import org.jetbrains.kotlin.ir.generator.util.*
|
||||
import org.jetbrains.kotlin.types.Variance
|
||||
import org.jetbrains.kotlin.generators.tree.ElementRef as GenericElementRef
|
||||
import org.jetbrains.kotlin.generators.tree.ElementOrRef as GenericElementOrRef
|
||||
|
||||
fun Element.toPoet() = ClassName(packageName, typeName)
|
||||
fun Element.toPoetSelfParameterized() = toPoet().parameterizedByIfAny(poetTypeVariables)
|
||||
@@ -68,7 +69,6 @@ fun TypeVariable.toPoet() = TypeVariableName(
|
||||
|
||||
val ClassOrElementRef.typeKind: TypeKind
|
||||
get() = when (this) {
|
||||
is GenericElementRef<*, *> -> element.kind!!.typeKind
|
||||
is GenericElementOrRef<*, *> -> element.kind!!.typeKind
|
||||
is ClassRef<*> -> kind
|
||||
else -> error("Unexpected type: $this")
|
||||
}
|
||||
|
||||
+10
-2
@@ -20,13 +20,21 @@ abstract class AbstractElement<Element, Field> : ElementOrRef<Element, Field>, F
|
||||
|
||||
abstract val params: List<TypeVariable>
|
||||
|
||||
abstract val parentRefs: List<ElementOrRef<Element, Field>>
|
||||
abstract val elementParents: List<ElementRef<Element, Field>>
|
||||
|
||||
abstract val otherParents: List<ClassRef<*>>
|
||||
|
||||
val parentRefs: List<ClassOrElementRef>
|
||||
get() = elementParents + otherParents
|
||||
|
||||
val isRootElement: Boolean
|
||||
get() = elementParents.isEmpty()
|
||||
|
||||
open val isSealed: Boolean
|
||||
get() = false
|
||||
|
||||
override val allParents: List<Element>
|
||||
get() = parentRefs.map { it.element }
|
||||
get() = elementParents.map { it.element }
|
||||
|
||||
final override fun getTypeWithArguments(notNull: Boolean): String = type + generics
|
||||
|
||||
|
||||
+1
-1
@@ -23,7 +23,7 @@ interface TypeRef : Importable {
|
||||
}
|
||||
}
|
||||
|
||||
interface ClassOrElementRef : TypeRefWithNullability
|
||||
sealed interface ClassOrElementRef : TypeRefWithNullability
|
||||
|
||||
// Based on com.squareup.kotlinpoet.ClassName
|
||||
class ClassRef<P : TypeParameterRef> private constructor(
|
||||
|
||||
Reference in New Issue
Block a user