[FIR/IR generator] Introduce the common entry point for tree generators

This reduces code duplication.
This commit is contained in:
Sergej Jaskiewicz
2023-12-05 15:09:21 +01:00
committed by Space Team
parent 858343695c
commit 8d1907e2f5
26 changed files with 220 additions and 275 deletions
@@ -6,31 +6,36 @@
package org.jetbrains.kotlin.fir.tree.generator
import org.jetbrains.kotlin.fir.tree.generator.context.AbstractFirTreeBuilder
import org.jetbrains.kotlin.fir.tree.generator.printer.generateElements
import org.jetbrains.kotlin.generators.tree.InterfaceAndAbstractClassConfigurator
import org.jetbrains.kotlin.fir.tree.generator.printer.*
import org.jetbrains.kotlin.generators.tree.Model
import org.jetbrains.kotlin.generators.tree.addPureAbstractElement
import org.jetbrains.kotlin.generators.tree.detectBaseTransformerTypes
import org.jetbrains.kotlin.generators.util.GeneratorsFileUtil
import org.jetbrains.kotlin.generators.util.GeneratorsFileUtil.collectPreviouslyGeneratedFiles
import org.jetbrains.kotlin.generators.util.GeneratorsFileUtil.removeExtraFilesFromPreviousGeneration
import org.jetbrains.kotlin.generators.tree.bind
import org.jetbrains.kotlin.generators.tree.printer.generateTree
import java.io.File
internal const val BASE_PACKAGE = "org.jetbrains.kotlin.fir"
internal const val VISITOR_PACKAGE = "$BASE_PACKAGE.visitors"
fun main(args: Array<String>) {
val generationPath = args.firstOrNull()?.let { File(it) }
?: File("../../tree/gen").canonicalFile
NodeConfigurator.configureFields()
val model = Model(FirTreeBuilder.elements, AbstractFirTreeBuilder.baseFirElement)
detectBaseTransformerTypes(model)
ImplementationConfigurator.configureImplementations(model)
InterfaceAndAbstractClassConfigurator((model.elements + model.elements.flatMap { it.allImplementations }))
.configureInterfacesAndAbstractClasses()
addPureAbstractElement(FirTreeBuilder.elements, pureAbstractElementType)
BuilderConfigurator.configureBuilders()
val previouslyGeneratedFiles = collectPreviouslyGeneratedFiles(generationPath)
val generatedFiles = generateElements(FirTreeBuilder, BuilderConfigurator, generationPath)
generatedFiles.forEach { GeneratorsFileUtil.writeFileIfContentChanged(it.file, it.newText, logNotChanged = false) }
removeExtraFilesFromPreviousGeneration(previouslyGeneratedFiles, generatedFiles.map { it.file })
generateTree(
generationPath,
"compiler/fir/tree/tree-generator/Readme.md",
model,
pureAbstractElementType,
::ElementPrinter,
listOf(
firVisitorType to ::VisitorPrinter.bind(false),
firDefaultVisitorType to ::VisitorPrinter.bind(true),
firVisitorVoidType to ::VisitorVoidPrinter,
firDefaultVisitorVoidType to ::DefaultVisitorVoidPrinter,
firTransformerType to ::TransformerPrinter,
),
ImplementationConfigurator,
BuilderConfigurator,
::ImplementationPrinter,
::BuilderPrinter,
)
}
@@ -15,7 +15,6 @@ import org.jetbrains.kotlin.descriptors.Visibility
import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget
import org.jetbrains.kotlin.fir.tree.generator.context.generatedType
import org.jetbrains.kotlin.fir.tree.generator.context.type
import org.jetbrains.kotlin.fir.tree.generator.printer.VISITOR_PACKAGE
import org.jetbrains.kotlin.fir.types.ConeClassLikeType
import org.jetbrains.kotlin.fir.types.ConeErrorType
import org.jetbrains.kotlin.fir.types.ConeKotlinType
@@ -5,9 +5,9 @@
package org.jetbrains.kotlin.fir.tree.generator.context
import org.jetbrains.kotlin.fir.tree.generator.BASE_PACKAGE
import org.jetbrains.kotlin.fir.tree.generator.model.Element
import org.jetbrains.kotlin.fir.tree.generator.model.ElementRef
import org.jetbrains.kotlin.fir.tree.generator.printer.BASE_PACKAGE
import org.jetbrains.kotlin.generators.tree.ClassRef
import org.jetbrains.kotlin.generators.tree.PositionTypeParameterRef
import org.jetbrains.kotlin.generators.tree.TypeKind
@@ -5,7 +5,6 @@
package org.jetbrains.kotlin.fir.tree.generator
import org.jetbrains.kotlin.fir.tree.generator.printer.VISITOR_PACKAGE
import org.jetbrains.kotlin.generators.tree.ArbitraryImportable
val phaseAsResolveStateExtentionImport = ArbitraryImportable("org.jetbrains.kotlin.fir.declarations", "asResolveState")
@@ -5,7 +5,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.BASE_PACKAGE
import org.jetbrains.kotlin.fir.tree.generator.printer.safeDecapitalizedName
import org.jetbrains.kotlin.generators.tree.*
import org.jetbrains.kotlin.generators.tree.ElementOrRef as GenericElementOrRef
@@ -8,28 +8,17 @@ package org.jetbrains.kotlin.fir.tree.generator.printer
import org.jetbrains.kotlin.fir.tree.generator.declarationAttributesType
import org.jetbrains.kotlin.fir.tree.generator.firBuilderDslAnnotation
import org.jetbrains.kotlin.fir.tree.generator.firImplementationDetailType
import org.jetbrains.kotlin.fir.tree.generator.model.*
import org.jetbrains.kotlin.fir.tree.generator.model.Element
import org.jetbrains.kotlin.fir.tree.generator.model.Field
import org.jetbrains.kotlin.fir.tree.generator.model.FieldWithDefault
import org.jetbrains.kotlin.fir.tree.generator.model.Implementation
import org.jetbrains.kotlin.fir.tree.generator.toMutableOrEmptyImport
import org.jetbrains.kotlin.generators.tree.AbstractBuilderPrinter
import org.jetbrains.kotlin.generators.tree.ClassRef
import org.jetbrains.kotlin.generators.tree.ImportCollector
import org.jetbrains.kotlin.generators.tree.printer.GeneratedFile
import org.jetbrains.kotlin.generators.tree.printer.printGeneratedType
import org.jetbrains.kotlin.utils.SmartPrinter
import java.io.File
fun Builder.generateCode(generationPath: File): GeneratedFile =
printGeneratedType(
generationPath,
TREE_GENERATOR_README,
packageName,
typeName,
fileSuppressions = listOf("DuplicatedCode", "unused"),
) {
BuilderPrinter(this).printBuilder(this@generateCode)
}
class BuilderPrinter(printer: SmartPrinter) : AbstractBuilderPrinter<Element, Implementation, FieldWithDefault, Field>(printer) {
internal class BuilderPrinter(printer: SmartPrinter) : AbstractBuilderPrinter<Element, Implementation, FieldWithDefault, Field>(printer) {
override val implementationDetailAnnotation: ClassRef<*>
get() = firImplementationDetailType
@@ -5,15 +5,13 @@
package org.jetbrains.kotlin.fir.tree.generator.printer
import org.jetbrains.kotlin.fir.tree.generator.firDefaultVisitorVoidType
import org.jetbrains.kotlin.fir.tree.generator.firVisitorVoidType
import org.jetbrains.kotlin.fir.tree.generator.model.Element
import org.jetbrains.kotlin.fir.tree.generator.model.Field
import org.jetbrains.kotlin.generators.tree.*
import org.jetbrains.kotlin.utils.SmartPrinter
import java.io.File
private class DefaultVisitorVoidPrinter(
internal class DefaultVisitorVoidPrinter(
printer: SmartPrinter,
override val visitorType: ClassRef<*>,
) : AbstractVisitorPrinter<Element, Field>(printer) {
@@ -46,6 +44,3 @@ private class DefaultVisitorVoidPrinter(
}
}
}
fun printDefaultVisitorVoid(elements: List<Element>, generationPath: File) =
printVisitorCommon(elements, generationPath, firDefaultVisitorVoidType, ::DefaultVisitorVoidPrinter)
@@ -9,13 +9,14 @@ import org.jetbrains.kotlin.fir.tree.generator.*
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.Field
import org.jetbrains.kotlin.generators.tree.get
import org.jetbrains.kotlin.generators.tree.*
import org.jetbrains.kotlin.generators.tree.printer.*
import org.jetbrains.kotlin.generators.tree.printer.printAcceptChildrenMethod
import org.jetbrains.kotlin.generators.tree.printer.printAcceptMethod
import org.jetbrains.kotlin.generators.tree.printer.printTransformChildrenMethod
import org.jetbrains.kotlin.generators.tree.printer.printTransformMethod
import org.jetbrains.kotlin.utils.SmartPrinter
import java.io.File
private class ElementPrinter(printer: SmartPrinter) : AbstractElementPrinter<Element, Field>(printer) {
internal class ElementPrinter(printer: SmartPrinter) : AbstractElementPrinter<Element, Field>(printer) {
override fun makeFieldPrinter(printer: SmartPrinter) = object : AbstractFieldPrinter<Field>(printer) {}
@@ -89,8 +90,3 @@ private class ElementPrinter(printer: SmartPrinter) : AbstractElementPrinter<Ele
}
}
}
fun Element.generateCode(generationPath: File): GeneratedFile =
printGeneratedType(generationPath, TREE_GENERATOR_README, packageName, typeName) {
ElementPrinter(this).printElement(element)
}
@@ -9,21 +9,12 @@ import org.jetbrains.kotlin.descriptors.Modality
import org.jetbrains.kotlin.fir.tree.generator.*
import org.jetbrains.kotlin.fir.tree.generator.model.*
import org.jetbrains.kotlin.generators.tree.*
import org.jetbrains.kotlin.generators.tree.printer.*
import org.jetbrains.kotlin.generators.tree.printer.call
import org.jetbrains.kotlin.generators.tree.printer.printAcceptChildrenMethod
import org.jetbrains.kotlin.generators.tree.printer.printBlock
import org.jetbrains.kotlin.generators.tree.printer.printTransformChildrenMethod
import org.jetbrains.kotlin.utils.SmartPrinter
import org.jetbrains.kotlin.utils.withIndent
import java.io.File
fun Implementation.generateCode(generationPath: File): GeneratedFile =
printGeneratedType(
generationPath,
TREE_GENERATOR_README,
packageName,
this.typeName,
fileSuppressions = listOf("DuplicatedCode", "unused"),
) {
ImplementationPrinter(this).printImplementation(this@generateCode)
}
private class ImplementationFieldPrinter(printer: SmartPrinter) : AbstractFieldPrinter<FieldWithDefault>(printer) {
@@ -38,7 +29,7 @@ private class ImplementationFieldPrinter(printer: SmartPrinter) : AbstractFieldP
override fun actualTypeOfField(field: FieldWithDefault) = field.getMutableType()
}
private class ImplementationPrinter(
internal class ImplementationPrinter(
printer: SmartPrinter
) : AbstractImplementationPrinter<Implementation, Element, FieldWithDefault>(printer) {
@@ -49,7 +40,7 @@ private class ImplementationPrinter(
override val pureAbstractElementType: ClassRef<*>
get() = org.jetbrains.kotlin.fir.tree.generator.pureAbstractElementType
override fun makeFieldPrinter(printer: SmartPrinter) = ImplementationFieldPrinter(printer)
override fun makeFieldPrinter(printer: SmartPrinter): AbstractFieldPrinter<FieldWithDefault> = ImplementationFieldPrinter(printer)
context(ImportCollector)
override fun SmartPrinter.printAdditionalMethods(implementation: Implementation) {
@@ -7,22 +7,21 @@ package org.jetbrains.kotlin.fir.tree.generator.printer
import org.jetbrains.kotlin.descriptors.Modality
import org.jetbrains.kotlin.fir.tree.generator.context.AbstractFirTreeBuilder
import org.jetbrains.kotlin.fir.tree.generator.firTransformerType
import org.jetbrains.kotlin.fir.tree.generator.firVisitorType
import org.jetbrains.kotlin.fir.tree.generator.model.Element
import org.jetbrains.kotlin.fir.tree.generator.model.Field
import org.jetbrains.kotlin.generators.tree.*
import org.jetbrains.kotlin.generators.tree.printer.*
import org.jetbrains.kotlin.generators.tree.printer.FunctionParameter
import org.jetbrains.kotlin.generators.tree.printer.printBlock
import org.jetbrains.kotlin.generators.tree.printer.printFunctionDeclaration
import org.jetbrains.kotlin.generators.tree.printer.printFunctionWithBlockBody
import org.jetbrains.kotlin.utils.SmartPrinter
import java.io.File
private class TransformerPrinter(
internal class TransformerPrinter(
printer: SmartPrinter,
override val visitorType: ClassRef<*>,
) : AbstractVisitorPrinter<Element, Field>(printer) {
override val visitorType: ClassRef<*>
get() = firTransformerType
override val visitorSuperType: ClassRef<PositionTypeParameterRef>
get() = firVisitorType.withArgs(AbstractFirTreeBuilder.baseFirElement, visitorDataType)
@@ -88,13 +87,3 @@ private class TransformerPrinter(
}
}
}
fun printTransformer(elements: List<Element>, generationPath: File): GeneratedFile =
printGeneratedType(
generationPath,
TREE_GENERATOR_README,
firTransformerType.packageName,
firTransformerType.simpleName,
) {
TransformerPrinter(this).printVisitor(elements)
}
@@ -6,15 +6,13 @@
package org.jetbrains.kotlin.fir.tree.generator.printer
import org.jetbrains.kotlin.fir.tree.generator.context.AbstractFirTreeBuilder
import org.jetbrains.kotlin.fir.tree.generator.firDefaultVisitorType
import org.jetbrains.kotlin.fir.tree.generator.firVisitorType
import org.jetbrains.kotlin.fir.tree.generator.model.Element
import org.jetbrains.kotlin.fir.tree.generator.model.Field
import org.jetbrains.kotlin.generators.tree.*
import org.jetbrains.kotlin.utils.SmartPrinter
import java.io.File
private class VisitorPrinter(
internal class VisitorPrinter(
printer: SmartPrinter,
override val visitorType: ClassRef<*>,
private val visitSuperTypeByDefault: Boolean,
@@ -42,13 +40,3 @@ private class VisitorPrinter(
else -> AbstractFirTreeBuilder.baseFirElement
}
}
fun printVisitor(elements: List<Element>, generationPath: File, visitSuperTypeByDefault: Boolean) =
printVisitorCommon(
elements,
generationPath,
if (visitSuperTypeByDefault) firDefaultVisitorType else firVisitorType,
) { printer, visitorType ->
VisitorPrinter(printer, visitorType, visitSuperTypeByDefault)
}
@@ -7,16 +7,14 @@ package org.jetbrains.kotlin.fir.tree.generator.printer
import org.jetbrains.kotlin.fir.tree.generator.context.AbstractFirTreeBuilder
import org.jetbrains.kotlin.fir.tree.generator.firVisitorType
import org.jetbrains.kotlin.fir.tree.generator.firVisitorVoidType
import org.jetbrains.kotlin.fir.tree.generator.model.Element
import org.jetbrains.kotlin.fir.tree.generator.model.Field
import org.jetbrains.kotlin.generators.tree.AbstractVisitorVoidPrinter
import org.jetbrains.kotlin.generators.tree.ClassRef
import org.jetbrains.kotlin.generators.tree.PositionTypeParameterRef
import org.jetbrains.kotlin.utils.SmartPrinter
import java.io.File
private class VisitorVoidPrinter(
internal class VisitorVoidPrinter(
printer: SmartPrinter,
override val visitorType: ClassRef<*>,
) : AbstractVisitorVoidPrinter<Element, Field>(printer) {
@@ -35,6 +33,3 @@ private class VisitorVoidPrinter(
override fun parentInVisitor(element: Element): Element = AbstractFirTreeBuilder.baseFirElement
}
fun printVisitorVoid(elements: List<Element>, generationPath: File) =
printVisitorCommon(elements, generationPath, firVisitorVoidType, ::VisitorVoidPrinter)
@@ -1,37 +0,0 @@
/*
* Copyright 2010-2020 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.fir.tree.generator.printer
import org.jetbrains.kotlin.fir.tree.generator.context.AbstractFirBuilderConfigurator
import org.jetbrains.kotlin.fir.tree.generator.context.AbstractFirTreeBuilder
import org.jetbrains.kotlin.generators.tree.printer.GeneratedFile
import org.jetbrains.kotlin.generators.util.GeneratorsFileUtil.GENERATED_MESSAGE
import org.jetbrains.kotlin.utils.SmartPrinter
import java.io.File
const val VISITOR_PACKAGE = "org.jetbrains.kotlin.fir.visitors"
const val BASE_PACKAGE = "org.jetbrains.kotlin.fir"
internal const val TREE_GENERATOR_README = "compiler/fir/tree/tree-generator/Readme.md"
fun generateElements(
builder: AbstractFirTreeBuilder,
builderConfigurator: AbstractFirBuilderConfigurator<*>,
generationPath: File,
): List<GeneratedFile> {
val generatedFiles = mutableListOf<GeneratedFile>()
builder.elements.mapTo(generatedFiles) { it.generateCode(generationPath) }
builder.elements.flatMap { it.allImplementations }.mapTo(generatedFiles) { it.generateCode(generationPath) }
builder.elements.flatMap { it.allImplementations }.mapNotNull { it.builder }.mapTo(generatedFiles) { it.generateCode(generationPath) }
builderConfigurator.intermediateBuilders.mapTo(generatedFiles) { it.generateCode(generationPath) }
generatedFiles += printVisitor(builder.elements, generationPath, false)
generatedFiles += printVisitorVoid(builder.elements, generationPath)
generatedFiles += printVisitor(builder.elements, generationPath, true)
generatedFiles += printDefaultVisitorVoid(builder.elements, generationPath)
generatedFiles += printTransformer(builder.elements, generationPath)
return generatedFiles
}
@@ -6,15 +6,16 @@
package org.jetbrains.kotlin.fir.tree.generator.printer
import org.jetbrains.kotlin.descriptors.Modality
import org.jetbrains.kotlin.fir.tree.generator.BASE_PACKAGE
import org.jetbrains.kotlin.fir.tree.generator.firTransformerType
import org.jetbrains.kotlin.fir.tree.generator.model.*
import org.jetbrains.kotlin.fir.tree.generator.model.Element
import org.jetbrains.kotlin.fir.tree.generator.model.Field
import org.jetbrains.kotlin.fir.tree.generator.model.FieldList
import org.jetbrains.kotlin.fir.tree.generator.model.FieldWithDefault
import org.jetbrains.kotlin.generators.tree.*
import org.jetbrains.kotlin.generators.tree.printer.FunctionParameter
import org.jetbrains.kotlin.generators.tree.printer.GeneratedFile
import org.jetbrains.kotlin.generators.tree.printer.printFunctionDeclaration
import org.jetbrains.kotlin.generators.tree.printer.printGeneratedType
import org.jetbrains.kotlin.utils.SmartPrinter
import java.io.File
context(ImportCollector)
fun SmartPrinter.transformFunctionDeclaration(
@@ -92,13 +93,3 @@ fun Field.getMutableType(forBuilder: Boolean = false): TypeRefWithNullability =
}
val Element.safeDecapitalizedName: String get() = if (name == "Class") "klass" else name.replaceFirstChar(Char::lowercaseChar)
internal fun printVisitorCommon(
elements: List<Element>,
generationPath: File,
visitorType: ClassRef<*>,
makePrinter: (SmartPrinter, ClassRef<*>) -> AbstractVisitorPrinter<Element, Field>,
): GeneratedFile =
printGeneratedType(generationPath, TREE_GENERATOR_README, visitorType.packageName, visitorType.simpleName) {
makePrinter(this, visitorType).printVisitor(elements)
}