[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
@@ -78,7 +78,52 @@ abstract class AbstractElement<Element, Field>(
}
}
abstract override val allFields: List<Field>
override val allFields: List<Field> by lazy {
val result = LinkedHashSet<Field>()
result.addAll(fields.toList().asReversed())
result.forEach { overriddenFieldsHaveSameClass[it, it] = false }
for (parentField in parentFields.asReversed()) {
val overrides = !result.add(parentField)
if (overrides) {
val existingField = result.first { it == parentField }
existingField.fromParent = true
val haveSameClass = parentField.typeRef.copy(nullable = false) == existingField.typeRef.copy(nullable = false)
if (!haveSameClass) {
existingField.overriddenTypes += parentField.typeRef
}
overriddenFieldsHaveSameClass[existingField, parentField] = haveSameClass
existingField.updatePropertiesFromOverriddenField(parentField, haveSameClass)
} else {
overriddenFieldsHaveSameClass[parentField, parentField] = true
}
}
result.toList().asReversed()
}
val overriddenFieldsHaveSameClass: MutableMap<Field, MutableMap<Field, Boolean>> = mutableMapOf()
val parentFields: List<Field> by lazy {
val result = LinkedHashMap<String, Field>()
elementParents.forEach { parentRef ->
val parent = parentRef.element
val fields = parent.allFields.map { field ->
field.replaceType(field.typeRef.substitute(parentRef.args) as TypeRefWithNullability)
.apply {
fromParent = true
}
}
fields.forEach {
result.merge(it.name, it) { previousField, thisField ->
val resultField = previousField.copy()
if (thisField.isMutable) {
resultField.isMutable = true
}
resultField
}
}
}
result.values.toList()
}
/**
* A custom return type of the corresponding transformer method for this element.
@@ -27,6 +27,8 @@ abstract class AbstractElementPrinter<Element : AbstractElement<Element, Field>,
protected open val separateFieldsWithBlankLine: Boolean
get() = false
protected open fun filterFields(element: Element): Collection<Field> = element.allFields
context(ImportCollector)
fun printElement(element: Element) {
printer.run {
@@ -49,11 +51,9 @@ abstract class AbstractElementPrinter<Element : AbstractElement<Element, Field>,
val body = SmartPrinter(StringBuilder()).apply {
val fieldPrinter = makeFieldPrinter(this)
withIndent {
for (field in element.allFields) {
if (
!field.withGetter && field.defaultValueInImplementation == null && field.isFinal && field.fromParent ||
field.isParameter
) {
for (field in filterFields(element)) {
if (field.isParameter) continue
if (!field.withGetter && field.defaultValueInImplementation == null && field.isFinal && field.fromParent) {
continue
}
if (separateFieldsWithBlankLine) println()
@@ -28,7 +28,7 @@ abstract class AbstractField<Field : AbstractField<Field>> {
open var optInAnnotation: ClassRef<*>? = null
abstract val isMutable: Boolean
abstract var isMutable: Boolean
open val withGetter: Boolean get() = false
open val customSetter: String? get() = null
@@ -58,6 +58,10 @@ abstract class AbstractField<Field : AbstractField<Field>> {
*/
var needAcceptAndTransform: Boolean = true
open val overriddenTypes: MutableSet<TypeRefWithNullability> = mutableSetOf()
open fun updatePropertiesFromOverriddenField(parentField: Field, haveSameClass: Boolean) {}
override fun toString(): String {
return name
}
@@ -73,4 +77,14 @@ abstract class AbstractField<Field : AbstractField<Field>> {
override fun hashCode(): Int {
return name.hashCode()
}
/**
* Returns a copy of this field with its [typeRef] set to [newType] (if it's possible).
*/
abstract fun replaceType(newType: TypeRefWithNullability): Field
/**
* Returns a copy of this field.
*/
abstract fun copy(): Field
}
@@ -34,7 +34,9 @@ abstract class AbstractFieldPrinter<Field : AbstractField<Field>>(
modality: Modality? = null,
) {
printer.run {
printKDoc(field.kDoc)
if (!field.fromParent) {
printKDoc(field.kDoc)
}
field.deprecation?.let {
println("@Deprecated(")
@@ -107,4 +109,4 @@ abstract class AbstractFieldPrinter<Field : AbstractField<Field>>(
}
}
}
}
}
@@ -6,7 +6,12 @@
package org.jetbrains.kotlin.generators.tree
interface FieldContainer<out Field : AbstractField<*>> {
/**
* All the fields of this element, including the fields of all its parents.
*/
val allFields: List<Field>
operator fun get(fieldName: String): Field?
val hasAcceptMethod: Boolean
@@ -32,4 +37,4 @@ interface FieldContainer<out Field : AbstractField<*>> {
*/
val transformableChildren: List<Field>
get() = walkableChildren.filter { it.isMutable || it is ListField }
}
}
@@ -36,4 +36,14 @@ fun <Element : AbstractElement<Element, *>> detectBaseTransformerTypes(model: Mo
}
}
}
}
operator fun <K, V, U> MutableMap<K, MutableMap<V, U>>.set(k1: K, k2: V, value: U) {
this.putIfAbsent(k1, mutableMapOf())
val map = getValue(k1)
map[k2] = value
}
operator fun <K, V, U> Map<K, Map<V, U>>.get(k1: K, k2: V): U {
return getValue(k1).getValue(k2)
}