[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 package org.jetbrains.kotlin.fir.tree.generator
import org.jetbrains.kotlin.fir.tree.generator.context.AbstractFirTreeBuilder import org.jetbrains.kotlin.fir.tree.generator.context.AbstractFirTreeBuilder
import org.jetbrains.kotlin.fir.tree.generator.printer.generateElements import org.jetbrains.kotlin.fir.tree.generator.printer.*
import org.jetbrains.kotlin.generators.tree.InterfaceAndAbstractClassConfigurator
import org.jetbrains.kotlin.generators.tree.Model import org.jetbrains.kotlin.generators.tree.Model
import org.jetbrains.kotlin.generators.tree.addPureAbstractElement import org.jetbrains.kotlin.generators.tree.bind
import org.jetbrains.kotlin.generators.tree.detectBaseTransformerTypes import org.jetbrains.kotlin.generators.tree.printer.generateTree
import org.jetbrains.kotlin.generators.util.GeneratorsFileUtil
import org.jetbrains.kotlin.generators.util.GeneratorsFileUtil.collectPreviouslyGeneratedFiles
import org.jetbrains.kotlin.generators.util.GeneratorsFileUtil.removeExtraFilesFromPreviousGeneration
import java.io.File 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>) { fun main(args: Array<String>) {
val generationPath = args.firstOrNull()?.let { File(it) } val generationPath = args.firstOrNull()?.let { File(it) }
?: File("../../tree/gen").canonicalFile ?: File("../../tree/gen").canonicalFile
NodeConfigurator.configureFields() NodeConfigurator.configureFields()
val model = Model(FirTreeBuilder.elements, AbstractFirTreeBuilder.baseFirElement) val model = Model(FirTreeBuilder.elements, AbstractFirTreeBuilder.baseFirElement)
detectBaseTransformerTypes(model) generateTree(
ImplementationConfigurator.configureImplementations(model) generationPath,
InterfaceAndAbstractClassConfigurator((model.elements + model.elements.flatMap { it.allImplementations })) "compiler/fir/tree/tree-generator/Readme.md",
.configureInterfacesAndAbstractClasses() model,
addPureAbstractElement(FirTreeBuilder.elements, pureAbstractElementType) pureAbstractElementType,
BuilderConfigurator.configureBuilders() ::ElementPrinter,
val previouslyGeneratedFiles = collectPreviouslyGeneratedFiles(generationPath) listOf(
val generatedFiles = generateElements(FirTreeBuilder, BuilderConfigurator, generationPath) firVisitorType to ::VisitorPrinter.bind(false),
generatedFiles.forEach { GeneratorsFileUtil.writeFileIfContentChanged(it.file, it.newText, logNotChanged = false) } firDefaultVisitorType to ::VisitorPrinter.bind(true),
removeExtraFilesFromPreviousGeneration(previouslyGeneratedFiles, generatedFiles.map { it.file }) 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.descriptors.annotations.AnnotationUseSiteTarget
import org.jetbrains.kotlin.fir.tree.generator.context.generatedType 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.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.ConeClassLikeType
import org.jetbrains.kotlin.fir.types.ConeErrorType import org.jetbrains.kotlin.fir.types.ConeErrorType
import org.jetbrains.kotlin.fir.types.ConeKotlinType import org.jetbrains.kotlin.fir.types.ConeKotlinType
@@ -5,9 +5,9 @@
package org.jetbrains.kotlin.fir.tree.generator.context 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.Element
import org.jetbrains.kotlin.fir.tree.generator.model.ElementRef 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.ClassRef
import org.jetbrains.kotlin.generators.tree.PositionTypeParameterRef import org.jetbrains.kotlin.generators.tree.PositionTypeParameterRef
import org.jetbrains.kotlin.generators.tree.TypeKind import org.jetbrains.kotlin.generators.tree.TypeKind
@@ -5,7 +5,6 @@
package org.jetbrains.kotlin.fir.tree.generator package org.jetbrains.kotlin.fir.tree.generator
import org.jetbrains.kotlin.fir.tree.generator.printer.VISITOR_PACKAGE
import org.jetbrains.kotlin.generators.tree.ArbitraryImportable import org.jetbrains.kotlin.generators.tree.ArbitraryImportable
val phaseAsResolveStateExtentionImport = ArbitraryImportable("org.jetbrains.kotlin.fir.declarations", "asResolveState") val phaseAsResolveStateExtentionImport = ArbitraryImportable("org.jetbrains.kotlin.fir.declarations", "asResolveState")
@@ -5,7 +5,7 @@
package org.jetbrains.kotlin.fir.tree.generator.model 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.fir.tree.generator.printer.safeDecapitalizedName
import org.jetbrains.kotlin.generators.tree.* import org.jetbrains.kotlin.generators.tree.*
import org.jetbrains.kotlin.generators.tree.ElementOrRef as GenericElementOrRef 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.declarationAttributesType
import org.jetbrains.kotlin.fir.tree.generator.firBuilderDslAnnotation import org.jetbrains.kotlin.fir.tree.generator.firBuilderDslAnnotation
import org.jetbrains.kotlin.fir.tree.generator.firImplementationDetailType 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.fir.tree.generator.toMutableOrEmptyImport
import org.jetbrains.kotlin.generators.tree.AbstractBuilderPrinter import org.jetbrains.kotlin.generators.tree.AbstractBuilderPrinter
import org.jetbrains.kotlin.generators.tree.ClassRef import org.jetbrains.kotlin.generators.tree.ClassRef
import org.jetbrains.kotlin.generators.tree.ImportCollector 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 org.jetbrains.kotlin.utils.SmartPrinter
import java.io.File
fun Builder.generateCode(generationPath: File): GeneratedFile = internal class BuilderPrinter(printer: SmartPrinter) : AbstractBuilderPrinter<Element, Implementation, FieldWithDefault, Field>(printer) {
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) {
override val implementationDetailAnnotation: ClassRef<*> override val implementationDetailAnnotation: ClassRef<*>
get() = firImplementationDetailType get() = firImplementationDetailType
@@ -5,15 +5,13 @@
package org.jetbrains.kotlin.fir.tree.generator.printer 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.firVisitorVoidType
import org.jetbrains.kotlin.fir.tree.generator.model.Element 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.Field
import org.jetbrains.kotlin.generators.tree.* import org.jetbrains.kotlin.generators.tree.*
import org.jetbrains.kotlin.utils.SmartPrinter import org.jetbrains.kotlin.utils.SmartPrinter
import java.io.File
private class DefaultVisitorVoidPrinter( internal class DefaultVisitorVoidPrinter(
printer: SmartPrinter, printer: SmartPrinter,
override val visitorType: ClassRef<*>, override val visitorType: ClassRef<*>,
) : AbstractVisitorPrinter<Element, Field>(printer) { ) : 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.context.AbstractFirTreeBuilder
import org.jetbrains.kotlin.fir.tree.generator.model.Element 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.Field
import org.jetbrains.kotlin.generators.tree.get
import org.jetbrains.kotlin.generators.tree.* 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 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) {} 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.*
import org.jetbrains.kotlin.fir.tree.generator.model.* import org.jetbrains.kotlin.fir.tree.generator.model.*
import org.jetbrains.kotlin.generators.tree.* 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.SmartPrinter
import org.jetbrains.kotlin.utils.withIndent 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) { 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() override fun actualTypeOfField(field: FieldWithDefault) = field.getMutableType()
} }
private class ImplementationPrinter( internal class ImplementationPrinter(
printer: SmartPrinter printer: SmartPrinter
) : AbstractImplementationPrinter<Implementation, Element, FieldWithDefault>(printer) { ) : AbstractImplementationPrinter<Implementation, Element, FieldWithDefault>(printer) {
@@ -49,7 +40,7 @@ private class ImplementationPrinter(
override val pureAbstractElementType: ClassRef<*> override val pureAbstractElementType: ClassRef<*>
get() = org.jetbrains.kotlin.fir.tree.generator.pureAbstractElementType 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) context(ImportCollector)
override fun SmartPrinter.printAdditionalMethods(implementation: Implementation) { 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.descriptors.Modality
import org.jetbrains.kotlin.fir.tree.generator.context.AbstractFirTreeBuilder 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.firVisitorType
import org.jetbrains.kotlin.fir.tree.generator.model.Element 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.Field
import org.jetbrains.kotlin.generators.tree.* 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 org.jetbrains.kotlin.utils.SmartPrinter
import java.io.File
private class TransformerPrinter( internal class TransformerPrinter(
printer: SmartPrinter, printer: SmartPrinter,
override val visitorType: ClassRef<*>,
) : AbstractVisitorPrinter<Element, Field>(printer) { ) : AbstractVisitorPrinter<Element, Field>(printer) {
override val visitorType: ClassRef<*>
get() = firTransformerType
override val visitorSuperType: ClassRef<PositionTypeParameterRef> override val visitorSuperType: ClassRef<PositionTypeParameterRef>
get() = firVisitorType.withArgs(AbstractFirTreeBuilder.baseFirElement, visitorDataType) 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 package org.jetbrains.kotlin.fir.tree.generator.printer
import org.jetbrains.kotlin.fir.tree.generator.context.AbstractFirTreeBuilder 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.firVisitorType
import org.jetbrains.kotlin.fir.tree.generator.model.Element 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.Field
import org.jetbrains.kotlin.generators.tree.* import org.jetbrains.kotlin.generators.tree.*
import org.jetbrains.kotlin.utils.SmartPrinter import org.jetbrains.kotlin.utils.SmartPrinter
import java.io.File
private class VisitorPrinter( internal class VisitorPrinter(
printer: SmartPrinter, printer: SmartPrinter,
override val visitorType: ClassRef<*>, override val visitorType: ClassRef<*>,
private val visitSuperTypeByDefault: Boolean, private val visitSuperTypeByDefault: Boolean,
@@ -42,13 +40,3 @@ private class VisitorPrinter(
else -> AbstractFirTreeBuilder.baseFirElement 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.context.AbstractFirTreeBuilder
import org.jetbrains.kotlin.fir.tree.generator.firVisitorType 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.Element
import org.jetbrains.kotlin.fir.tree.generator.model.Field import org.jetbrains.kotlin.fir.tree.generator.model.Field
import org.jetbrains.kotlin.generators.tree.AbstractVisitorVoidPrinter import org.jetbrains.kotlin.generators.tree.AbstractVisitorVoidPrinter
import org.jetbrains.kotlin.generators.tree.ClassRef import org.jetbrains.kotlin.generators.tree.ClassRef
import org.jetbrains.kotlin.generators.tree.PositionTypeParameterRef import org.jetbrains.kotlin.generators.tree.PositionTypeParameterRef
import org.jetbrains.kotlin.utils.SmartPrinter import org.jetbrains.kotlin.utils.SmartPrinter
import java.io.File
private class VisitorVoidPrinter( internal class VisitorVoidPrinter(
printer: SmartPrinter, printer: SmartPrinter,
override val visitorType: ClassRef<*>, override val visitorType: ClassRef<*>,
) : AbstractVisitorVoidPrinter<Element, Field>(printer) { ) : AbstractVisitorVoidPrinter<Element, Field>(printer) {
@@ -35,6 +33,3 @@ private class VisitorVoidPrinter(
override fun parentInVisitor(element: Element): Element = AbstractFirTreeBuilder.baseFirElement 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 package org.jetbrains.kotlin.fir.tree.generator.printer
import org.jetbrains.kotlin.descriptors.Modality 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.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.*
import org.jetbrains.kotlin.generators.tree.printer.FunctionParameter 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.printFunctionDeclaration
import org.jetbrains.kotlin.generators.tree.printer.printGeneratedType
import org.jetbrains.kotlin.utils.SmartPrinter import org.jetbrains.kotlin.utils.SmartPrinter
import java.io.File
context(ImportCollector) context(ImportCollector)
fun SmartPrinter.transformFunctionDeclaration( 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) 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)
}
@@ -9,7 +9,6 @@ val compileOnly by configurations
runtimeOnly.extendsFrom(compileOnly) runtimeOnly.extendsFrom(compileOnly)
dependencies { dependencies {
implementation(project(":generators"))
implementation(project(":generators:tree-generator-common")) implementation(project(":generators:tree-generator-common"))
implementation(project(":compiler:util")) implementation(project(":compiler:util"))
@@ -5,11 +5,8 @@
package org.jetbrains.kotlin.ir.generator package org.jetbrains.kotlin.ir.generator
import org.jetbrains.kotlin.generators.tree.InterfaceAndAbstractClassConfigurator import org.jetbrains.kotlin.generators.tree.bind
import org.jetbrains.kotlin.generators.tree.addPureAbstractElement import org.jetbrains.kotlin.generators.tree.printer.generateTree
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.ir.generator.model.markLeaves import org.jetbrains.kotlin.ir.generator.model.markLeaves
import org.jetbrains.kotlin.ir.generator.print.* import org.jetbrains.kotlin.ir.generator.print.*
import java.io.File import java.io.File
@@ -21,25 +18,24 @@ internal const val TREE_GENERATOR_README = "compiler/ir/ir.tree/tree-generator/R
fun main(args: Array<String>) { fun main(args: Array<String>) {
val generationPath = args.firstOrNull()?.let { File(it) } val generationPath = args.firstOrNull()?.let { File(it) }
?: File("compiler/ir/ir.tree/gen").canonicalFile ?: File("compiler/ir/ir.tree/gen").canonicalFile
val model = IrTree.build() val model = IrTree.build()
generateTree(
InterfaceAndAbstractClassConfigurator(model.elements).configureInterfacesAndAbstractClasses() generationPath,
addPureAbstractElement(model.elements, elementBaseType) TREE_GENERATOR_README,
markLeaves(model.elements) model,
elementBaseType,
val previouslyGeneratedFiles = collectPreviouslyGeneratedFiles(generationPath) ::ElementPrinter,
val generatedFiles = sequence { listOf(
yieldAll(printElements(generationPath, model)) elementVisitorType to ::VisitorPrinter,
yield(printVisitor(generationPath, model)) elementVisitorVoidType to ::VisitorVoidPrinter,
yield(printVisitorVoid(generationPath, model)) elementTransformerType to ::TransformerPrinter.bind(model.rootElement),
yield(printTransformer(generationPath, model)) elementTransformerVoidType to ::TransformerVoidPrinter,
yield(printTransformerVoid(generationPath, model)) typeTransformerType to ::TypeTransformerPrinter.bind(model.rootElement),
yield(printTypeVisitor(generationPath, model)) ),
yield(printFactory(generationPath, model)) afterConfiguration = {
}.map { markLeaves(model.elements)
GeneratorsFileUtil.writeFileIfContentChanged(it.file, it.newText, logNotChanged = false) },
it.file enableBaseTransformerTypeDetection = false,
}.toList() addFiles = { add(printFactory(generationPath, model)) }
removeExtraFilesFromPreviousGeneration(previouslyGeneratedFiles, generatedFiles) )
} }
@@ -8,22 +8,19 @@ package org.jetbrains.kotlin.ir.generator.print
import org.jetbrains.kotlin.generators.tree.* import org.jetbrains.kotlin.generators.tree.*
import org.jetbrains.kotlin.generators.tree.printer.* import org.jetbrains.kotlin.generators.tree.printer.*
import org.jetbrains.kotlin.ir.generator.BASE_PACKAGE import org.jetbrains.kotlin.ir.generator.BASE_PACKAGE
import org.jetbrains.kotlin.ir.generator.TREE_GENERATOR_README
import org.jetbrains.kotlin.ir.generator.elementTransformerType import org.jetbrains.kotlin.ir.generator.elementTransformerType
import org.jetbrains.kotlin.ir.generator.elementVisitorType import org.jetbrains.kotlin.ir.generator.elementVisitorType
import org.jetbrains.kotlin.ir.generator.model.Element import org.jetbrains.kotlin.ir.generator.model.Element
import org.jetbrains.kotlin.ir.generator.model.Field import org.jetbrains.kotlin.ir.generator.model.Field
import org.jetbrains.kotlin.ir.generator.model.ListField import org.jetbrains.kotlin.ir.generator.model.ListField
import org.jetbrains.kotlin.ir.generator.model.Model
import org.jetbrains.kotlin.ir.generator.model.SingleField import org.jetbrains.kotlin.ir.generator.model.SingleField
import org.jetbrains.kotlin.utils.SmartPrinter import org.jetbrains.kotlin.utils.SmartPrinter
import java.io.File
import org.jetbrains.kotlin.generators.tree.ElementRef as GenericElementRef import org.jetbrains.kotlin.generators.tree.ElementRef as GenericElementRef
private val transformIfNeeded = ArbitraryImportable("$BASE_PACKAGE.util", "transformIfNeeded") private val transformIfNeeded = ArbitraryImportable("$BASE_PACKAGE.util", "transformIfNeeded")
private val transformInPlace = ArbitraryImportable("$BASE_PACKAGE.util", "transformInPlace") private val transformInPlace = ArbitraryImportable("$BASE_PACKAGE.util", "transformInPlace")
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) { override fun makeFieldPrinter(printer: SmartPrinter) = object : AbstractFieldPrinter<Field>(printer) {
override fun forceMutable(field: Field) = field.isMutable override fun forceMutable(field: Field) = field.isMutable
@@ -134,9 +131,3 @@ private class ElementPrinter(printer: SmartPrinter) : AbstractElementPrinter<Ele
} }
} }
} }
fun printElements(generationPath: File, model: Model) = model.elements.map { element ->
printGeneratedType(generationPath, TREE_GENERATOR_README, element.packageName, element.typeName) {
ElementPrinter(this).printElement(element)
}
}
@@ -6,21 +6,17 @@
package org.jetbrains.kotlin.ir.generator.print package org.jetbrains.kotlin.ir.generator.print
import org.jetbrains.kotlin.generators.tree.* import org.jetbrains.kotlin.generators.tree.*
import org.jetbrains.kotlin.generators.tree.printer.GeneratedFile
import org.jetbrains.kotlin.generators.tree.printer.printBlock import org.jetbrains.kotlin.generators.tree.printer.printBlock
import org.jetbrains.kotlin.ir.generator.elementTransformerType
import org.jetbrains.kotlin.ir.generator.elementVisitorType import org.jetbrains.kotlin.ir.generator.elementVisitorType
import org.jetbrains.kotlin.ir.generator.model.Element import org.jetbrains.kotlin.ir.generator.model.Element
import org.jetbrains.kotlin.ir.generator.model.Field import org.jetbrains.kotlin.ir.generator.model.Field
import org.jetbrains.kotlin.ir.generator.model.Model
import org.jetbrains.kotlin.utils.SmartPrinter import org.jetbrains.kotlin.utils.SmartPrinter
import org.jetbrains.kotlin.utils.withIndent import org.jetbrains.kotlin.utils.withIndent
import java.io.File
private class TransformerPrinter( internal class TransformerPrinter(
printer: SmartPrinter, printer: SmartPrinter,
override val visitorType: ClassRef<*>, override val visitorType: ClassRef<*>,
val rootElement: Element, private val rootElement: Element,
) : AbstractVisitorPrinter<Element, Field>(printer) { ) : AbstractVisitorPrinter<Element, Field>(printer) {
override val visitorSuperType: ClassRef<PositionTypeParameterRef> override val visitorSuperType: ClassRef<PositionTypeParameterRef>
@@ -62,8 +58,3 @@ private class TransformerPrinter(
} }
} }
} }
fun printTransformer(generationPath: File, model: Model): GeneratedFile =
printVisitorCommon(generationPath, model, elementTransformerType) { printer, visitorType ->
TransformerPrinter(printer, visitorType, model.rootElement)
}
@@ -7,19 +7,17 @@ package org.jetbrains.kotlin.ir.generator.print
import org.jetbrains.kotlin.descriptors.Modality import org.jetbrains.kotlin.descriptors.Modality
import org.jetbrains.kotlin.generators.tree.* 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.printFunctionWithBlockBody
import org.jetbrains.kotlin.ir.generator.IrTree import org.jetbrains.kotlin.ir.generator.IrTree
import org.jetbrains.kotlin.ir.generator.TREE_GENERATOR_README
import org.jetbrains.kotlin.ir.generator.elementTransformerType import org.jetbrains.kotlin.ir.generator.elementTransformerType
import org.jetbrains.kotlin.ir.generator.elementTransformerVoidType
import org.jetbrains.kotlin.ir.generator.model.Element import org.jetbrains.kotlin.ir.generator.model.Element
import org.jetbrains.kotlin.ir.generator.model.Field import org.jetbrains.kotlin.ir.generator.model.Field
import org.jetbrains.kotlin.ir.generator.model.Model
import org.jetbrains.kotlin.utils.SmartPrinter import org.jetbrains.kotlin.utils.SmartPrinter
import org.jetbrains.kotlin.utils.withIndent import org.jetbrains.kotlin.utils.withIndent
import java.io.File
private class TransformerVoidPrinter( internal class TransformerVoidPrinter(
printer: SmartPrinter, printer: SmartPrinter,
override val visitorType: ClassRef<*>, override val visitorType: ClassRef<*>,
) : AbstractVisitorPrinter<Element, Field>(printer) { ) : AbstractVisitorPrinter<Element, Field>(printer) {
@@ -119,24 +117,21 @@ private class TransformerVoidPrinter(
} }
} }
} }
}
fun printTransformerVoid(generationPath: File, model: Model): GeneratedFile = context(ImportCollector)
printGeneratedType( override fun printVisitor(elements: List<Element>) {
generationPath, super.printVisitor(elements)
TREE_GENERATOR_README, printer.run {
elementTransformerVoidType.packageName, println()
elementTransformerVoidType.simpleName, val transformerParameter = FunctionParameter("transformer", visitorType)
) { printFunctionWithBlockBody(
TransformerVoidPrinter(this, elementTransformerVoidType).printVisitor(model.elements) name = "transformChildrenVoid",
println() parameters = listOf(transformerParameter),
val transformerParameter = FunctionParameter("transformer", elementTransformerVoidType) returnType = StandardTypes.unit,
printFunctionWithBlockBody( extensionReceiver = IrTree.rootElement,
name = "transformChildrenVoid", ) {
parameters = listOf(transformerParameter), println("transformChildren(", transformerParameter.name, ", null)")
returnType = StandardTypes.unit, }
extensionReceiver = IrTree.rootElement,
) {
println("transformChildren(", transformerParameter.name, ", null)")
} }
} }
}
@@ -7,7 +7,6 @@ package org.jetbrains.kotlin.ir.generator.print
import org.jetbrains.kotlin.generators.tree.* import org.jetbrains.kotlin.generators.tree.*
import org.jetbrains.kotlin.generators.tree.printer.FunctionParameter import org.jetbrains.kotlin.generators.tree.printer.FunctionParameter
import org.jetbrains.kotlin.generators.tree.printer.GeneratedFile
import org.jetbrains.kotlin.generators.tree.printer.printBlock import org.jetbrains.kotlin.generators.tree.printer.printBlock
import org.jetbrains.kotlin.generators.tree.printer.printFunctionDeclaration import org.jetbrains.kotlin.generators.tree.printer.printFunctionDeclaration
import org.jetbrains.kotlin.ir.generator.IrTree import org.jetbrains.kotlin.ir.generator.IrTree
@@ -16,17 +15,14 @@ import org.jetbrains.kotlin.ir.generator.irTypeType
import org.jetbrains.kotlin.ir.generator.model.Element import org.jetbrains.kotlin.ir.generator.model.Element
import org.jetbrains.kotlin.ir.generator.model.Field import org.jetbrains.kotlin.ir.generator.model.Field
import org.jetbrains.kotlin.ir.generator.model.ListField import org.jetbrains.kotlin.ir.generator.model.ListField
import org.jetbrains.kotlin.ir.generator.model.Model
import org.jetbrains.kotlin.ir.generator.model.SingleField import org.jetbrains.kotlin.ir.generator.model.SingleField
import org.jetbrains.kotlin.ir.generator.typeTransformerType
import org.jetbrains.kotlin.utils.SmartPrinter import org.jetbrains.kotlin.utils.SmartPrinter
import org.jetbrains.kotlin.utils.withIndent import org.jetbrains.kotlin.utils.withIndent
import java.io.File
private class TypeTransformerPrinter( internal class TypeTransformerPrinter(
printer: SmartPrinter, printer: SmartPrinter,
override val visitorType: ClassRef<*>, override val visitorType: ClassRef<*>,
val rootElement: Element, private val rootElement: Element,
) : AbstractVisitorPrinter<Element, Field>(printer) { ) : AbstractVisitorPrinter<Element, Field>(printer) {
override val visitorSuperType: ClassRef<PositionTypeParameterRef> override val visitorSuperType: ClassRef<PositionTypeParameterRef>
@@ -155,8 +151,3 @@ private class TypeTransformerPrinter(
} }
} }
} }
fun printTypeVisitor(generationPath: File, model: Model): GeneratedFile =
printVisitorCommon(generationPath, model, typeTransformerType) { printer, visitorType ->
TypeTransformerPrinter(printer, visitorType, model.rootElement)
}
@@ -6,14 +6,14 @@
package org.jetbrains.kotlin.ir.generator.print package org.jetbrains.kotlin.ir.generator.print
import org.jetbrains.kotlin.generators.tree.* import org.jetbrains.kotlin.generators.tree.*
import org.jetbrains.kotlin.ir.generator.* import org.jetbrains.kotlin.ir.generator.model.Element
import org.jetbrains.kotlin.ir.generator.model.* import org.jetbrains.kotlin.ir.generator.model.Field
import org.jetbrains.kotlin.ir.generator.model.Model
import org.jetbrains.kotlin.utils.SmartPrinter import org.jetbrains.kotlin.utils.SmartPrinter
import java.io.File
private open class VisitorPrinter(printer: SmartPrinter, override val visitorType: ClassRef<*>) : internal class VisitorPrinter(
AbstractVisitorPrinter<Element, Field>(printer) { printer: SmartPrinter,
override val visitorType: ClassRef<*>
) : AbstractVisitorPrinter<Element, Field>(printer) {
override val visitorTypeParameters: List<TypeVariable> override val visitorTypeParameters: List<TypeVariable>
get() = listOf(resultTypeVariable, dataTypeVariable) get() = listOf(resultTypeVariable, dataTypeVariable)
@@ -29,6 +29,3 @@ private open class VisitorPrinter(printer: SmartPrinter, override val visitorTyp
override val allowTypeParametersInVisitorMethods: Boolean override val allowTypeParametersInVisitorMethods: Boolean
get() = false get() = false
} }
fun printVisitor(generationPath: File, model: Model) = printVisitorCommon(generationPath, model, elementVisitorType, ::VisitorPrinter)
@@ -9,14 +9,11 @@ import org.jetbrains.kotlin.generators.tree.AbstractVisitorVoidPrinter
import org.jetbrains.kotlin.generators.tree.ClassRef import org.jetbrains.kotlin.generators.tree.ClassRef
import org.jetbrains.kotlin.generators.tree.PositionTypeParameterRef import org.jetbrains.kotlin.generators.tree.PositionTypeParameterRef
import org.jetbrains.kotlin.ir.generator.elementVisitorType import org.jetbrains.kotlin.ir.generator.elementVisitorType
import org.jetbrains.kotlin.ir.generator.elementVisitorVoidType
import org.jetbrains.kotlin.ir.generator.model.Element import org.jetbrains.kotlin.ir.generator.model.Element
import org.jetbrains.kotlin.ir.generator.model.Field import org.jetbrains.kotlin.ir.generator.model.Field
import org.jetbrains.kotlin.ir.generator.model.Model
import org.jetbrains.kotlin.utils.SmartPrinter import org.jetbrains.kotlin.utils.SmartPrinter
import java.io.File
private class VisitorVoidPrinter( internal class VisitorVoidPrinter(
printer: SmartPrinter, printer: SmartPrinter,
override val visitorType: ClassRef<*>, override val visitorType: ClassRef<*>,
) : AbstractVisitorVoidPrinter<Element, Field>(printer) { ) : AbstractVisitorVoidPrinter<Element, Field>(printer) {
@@ -33,6 +30,3 @@ private class VisitorVoidPrinter(
override val overriddenVisitMethodsAreFinal: Boolean override val overriddenVisitMethodsAreFinal: Boolean
get() = false get() = false
} }
fun printVisitorVoid(generationPath: File, model: Model) =
printVisitorCommon(generationPath, model, elementVisitorVoidType, ::VisitorVoidPrinter)
@@ -5,26 +5,7 @@
package org.jetbrains.kotlin.ir.generator.print package org.jetbrains.kotlin.ir.generator.print
import org.jetbrains.kotlin.generators.tree.AbstractVisitorPrinter
import org.jetbrains.kotlin.generators.tree.ClassRef
import org.jetbrains.kotlin.generators.tree.printer.GeneratedFile
import org.jetbrains.kotlin.generators.tree.printer.printGeneratedType
import org.jetbrains.kotlin.ir.generator.TREE_GENERATOR_README
import org.jetbrains.kotlin.ir.generator.model.Element import org.jetbrains.kotlin.ir.generator.model.Element
import org.jetbrains.kotlin.ir.generator.model.Field
import org.jetbrains.kotlin.ir.generator.model.Model
import org.jetbrains.kotlin.utils.SmartPrinter
import java.io.File
internal fun printVisitorCommon(
generationPath: File,
model: Model,
visitorType: ClassRef<*>,
makePrinter: (SmartPrinter, ClassRef<*>) -> AbstractVisitorPrinter<Element, Field>,
): GeneratedFile =
printGeneratedType(generationPath, TREE_GENERATOR_README, visitorType.packageName, visitorType.simpleName) {
makePrinter(this, visitorType).printVisitor(model.elements)
}
internal fun Element.getTransformExplicitType(): Element { internal fun Element.getTransformExplicitType(): Element {
return generateSequence(this) { it.parentInVisitor } return generateSequence(this) { it.parentInVisitor }
@@ -134,7 +134,7 @@ abstract class AbstractVisitorPrinter<Element : AbstractElement<Element, Field,
} }
context(ImportCollector) context(ImportCollector)
fun printVisitor(elements: List<Element>) { open fun printVisitor(elements: List<Element>) {
val visitorType = this.visitorType val visitorType = this.visitorType
printer.run { printer.run {
printKDoc("Auto-generated by [${this@AbstractVisitorPrinter::class.qualifiedName}]") printKDoc("Auto-generated by [${this@AbstractVisitorPrinter::class.qualifiedName}]")
@@ -5,7 +5,10 @@
package org.jetbrains.kotlin.generators.tree.printer package org.jetbrains.kotlin.generators.tree.printer
import org.jetbrains.kotlin.generators.tree.ImportCollector import org.jetbrains.kotlin.generators.tree.*
import org.jetbrains.kotlin.generators.tree.config.AbstractBuilderConfigurator
import org.jetbrains.kotlin.generators.tree.config.AbstractImplementationConfigurator
import org.jetbrains.kotlin.generators.util.GeneratorsFileUtil
import org.jetbrains.kotlin.utils.SmartPrinter import org.jetbrains.kotlin.utils.SmartPrinter
import java.io.File import java.io.File
@@ -51,4 +54,109 @@ fun printGeneratedType(
append(stringBuilder) append(stringBuilder)
} }
) )
} }
/**
* The entry point of the tree generator.
*
* @param generationPath Where to put the generated files.
* @param treeGeneratorReadme A relative path to the README file of the tree generator. This path is mentioned in the auto-generation
* warning in each generated file.
* @param model The configured elements of the tree.
* @param pureAbstractElement The abstract class for elements that only implement interfaces to inherit from, see [addPureAbstractElement]
* for details.
* @param createElementPrinter Provide the class that prints elements, see [AbstractElementPrinter].
* @param createVisitorPrinters Provide the class that prints various visitors, see [AbstractVisitorPrinter].
* @param implementationConfigurator The class for configuring the set of implementation classes, see [AbstractImplementation] and
* [AbstractImplementationConfigurator].
* @param builderConfigurator The class for configuring the set of builders, see [Builder] and [AbstractBuilderConfigurator].
* @param createImplementationPrinter Provide the class that prints implementations of elements, see [AbstractImplementationPrinter].
* @param createBuilderPrinter Provide the class that prints the corresponding builder for each element class, see [AbstractBuilderPrinter].
* @param afterConfiguration The routine to run after all implementations and builders were fully configured,
* but before anything was printed to a file.
* @param enableBaseTransformerTypeDetection Whether to use a special algorithm for inferring return types of transformer methods for each
* element, see [detectBaseTransformerTypes].
* @param addFiles Arbitrary files to add to the set of generated files.
*/
fun <Element, Implementation, ElementField, ImplementationField> generateTree(
generationPath: File,
treeGeneratorReadme: String,
model: Model<Element>,
pureAbstractElement: ClassRef<*>,
createElementPrinter: (SmartPrinter) -> AbstractElementPrinter<Element, ElementField>,
createVisitorPrinters: List<Pair<ClassRef<*>, (SmartPrinter, ClassRef<*>) -> AbstractVisitorPrinter<Element, ElementField>>>,
implementationConfigurator: AbstractImplementationConfigurator<Implementation, Element, ImplementationField>? = null,
builderConfigurator: AbstractBuilderConfigurator<Element, Implementation, ImplementationField, ElementField>? = null,
createImplementationPrinter: ((SmartPrinter) -> AbstractImplementationPrinter<Implementation, Element, ImplementationField>)? = null,
createBuilderPrinter: ((SmartPrinter) -> AbstractBuilderPrinter<Element, Implementation, ImplementationField, ElementField>)? = null,
afterConfiguration: () -> Unit = {},
enableBaseTransformerTypeDetection: Boolean = true,
addFiles: MutableList<GeneratedFile>.() -> Unit = {},
) where Element : AbstractElement<Element, ElementField, Implementation>,
Implementation : AbstractImplementation<Implementation, Element, ImplementationField>,
ElementField : AbstractField<ElementField>,
ImplementationField : AbstractField<*>,
ImplementationField : AbstractFieldWithDefaultValue<ElementField> {
if (enableBaseTransformerTypeDetection) {
detectBaseTransformerTypes(model)
}
implementationConfigurator?.configureImplementations(model)
val implementations = model.elements.flatMap { it.allImplementations }
InterfaceAndAbstractClassConfigurator((model.elements + implementations))
.configureInterfacesAndAbstractClasses()
addPureAbstractElement(model.elements, pureAbstractElement)
builderConfigurator?.configureBuilders()
afterConfiguration()
val generatedFiles = mutableListOf<GeneratedFile>()
model.elements.mapTo(generatedFiles) { element ->
printGeneratedType(
generationPath,
treeGeneratorReadme,
element.packageName,
element.typeName,
) {
createElementPrinter(this).printElement(element)
}
}
if (createImplementationPrinter != null) {
implementations.mapTo(generatedFiles) { implementation ->
printGeneratedType(
generationPath,
treeGeneratorReadme,
implementation.packageName,
implementation.typeName,
fileSuppressions = listOf("DuplicatedCode", "unused"),
) {
createImplementationPrinter(this).printImplementation(implementation)
}
}
}
if (createBuilderPrinter != null && builderConfigurator != null) {
(implementations.mapNotNull { it.builder } + builderConfigurator.intermediateBuilders).mapTo(generatedFiles) { builder ->
printGeneratedType(
generationPath,
treeGeneratorReadme,
builder.packageName,
builder.typeName,
fileSuppressions = listOf("DuplicatedCode", "unused"),
) {
createBuilderPrinter(this).printBuilder(builder)
}
}
}
createVisitorPrinters.mapTo(generatedFiles) { (visitorClass, createVisitorPrinter) ->
printGeneratedType(generationPath, treeGeneratorReadme, visitorClass.packageName, visitorClass.simpleName) {
createVisitorPrinter(this, visitorClass).printVisitor(model.elements)
}
}
generatedFiles.addFiles()
val previouslyGeneratedFiles = GeneratorsFileUtil.collectPreviouslyGeneratedFiles(generationPath)
generatedFiles.forEach { GeneratorsFileUtil.writeFileIfContentChanged(it.file, it.newText, logNotChanged = false) }
GeneratorsFileUtil.removeExtraFilesFromPreviousGeneration(previouslyGeneratedFiles, generatedFiles.map { it.file })
}
@@ -65,6 +65,8 @@ operator fun <K, V, U> Map<K, Map<V, U>>.get(k1: K, k2: V): U {
return getValue(k1).getValue(k2) return getValue(k1).getValue(k2)
} }
fun <T1, T2, T3, R> ((T1, T2, T3) -> R).bind(t3: T3): ((T1, T2) -> R) = { t1, t2 -> invoke(t1, t2, t3) }
internal fun <Field : AbstractField<*>> List<Field>.reorderFieldsIfNecessary(order: List<String>?): List<Field> = internal fun <Field : AbstractField<*>> List<Field>.reorderFieldsIfNecessary(order: List<String>?): List<Field> =
if (order == null) { if (order == null) {
this this