[IR generator] Inherit Element from AbstractElement
This is a step towards commonizing the code generator between FIR and IR: KT-61970
This commit is contained in:
committed by
Space Team
parent
f9d17a2d51
commit
7ab4ca6f51
+2
-10
@@ -12,7 +12,7 @@ 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
|
||||
|
||||
class Element(override val name: String, kind: Kind) : AbstractElement<Element, Field> {
|
||||
class Element(override val name: String, kind: Kind) : AbstractElement<Element, Field>() {
|
||||
companion object {
|
||||
private val allowedKinds = setOf(
|
||||
ImplementationKind.Interface,
|
||||
@@ -31,10 +31,6 @@ class Element(override val name: String, kind: Kind) : AbstractElement<Element,
|
||||
override val nullable: Boolean
|
||||
get() = false
|
||||
|
||||
override fun copy(nullable: Boolean) = ElementRef(this, args, nullable)
|
||||
|
||||
override fun copy(args: Map<NamedTypeParameterRef, TypeRef>) = ElementRef(this, args, nullable)
|
||||
|
||||
override val fields = mutableSetOf<Field>()
|
||||
override val type: String = "Fir$name"
|
||||
override val packageName: String = BASE_PACKAGE + kind.packageName.let { if (it.isBlank()) it else "." + it }
|
||||
@@ -63,7 +59,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 }
|
||||
override val overridenFields: MutableMap<Field, MutableMap<Field, Boolean>> = mutableMapOf()
|
||||
val overridenFields: MutableMap<Field, MutableMap<Field, Boolean>> = mutableMapOf()
|
||||
val useNullableForReplace: MutableSet<Field> = mutableSetOf()
|
||||
val allImplementations: List<Implementation> by lazy {
|
||||
if (doesNotNeedImplementation) {
|
||||
@@ -149,10 +145,6 @@ class Element(override val name: String, kind: Kind) : AbstractElement<Element,
|
||||
return typeWithArguments
|
||||
}
|
||||
|
||||
override fun get(fieldName: String): Field? {
|
||||
return allFields.firstOrNull { it.name == fieldName }
|
||||
}
|
||||
|
||||
enum class Kind(val packageName: String) {
|
||||
Expression("expressions"),
|
||||
Declaration("declarations"),
|
||||
|
||||
+30
-27
@@ -11,25 +11,45 @@ import org.jetbrains.kotlin.ir.generator.config.ElementConfig
|
||||
import org.jetbrains.kotlin.ir.generator.config.FieldConfig
|
||||
import org.jetbrains.kotlin.ir.generator.util.*
|
||||
import org.jetbrains.kotlin.utils.topologicalSort
|
||||
import org.jetbrains.kotlin.generators.tree.ElementOrRef as GenericElementOrRef
|
||||
import org.jetbrains.kotlin.generators.tree.ElementRef as GenericElementRef
|
||||
|
||||
class Element(
|
||||
config: ElementConfig,
|
||||
val name: String,
|
||||
val packageName: String,
|
||||
val params: List<TypeVariable>,
|
||||
val fields: MutableList<Field>,
|
||||
override val name: String,
|
||||
override val packageName: String,
|
||||
override val params: List<TypeVariable>,
|
||||
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 val allFields: List<Field>
|
||||
get() = fields.toList()
|
||||
|
||||
override val element: Element
|
||||
get() = this
|
||||
|
||||
override val nullable: Boolean
|
||||
get() = false
|
||||
|
||||
override val args: Map<NamedTypeParameterRef, TypeRef>
|
||||
get() = emptyMap()
|
||||
|
||||
var visitorParent: ElementRef? = null
|
||||
var transformerReturnType: Element? = null
|
||||
val targetKind = config.typeKind
|
||||
var kind: ImplementationKind? = null
|
||||
override var kind: ImplementationKind? = null
|
||||
val typeName
|
||||
get() = elementName2typeName(name)
|
||||
val allParents: List<ClassOrElementRef>
|
||||
get() = elementParents + otherParents
|
||||
|
||||
override val type: String
|
||||
get() = typeName
|
||||
|
||||
var isLeaf = config.isForcedLeaf
|
||||
val childrenOrderOverride: List<String>? = config.childrenOrderOverride
|
||||
var walkableChildren: List<Field> = emptyList()
|
||||
@@ -79,25 +99,8 @@ class Element(
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME: Replace this class with `typealias ElementRef = org.jetbrains.kotlin.generators.tree.ElementRef<Element, Field>`
|
||||
// FIXME: as soon as Element implements the org.jetbrains.kotlin.generators.tree.AbstractElement interface.
|
||||
data class ElementRef(
|
||||
val element: Element,
|
||||
override val args: Map<NamedTypeParameterRef, TypeRef> = emptyMap(),
|
||||
override val nullable: Boolean = false,
|
||||
) : ParametrizedTypeRef<ElementRef, NamedTypeParameterRef>, ClassOrElementRef {
|
||||
override fun copy(args: Map<NamedTypeParameterRef, TypeRef>) = ElementRef(element, args, nullable)
|
||||
override fun copy(nullable: Boolean) = ElementRef(element, args, nullable)
|
||||
override fun toString() = "${element.name}<${args}>"
|
||||
|
||||
override val type: String
|
||||
get() = element.typeName
|
||||
|
||||
override val packageName: String
|
||||
get() = element.packageName
|
||||
|
||||
override fun getTypeWithArguments(notNull: Boolean): String = type + generics
|
||||
}
|
||||
typealias ElementRef = GenericElementRef<Element, Field>
|
||||
typealias ElementOrRef = GenericElementOrRef<Element, Field>
|
||||
|
||||
sealed class Field(
|
||||
config: FieldConfig,
|
||||
|
||||
+6
-4
@@ -11,6 +11,7 @@ import org.jetbrains.kotlin.ir.generator.elementBaseType
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.UnsafeCastFunction
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.castAll
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.partitionIsInstance
|
||||
import org.jetbrains.kotlin.generators.tree.ElementRef as GenericElementRef
|
||||
|
||||
private object InferredOverriddenType : TypeRef {
|
||||
override val type: String
|
||||
@@ -34,7 +35,7 @@ fun config2model(config: Config): Model {
|
||||
name = ec.name,
|
||||
packageName = ec.category.packageName,
|
||||
params = ec.params,
|
||||
fields = ec.fields.mapTo(mutableListOf(), ::transformFieldConfig),
|
||||
fields = ec.fields.mapTo(mutableSetOf(), ::transformFieldConfig),
|
||||
additionalFactoryMethodParameters = ec.additionalIrFactoryMethodParameters.mapTo(mutableListOf(), ::transformFieldConfig)
|
||||
).also {
|
||||
ec2el[ec.element] = it
|
||||
@@ -85,6 +86,7 @@ private fun transformFieldConfig(fc: FieldConfig): Field = when (fc) {
|
||||
}
|
||||
|
||||
@OptIn(UnsafeCastFunction::class)
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
private fun replaceElementRefs(config: Config, mapping: Map<ElementConfig, Element>): Element {
|
||||
val visited = mutableMapOf<TypeRef, TypeRef>()
|
||||
|
||||
@@ -110,7 +112,7 @@ private fun replaceElementRefs(config: Config, mapping: Map<ElementConfig, Eleme
|
||||
}.also { visited[type] = it }
|
||||
}
|
||||
|
||||
val rootEl = transform(config.rootElement) as ElementRef
|
||||
val rootEl = transform(config.rootElement) as GenericElementRef<Element, Field>
|
||||
|
||||
for (ec in config.elements) {
|
||||
val el = mapping[ec.element]!!
|
||||
@@ -119,8 +121,8 @@ private fun replaceElementRefs(config: Config, mapping: Map<ElementConfig, Eleme
|
||||
.partitionIsInstance<TypeRef, ElementRef>()
|
||||
el.elementParents = elParents.takeIf { it.isNotEmpty() || el == rootEl.element } ?: listOf(rootEl)
|
||||
el.otherParents = otherParents.castAll<ClassRef<*>>().toList()
|
||||
el.visitorParent = ec.visitorParent?.let(::transform) as ElementRef?
|
||||
el.transformerReturnType = (ec.transformerReturnType?.let(::transform) as ElementRef?)?.element
|
||||
el.visitorParent = ec.visitorParent?.let(::transform) as GenericElementRef<Element, Field>?
|
||||
el.transformerReturnType = (ec.transformerReturnType?.let(::transform) as GenericElementRef<Element, Field>?)?.element
|
||||
|
||||
for (field in el.fields) {
|
||||
when (field) {
|
||||
|
||||
+4
-2
@@ -15,6 +15,7 @@ import org.jetbrains.kotlin.ir.generator.model.*
|
||||
import org.jetbrains.kotlin.generators.tree.TypeRefWithNullability
|
||||
import org.jetbrains.kotlin.ir.generator.util.tryParameterizedBy
|
||||
import java.io.File
|
||||
import org.jetbrains.kotlin.generators.tree.ElementRef as GenericElementRef
|
||||
|
||||
fun printElements(generationPath: File, model: Model) = sequence {
|
||||
for (element in model.elements) {
|
||||
@@ -39,7 +40,7 @@ fun printElements(generationPath: File, model: Model) = sequence {
|
||||
)
|
||||
addTypeVariables(element.params.map { it.toPoet() })
|
||||
|
||||
val (classes, interfaces) = element.allParents.partition { it.typeKind == TypeKind.Class }
|
||||
val (classes, interfaces) = (element.elementParents + element.otherParents).partition { it.typeKind == TypeKind.Class }
|
||||
classes.singleOrNull()?.let {
|
||||
superclass(it.toPoet())
|
||||
}
|
||||
@@ -229,7 +230,8 @@ fun printElements(generationPath: File, model: Model) = sequence {
|
||||
args.add(dataParam)
|
||||
|
||||
if (child is SingleField) {
|
||||
val elRef = child.typeRef as ElementRef
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
val elRef = child.typeRef as GenericElementRef<Element, Field>
|
||||
if (!elRef.element.transform) {
|
||||
append(" as %T")
|
||||
if (child.nullable) append("?")
|
||||
|
||||
+4
-4
@@ -10,9 +10,9 @@ import org.jetbrains.kotlin.generators.tree.*
|
||||
import org.jetbrains.kotlin.ir.generator.config.ElementConfigOrRef
|
||||
import org.jetbrains.kotlin.ir.generator.model.Element
|
||||
import org.jetbrains.kotlin.ir.generator.model.Element.Companion.elementName2typeName
|
||||
import org.jetbrains.kotlin.ir.generator.model.ElementRef
|
||||
import org.jetbrains.kotlin.ir.generator.util.*
|
||||
import org.jetbrains.kotlin.types.Variance
|
||||
import org.jetbrains.kotlin.generators.tree.ElementRef as GenericElementRef
|
||||
|
||||
fun Element.toPoet() = ClassName(packageName, typeName)
|
||||
fun Element.toPoetSelfParameterized() = toPoet().parameterizedByIfAny(poetTypeVariables)
|
||||
@@ -21,7 +21,7 @@ val Element.poetTypeVariables get() = params.map { TypeVariableName(it.name) }
|
||||
|
||||
fun TypeRef.toPoet(): TypeName {
|
||||
return when (this) {
|
||||
is ElementRef -> ClassName(element.packageName, element.typeName).parameterizedByIfAny(typeArgsToPoet())
|
||||
is GenericElementRef<*, *> -> ClassName(element.packageName!!, element.type).parameterizedByIfAny(typeArgsToPoet())
|
||||
is ClassRef<*> -> ClassName(packageName, simpleNames).parameterizedByIfAny(typeArgsToPoet())
|
||||
is NamedTypeParameterRef -> TypeVariableName(name)
|
||||
is ElementConfigOrRef -> ClassName(this.element.category.packageName, elementName2typeName(element.name)).parameterizedByIfAny(
|
||||
@@ -50,7 +50,7 @@ private fun ParametrizedTypeRef<*, *>.typeArgsToPoet(): List<TypeName> {
|
||||
return fromPositional(args as Map<PositionTypeParameterRef, TypeRef>)
|
||||
} else {
|
||||
check(positional.isEmpty()) { "Can't yet handle mixed index-name args" }
|
||||
this as ElementRef // Named args must only be used with generated elements (for now)
|
||||
this as GenericElementRef<*, *> // Named args must only be used with generated elements (for now)
|
||||
|
||||
val args = args.entries
|
||||
.associate { p -> PositionTypeParameterRef(element.params.withIndex().single { it.value.name == p.key.name }.index) to p.value }
|
||||
@@ -68,7 +68,7 @@ fun TypeVariable.toPoet() = TypeVariableName(
|
||||
|
||||
val ClassOrElementRef.typeKind: TypeKind
|
||||
get() = when (this) {
|
||||
is ElementRef -> element.kind!!.typeKind
|
||||
is GenericElementRef<*, *> -> element.kind!!.typeKind
|
||||
is ClassRef<*> -> kind
|
||||
else -> error("Unexpected type: $this")
|
||||
}
|
||||
|
||||
+23
-11
@@ -8,27 +8,39 @@ package org.jetbrains.kotlin.generators.tree
|
||||
import org.jetbrains.kotlin.generators.tree.printer.generics
|
||||
|
||||
/**
|
||||
* A common interface representing a FIR or IR tree element.
|
||||
* A class representing a FIR or IR tree element.
|
||||
*/
|
||||
interface AbstractElement<Element, Field> : ElementOrRef<Element, Field>, FieldContainer, ImplementationKindOwner
|
||||
abstract class AbstractElement<Element, Field> : ElementOrRef<Element, Field>, FieldContainer, ImplementationKindOwner
|
||||
where Element : AbstractElement<Element, Field>,
|
||||
Field : AbstractField {
|
||||
|
||||
val name: String
|
||||
abstract val name: String
|
||||
|
||||
val fields: Set<Field>
|
||||
abstract val fields: Set<Field>
|
||||
|
||||
val params: List<TypeVariable>
|
||||
abstract val params: List<TypeVariable>
|
||||
|
||||
val parentRefs: List<ElementOrRef<Element, Field>>
|
||||
abstract val parentRefs: List<ElementOrRef<Element, Field>>
|
||||
|
||||
val overridenFields: Map<Field, Map<Field, Boolean>>
|
||||
|
||||
val isSealed: Boolean
|
||||
open val isSealed: Boolean
|
||||
get() = false
|
||||
|
||||
override val allParents: List<ImplementationKindOwner>
|
||||
override val allParents: List<Element>
|
||||
get() = parentRefs.map { it.element }
|
||||
|
||||
override fun getTypeWithArguments(notNull: Boolean): String = type + generics
|
||||
final override fun getTypeWithArguments(notNull: Boolean): String = type + generics
|
||||
|
||||
abstract override val allFields: List<Field>
|
||||
|
||||
final override fun get(fieldName: String): Field? {
|
||||
return allFields.firstOrNull { it.name == fieldName }
|
||||
}
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
final override fun copy(nullable: Boolean) =
|
||||
ElementRef(this as Element, args, nullable)
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
final override fun copy(args: Map<NamedTypeParameterRef, TypeRef>) =
|
||||
ElementRef(this as Element, args, nullable)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user