From 8d1907e2f5abccaad2a1db15be0958d91dc81efe Mon Sep 17 00:00:00 2001 From: Sergej Jaskiewicz Date: Tue, 5 Dec 2023 15:09:21 +0100 Subject: [PATCH] [FIR/IR generator] Introduce the common entry point for tree generators This reduces code duplication. --- .../kotlin/fir/tree/generator/Main.kt | 41 ++++--- .../kotlin/fir/tree/generator/Types.kt | 1 - .../context/AbstractFirTreeBuilder.kt | 2 +- .../kotlin/fir/tree/generator/importables.kt | 1 - .../fir/tree/generator/model/Element.kt | 2 +- .../tree/generator/printer/BuilderPrinter.kt | 21 +--- .../printer/DefaultVisitorVoidPrinter.kt | 7 +- .../tree/generator/printer/ElementPrinter.kt | 14 +-- .../printer/ImplementationPrinter.kt | 21 +--- .../generator/printer/TransformerPrinter.kt | 23 +--- .../tree/generator/printer/VisitorPrinter.kt | 14 +-- .../generator/printer/VisitorVoidPrinter.kt | 7 +- .../kotlin/fir/tree/generator/printer/main.kt | 37 ------ .../fir/tree/generator/printer/utils.kt | 19 +-- .../ir.tree/tree-generator/build.gradle.kts | 1 - .../org/jetbrains/kotlin/ir/generator/Main.kt | 46 ++++--- .../ir/generator/print/ElementPrinter.kt | 11 +- .../ir/generator/print/TransformerPrinter.kt | 13 +- .../generator/print/TransformerVoidPrinter.kt | 43 +++---- .../generator/print/TypeTransformerPrinter.kt | 13 +- .../ir/generator/print/VisitorPrinter.kt | 15 +-- .../ir/generator/print/VisitorVoidPrinter.kt | 8 +- .../kotlin/ir/generator/print/utils.kt | 19 --- .../generators/tree/AbstractVisitorPrinter.kt | 2 +- .../kotlin/generators/tree/printer/common.kt | 112 +++++++++++++++++- .../jetbrains/kotlin/generators/tree/utils.kt | 2 + 26 files changed, 220 insertions(+), 275 deletions(-) delete mode 100644 compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/printer/main.kt diff --git a/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/Main.kt b/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/Main.kt index 693fde26746..cf49eada6e0 100644 --- a/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/Main.kt +++ b/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/Main.kt @@ -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) { 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, + ) } diff --git a/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/Types.kt b/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/Types.kt index b0be0d6c651..9cad8db05eb 100644 --- a/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/Types.kt +++ b/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/Types.kt @@ -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 diff --git a/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/context/AbstractFirTreeBuilder.kt b/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/context/AbstractFirTreeBuilder.kt index 9f8d888b055..a3c0f8ca0e1 100644 --- a/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/context/AbstractFirTreeBuilder.kt +++ b/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/context/AbstractFirTreeBuilder.kt @@ -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 diff --git a/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/importables.kt b/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/importables.kt index 5b40bcbc835..98d32387f61 100644 --- a/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/importables.kt +++ b/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/importables.kt @@ -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") diff --git a/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/model/Element.kt b/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/model/Element.kt index 6e091a79ba6..29a7e4019ed 100644 --- a/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/model/Element.kt +++ b/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/model/Element.kt @@ -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 diff --git a/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/printer/BuilderPrinter.kt b/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/printer/BuilderPrinter.kt index 0ff26cae468..15ba4ad0b20 100644 --- a/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/printer/BuilderPrinter.kt +++ b/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/printer/BuilderPrinter.kt @@ -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(printer) { +internal class BuilderPrinter(printer: SmartPrinter) : AbstractBuilderPrinter(printer) { override val implementationDetailAnnotation: ClassRef<*> get() = firImplementationDetailType diff --git a/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/printer/DefaultVisitorVoidPrinter.kt b/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/printer/DefaultVisitorVoidPrinter.kt index ace2cea8035..90542cc8a0d 100644 --- a/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/printer/DefaultVisitorVoidPrinter.kt +++ b/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/printer/DefaultVisitorVoidPrinter.kt @@ -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(printer) { @@ -46,6 +44,3 @@ private class DefaultVisitorVoidPrinter( } } } - -fun printDefaultVisitorVoid(elements: List, generationPath: File) = - printVisitorCommon(elements, generationPath, firDefaultVisitorVoidType, ::DefaultVisitorVoidPrinter) diff --git a/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/printer/ElementPrinter.kt b/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/printer/ElementPrinter.kt index 91f78636a86..35e8c50776f 100644 --- a/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/printer/ElementPrinter.kt +++ b/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/printer/ElementPrinter.kt @@ -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(printer) { +internal class ElementPrinter(printer: SmartPrinter) : AbstractElementPrinter(printer) { override fun makeFieldPrinter(printer: SmartPrinter) = object : AbstractFieldPrinter(printer) {} @@ -89,8 +90,3 @@ private class ElementPrinter(printer: SmartPrinter) : AbstractElementPrinter(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(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 = ImplementationFieldPrinter(printer) context(ImportCollector) override fun SmartPrinter.printAdditionalMethods(implementation: Implementation) { diff --git a/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/printer/TransformerPrinter.kt b/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/printer/TransformerPrinter.kt index 5a9c9e083f3..e7867b3b993 100644 --- a/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/printer/TransformerPrinter.kt +++ b/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/printer/TransformerPrinter.kt @@ -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(printer) { - override val visitorType: ClassRef<*> - get() = firTransformerType - override val visitorSuperType: ClassRef get() = firVisitorType.withArgs(AbstractFirTreeBuilder.baseFirElement, visitorDataType) @@ -88,13 +87,3 @@ private class TransformerPrinter( } } } - -fun printTransformer(elements: List, generationPath: File): GeneratedFile = - printGeneratedType( - generationPath, - TREE_GENERATOR_README, - firTransformerType.packageName, - firTransformerType.simpleName, - ) { - TransformerPrinter(this).printVisitor(elements) - } diff --git a/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/printer/VisitorPrinter.kt b/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/printer/VisitorPrinter.kt index ffe7b9725e1..2995c4de6b8 100644 --- a/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/printer/VisitorPrinter.kt +++ b/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/printer/VisitorPrinter.kt @@ -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, generationPath: File, visitSuperTypeByDefault: Boolean) = - printVisitorCommon( - elements, - generationPath, - if (visitSuperTypeByDefault) firDefaultVisitorType else firVisitorType, - ) { printer, visitorType -> - VisitorPrinter(printer, visitorType, visitSuperTypeByDefault) - } - diff --git a/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/printer/VisitorVoidPrinter.kt b/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/printer/VisitorVoidPrinter.kt index 2167ef624da..5d1678edbdc 100644 --- a/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/printer/VisitorVoidPrinter.kt +++ b/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/printer/VisitorVoidPrinter.kt @@ -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(printer) { @@ -35,6 +33,3 @@ private class VisitorVoidPrinter( override fun parentInVisitor(element: Element): Element = AbstractFirTreeBuilder.baseFirElement } - -fun printVisitorVoid(elements: List, generationPath: File) = - printVisitorCommon(elements, generationPath, firVisitorVoidType, ::VisitorVoidPrinter) diff --git a/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/printer/main.kt b/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/printer/main.kt deleted file mode 100644 index 6a088fdbf88..00000000000 --- a/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/printer/main.kt +++ /dev/null @@ -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 { - val generatedFiles = mutableListOf() - 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 -} diff --git a/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/printer/utils.kt b/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/printer/utils.kt index b2be225e743..14ff7555122 100644 --- a/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/printer/utils.kt +++ b/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/printer/utils.kt @@ -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, - generationPath: File, - visitorType: ClassRef<*>, - makePrinter: (SmartPrinter, ClassRef<*>) -> AbstractVisitorPrinter, -): GeneratedFile = - printGeneratedType(generationPath, TREE_GENERATOR_README, visitorType.packageName, visitorType.simpleName) { - makePrinter(this, visitorType).printVisitor(elements) - } diff --git a/compiler/ir/ir.tree/tree-generator/build.gradle.kts b/compiler/ir/ir.tree/tree-generator/build.gradle.kts index 03db13b1e91..52f1171df9a 100644 --- a/compiler/ir/ir.tree/tree-generator/build.gradle.kts +++ b/compiler/ir/ir.tree/tree-generator/build.gradle.kts @@ -9,7 +9,6 @@ val compileOnly by configurations runtimeOnly.extendsFrom(compileOnly) dependencies { - implementation(project(":generators")) implementation(project(":generators:tree-generator-common")) implementation(project(":compiler:util")) diff --git a/compiler/ir/ir.tree/tree-generator/src/org/jetbrains/kotlin/ir/generator/Main.kt b/compiler/ir/ir.tree/tree-generator/src/org/jetbrains/kotlin/ir/generator/Main.kt index 4a0b0871c7c..e69beada3c2 100644 --- a/compiler/ir/ir.tree/tree-generator/src/org/jetbrains/kotlin/ir/generator/Main.kt +++ b/compiler/ir/ir.tree/tree-generator/src/org/jetbrains/kotlin/ir/generator/Main.kt @@ -5,11 +5,8 @@ package org.jetbrains.kotlin.ir.generator -import org.jetbrains.kotlin.generators.tree.InterfaceAndAbstractClassConfigurator -import org.jetbrains.kotlin.generators.tree.addPureAbstractElement -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 org.jetbrains.kotlin.ir.generator.model.markLeaves import org.jetbrains.kotlin.ir.generator.print.* 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) { val generationPath = args.firstOrNull()?.let { File(it) } ?: File("compiler/ir/ir.tree/gen").canonicalFile - val model = IrTree.build() - - InterfaceAndAbstractClassConfigurator(model.elements).configureInterfacesAndAbstractClasses() - addPureAbstractElement(model.elements, elementBaseType) - markLeaves(model.elements) - - val previouslyGeneratedFiles = collectPreviouslyGeneratedFiles(generationPath) - val generatedFiles = sequence { - yieldAll(printElements(generationPath, model)) - yield(printVisitor(generationPath, model)) - yield(printVisitorVoid(generationPath, model)) - yield(printTransformer(generationPath, model)) - yield(printTransformerVoid(generationPath, model)) - yield(printTypeVisitor(generationPath, model)) - yield(printFactory(generationPath, model)) - }.map { - GeneratorsFileUtil.writeFileIfContentChanged(it.file, it.newText, logNotChanged = false) - it.file - }.toList() - removeExtraFilesFromPreviousGeneration(previouslyGeneratedFiles, generatedFiles) + generateTree( + generationPath, + TREE_GENERATOR_README, + model, + elementBaseType, + ::ElementPrinter, + listOf( + elementVisitorType to ::VisitorPrinter, + elementVisitorVoidType to ::VisitorVoidPrinter, + elementTransformerType to ::TransformerPrinter.bind(model.rootElement), + elementTransformerVoidType to ::TransformerVoidPrinter, + typeTransformerType to ::TypeTransformerPrinter.bind(model.rootElement), + ), + afterConfiguration = { + markLeaves(model.elements) + }, + enableBaseTransformerTypeDetection = false, + addFiles = { add(printFactory(generationPath, model)) } + ) } diff --git a/compiler/ir/ir.tree/tree-generator/src/org/jetbrains/kotlin/ir/generator/print/ElementPrinter.kt b/compiler/ir/ir.tree/tree-generator/src/org/jetbrains/kotlin/ir/generator/print/ElementPrinter.kt index 45397011252..78f48d124cf 100644 --- a/compiler/ir/ir.tree/tree-generator/src/org/jetbrains/kotlin/ir/generator/print/ElementPrinter.kt +++ b/compiler/ir/ir.tree/tree-generator/src/org/jetbrains/kotlin/ir/generator/print/ElementPrinter.kt @@ -8,22 +8,19 @@ package org.jetbrains.kotlin.ir.generator.print import org.jetbrains.kotlin.generators.tree.* import org.jetbrains.kotlin.generators.tree.printer.* 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.elementVisitorType import org.jetbrains.kotlin.ir.generator.model.Element import org.jetbrains.kotlin.ir.generator.model.Field 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.utils.SmartPrinter -import java.io.File import org.jetbrains.kotlin.generators.tree.ElementRef as GenericElementRef private val transformIfNeeded = ArbitraryImportable("$BASE_PACKAGE.util", "transformIfNeeded") private val transformInPlace = ArbitraryImportable("$BASE_PACKAGE.util", "transformInPlace") -private class ElementPrinter(printer: SmartPrinter) : AbstractElementPrinter(printer) { +internal class ElementPrinter(printer: SmartPrinter) : AbstractElementPrinter(printer) { override fun makeFieldPrinter(printer: SmartPrinter) = object : AbstractFieldPrinter(printer) { override fun forceMutable(field: Field) = field.isMutable @@ -134,9 +131,3 @@ private class ElementPrinter(printer: SmartPrinter) : AbstractElementPrinter - printGeneratedType(generationPath, TREE_GENERATOR_README, element.packageName, element.typeName) { - ElementPrinter(this).printElement(element) - } -} diff --git a/compiler/ir/ir.tree/tree-generator/src/org/jetbrains/kotlin/ir/generator/print/TransformerPrinter.kt b/compiler/ir/ir.tree/tree-generator/src/org/jetbrains/kotlin/ir/generator/print/TransformerPrinter.kt index 39e41910206..d579f7edb2e 100644 --- a/compiler/ir/ir.tree/tree-generator/src/org/jetbrains/kotlin/ir/generator/print/TransformerPrinter.kt +++ b/compiler/ir/ir.tree/tree-generator/src/org/jetbrains/kotlin/ir/generator/print/TransformerPrinter.kt @@ -6,21 +6,17 @@ package org.jetbrains.kotlin.ir.generator.print 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.ir.generator.elementTransformerType import org.jetbrains.kotlin.ir.generator.elementVisitorType 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 org.jetbrains.kotlin.utils.withIndent -import java.io.File -private class TransformerPrinter( +internal class TransformerPrinter( printer: SmartPrinter, override val visitorType: ClassRef<*>, - val rootElement: Element, + private val rootElement: Element, ) : AbstractVisitorPrinter(printer) { override val visitorSuperType: ClassRef @@ -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) - } diff --git a/compiler/ir/ir.tree/tree-generator/src/org/jetbrains/kotlin/ir/generator/print/TransformerVoidPrinter.kt b/compiler/ir/ir.tree/tree-generator/src/org/jetbrains/kotlin/ir/generator/print/TransformerVoidPrinter.kt index 1eef8743cff..030b6573945 100644 --- a/compiler/ir/ir.tree/tree-generator/src/org/jetbrains/kotlin/ir/generator/print/TransformerVoidPrinter.kt +++ b/compiler/ir/ir.tree/tree-generator/src/org/jetbrains/kotlin/ir/generator/print/TransformerVoidPrinter.kt @@ -7,19 +7,17 @@ package org.jetbrains.kotlin.ir.generator.print import org.jetbrains.kotlin.descriptors.Modality 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.TREE_GENERATOR_README 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.Field -import org.jetbrains.kotlin.ir.generator.model.Model import org.jetbrains.kotlin.utils.SmartPrinter import org.jetbrains.kotlin.utils.withIndent -import java.io.File -private class TransformerVoidPrinter( +internal class TransformerVoidPrinter( printer: SmartPrinter, override val visitorType: ClassRef<*>, ) : AbstractVisitorPrinter(printer) { @@ -119,24 +117,21 @@ private class TransformerVoidPrinter( } } } -} -fun printTransformerVoid(generationPath: File, model: Model): GeneratedFile = - printGeneratedType( - generationPath, - TREE_GENERATOR_README, - elementTransformerVoidType.packageName, - elementTransformerVoidType.simpleName, - ) { - TransformerVoidPrinter(this, elementTransformerVoidType).printVisitor(model.elements) - println() - val transformerParameter = FunctionParameter("transformer", elementTransformerVoidType) - printFunctionWithBlockBody( - name = "transformChildrenVoid", - parameters = listOf(transformerParameter), - returnType = StandardTypes.unit, - extensionReceiver = IrTree.rootElement, - ) { - println("transformChildren(", transformerParameter.name, ", null)") + context(ImportCollector) + override fun printVisitor(elements: List) { + super.printVisitor(elements) + printer.run { + println() + val transformerParameter = FunctionParameter("transformer", visitorType) + printFunctionWithBlockBody( + name = "transformChildrenVoid", + parameters = listOf(transformerParameter), + returnType = StandardTypes.unit, + extensionReceiver = IrTree.rootElement, + ) { + println("transformChildren(", transformerParameter.name, ", null)") + } } } +} diff --git a/compiler/ir/ir.tree/tree-generator/src/org/jetbrains/kotlin/ir/generator/print/TypeTransformerPrinter.kt b/compiler/ir/ir.tree/tree-generator/src/org/jetbrains/kotlin/ir/generator/print/TypeTransformerPrinter.kt index d42bce671e0..2da95102ce3 100644 --- a/compiler/ir/ir.tree/tree-generator/src/org/jetbrains/kotlin/ir/generator/print/TypeTransformerPrinter.kt +++ b/compiler/ir/ir.tree/tree-generator/src/org/jetbrains/kotlin/ir/generator/print/TypeTransformerPrinter.kt @@ -7,7 +7,6 @@ package org.jetbrains.kotlin.ir.generator.print 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.printBlock import org.jetbrains.kotlin.generators.tree.printer.printFunctionDeclaration 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.Field 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.typeTransformerType import org.jetbrains.kotlin.utils.SmartPrinter import org.jetbrains.kotlin.utils.withIndent -import java.io.File -private class TypeTransformerPrinter( +internal class TypeTransformerPrinter( printer: SmartPrinter, override val visitorType: ClassRef<*>, - val rootElement: Element, + private val rootElement: Element, ) : AbstractVisitorPrinter(printer) { override val visitorSuperType: ClassRef @@ -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) - } diff --git a/compiler/ir/ir.tree/tree-generator/src/org/jetbrains/kotlin/ir/generator/print/VisitorPrinter.kt b/compiler/ir/ir.tree/tree-generator/src/org/jetbrains/kotlin/ir/generator/print/VisitorPrinter.kt index 2d6de4f4bea..b3e9efd6d9d 100644 --- a/compiler/ir/ir.tree/tree-generator/src/org/jetbrains/kotlin/ir/generator/print/VisitorPrinter.kt +++ b/compiler/ir/ir.tree/tree-generator/src/org/jetbrains/kotlin/ir/generator/print/VisitorPrinter.kt @@ -6,14 +6,14 @@ package org.jetbrains.kotlin.ir.generator.print import org.jetbrains.kotlin.generators.tree.* -import org.jetbrains.kotlin.ir.generator.* -import org.jetbrains.kotlin.ir.generator.model.* -import org.jetbrains.kotlin.ir.generator.model.Model +import org.jetbrains.kotlin.ir.generator.model.Element +import org.jetbrains.kotlin.ir.generator.model.Field import org.jetbrains.kotlin.utils.SmartPrinter -import java.io.File -private open class VisitorPrinter(printer: SmartPrinter, override val visitorType: ClassRef<*>) : - AbstractVisitorPrinter(printer) { +internal class VisitorPrinter( + printer: SmartPrinter, + override val visitorType: ClassRef<*> +) : AbstractVisitorPrinter(printer) { override val visitorTypeParameters: List get() = listOf(resultTypeVariable, dataTypeVariable) @@ -29,6 +29,3 @@ private open class VisitorPrinter(printer: SmartPrinter, override val visitorTyp override val allowTypeParametersInVisitorMethods: Boolean get() = false } - -fun printVisitor(generationPath: File, model: Model) = printVisitorCommon(generationPath, model, elementVisitorType, ::VisitorPrinter) - diff --git a/compiler/ir/ir.tree/tree-generator/src/org/jetbrains/kotlin/ir/generator/print/VisitorVoidPrinter.kt b/compiler/ir/ir.tree/tree-generator/src/org/jetbrains/kotlin/ir/generator/print/VisitorVoidPrinter.kt index f4b2c239cd1..d54613aba38 100644 --- a/compiler/ir/ir.tree/tree-generator/src/org/jetbrains/kotlin/ir/generator/print/VisitorVoidPrinter.kt +++ b/compiler/ir/ir.tree/tree-generator/src/org/jetbrains/kotlin/ir/generator/print/VisitorVoidPrinter.kt @@ -9,14 +9,11 @@ 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.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.Field -import org.jetbrains.kotlin.ir.generator.model.Model import org.jetbrains.kotlin.utils.SmartPrinter -import java.io.File -private class VisitorVoidPrinter( +internal class VisitorVoidPrinter( printer: SmartPrinter, override val visitorType: ClassRef<*>, ) : AbstractVisitorVoidPrinter(printer) { @@ -33,6 +30,3 @@ private class VisitorVoidPrinter( override val overriddenVisitMethodsAreFinal: Boolean get() = false } - -fun printVisitorVoid(generationPath: File, model: Model) = - printVisitorCommon(generationPath, model, elementVisitorVoidType, ::VisitorVoidPrinter) diff --git a/compiler/ir/ir.tree/tree-generator/src/org/jetbrains/kotlin/ir/generator/print/utils.kt b/compiler/ir/ir.tree/tree-generator/src/org/jetbrains/kotlin/ir/generator/print/utils.kt index 70c89ce5c17..c293d751598 100644 --- a/compiler/ir/ir.tree/tree-generator/src/org/jetbrains/kotlin/ir/generator/print/utils.kt +++ b/compiler/ir/ir.tree/tree-generator/src/org/jetbrains/kotlin/ir/generator/print/utils.kt @@ -5,26 +5,7 @@ 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.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, -): GeneratedFile = - printGeneratedType(generationPath, TREE_GENERATOR_README, visitorType.packageName, visitorType.simpleName) { - makePrinter(this, visitorType).printVisitor(model.elements) - } internal fun Element.getTransformExplicitType(): Element { return generateSequence(this) { it.parentInVisitor } diff --git a/generators/tree-generator-common/src/org/jetbrains/kotlin/generators/tree/AbstractVisitorPrinter.kt b/generators/tree-generator-common/src/org/jetbrains/kotlin/generators/tree/AbstractVisitorPrinter.kt index 0193172d53d..33d03c60667 100644 --- a/generators/tree-generator-common/src/org/jetbrains/kotlin/generators/tree/AbstractVisitorPrinter.kt +++ b/generators/tree-generator-common/src/org/jetbrains/kotlin/generators/tree/AbstractVisitorPrinter.kt @@ -134,7 +134,7 @@ abstract class AbstractVisitorPrinter) { + open fun printVisitor(elements: List) { val visitorType = this.visitorType printer.run { printKDoc("Auto-generated by [${this@AbstractVisitorPrinter::class.qualifiedName}]") diff --git a/generators/tree-generator-common/src/org/jetbrains/kotlin/generators/tree/printer/common.kt b/generators/tree-generator-common/src/org/jetbrains/kotlin/generators/tree/printer/common.kt index 4ed7dcb651d..76ad17aa15f 100644 --- a/generators/tree-generator-common/src/org/jetbrains/kotlin/generators/tree/printer/common.kt +++ b/generators/tree-generator-common/src/org/jetbrains/kotlin/generators/tree/printer/common.kt @@ -5,7 +5,10 @@ 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 java.io.File @@ -51,4 +54,109 @@ fun printGeneratedType( append(stringBuilder) } ) -} \ No newline at end of file +} + +/** + * 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 generateTree( + generationPath: File, + treeGeneratorReadme: String, + model: Model, + pureAbstractElement: ClassRef<*>, + createElementPrinter: (SmartPrinter) -> AbstractElementPrinter, + createVisitorPrinters: List, (SmartPrinter, ClassRef<*>) -> AbstractVisitorPrinter>>, + implementationConfigurator: AbstractImplementationConfigurator? = null, + builderConfigurator: AbstractBuilderConfigurator? = null, + createImplementationPrinter: ((SmartPrinter) -> AbstractImplementationPrinter)? = null, + createBuilderPrinter: ((SmartPrinter) -> AbstractBuilderPrinter)? = null, + afterConfiguration: () -> Unit = {}, + enableBaseTransformerTypeDetection: Boolean = true, + addFiles: MutableList.() -> Unit = {}, +) where Element : AbstractElement, + Implementation : AbstractImplementation, + ElementField : AbstractField, + ImplementationField : AbstractField<*>, + ImplementationField : AbstractFieldWithDefaultValue { + 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() + + 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 }) +} diff --git a/generators/tree-generator-common/src/org/jetbrains/kotlin/generators/tree/utils.kt b/generators/tree-generator-common/src/org/jetbrains/kotlin/generators/tree/utils.kt index 6613c0747cf..23a61a88b3e 100644 --- a/generators/tree-generator-common/src/org/jetbrains/kotlin/generators/tree/utils.kt +++ b/generators/tree-generator-common/src/org/jetbrains/kotlin/generators/tree/utils.kt @@ -65,6 +65,8 @@ operator fun Map>.get(k1: K, k2: V): U { return getValue(k1).getValue(k2) } +fun ((T1, T2, T3) -> R).bind(t3: T3): ((T1, T2) -> R) = { t1, t2 -> invoke(t1, t2, t3) } + internal fun > List.reorderFieldsIfNecessary(order: List?): List = if (order == null) { this