[FIR/IR generator] Make AbstractField generic over itself

This will make some code more type-safe.
This commit is contained in:
Sergej Jaskiewicz
2023-11-14 19:04:31 +01:00
committed by Space Team
parent c6eb7d6c21
commit 38ee477ab4
14 changed files with 21 additions and 23 deletions
@@ -9,7 +9,7 @@ import org.jetbrains.kotlin.generators.tree.*
private const val DEFAULT_BUILDER_PACKAGE = "org.jetbrains.kotlin.fir.tree.builder" private const val DEFAULT_BUILDER_PACKAGE = "org.jetbrains.kotlin.fir.tree.builder"
sealed class Builder : FieldContainer, TypeRef, Importable { sealed class Builder : FieldContainer<FieldWithDefault>, TypeRef, Importable {
val parents: MutableList<IntermediateBuilder> = mutableListOf() val parents: MutableList<IntermediateBuilder> = mutableListOf()
val usedTypes: MutableList<Importable> = mutableListOf() val usedTypes: MutableList<Importable> = mutableListOf()
abstract override val allFields: List<FieldWithDefault> abstract override val allFields: List<FieldWithDefault>
@@ -7,7 +7,7 @@ package org.jetbrains.kotlin.fir.tree.generator.model
import org.jetbrains.kotlin.generators.tree.* import org.jetbrains.kotlin.generators.tree.*
sealed class Field : AbstractField() { sealed class Field : AbstractField<Field>() {
open var withReplace: Boolean = false open var withReplace: Boolean = false
open var needsSeparateTransform: Boolean = false open var needsSeparateTransform: Boolean = false
@@ -7,7 +7,7 @@ package org.jetbrains.kotlin.fir.tree.generator.model
import org.jetbrains.kotlin.generators.tree.* import org.jetbrains.kotlin.generators.tree.*
class Implementation(val element: Element, val name: String?) : FieldContainer, ImplementationKindOwner { class Implementation(val element: Element, val name: String?) : FieldContainer<FieldWithDefault>, ImplementationKindOwner {
override val allParents: List<ImplementationKindOwner> get() = listOf(element) override val allParents: List<ImplementationKindOwner> get() = listOf(element)
val isDefault = name == null val isDefault = name == null
override val typeName = name ?: (element.typeName + "Impl") override val typeName = name ?: (element.typeName + "Impl")
@@ -159,7 +159,6 @@ fun SmartPrinter.printImplementation(implementation: Implementation) {
println() println()
withIndent { withIndent {
for (field in walkableFields) { for (field in walkableFields) {
check(field is FieldWithDefault)
when (field.name) { when (field.name) {
"explicitReceiver" -> { "explicitReceiver" -> {
val explicitReceiver = implementation["explicitReceiver"]!! val explicitReceiver = implementation["explicitReceiver"]!!
@@ -226,7 +225,6 @@ fun SmartPrinter.printImplementation(implementation: Implementation) {
if (!isInterface && !isAbstract) { if (!isInterface && !isAbstract) {
printBlock { printBlock {
for (field in transformableChildren) { for (field in transformableChildren) {
check(field is FieldWithDefault)
when { when {
field.name == "explicitReceiver" -> { field.name == "explicitReceiver" -> {
val explicitReceiver = implementation["explicitReceiver"]!! val explicitReceiver = implementation["explicitReceiver"]!!
@@ -163,7 +163,7 @@ sealed class Field(
override val name: String, override val name: String,
override var isMutable: Boolean, override var isMutable: Boolean,
val isChild: Boolean, val isChild: Boolean,
) : AbstractField() { ) : AbstractField<Field>() {
var baseDefaultValue: String? = null var baseDefaultValue: String? = null
var baseGetter: String? = null var baseGetter: String? = null
@@ -10,9 +10,9 @@ package org.jetbrains.kotlin.generators.tree
*/ */
abstract class AbstractElement<Element, Field>( abstract class AbstractElement<Element, Field>(
val name: String, val name: String,
) : ElementOrRef<Element, Field>, FieldContainer, ImplementationKindOwner ) : ElementOrRef<Element, Field>, FieldContainer<Field>, ImplementationKindOwner
where Element : AbstractElement<Element, Field>, where Element : AbstractElement<Element, Field>,
Field : AbstractField { Field : AbstractField<Field> {
/** /**
* The fully-qualified name of the property in the tree generator that is used to configure this element. * The fully-qualified name of the property in the tree generator that is used to configure this element.
@@ -13,7 +13,7 @@ import org.jetbrains.kotlin.utils.withIndent
/** /**
* A common class for printing FIR or IR tree elements. * A common class for printing FIR or IR tree elements.
*/ */
abstract class AbstractElementPrinter<Element : AbstractElement<Element, Field>, Field : AbstractField>( abstract class AbstractElementPrinter<Element : AbstractElement<Element, Field>, Field : AbstractField<Field>>(
private val printer: SmartPrinter, private val printer: SmartPrinter,
) { ) {
@@ -5,7 +5,7 @@
package org.jetbrains.kotlin.generators.tree package org.jetbrains.kotlin.generators.tree
abstract class AbstractField { abstract class AbstractField<Field : AbstractField<Field>> {
abstract val name: String abstract val name: String
@@ -66,7 +66,7 @@ abstract class AbstractField {
if (this === other) return true if (this === other) return true
if (other == null) return false if (other == null) return false
if (javaClass != other.javaClass) return false if (javaClass != other.javaClass) return false
other as AbstractField other as AbstractField<*>
return name == other.name return name == other.name
} }
@@ -11,7 +11,7 @@ import org.jetbrains.kotlin.util.capitalizeDecapitalize.toLowerCaseAsciiOnly
import org.jetbrains.kotlin.utils.SmartPrinter import org.jetbrains.kotlin.utils.SmartPrinter
import org.jetbrains.kotlin.utils.withIndent import org.jetbrains.kotlin.utils.withIndent
abstract class AbstractFieldPrinter<Field : AbstractField>( abstract class AbstractFieldPrinter<Field : AbstractField<Field>>(
private val printer: SmartPrinter, private val printer: SmartPrinter,
) { ) {
@@ -11,7 +11,7 @@ import org.jetbrains.kotlin.types.Variance
import org.jetbrains.kotlin.utils.SmartPrinter import org.jetbrains.kotlin.utils.SmartPrinter
import org.jetbrains.kotlin.utils.withIndent import org.jetbrains.kotlin.utils.withIndent
abstract class AbstractVisitorPrinter<Element : AbstractElement<Element, Field>, Field : AbstractField>( abstract class AbstractVisitorPrinter<Element : AbstractElement<Element, Field>, Field : AbstractField<Field>>(
val printer: SmartPrinter, val printer: SmartPrinter,
) { ) {
@@ -13,7 +13,7 @@ abstract class AbstractVisitorVoidPrinter<Element, Field>(
printer: SmartPrinter, printer: SmartPrinter,
) : AbstractVisitorPrinter<Element, Field>(printer) ) : AbstractVisitorPrinter<Element, Field>(printer)
where Element : AbstractElement<Element, Field>, where Element : AbstractElement<Element, Field>,
Field : AbstractField { Field : AbstractField<Field> {
final override val visitorTypeParameters: List<TypeVariable> final override val visitorTypeParameters: List<TypeVariable>
get() = emptyList() get() = emptyList()
@@ -5,9 +5,9 @@
package org.jetbrains.kotlin.generators.tree package org.jetbrains.kotlin.generators.tree
interface FieldContainer { interface FieldContainer<out Field : AbstractField<*>> {
val allFields: List<AbstractField> val allFields: List<Field>
operator fun get(fieldName: String): AbstractField? operator fun get(fieldName: String): Field?
val hasAcceptMethod: Boolean val hasAcceptMethod: Boolean
get() = false get() = false
@@ -24,12 +24,12 @@ interface FieldContainer {
/** /**
* The fields on which to run the visitor in generated `acceptChildren` methods. * The fields on which to run the visitor in generated `acceptChildren` methods.
*/ */
val walkableChildren: List<AbstractField> val walkableChildren: List<Field>
get() = allFields.filter { it.containsElement && !it.withGetter && it.needAcceptAndTransform } get() = allFields.filter { it.containsElement && !it.withGetter && it.needAcceptAndTransform }
/** /**
* The fields on which to run the transformer in generated `transformChildren` methods. * The fields on which to run the transformer in generated `transformChildren` methods.
*/ */
val transformableChildren: List<AbstractField> val transformableChildren: List<Field>
get() = walkableChildren.filter { it.isMutable || it is ListField } get() = walkableChildren.filter { it.isMutable || it is ListField }
} }
@@ -130,13 +130,13 @@ data class TypeRefWithVariance<out T : TypeRef>(val variance: Variance, val type
interface ElementOrRef<Element, Field> : ParametrizedTypeRef<ElementOrRef<Element, Field>, NamedTypeParameterRef>, ClassOrElementRef interface ElementOrRef<Element, Field> : ParametrizedTypeRef<ElementOrRef<Element, Field>, NamedTypeParameterRef>, ClassOrElementRef
where Element : AbstractElement<Element, Field>, where Element : AbstractElement<Element, Field>,
Field : AbstractField { Field : AbstractField<Field> {
val element: Element val element: Element
override fun copy(nullable: Boolean): ElementRef<Element, Field> override fun copy(nullable: Boolean): ElementRef<Element, Field>
} }
data class ElementRef<Element : AbstractElement<Element, Field>, Field : AbstractField>( data class ElementRef<Element : AbstractElement<Element, Field>, Field : AbstractField<Field>>(
override val element: Element, override val element: Element,
override val args: Map<NamedTypeParameterRef, TypeRef> = emptyMap(), override val args: Map<NamedTypeParameterRef, TypeRef> = emptyMap(),
override val nullable: Boolean = false, override val nullable: Boolean = false,
@@ -280,7 +280,7 @@ fun SmartPrinter.printTransformMethod(
context(ImportCollector) context(ImportCollector)
fun SmartPrinter.printAcceptChildrenMethod( fun SmartPrinter.printAcceptChildrenMethod(
element: FieldContainer, element: FieldContainer<*>,
visitorClass: ClassRef<PositionTypeParameterRef>, visitorClass: ClassRef<PositionTypeParameterRef>,
visitorResultType: TypeRef, visitorResultType: TypeRef,
modality: Modality? = null, modality: Modality? = null,
@@ -315,7 +315,7 @@ fun SmartPrinter.printAcceptChildrenMethod(
context(ImportCollector) context(ImportCollector)
fun SmartPrinter.printTransformChildrenMethod( fun SmartPrinter.printTransformChildrenMethod(
element: FieldContainer, element: FieldContainer<*>,
transformerClass: ClassRef<PositionTypeParameterRef>, transformerClass: ClassRef<PositionTypeParameterRef>,
returnType: TypeRef, returnType: TypeRef,
modality: Modality? = null, modality: Modality? = null,