[FIR/IR generator] Factor out walkableChildren and transformableChildren

This commit is contained in:
Sergej Jaskiewicz
2023-11-14 18:21:08 +01:00
committed by Space Team
parent 13ae129505
commit c6eb7d6c21
9 changed files with 35 additions and 40 deletions
@@ -112,7 +112,6 @@ class FieldWithDefault(val origin: Field) : Field() {
override var withGetter: Boolean = false override var withGetter: Boolean = false
override var customSetter: String? = null override var customSetter: String? = null
override var fromDelegate: Boolean = false override var fromDelegate: Boolean = false
var needAcceptAndTransform: Boolean = true
override val overridenTypes: MutableSet<TypeRefWithNullability> override val overridenTypes: MutableSet<TypeRefWithNullability>
get() = origin.overridenTypes get() = origin.overridenTypes
@@ -64,12 +64,6 @@ class Implementation(val element: Element, val name: String?) : FieldContainer,
override val hasTransformChildrenMethod: Boolean override val hasTransformChildrenMethod: Boolean
get() = true get() = true
override val walkableChildren: List<FieldWithDefault>
get() = allFields.filter { it.containsElement && !it.withGetter && it.needAcceptAndTransform }
override val transformableChildren: List<FieldWithDefault>
get() = walkableChildren.filter { it.isMutable }
override fun get(fieldName: String): FieldWithDefault? { override fun get(fieldName: String): FieldWithDefault? {
return allFields.firstOrNull { it.name == fieldName } return allFields.firstOrNull { it.name == fieldName }
} }
@@ -159,6 +159,7 @@ 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"]!!
@@ -225,6 +226,7 @@ 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"]!!
@@ -18,7 +18,7 @@ import org.jetbrains.kotlin.ir.generator.model.Element
import org.jetbrains.kotlin.ir.generator.model.Element.Category.* import org.jetbrains.kotlin.ir.generator.model.Element.Category.*
import org.jetbrains.kotlin.ir.generator.model.ListField.Mutability.* import org.jetbrains.kotlin.ir.generator.model.ListField.Mutability.*
import org.jetbrains.kotlin.ir.generator.model.ListField.Mutability.Array import org.jetbrains.kotlin.ir.generator.model.ListField.Mutability.Array
import org.jetbrains.kotlin.ir.generator.model.ListField.Mutability.List import org.jetbrains.kotlin.ir.generator.model.ListField.Mutability.MutableList
import org.jetbrains.kotlin.ir.generator.model.SingleField import org.jetbrains.kotlin.ir.generator.model.SingleField
import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.Name
@@ -338,7 +338,7 @@ object IrTree : AbstractTreeBuilder() {
parent(declarationParent) parent(declarationParent)
+listField("declarations", declaration, mutability = List, isChild = true) { +listField("declarations", declaration, mutability = MutableList, isChild = true) {
kDoc = """ kDoc = """
Accessing list of declaration may trigger lazy declaration list computation for lazy class, Accessing list of declaration may trigger lazy declaration list computation for lazy class,
which requires computation of fake-overrides for this class. So it's unsafe to access it which requires computation of fake-overrides for this class. So it's unsafe to access it
@@ -482,7 +482,7 @@ object IrTree : AbstractTreeBuilder() {
} }
+field("name", type<Name>(), mutable = false) +field("name", type<Name>(), mutable = false)
+field("irBuiltins", type(Packages.tree, "IrBuiltIns"), mutable = false) +field("irBuiltins", type(Packages.tree, "IrBuiltIns"), mutable = false)
+listField("files", file, mutability = List, isChild = true) +listField("files", file, mutability = MutableList, isChild = true)
usedTypes += ArbitraryImportable(Packages.tree, "UNDEFINED_OFFSET") usedTypes += ArbitraryImportable(Packages.tree, "UNDEFINED_OFFSET")
+field("startOffset", int, mutable = false) { +field("startOffset", int, mutable = false) {
baseGetter = "UNDEFINED_OFFSET" baseGetter = "UNDEFINED_OFFSET"
@@ -661,7 +661,7 @@ object IrTree : AbstractTreeBuilder() {
val statementContainer: Element by element(Expression) { val statementContainer: Element by element(Expression) {
ownsChildren = false ownsChildren = false
+listField("statements", statement, mutability = List, isChild = true) +listField("statements", statement, mutability = MutableList, isChild = true)
} }
val body: Element by element(Expression) { val body: Element by element(Expression) {
needTransformMethod() needTransformMethod()
@@ -831,7 +831,7 @@ object IrTree : AbstractTreeBuilder() {
parent(statementContainer) parent(statementContainer)
+field("origin", statementOriginType, nullable = true) +field("origin", statementOriginType, nullable = true)
+listField("statements", statement, mutability = List, isChild = true) { +listField("statements", statement, mutability = MutableList, isChild = true) {
baseDefaultValue = "ArrayList(2)" baseDefaultValue = "ArrayList(2)"
} }
} }
@@ -965,13 +965,13 @@ object IrTree : AbstractTreeBuilder() {
parent(constantValue) parent(constantValue)
+field("constructor", constructorSymbolType) +field("constructor", constructorSymbolType)
+listField("valueArguments", constantValue, mutability = List, isChild = true) +listField("valueArguments", constantValue, mutability = MutableList, isChild = true)
+listField("typeArguments", irTypeType, mutability = List) +listField("typeArguments", irTypeType, mutability = MutableList)
} }
val constantArray: Element by element(Expression) { val constantArray: Element by element(Expression) {
parent(constantValue) parent(constantValue)
+listField("elements", constantValue, mutability = List, isChild = true) +listField("elements", constantValue, mutability = MutableList, isChild = true)
} }
val delegatingConstructorCall: Element by element(Expression) { val delegatingConstructorCall: Element by element(Expression) {
parent(functionAccessExpression) parent(functionAccessExpression)
@@ -986,7 +986,7 @@ object IrTree : AbstractTreeBuilder() {
+field("operator", type(Packages.exprs, "IrDynamicOperator")) +field("operator", type(Packages.exprs, "IrDynamicOperator"))
+field("receiver", expression, isChild = true) +field("receiver", expression, isChild = true)
+listField("arguments", expression, mutability = List, isChild = true) +listField("arguments", expression, mutability = MutableList, isChild = true)
} }
val dynamicMemberExpression: Element by element(Expression) { val dynamicMemberExpression: Element by element(Expression) {
parent(dynamicExpression) parent(dynamicExpression)
@@ -1010,7 +1010,7 @@ object IrTree : AbstractTreeBuilder() {
parent(errorExpression) parent(errorExpression)
+field("explicitReceiver", expression, nullable = true, isChild = true) +field("explicitReceiver", expression, nullable = true, isChild = true)
+listField("arguments", expression, mutability = List, isChild = true) +listField("arguments", expression, mutability = MutableList, isChild = true)
} }
val fieldAccessExpression: Element by element(Expression) { val fieldAccessExpression: Element by element(Expression) {
nameInVisitorMethod = "FieldAccess" nameInVisitorMethod = "FieldAccess"
@@ -1086,7 +1086,7 @@ object IrTree : AbstractTreeBuilder() {
val stringConcatenation: Element by element(Expression) { val stringConcatenation: Element by element(Expression) {
parent(expression) parent(expression)
+listField("arguments", expression, mutability = List, isChild = true) +listField("arguments", expression, mutability = MutableList, isChild = true)
} }
val suspensionPoint: Element by element(Expression) { val suspensionPoint: Element by element(Expression) {
parent(expression) parent(expression)
@@ -1112,7 +1112,7 @@ object IrTree : AbstractTreeBuilder() {
parent(expression) parent(expression)
+field("tryResult", expression, isChild = true) +field("tryResult", expression, isChild = true)
+listField("catches", catch, mutability = List, isChild = true) +listField("catches", catch, mutability = MutableList, isChild = true)
+field("finallyExpression", expression, nullable = true, isChild = true) +field("finallyExpression", expression, nullable = true, isChild = true)
} }
val catch: Element by element(Expression) { val catch: Element by element(Expression) {
@@ -1153,7 +1153,7 @@ object IrTree : AbstractTreeBuilder() {
parent(expression) parent(expression)
+field("varargElementType", irTypeType) +field("varargElementType", irTypeType)
+listField("elements", varargElement, mutability = List, isChild = true) +listField("elements", varargElement, mutability = MutableList, isChild = true)
} }
val spreadElement: Element by element(Expression) { val spreadElement: Element by element(Expression) {
visitorParameterName = "spread" visitorParameterName = "spread"
@@ -1168,7 +1168,7 @@ object IrTree : AbstractTreeBuilder() {
parent(expression) parent(expression)
+field("origin", statementOriginType, nullable = true) +field("origin", statementOriginType, nullable = true)
+listField("branches", branch, mutability = List, isChild = true) +listField("branches", branch, mutability = MutableList, isChild = true)
} }
val branch: Element by element(Expression) { val branch: Element by element(Expression) {
visitorParameterName = "branch" visitorParameterName = "branch"
@@ -86,13 +86,13 @@ abstract class AbstractTreeBuilder {
name: String, name: String,
elementType: TypeRef?, elementType: TypeRef?,
nullable: Boolean = false, nullable: Boolean = false,
mutability: ListField.Mutability = ListField.Mutability.Immutable, mutability: ListField.Mutability,
isChild: Boolean = false, isChild: Boolean = false,
initializer: ListField.() -> Unit = {} initializer: ListField.() -> Unit = {}
): ListField { ): ListField {
checkChildType(isChild, elementType, name) checkChildType(isChild, elementType, name)
val listType = when (mutability) { val listType = when (mutability) {
ListField.Mutability.List -> StandardTypes.mutableList ListField.Mutability.MutableList -> StandardTypes.mutableList
ListField.Mutability.Array -> StandardTypes.array ListField.Mutability.Array -> StandardTypes.array
else -> StandardTypes.list else -> StandardTypes.list
} }
@@ -103,7 +103,6 @@ abstract class AbstractTreeBuilder {
isNullable = nullable, isNullable = nullable,
mutable = mutability == ListField.Mutability.Var, mutable = mutability == ListField.Mutability.Var,
isChild = isChild, isChild = isChild,
transformable = mutability != ListField.Mutability.Immutable,
).apply(initializer) ).apply(initializer)
} }
@@ -96,7 +96,6 @@ class Element(
var childrenOrderOverride: List<String>? = null var childrenOrderOverride: List<String>? = null
override var walkableChildren: List<Field> = emptyList() override var walkableChildren: List<Field> = emptyList()
override val transformableChildren get() = walkableChildren.filter { it.transformable }
override var visitorParameterName = category.defaultVisitorParam override var visitorParameterName = category.defaultVisitorParam
@@ -168,8 +167,6 @@ sealed class Field(
var baseDefaultValue: String? = null var baseDefaultValue: String? = null
var baseGetter: String? = null var baseGetter: String? = null
abstract val transformable: Boolean
sealed class UseFieldAsParameterInIrFactoryStrategy { sealed class UseFieldAsParameterInIrFactoryStrategy {
data object No : UseFieldAsParameterInIrFactoryStrategy() data object No : UseFieldAsParameterInIrFactoryStrategy()
@@ -208,10 +205,7 @@ class SingleField(
override var typeRef: TypeRefWithNullability, override var typeRef: TypeRefWithNullability,
mutable: Boolean, mutable: Boolean,
isChild: Boolean, isChild: Boolean,
) : Field(name, mutable, isChild) { ) : Field(name, mutable, isChild)
override val transformable: Boolean
get() = isMutable
}
class ListField( class ListField(
name: String, name: String,
@@ -220,16 +214,14 @@ class ListField(
override val listType: ClassRef<PositionTypeParameterRef>, override val listType: ClassRef<PositionTypeParameterRef>,
mutable: Boolean, mutable: Boolean,
isChild: Boolean, isChild: Boolean,
override val transformable: Boolean,
) : Field(name, mutable, isChild), AbstractListField { ) : Field(name, mutable, isChild), AbstractListField {
override val typeRef: ClassRef<PositionTypeParameterRef> override val typeRef: ClassRef<PositionTypeParameterRef>
get() = listType.withArgs(baseType).copy(isNullable) get() = listType.withArgs(baseType).copy(isNullable)
enum class Mutability { enum class Mutability {
Immutable,
Var, Var,
List, MutableList,
Array Array
} }
} }
@@ -80,10 +80,6 @@ abstract class AbstractElement<Element, Field>(
abstract override val allFields: List<Field> abstract override val allFields: List<Field>
abstract override val walkableChildren: List<Field>
abstract override val transformableChildren: List<Field>
/** /**
* A custom return type of the corresponding transformer method for this element. * A custom return type of the corresponding transformer method for this element.
*/ */
@@ -51,6 +51,13 @@ abstract class AbstractField {
*/ */
var useInBaseTransformerDetection = true var useInBaseTransformerDetection = true
/**
* Whether a visitor should be run on this field in the generated `acceptChildren` in `transformChildren` method.
*
* Only has effect if [containsElement] is `true`.
*/
var needAcceptAndTransform: Boolean = true
override fun toString(): String { override fun toString(): String {
return name return name
} }
@@ -21,9 +21,15 @@ interface FieldContainer {
val hasTransformChildrenMethod: Boolean val hasTransformChildrenMethod: Boolean
get() = false get() = false
/**
* The fields on which to run the visitor in generated `acceptChildren` methods.
*/
val walkableChildren: List<AbstractField> val walkableChildren: List<AbstractField>
get() = emptyList() get() = allFields.filter { it.containsElement && !it.withGetter && it.needAcceptAndTransform }
/**
* The fields on which to run the transformer in generated `transformChildren` methods.
*/
val transformableChildren: List<AbstractField> val transformableChildren: List<AbstractField>
get() = emptyList() get() = walkableChildren.filter { it.isMutable || it is ListField }
} }