[FIR/IR generator] Share visitor-related properties between FIR & IR
This commit is contained in:
committed by
Space Team
parent
bdfb3c3ac9
commit
75b509c185
+1
-2
@@ -38,8 +38,7 @@ internal class FirResolvedImportImpl(
|
||||
override val importedName: Name?
|
||||
get() = importedFqName?.shortName()
|
||||
|
||||
override fun <R, D> acceptChildren(visitor: FirVisitor<R, D>, data: D) {
|
||||
}
|
||||
override fun <R, D> acceptChildren(visitor: FirVisitor<R, D>, data: D) {}
|
||||
|
||||
override fun <D> transformChildren(transformer: FirTransformer<D>, data: D): FirResolvedImportImpl {
|
||||
return this
|
||||
|
||||
+1
-2
@@ -31,8 +31,7 @@ class FirEmptyExpressionBlock : FirBlock() {
|
||||
override val statements: List<FirStatement>
|
||||
get() = emptyList()
|
||||
|
||||
override fun <R, D> acceptChildren(visitor: FirVisitor<R, D>, data: D) {
|
||||
}
|
||||
override fun <R, D> acceptChildren(visitor: FirVisitor<R, D>, data: D) {}
|
||||
|
||||
override fun <D> transformChildren(transformer: FirTransformer<D>, data: D): FirEmptyExpressionBlock {
|
||||
transformOtherChildren(transformer, data)
|
||||
|
||||
@@ -31,8 +31,7 @@ internal class FirLazyBlockImpl : FirLazyBlock() {
|
||||
override val statements: List<FirStatement>
|
||||
get() = error("FirLazyBlock should be calculated before accessing")
|
||||
|
||||
override fun <R, D> acceptChildren(visitor: FirVisitor<R, D>, data: D) {
|
||||
}
|
||||
override fun <R, D> acceptChildren(visitor: FirVisitor<R, D>, data: D) {}
|
||||
|
||||
override fun <D> transformChildren(transformer: FirTransformer<D>, data: D): FirLazyBlockImpl {
|
||||
transformOtherChildren(transformer, data)
|
||||
|
||||
+1
-2
@@ -28,8 +28,7 @@ internal class FirLazyExpressionImpl(
|
||||
override val annotations: List<FirAnnotation>
|
||||
get() = error("FirLazyExpression should be calculated before accessing")
|
||||
|
||||
override fun <R, D> acceptChildren(visitor: FirVisitor<R, D>, data: D) {
|
||||
}
|
||||
override fun <R, D> acceptChildren(visitor: FirVisitor<R, D>, data: D) {}
|
||||
|
||||
override fun <D> transformChildren(transformer: FirTransformer<D>, data: D): FirLazyExpressionImpl {
|
||||
return this
|
||||
|
||||
+18
@@ -55,6 +55,24 @@ class Element(override val name: String, kind: Kind) : AbstractElement<Element,
|
||||
|
||||
override var isSealed: Boolean = false
|
||||
|
||||
override val hasAcceptMethod: Boolean
|
||||
get() = true
|
||||
|
||||
override val hasTransformMethod: Boolean
|
||||
get() = true
|
||||
|
||||
override val hasAcceptChildrenMethod: Boolean
|
||||
get() = isRootElement
|
||||
|
||||
override val hasTransformChildrenMethod: Boolean
|
||||
get() = isRootElement
|
||||
|
||||
override val walkableChildren: List<Field>
|
||||
get() = emptyList() // Use Implementation#walkableChildren instead
|
||||
|
||||
override val transformableChildren: List<Field>
|
||||
get() = emptyList() // Use Implementation#transformableChildren instead
|
||||
|
||||
var baseTransformerType: Element? = null
|
||||
val transformerType: Element get() = baseTransformerType ?: this
|
||||
|
||||
|
||||
+16
@@ -59,6 +59,22 @@ class Implementation(val element: Element, val name: String?) : FieldContainer,
|
||||
}
|
||||
}
|
||||
|
||||
override val hasAcceptChildrenMethod: Boolean
|
||||
get() {
|
||||
val isInterface = kind == ImplementationKind.Interface || kind == ImplementationKind.SealedInterface
|
||||
val isAbstract = kind == ImplementationKind.AbstractClass || kind == ImplementationKind.SealedClass
|
||||
return !isInterface && !isAbstract
|
||||
}
|
||||
|
||||
override val hasTransformChildrenMethod: Boolean
|
||||
get() = true
|
||||
|
||||
override val walkableChildren: List<FieldWithDefault>
|
||||
get() = allFields.filter { it.isFirType && !it.withGetter && it.needAcceptAndTransform }
|
||||
|
||||
override val transformableChildren: List<FieldWithDefault>
|
||||
get() = walkableChildren.filter { it.isMutable }
|
||||
|
||||
fun addParent(parent: Implementation, arg: Importable? = null) {
|
||||
_parents += ImplementationWithArg(parent, arg)
|
||||
}
|
||||
|
||||
+27
-19
@@ -60,22 +60,26 @@ fun SmartPrinter.printElement(element: Element) {
|
||||
}
|
||||
}
|
||||
}
|
||||
if (allFields.isNotEmpty()) {
|
||||
|
||||
if (hasAcceptMethod) {
|
||||
if (allFields.isNotEmpty()) {
|
||||
println()
|
||||
}
|
||||
override()
|
||||
println("fun <R, D> accept(visitor: FirVisitor<R, D>, data: D): R =")
|
||||
withIndent {
|
||||
println("visitor.visit${element.name}(this, data)")
|
||||
}
|
||||
}
|
||||
|
||||
if (hasTransformMethod) {
|
||||
println()
|
||||
}
|
||||
|
||||
override()
|
||||
println("fun <R, D> accept(visitor: FirVisitor<R, D>, data: D): R =")
|
||||
withIndent {
|
||||
println("visitor.visit${element.name}(this, data)")
|
||||
}
|
||||
|
||||
println()
|
||||
println("@Suppress(\"UNCHECKED_CAST\")")
|
||||
override()
|
||||
println("fun <E : FirElement, D> transform(transformer: FirTransformer<D>, data: D): E =")
|
||||
withIndent {
|
||||
println("transformer.transform$name(this, data) as E")
|
||||
println("@Suppress(\"UNCHECKED_CAST\")")
|
||||
override()
|
||||
println("fun <E : FirElement, D> transform(transformer: FirTransformer<D>, data: D): E =")
|
||||
withIndent {
|
||||
println("transformer.transform$name(this, data) as E")
|
||||
}
|
||||
}
|
||||
|
||||
fun Field.replaceDeclaration(override: Boolean, overridenType: TypeRef? = null, forceNullable: Boolean = false) {
|
||||
@@ -121,12 +125,16 @@ fun SmartPrinter.printElement(element: Element) {
|
||||
}
|
||||
println()
|
||||
println("fun accept(visitor: FirVisitorVoid) = accept(visitor, null)")
|
||||
println()
|
||||
println("fun <R, D> acceptChildren(visitor: FirVisitor<R, D>, data: D)")
|
||||
if (element.hasAcceptChildrenMethod) {
|
||||
println()
|
||||
println("fun <R, D> acceptChildren(visitor: FirVisitor<R, D>, data: D)")
|
||||
}
|
||||
println()
|
||||
println("fun acceptChildren(visitor: FirVisitorVoid) = acceptChildren(visitor, null)")
|
||||
println()
|
||||
println("fun <D> transformChildren(transformer: FirTransformer<D>, data: D): FirElement")
|
||||
if (element.hasTransformChildrenMethod) {
|
||||
println()
|
||||
println("fun <D> transformChildren(transformer: FirTransformer<D>, data: D): FirElement")
|
||||
}
|
||||
}
|
||||
}
|
||||
println("}")
|
||||
|
||||
+46
-46
@@ -138,14 +138,14 @@ fun SmartPrinter.printImplementation(implementation: Implementation) {
|
||||
}
|
||||
|
||||
fun Field.acceptString(): String = "${name}${call()}accept(visitor, data)"
|
||||
if (!isInterface && !isAbstract) {
|
||||
if (hasAcceptChildrenMethod) {
|
||||
print("override fun <R, D> acceptChildren(visitor: FirVisitor<R, D>, data: D) {")
|
||||
|
||||
if (element.allFirFields.isNotEmpty()) {
|
||||
val walkableFields = walkableChildren
|
||||
if (walkableFields.isNotEmpty()) {
|
||||
println()
|
||||
withIndent {
|
||||
for (field in allFields.filter { it.isFirType }) {
|
||||
if (field.withGetter || !field.needAcceptAndTransform) continue
|
||||
for (field in walkableFields) {
|
||||
when (field.name) {
|
||||
"explicitReceiver" -> {
|
||||
val explicitReceiver = implementation["explicitReceiver"]!!
|
||||
@@ -202,65 +202,65 @@ fun SmartPrinter.printImplementation(implementation: Implementation) {
|
||||
println()
|
||||
}
|
||||
|
||||
abstract()
|
||||
print("override fun <D> transformChildren(transformer: FirTransformer<D>, data: D): $typeWithArguments")
|
||||
if (!isInterface && !isAbstract) {
|
||||
println(" {")
|
||||
withIndent {
|
||||
for (field in allFields) {
|
||||
when {
|
||||
!field.isMutable || !field.isFirType || field.withGetter || !field.needAcceptAndTransform -> {}
|
||||
|
||||
field.name == "explicitReceiver" -> {
|
||||
val explicitReceiver = implementation["explicitReceiver"]!!
|
||||
val dispatchReceiver = implementation["dispatchReceiver"]!!
|
||||
val extensionReceiver = implementation["extensionReceiver"]!!
|
||||
if (explicitReceiver.isMutable) {
|
||||
println("explicitReceiver = explicitReceiver${explicitReceiver.call()}transform(transformer, data)")
|
||||
}
|
||||
if (dispatchReceiver.isMutable) {
|
||||
println(
|
||||
"""
|
||||
if (hasTransformChildrenMethod) {
|
||||
abstract()
|
||||
print("override fun <D> transformChildren(transformer: FirTransformer<D>, data: D): $typeWithArguments")
|
||||
if (!isInterface && !isAbstract) {
|
||||
println(" {")
|
||||
withIndent {
|
||||
for (field in transformableChildren) {
|
||||
when {
|
||||
field.name == "explicitReceiver" -> {
|
||||
val explicitReceiver = implementation["explicitReceiver"]!!
|
||||
val dispatchReceiver = implementation["dispatchReceiver"]!!
|
||||
val extensionReceiver = implementation["extensionReceiver"]!!
|
||||
if (explicitReceiver.isMutable) {
|
||||
println("explicitReceiver = explicitReceiver${explicitReceiver.call()}transform(transformer, data)")
|
||||
}
|
||||
if (dispatchReceiver.isMutable) {
|
||||
println(
|
||||
"""
|
||||
|if (dispatchReceiver !== explicitReceiver) {
|
||||
| dispatchReceiver = dispatchReceiver?.transform(transformer, data)
|
||||
| }
|
||||
""".trimMargin(),
|
||||
)
|
||||
}
|
||||
if (extensionReceiver.isMutable) {
|
||||
println(
|
||||
"""
|
||||
)
|
||||
}
|
||||
if (extensionReceiver.isMutable) {
|
||||
println(
|
||||
"""
|
||||
|if (extensionReceiver !== explicitReceiver && extensionReceiver !== dispatchReceiver) {
|
||||
| extensionReceiver = extensionReceiver?.transform(transformer, data)
|
||||
| }
|
||||
""".trimMargin(),
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
field.name in setOf("dispatchReceiver", "extensionReceiver") -> {}
|
||||
field.name in setOf("dispatchReceiver", "extensionReceiver") -> {}
|
||||
|
||||
field.needsSeparateTransform -> {
|
||||
if (!(element.needTransformOtherChildren && field.needTransformInOtherChildren)) {
|
||||
println("transform${field.name.replaceFirstChar(Char::uppercaseChar)}(transformer, data)")
|
||||
field.needsSeparateTransform -> {
|
||||
if (!(element.needTransformOtherChildren && field.needTransformInOtherChildren)) {
|
||||
println("transform${field.name.replaceFirstChar(Char::uppercaseChar)}(transformer, data)")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
!element.needTransformOtherChildren -> {
|
||||
field.transform()
|
||||
}
|
||||
!element.needTransformOtherChildren -> {
|
||||
field.transform()
|
||||
}
|
||||
|
||||
else -> {}
|
||||
else -> {}
|
||||
}
|
||||
}
|
||||
if (element.needTransformOtherChildren) {
|
||||
println("transformOtherChildren(transformer, data)")
|
||||
}
|
||||
println("return this")
|
||||
}
|
||||
if (element.needTransformOtherChildren) {
|
||||
println("transformOtherChildren(transformer, data)")
|
||||
}
|
||||
println("return this")
|
||||
println("}")
|
||||
} else {
|
||||
println()
|
||||
}
|
||||
println("}")
|
||||
} else {
|
||||
println()
|
||||
}
|
||||
|
||||
for (field in allFields) {
|
||||
|
||||
+13
-4
@@ -54,13 +54,22 @@ class Element(
|
||||
|
||||
var isLeaf = config.isForcedLeaf
|
||||
val childrenOrderOverride: List<String>? = config.childrenOrderOverride
|
||||
var walkableChildren: List<Field> = emptyList()
|
||||
val transformableChildren get() = walkableChildren.filter { it.transformable }
|
||||
override var walkableChildren: List<Field> = emptyList()
|
||||
override val transformableChildren get() = walkableChildren.filter { it.transformable }
|
||||
|
||||
val visitFunName = "visit" + (config.visitorName ?: name).replaceFirstChar(Char::uppercaseChar)
|
||||
val visitorParam = config.visitorParam ?: config.category.defaultVisitorParam
|
||||
var accept = config.accept
|
||||
val transform = config.transform
|
||||
|
||||
override var hasAcceptMethod = config.accept
|
||||
|
||||
override val hasTransformMethod = config.transform
|
||||
|
||||
override val hasAcceptChildrenMethod: Boolean
|
||||
get() = ownsChildren && (isRootElement || walkableChildren.isNotEmpty())
|
||||
|
||||
override val hasTransformChildrenMethod: Boolean
|
||||
get() = ownsChildren && (isRootElement || transformableChildren.isNotEmpty())
|
||||
|
||||
val transformByChildren = config.transformByChildren
|
||||
val ownsChildren = config.ownsChildren
|
||||
val generateIrFactoryMethod = config.generateIrFactoryMethod
|
||||
|
||||
+1
-1
@@ -153,7 +153,7 @@ private fun markLeaves(elements: List<Element>) {
|
||||
for (el in leaves) {
|
||||
el.isLeaf = true
|
||||
if (el.visitorParent != null) {
|
||||
el.accept = true
|
||||
el.hasAcceptMethod = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+5
-5
@@ -81,7 +81,7 @@ fun printElements(generationPath: File, model: Model) = sequence {
|
||||
val isRootElement = element.isRootElement
|
||||
val acceptMethodName = "accept"
|
||||
val transformMethodName = "transform"
|
||||
if (element.accept) {
|
||||
if (element.hasAcceptMethod) {
|
||||
addFunction(FunSpec.builder(acceptMethodName).apply {
|
||||
addModifiers(if (isRootElement) KModifier.ABSTRACT else KModifier.OVERRIDE)
|
||||
val r = TypeVariableName("R")
|
||||
@@ -114,7 +114,7 @@ fun printElements(generationPath: File, model: Model) = sequence {
|
||||
}.build())
|
||||
}
|
||||
|
||||
if (element.transform) {
|
||||
if (element.hasTransformMethod) {
|
||||
addFunction(FunSpec.builder(transformMethodName).apply {
|
||||
addModifiers(if (isRootElement) KModifier.ABSTRACT else KModifier.OVERRIDE)
|
||||
val d = TypeVariableName("D")
|
||||
@@ -145,7 +145,7 @@ fun printElements(generationPath: File, model: Model) = sequence {
|
||||
}.build())
|
||||
}
|
||||
|
||||
if (element.ownsChildren && (isRootElement || element.walkableChildren.isNotEmpty())) {
|
||||
if (element.hasAcceptChildrenMethod) {
|
||||
addFunction(FunSpec.builder("acceptChildren").apply {
|
||||
addModifiers(if (isRootElement) KModifier.ABSTRACT else KModifier.OVERRIDE)
|
||||
val d = TypeVariableName("D")
|
||||
@@ -193,7 +193,7 @@ fun printElements(generationPath: File, model: Model) = sequence {
|
||||
}.build())
|
||||
}
|
||||
|
||||
if (element.ownsChildren && (isRootElement || element.transformableChildren.isNotEmpty())) {
|
||||
if (element.hasTransformChildrenMethod) {
|
||||
addFunction(FunSpec.builder("transformChildren").apply {
|
||||
addModifiers(if (isRootElement) KModifier.ABSTRACT else KModifier.OVERRIDE)
|
||||
val d = TypeVariableName("D")
|
||||
@@ -233,7 +233,7 @@ fun printElements(generationPath: File, model: Model) = sequence {
|
||||
if (child is SingleField) {
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
val elRef = child.typeRef as GenericElementRef<Element, Field>
|
||||
if (!elRef.element.transform) {
|
||||
if (!elRef.element.hasTransformMethod) {
|
||||
append(" as %T")
|
||||
if (child.nullable) append("?")
|
||||
args.add(elRef.toPoet())
|
||||
|
||||
+4
@@ -40,6 +40,10 @@ abstract class AbstractElement<Element, Field> : ElementOrRef<Element, Field>, F
|
||||
|
||||
abstract override val allFields: List<Field>
|
||||
|
||||
abstract override val walkableChildren: List<Field>
|
||||
|
||||
abstract override val transformableChildren: List<Field>
|
||||
|
||||
final override fun get(fieldName: String): Field? {
|
||||
return allFields.firstOrNull { it.name == fieldName }
|
||||
}
|
||||
|
||||
+18
@@ -8,4 +8,22 @@ package org.jetbrains.kotlin.generators.tree
|
||||
interface FieldContainer {
|
||||
val allFields: List<AbstractField>
|
||||
operator fun get(fieldName: String): AbstractField?
|
||||
|
||||
val hasAcceptMethod: Boolean
|
||||
get() = false
|
||||
|
||||
val hasTransformMethod: Boolean
|
||||
get() = false
|
||||
|
||||
val hasAcceptChildrenMethod: Boolean
|
||||
get() = false
|
||||
|
||||
val hasTransformChildrenMethod: Boolean
|
||||
get() = false
|
||||
|
||||
val walkableChildren: List<AbstractField>
|
||||
get() = emptyList()
|
||||
|
||||
val transformableChildren: List<AbstractField>
|
||||
get() = emptyList()
|
||||
}
|
||||
Reference in New Issue
Block a user