[FIR] Add replaceCalleeReference to all FirResolvable
Also improve tree generator: now it generates abstract overrides for `replace` functions and correctly generates replace for fields with overriden type
This commit is contained in:
+3
-2
@@ -8,6 +8,7 @@ package org.jetbrains.kotlin.fir.tree.generator
|
||||
import org.jetbrains.kotlin.fir.tree.generator.FieldSets.annotations
|
||||
import org.jetbrains.kotlin.fir.tree.generator.FieldSets.arguments
|
||||
import org.jetbrains.kotlin.fir.tree.generator.FieldSets.body
|
||||
import org.jetbrains.kotlin.fir.tree.generator.FieldSets.calleeReference
|
||||
import org.jetbrains.kotlin.fir.tree.generator.FieldSets.classKind
|
||||
import org.jetbrains.kotlin.fir.tree.generator.FieldSets.controlFlowGraphReferenceField
|
||||
import org.jetbrains.kotlin.fir.tree.generator.FieldSets.declarations
|
||||
@@ -62,7 +63,7 @@ object NodeConfigurator : AbstractFieldConfigurator<FirTreeBuilder>(FirTreeBuild
|
||||
}
|
||||
|
||||
resolvable.configure {
|
||||
+field("calleeReference", reference).withTransform()
|
||||
+calleeReference.withTransform()
|
||||
}
|
||||
|
||||
diagnosticHolder.configure {
|
||||
@@ -440,7 +441,7 @@ object NodeConfigurator : AbstractFieldConfigurator<FirTreeBuilder>(FirTreeBuild
|
||||
}
|
||||
|
||||
callableReferenceAccess.configure {
|
||||
+field("calleeReference", namedReference)
|
||||
+field("calleeReference", namedReference, withReplace = true).withTransform()
|
||||
}
|
||||
|
||||
getClassCall.configure {
|
||||
|
||||
+20
-8
@@ -7,6 +7,7 @@ package org.jetbrains.kotlin.fir.tree.generator.model
|
||||
|
||||
import org.jetbrains.kotlin.fir.tree.generator.printer.BASE_PACKAGE
|
||||
import org.jetbrains.kotlin.fir.tree.generator.printer.typeWithArguments
|
||||
import org.jetbrains.kotlin.fir.tree.generator.util.set
|
||||
|
||||
interface KindOwner : Importable {
|
||||
var kind: Implementation.Kind?
|
||||
@@ -31,6 +32,7 @@ interface AbstractElement : FieldContainer, KindOwner {
|
||||
val allFirFields: List<Field>
|
||||
val defaultImplementation: Implementation?
|
||||
val customImplementations: List<Implementation>
|
||||
val overridenFields: Map<Field, Map<Importable, Boolean>>
|
||||
|
||||
override val allParents: List<KindOwner> get() = parents
|
||||
}
|
||||
@@ -60,10 +62,10 @@ class Element(val name: String, kind: Kind) : AbstractElement {
|
||||
override var doesNotNeedImplementation: Boolean = false
|
||||
|
||||
override val needTransformOtherChildren: Boolean get() = _needTransformOtherChildren || parents.any { it.needTransformOtherChildren }
|
||||
|
||||
override val overridenFields: MutableMap<Field, MutableMap<Importable, Boolean>> = mutableMapOf()
|
||||
override val allImplementations: List<Implementation> by lazy {
|
||||
if (doesNotNeedImplementation) {
|
||||
emptyList<Implementation>()
|
||||
emptyList()
|
||||
} else {
|
||||
val implementations = customImplementations.toMutableList()
|
||||
defaultImplementation?.let { implementations += it }
|
||||
@@ -74,13 +76,23 @@ class Element(val name: String, kind: Kind) : AbstractElement {
|
||||
override val allFields: List<Field> by lazy {
|
||||
val result = LinkedHashSet<Field>()
|
||||
result.addAll(fields.toList().asReversed())
|
||||
for (field in parentFields.asReversed()) {
|
||||
val overrides = !result.add(field)
|
||||
result.forEach { overridenFields[it, it] = false }
|
||||
for (parentField in parentFields.asReversed()) {
|
||||
val overrides = !result.add(parentField)
|
||||
if (overrides) {
|
||||
val existingField = result.first { it == field }
|
||||
val existingField = result.first { it == parentField }
|
||||
existingField.fromParent = true
|
||||
existingField.needsSeparateTransform = existingField.needsSeparateTransform || field.needsSeparateTransform
|
||||
existingField.needTransformInOtherChildren = existingField.needTransformInOtherChildren || field.needTransformInOtherChildren
|
||||
existingField.needsSeparateTransform = existingField.needsSeparateTransform || parentField.needsSeparateTransform
|
||||
existingField.needTransformInOtherChildren = existingField.needTransformInOtherChildren || parentField.needTransformInOtherChildren
|
||||
existingField.withReplace = parentField.withReplace || existingField.withReplace
|
||||
if (parentField.type != existingField.type && parentField.withReplace) {
|
||||
existingField.overridenTypes += parentField
|
||||
overridenFields[existingField, parentField] = false
|
||||
} else {
|
||||
overridenFields[existingField, parentField] = true
|
||||
}
|
||||
} else {
|
||||
overridenFields[parentField, parentField] = true
|
||||
}
|
||||
}
|
||||
result.toList().asReversed()
|
||||
@@ -160,4 +172,4 @@ class TypeArgumentWithMultipleUpperBounds(name: String, override val upperBounds
|
||||
override fun toString(): String {
|
||||
return name
|
||||
}
|
||||
}
|
||||
}
|
||||
+12
-6
@@ -11,7 +11,7 @@ sealed class Field : Importable {
|
||||
abstract val name: String
|
||||
open val arguments = mutableListOf<Importable>()
|
||||
abstract val nullable: Boolean
|
||||
abstract val withReplace: Boolean
|
||||
open var withReplace: Boolean = false
|
||||
abstract val isFirType: Boolean
|
||||
|
||||
var fromParent: Boolean = false
|
||||
@@ -22,10 +22,11 @@ sealed class Field : Importable {
|
||||
abstract var isMutable: Boolean
|
||||
open var isMutableInInterface: Boolean = false
|
||||
open val withGetter: Boolean get() = false
|
||||
open val isLateinit: Boolean get() = false
|
||||
open val customSetter: String? get() = null
|
||||
open val fromDelegate: Boolean get() = false
|
||||
|
||||
open val overridenTypes: MutableSet<Importable> = mutableSetOf()
|
||||
|
||||
fun copy(): Field = internalCopy().also {
|
||||
updateFieldsInCopy(it)
|
||||
}
|
||||
@@ -37,6 +38,7 @@ sealed class Field : Importable {
|
||||
copy.needsSeparateTransform = needsSeparateTransform
|
||||
copy.needTransformInOtherChildren = needTransformInOtherChildren
|
||||
copy.isMutable = isMutable
|
||||
copy.overridenTypes += overridenTypes
|
||||
}
|
||||
copy.fromParent = fromParent
|
||||
}
|
||||
@@ -66,7 +68,9 @@ class FieldWithDefault(val origin: Field) : Field() {
|
||||
override val name: String get() = origin.name
|
||||
override val type: String get() = origin.type
|
||||
override val nullable: Boolean get() = origin.nullable
|
||||
override val withReplace: Boolean get() = origin.withReplace
|
||||
override var withReplace: Boolean
|
||||
get() = origin.withReplace
|
||||
set(_) {}
|
||||
override val packageName: String? get() = origin.packageName
|
||||
override val isFirType: Boolean get() = origin.isFirType
|
||||
override var needsSeparateTransform: Boolean
|
||||
@@ -91,6 +95,8 @@ class FieldWithDefault(val origin: Field) : Field() {
|
||||
override var customSetter: String? = null
|
||||
override var fromDelegate: Boolean = false
|
||||
var needAcceptAndTransform: Boolean = true
|
||||
override val overridenTypes: MutableSet<Importable>
|
||||
get() = origin.overridenTypes
|
||||
|
||||
override fun internalCopy(): Field {
|
||||
return FieldWithDefault(origin).also {
|
||||
@@ -109,7 +115,7 @@ class SimpleField(
|
||||
override val packageName: String?,
|
||||
val customType: Importable? = null,
|
||||
override val nullable: Boolean,
|
||||
override val withReplace: Boolean
|
||||
override var withReplace: Boolean
|
||||
) : Field() {
|
||||
override val isFirType: Boolean = false
|
||||
override val fullQualifiedName: String?
|
||||
@@ -144,7 +150,7 @@ class FirField(
|
||||
override val name: String,
|
||||
val element: AbstractElement,
|
||||
override val nullable: Boolean,
|
||||
override val withReplace: Boolean
|
||||
override var withReplace: Boolean
|
||||
) : Field() {
|
||||
init {
|
||||
if (element is ElementWithArguments) {
|
||||
@@ -173,7 +179,7 @@ class FirField(
|
||||
class FieldList(
|
||||
override val name: String,
|
||||
val baseType: Importable,
|
||||
override val withReplace: Boolean
|
||||
override var withReplace: Boolean
|
||||
) : Field() {
|
||||
override var defaultValueInImplementation: String? = null
|
||||
override val packageName: String? get() = baseType.packageName
|
||||
|
||||
+12
-5
@@ -6,9 +6,9 @@
|
||||
package org.jetbrains.kotlin.fir.tree.generator.printer
|
||||
|
||||
import org.jetbrains.kotlin.fir.tree.generator.context.AbstractFirTreeBuilder
|
||||
import org.jetbrains.kotlin.fir.tree.generator.model.Element
|
||||
import org.jetbrains.kotlin.fir.tree.generator.model.Implementation
|
||||
import org.jetbrains.kotlin.fir.tree.generator.model.*
|
||||
import org.jetbrains.kotlin.fir.tree.generator.pureAbstractElementType
|
||||
import org.jetbrains.kotlin.fir.tree.generator.util.get
|
||||
|
||||
import java.io.File
|
||||
|
||||
@@ -84,11 +84,18 @@ fun SmartPrinter.printElement(element: Element) {
|
||||
override()
|
||||
println("fun <R, D> accept(visitor: FirVisitor<R, D>, data: D): R = visitor.visit$name(this, data)")
|
||||
|
||||
fields.filter { it.withReplace }.forEach {
|
||||
fun Field.replaceDeclaration(override: Boolean, overridenType: Importable? = null) {
|
||||
println()
|
||||
abstract()
|
||||
if (it.fromParent) print("override ")
|
||||
println(it.replaceFunctionDeclaration())
|
||||
if (override) print("override ")
|
||||
println(replaceFunctionDeclaration(overridenType))
|
||||
}
|
||||
|
||||
allFields.filter { it.withReplace }.forEach {
|
||||
it.replaceDeclaration(overridenFields[it, it])
|
||||
for (overridenType in it.overridenTypes) {
|
||||
it.replaceDeclaration(true, overridenType)
|
||||
}
|
||||
}
|
||||
|
||||
for (field in allFields) {
|
||||
|
||||
+20
-6
@@ -302,22 +302,30 @@ fun SmartPrinter.printImplementation(implementation: Implementation) {
|
||||
}
|
||||
}
|
||||
|
||||
for (field in allFields.filter { it.withReplace }) {
|
||||
fun generateReplace(field: Field, overridenType: Importable? = null, body: () -> Unit) {
|
||||
println()
|
||||
abstract()
|
||||
print("override ${field.replaceFunctionDeclaration()}")
|
||||
print("override ${field.replaceFunctionDeclaration(overridenType)}")
|
||||
if (isInterface || isAbstract) {
|
||||
println()
|
||||
continue
|
||||
return
|
||||
}
|
||||
print(" {")
|
||||
if (!field.isMutable) {
|
||||
println("}")
|
||||
continue
|
||||
return
|
||||
}
|
||||
println()
|
||||
withIndent {
|
||||
val newValue = "new${field.name.capitalize()}"
|
||||
body()
|
||||
}
|
||||
println("}")
|
||||
}
|
||||
|
||||
for (field in allFields.filter { it.withReplace }) {
|
||||
val capitalizedFieldName = field.name.capitalize()
|
||||
val newValue = "new$capitalizedFieldName"
|
||||
generateReplace(field) {
|
||||
when {
|
||||
field.withGetter -> {}
|
||||
|
||||
@@ -331,7 +339,13 @@ fun SmartPrinter.printImplementation(implementation: Implementation) {
|
||||
}
|
||||
}
|
||||
}
|
||||
println("}")
|
||||
|
||||
for (overridenType in field.overridenTypes) {
|
||||
generateReplace(field, overridenType) {
|
||||
println("require($newValue is ${field.typeWithArguments})")
|
||||
println("replace$capitalizedFieldName($newValue)")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
println("}")
|
||||
|
||||
+4
-2
@@ -62,6 +62,7 @@ fun Element.collectImports(): List<String> {
|
||||
|
||||
private fun Element.collectImportsInternal(base: List<String>, kind: ImportKind): List<String> {
|
||||
val fqns = base + allFields.mapNotNull { it.fullQualifiedName } +
|
||||
allFields.flatMap { it.overridenTypes.mapNotNull { it.fullQualifiedName } } +
|
||||
allFields.flatMap { it.arguments.mapNotNull { it.fullQualifiedName } } +
|
||||
typeArguments.flatMap { it.upperBounds.mapNotNull { it.fullQualifiedName } }
|
||||
return fqns.filterRedundantImports(packageName, kind)
|
||||
@@ -93,9 +94,10 @@ fun transformFunctionDeclaration(transformName: String, returnType: String): Str
|
||||
return "fun <D> transform$transformName(transformer: FirTransformer<D>, data: D): $returnType"
|
||||
}
|
||||
|
||||
fun Field.replaceFunctionDeclaration(): String {
|
||||
fun Field.replaceFunctionDeclaration(overridenType: Importable? = null): String {
|
||||
val capName = name.capitalize()
|
||||
return "fun replace$capName(new$capName: $typeWithArguments)"
|
||||
val type = overridenType?.typeWithArguments ?: typeWithArguments
|
||||
return "fun replace$capName(new$capName: $type)"
|
||||
}
|
||||
|
||||
val Field.mutableType: String
|
||||
|
||||
+10
@@ -11,3 +11,13 @@ fun Element.traverseParents(block: (Element) -> Unit) {
|
||||
block(this)
|
||||
parents.forEach { it.traverseParents(block) }
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
Reference in New Issue
Block a user