[FIR/IR generator] Factor out allFields to AbstractElement

This commit is contained in:
Sergej Jaskiewicz
2023-11-14 19:45:41 +01:00
committed by Space Team
parent 38ee477ab4
commit ad4e97154f
17 changed files with 153 additions and 178 deletions
@@ -12,7 +12,6 @@ import org.jetbrains.kotlin.generators.util.GeneratorsFileUtil.collectPreviously
import org.jetbrains.kotlin.generators.util.GeneratorsFileUtil.removeExtraFilesFromPreviousGeneration
import org.jetbrains.kotlin.ir.generator.model.addWalkableChildren
import org.jetbrains.kotlin.ir.generator.model.markLeaves
import org.jetbrains.kotlin.ir.generator.model.processFieldOverrides
import org.jetbrains.kotlin.ir.generator.print.*
import java.io.File
@@ -29,7 +28,6 @@ fun main(args: Array<String>) {
InterfaceAndAbstractClassConfigurator(model.elements).configureInterfacesAndAbstractClasses()
addPureAbstractElement(model.elements, elementBaseType)
markLeaves(model.elements)
processFieldOverrides(model.elements)
addWalkableChildren(model.elements)
val previouslyGeneratedFiles = collectPreviouslyGeneratedFiles(generationPath)
@@ -72,19 +72,19 @@ abstract class AbstractTreeBuilder {
protected fun field(
name: String,
type: TypeRefWithNullability?,
type: TypeRefWithNullability,
nullable: Boolean = false,
mutable: Boolean = true,
isChild: Boolean = false,
initializer: SingleField.() -> Unit = {}
): SingleField {
checkChildType(isChild, type, name)
return SingleField(name, type?.copy(nullable) ?: InferredOverriddenType, mutable, isChild).apply(initializer)
return SingleField(name, type.copy(nullable), mutable, isChild).apply(initializer)
}
protected fun listField(
name: String,
elementType: TypeRef?,
elementType: TypeRef,
nullable: Boolean = false,
mutability: ListField.Mutability,
isChild: Boolean = false,
@@ -98,7 +98,7 @@ abstract class AbstractTreeBuilder {
}
return ListField(
name = name,
baseType = elementType ?: InferredOverriddenType,
baseType = elementType,
listType = listType,
isNullable = nullable,
mutable = mutability == ListField.Mutability.Var,
@@ -42,10 +42,6 @@ class Element(
var generateIrFactoryMethod = category == Category.Declaration
val fieldsToSkipInIrFactoryMethod = hashSetOf<String>()
override val allFields: List<Field>
get() = fields.toList()
override val element: Element
get() = this
@@ -124,29 +120,6 @@ class Element(
override fun toString() = name
fun elementParentsRecursively(): List<ElementRef> {
val linkedSet = buildSet {
fun recurse(element: Element) {
addAll(element.elementParents)
element.elementParents.forEach { recurse(it.element) }
}
recurse(this@Element)
}
return topologicalSort(linkedSet) {
element.elementParents
}
}
fun allFieldsRecursively(): List<Field> {
val parentFields = elementParentsRecursively()
.reversed()
.flatMap { it.element.fields }
return (parentFields + fields)
.asReversed()
.distinctBy { it.name }
.asReversed()
}
operator fun TypeVariable.unaryPlus() = apply {
params.add(this)
}
@@ -198,6 +171,24 @@ sealed class Field(
override val isParameter: Boolean
get() = false
override fun copy() = internalCopy().also(::updateFieldsInCopy)
protected fun updateFieldsInCopy(copy: Field) {
copy.useInBaseTransformerDetection = useInBaseTransformerDetection
copy.isMutable = isMutable
copy.optInAnnotation = optInAnnotation
copy.baseDefaultValue = baseDefaultValue
copy.baseGetter = baseGetter
copy.useInIrFactoryStrategy = useInIrFactoryStrategy
copy.fromParent = fromParent
copy.customSetter = customSetter
copy.visibility = visibility
copy.deprecation = deprecation
copy.kDoc = kDoc
}
protected abstract fun internalCopy(): Field
}
class SingleField(
@@ -205,7 +196,13 @@ class SingleField(
override var typeRef: TypeRefWithNullability,
mutable: Boolean,
isChild: Boolean,
) : Field(name, mutable, isChild)
) : Field(name, mutable, isChild) {
override fun replaceType(newType: TypeRefWithNullability) =
SingleField(name, newType, isMutable, isChild).also(::updateFieldsInCopy)
override fun internalCopy() = SingleField(name, typeRef, isMutable, isChild)
}
class ListField(
name: String,
@@ -219,6 +216,10 @@ class ListField(
override val typeRef: ClassRef<PositionTypeParameterRef>
get() = listType.withArgs(baseType).copy(isNullable)
override fun replaceType(newType: TypeRefWithNullability) = copy()
override fun internalCopy() = ListField(name, baseType, isNullable, listType, isMutable, isChild)
enum class Mutability {
Var,
MutableList,
@@ -7,21 +7,6 @@ package org.jetbrains.kotlin.ir.generator.model
import org.jetbrains.kotlin.generators.tree.*
internal object InferredOverriddenType : TypeRefWithNullability {
context(ImportCollector)
override fun renderTo(appendable: Appendable) {
renderingIsNotSupported()
}
override fun substitute(map: TypeParameterSubstitutionMap) = this
override val nullable: Boolean
get() = false
override fun copy(nullable: Boolean) = this
}
typealias Model = org.jetbrains.kotlin.generators.tree.Model<Element>
internal fun markLeaves(elements: List<Element>) {
@@ -40,39 +25,6 @@ internal fun markLeaves(elements: List<Element>) {
}
}
internal fun processFieldOverrides(elements: List<Element>) {
for (element in iterateElementsParentFirst(elements)) {
for (field in element.fields) {
fun visitParents(visited: Element) {
for (parent in visited.elementParents) {
val overriddenField = parent.element.fields.singleOrNull { it.name == field.name }
if (overriddenField != null) {
field.fromParent = true
field.optInAnnotation = field.optInAnnotation ?: overriddenField.optInAnnotation
fun transformInferredType(type: TypeRef, overriddenType: TypeRef) =
type.takeUnless { it is InferredOverriddenType } ?: overriddenType
when (field) {
is SingleField -> {
field.typeRef =
transformInferredType(field.typeRef, (overriddenField as SingleField).typeRef) as TypeRefWithNullability
}
is ListField -> {
field.baseType = transformInferredType(field.baseType, (overriddenField as ListField).baseType)
}
}
break
}
visitParents(parent.element)
}
}
visitParents(element)
}
}
}
internal fun addWalkableChildren(elements: List<Element>) {
for (element in elements) {
@@ -11,11 +11,12 @@ import org.jetbrains.kotlin.ir.generator.BASE_PACKAGE
import org.jetbrains.kotlin.ir.generator.TREE_GENERATOR_README
import org.jetbrains.kotlin.ir.generator.elementTransformerType
import org.jetbrains.kotlin.ir.generator.elementVisitorType
import org.jetbrains.kotlin.ir.generator.model.*
import org.jetbrains.kotlin.ir.generator.model.Element
import org.jetbrains.kotlin.ir.generator.model.Field
import org.jetbrains.kotlin.ir.generator.model.ListField
import org.jetbrains.kotlin.ir.generator.model.Model
import org.jetbrains.kotlin.ir.generator.model.SingleField
import org.jetbrains.kotlin.utils.SmartPrinter
import org.jetbrains.kotlin.utils.withIndent
import java.io.File
import org.jetbrains.kotlin.generators.tree.ElementRef as GenericElementRef
@@ -34,6 +35,16 @@ private class ElementPrinter(printer: SmartPrinter) : AbstractElementPrinter<Ele
override val separateFieldsWithBlankLine: Boolean
get() = true
// In IR classes we only print fields that are either declared in this element, or refine the type of a parent field
// and thus need an override.
override fun filterFields(element: Element): Collection<Field> = element.fields.map { field ->
field.copy().apply {
if (field in element.parentFields) {
fromParent = true
}
}
}
context(ImportCollector)
override fun SmartPrinter.printAdditionalMethods(element: Element) {
element.generationCallback?.invoke(this@ImportCollector, this)
@@ -255,7 +255,7 @@ private class FactoryMethod(val element: Element) {
val name = "create" + element.name.capitalizeAsciiOnly()
val parameters = (element.allFieldsRecursively() + element.additionalIrFactoryMethodParameters)
val parameters = (element.allFields + element.additionalIrFactoryMethodParameters)
.filterNot { it.name in element.fieldsToSkipInIrFactoryMethod }
.mapNotNull { field ->
(field.useInIrFactoryStrategy as? Field.UseFieldAsParameterInIrFactoryStrategy.Yes)?.let {