[FIR generator] Extract BaseTransformerTypeFinder into the common module
We want to use it in other tree generators.
This commit is contained in:
committed by
Space Team
parent
7787b53b4a
commit
62d32471e1
+19
@@ -79,6 +79,25 @@ abstract class AbstractElement<Element, Field>(
|
||||
|
||||
abstract override val transformableChildren: List<Field>
|
||||
|
||||
/**
|
||||
* A custom return type of the corresponding transformer method for this element.
|
||||
*/
|
||||
var transformerReturnType: Element? = null
|
||||
|
||||
/**
|
||||
* @see org.jetbrains.kotlin.generators.tree.detectBaseTransformerTypes
|
||||
*/
|
||||
internal var baseTransformerType: Element? = null
|
||||
|
||||
/**
|
||||
* The return type of the corresponding transformer method for this element.
|
||||
*
|
||||
* By default, computed using [org.jetbrains.kotlin.generators.tree.detectBaseTransformerTypes], but can be customizaed via
|
||||
* [transformerReturnType]
|
||||
*/
|
||||
val transformerClass: Element
|
||||
get() = transformerReturnType ?: baseTransformerType ?: element
|
||||
|
||||
final override fun get(fieldName: String): Field? {
|
||||
return allFields.firstOrNull { it.name == fieldName }
|
||||
}
|
||||
|
||||
+11
@@ -38,8 +38,19 @@ abstract class AbstractField {
|
||||
|
||||
var fromParent: Boolean = false
|
||||
|
||||
/**
|
||||
* Whether this field can contain an element either directly or e.g. in a list.
|
||||
*/
|
||||
open val containsElement: Boolean
|
||||
get() = typeRef is ElementOrRef<*, *> || this is ListField && baseType is ElementOrRef<*, *>
|
||||
|
||||
open val defaultValueInImplementation: String? get() = null
|
||||
|
||||
/**
|
||||
* @see org.jetbrains.kotlin.generators.tree.detectBaseTransformerTypes
|
||||
*/
|
||||
var useInBaseTransformerDetection = true
|
||||
|
||||
override fun toString(): String {
|
||||
return name
|
||||
}
|
||||
|
||||
+25
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
* Copyright 2010-2023 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.generators.tree
|
||||
|
||||
/**
|
||||
* A field that is used to store a list with arbitrary elements.
|
||||
*/
|
||||
interface ListField {
|
||||
|
||||
/**
|
||||
* The element type of the list.
|
||||
*/
|
||||
val baseType: TypeRef
|
||||
|
||||
/**
|
||||
* The list type of the field, e.g. [List] or [MutableList].
|
||||
*/
|
||||
val listType: ClassRef<PositionTypeParameterRef>
|
||||
|
||||
val typeRef: ClassRef<PositionTypeParameterRef>
|
||||
get() = listType.withArgs(baseType)
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* Copyright 2010-2023 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.generators.tree
|
||||
|
||||
fun <Element : AbstractElement<Element, *>> Element.traverseParents(block: (Element) -> Unit) {
|
||||
block(this)
|
||||
elementParents.forEach { it.element.traverseParents(block) }
|
||||
}
|
||||
|
||||
/**
|
||||
* For each tree element, sets its [AbstractElement.baseTransformerType] to one of it parents if that parent type is used at least once as
|
||||
* a type of a field, except when that field is explicitly opted out of it via
|
||||
* [AbstractField.useInBaseTransformerDetection].
|
||||
*/
|
||||
fun <Element : AbstractElement<Element, *>> detectBaseTransformerTypes(model: Model<Element>) {
|
||||
val usedAsFieldType = hashSetOf<AbstractElement<*, *>>()
|
||||
for (element in model.elements) {
|
||||
for (field in element.allFields.filter { it.containsElement }) {
|
||||
if (!field.useInBaseTransformerDetection) continue
|
||||
val fieldElement = (field.typeRef as? ElementOrRef<*, *>)?.element
|
||||
?: ((field as? ListField)?.baseType as? ElementOrRef<*, *>)?.element
|
||||
?: continue
|
||||
if (fieldElement.isRootElement) continue
|
||||
usedAsFieldType.add(fieldElement)
|
||||
}
|
||||
}
|
||||
|
||||
for (element in model.elements) {
|
||||
element.traverseParents {
|
||||
if (it in usedAsFieldType) {
|
||||
element.baseTransformerType = it
|
||||
return@traverseParents
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user