diff --git a/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/ImplementationConfigurator.kt b/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/ImplementationConfigurator.kt index 8072600c966..3d327ff2729 100644 --- a/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/ImplementationConfigurator.kt +++ b/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/ImplementationConfigurator.kt @@ -629,7 +629,7 @@ object ImplementationConfigurator : AbstractFirTreeImplementationConfigurator() override fun configureAllImplementations(model: Model) { configureFieldInAllImplementations( - field = "controlFlowGraphReference", + fieldName = "controlFlowGraphReference", implementationPredicate = { it.typeName != "FirAnonymousFunctionImpl" } ) { defaultNull(it) @@ -661,7 +661,7 @@ object ImplementationConfigurator : AbstractFirTreeImplementationConfigurator() "FirInaccessibleReceiverExpressionImpl" ) configureFieldInAllImplementations( - field = "typeRef", + fieldName = "typeRef", implementationPredicate = { it.typeName !in implementationWithConfigurableTypeRef }, fieldPredicate = { it.defaultValueInImplementation == null } ) { @@ -670,7 +670,7 @@ object ImplementationConfigurator : AbstractFirTreeImplementationConfigurator() } configureFieldInAllImplementations( - field = "lValueTypeRef", + fieldName = "lValueTypeRef", implementationPredicate = { it.typeName in "FirVariableAssignmentImpl" }, fieldPredicate = { it.defaultValueInImplementation == null } ) { diff --git a/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/printer/ImplementationPrinter.kt b/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/printer/ImplementationPrinter.kt index 09f1d1e9693..ec18dc42b4f 100644 --- a/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/printer/ImplementationPrinter.kt +++ b/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/printer/ImplementationPrinter.kt @@ -27,6 +27,9 @@ private class ImplementationFieldPrinter(printer: SmartPrinter) : AbstractFieldP override fun forceMutable(field: FieldWithDefault): Boolean = field.isMutable && field.isMutableOrEmptyIfList() override fun actualTypeOfField(field: FieldWithDefault) = field.getMutableType() + + override val wrapOptInAnnotations + get() = true } internal class ImplementationPrinter( diff --git a/compiler/ir/ir.tree/tree-generator/src/org/jetbrains/kotlin/ir/generator/ImplementationConfigurator.kt b/compiler/ir/ir.tree/tree-generator/src/org/jetbrains/kotlin/ir/generator/ImplementationConfigurator.kt index 6089c1317c7..91b5b9218ec 100644 --- a/compiler/ir/ir.tree/tree-generator/src/org/jetbrains/kotlin/ir/generator/ImplementationConfigurator.kt +++ b/compiler/ir/ir.tree/tree-generator/src/org/jetbrains/kotlin/ir/generator/ImplementationConfigurator.kt @@ -5,16 +5,139 @@ package org.jetbrains.kotlin.ir.generator +import org.jetbrains.kotlin.generators.tree.StandardTypes import org.jetbrains.kotlin.ir.generator.config.AbstractIrTreeImplementationConfigurator import org.jetbrains.kotlin.ir.generator.model.Element +import org.jetbrains.kotlin.ir.generator.model.ListField object ImplementationConfigurator : AbstractIrTreeImplementationConfigurator() { override fun configure(model: Model): Unit = with(IrTree) { - impl(simpleFunction) - impl(property) + impl(anonymousInitializer) { + implementation.doPrint = false + } + + impl(simpleFunction) { + implementation.doPrint = false + } + impl(functionWithLateBinding) { + implementation.doPrint = false + } + + impl(constructor) { + implementation.doPrint = false + } + + impl(field) { + implementation.doPrint = false + } + + impl(property) { + implementation.doPrint = false + } + impl(propertyWithLateBinding) { + implementation.doPrint = false + } + + impl(localDelegatedProperty) { + implementation.doPrint = false + } + + impl(typeParameter) { + implementation.doPrint = false + } + + impl(valueParameter) { + implementation.doPrint = false + } + + impl(variable) { + implementation.doPrint = false + } + + impl(`class`) { + implementation.doPrint = false + } + + impl(enumEntry) { + implementation.doPrint = false + } + + impl(script) { + implementation.doPrint = false + } + + impl(moduleFragment) { + implementation.doPrint = false + } + + impl(errorDeclaration) { + implementation.doPrint = false + } + + impl(externalPackageFragment) { + implementation.doPrint = false + } + + impl(file) { + implementation.doPrint = false + } + + impl(typeAlias) { + implementation.doPrint = false + } } override fun configureAllImplementations(model: Model) { - // Use configureFieldInAllImplementations to customize certain fields in all implementation classes + configureFieldInAllImplementations("parent") { + isLateinit("parent") + isMutable("parent") + } + + configureFieldInAllImplementations("attributeOwnerId") { + default(it, "this") + } + configureFieldInAllImplementations("originalBeforeInline") { + defaultNull(it) + } + + configureFieldInAllImplementations("metadata") { + defaultNull(it) + } + + configureFieldInAllImplementations("annotations") { + defaultEmptyList(it) + } + + configureFieldInAllImplementations("overriddenSymbols") { + defaultEmptyList(it) + } + + configureFieldInAllImplementations("typeParameters") { + defaultEmptyList(it) + } + + configureFieldInAllImplementations("statements") { + default(it, "ArrayList(2)") + } + + configureFieldInAllImplementations("descriptor", { impl -> impl.allFields.any { it.name == "symbol" } }) { + default(it, "symbol.descriptor", withGetter = true) + } + + configureFieldInAllImplementations( + fieldName = null, + fieldPredicate = { it is ListField && it.isChild && it.listType == StandardTypes.mutableList } + ) { + default(it, "ArrayList()") + } + + // Generation of implementation classes of IrExpression are left out for subsequent MR, as a part of KT-65773. + for (element in model.elements) { + if (element.category == Element.Category.Expression) { + for (implementation in element.implementations) { + implementation.doPrint = false + } + } + } } } \ No newline at end of file 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 5cb38b2c857..e7254ba8864 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 @@ -35,6 +35,7 @@ fun main(args: Array) { typeTransformerType to ::TypeTransformerPrinter.bind(model.rootElement), ), ImplementationConfigurator, + createImplementationPrinter = ::ImplementationPrinter, enableBaseTransformerTypeDetection = false, addFiles = { add(printFactory(generationPath, model)) } ) diff --git a/compiler/ir/ir.tree/tree-generator/src/org/jetbrains/kotlin/ir/generator/model/Element.kt b/compiler/ir/ir.tree/tree-generator/src/org/jetbrains/kotlin/ir/generator/model/Element.kt index 6f220670e96..0d8d206ad83 100644 --- a/compiler/ir/ir.tree/tree-generator/src/org/jetbrains/kotlin/ir/generator/model/Element.kt +++ b/compiler/ir/ir.tree/tree-generator/src/org/jetbrains/kotlin/ir/generator/model/Element.kt @@ -16,7 +16,7 @@ import org.jetbrains.kotlin.generators.tree.ElementRef as GenericElementRef class Element( name: String, override val propertyName: String, - category: Category, + val category: Category, ) : AbstractElement(name) { enum class Category(private val packageDir: String, val defaultVisitorParam: String) { diff --git a/compiler/ir/ir.tree/tree-generator/src/org/jetbrains/kotlin/ir/generator/model/Implementation.kt b/compiler/ir/ir.tree/tree-generator/src/org/jetbrains/kotlin/ir/generator/model/Implementation.kt index 8745e36578b..244bd06f6b3 100644 --- a/compiler/ir/ir.tree/tree-generator/src/org/jetbrains/kotlin/ir/generator/model/Implementation.kt +++ b/compiler/ir/ir.tree/tree-generator/src/org/jetbrains/kotlin/ir/generator/model/Implementation.kt @@ -7,8 +7,19 @@ package org.jetbrains.kotlin.ir.generator.model import org.jetbrains.kotlin.generators.tree.AbstractImplementation import org.jetbrains.kotlin.generators.tree.ImplementationKind +import org.jetbrains.kotlin.generators.tree.ImportCollector +import org.jetbrains.kotlin.utils.SmartPrinter class Implementation(element: Element, name: String?) : AbstractImplementation(element, name) { - override val allFields - get() = element.allFields + override val allFields: List = element.allFields.map { it.copy() } + + override var kind: ImplementationKind? = ImplementationKind.FinalClass + + var generationCallback: (context(ImportCollector) SmartPrinter.() -> Unit)? = null + + override var doPrint = true + + init { + isPublic = true + } } diff --git a/compiler/ir/ir.tree/tree-generator/src/org/jetbrains/kotlin/ir/generator/print/ImplementationPrinter.kt b/compiler/ir/ir.tree/tree-generator/src/org/jetbrains/kotlin/ir/generator/print/ImplementationPrinter.kt new file mode 100644 index 00000000000..ba5721e0e41 --- /dev/null +++ b/compiler/ir/ir.tree/tree-generator/src/org/jetbrains/kotlin/ir/generator/print/ImplementationPrinter.kt @@ -0,0 +1,49 @@ +/* + * Copyright 2010-2024 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.ir.generator.print + +import com.intellij.psi.util.PsiExpressionTrimRenderer.render +import org.jetbrains.kotlin.generators.tree.* +import org.jetbrains.kotlin.generators.tree.printer.printBlock +import org.jetbrains.kotlin.ir.generator.IrTree +import org.jetbrains.kotlin.ir.generator.IrTree.parent +import org.jetbrains.kotlin.ir.generator.irImplementationDetailType +import org.jetbrains.kotlin.ir.generator.model.* +import org.jetbrains.kotlin.utils.SmartPrinter + +internal class ImplementationPrinter(printer: SmartPrinter) : AbstractImplementationPrinter(printer) { + override fun makeFieldPrinter(printer: SmartPrinter) = object : AbstractFieldPrinter(printer) { + override fun forceMutable(field: Field) = field.isMutable + } + + override val pureAbstractElementType: ClassRef<*> + get() = org.jetbrains.kotlin.ir.generator.elementBaseType + + override val implementationOptInAnnotation: ClassRef<*> + get() = irImplementationDetailType + + override val separateFieldsWithBlankLine: Boolean + get() = true + + context(ImportCollector) + override fun SmartPrinter.printAdditionalMethods(implementation: Implementation) { + implementation.generationCallback?.invoke(this@ImportCollector, this) + + if ( + implementation.element.traverseParentsUntil { it == IrTree.symbolOwner } && + !implementation.element.let { it == IrTree.propertyWithLateBinding || it == IrTree.functionWithLateBinding } + ) { + val symbolField = implementation["symbol"] + if (symbolField != null) { + println() + print("init") + printBlock { + println("${symbolField.name}.bind(this)") + } + } + } + } +} \ No newline at end of file diff --git a/generators/tree-generator-common/src/org/jetbrains/kotlin/generators/tree/AbstractFieldPrinter.kt b/generators/tree-generator-common/src/org/jetbrains/kotlin/generators/tree/AbstractFieldPrinter.kt index 0d828ad16b6..89a1dedbe55 100644 --- a/generators/tree-generator-common/src/org/jetbrains/kotlin/generators/tree/AbstractFieldPrinter.kt +++ b/generators/tree-generator-common/src/org/jetbrains/kotlin/generators/tree/AbstractFieldPrinter.kt @@ -30,6 +30,9 @@ abstract class AbstractFieldPrinter>( */ protected open fun actualTypeOfField(field: Field): TypeRefWithNullability = field.typeRef + protected open val wrapOptInAnnotations: Boolean + get() = false + context(ImportCollector) fun printField( field: Field, @@ -51,9 +54,9 @@ abstract class AbstractFieldPrinter>( isLateinit = (inImplementation || field.isFinal) && field.isLateinit, isVolatile = (inImplementation || field.isFinal) && field.isVolatile, optInAnnotation = field.optInAnnotation, - printOptInWrapped = defaultValue != null, + printOptInWrapped = wrapOptInAnnotations && defaultValue != null, deprecation = field.deprecation, - kDoc = field.kDoc, + kDoc = field.kDoc.takeIf { !inImplementation }, initializer = defaultValue.takeUnless { field.withGetter } ) println() diff --git a/generators/tree-generator-common/src/org/jetbrains/kotlin/generators/tree/AbstractImplementation.kt b/generators/tree-generator-common/src/org/jetbrains/kotlin/generators/tree/AbstractImplementation.kt index cfeb52eb752..f7fe1837e8e 100644 --- a/generators/tree-generator-common/src/org/jetbrains/kotlin/generators/tree/AbstractImplementation.kt +++ b/generators/tree-generator-common/src/org/jetbrains/kotlin/generators/tree/AbstractImplementation.kt @@ -64,6 +64,10 @@ abstract class AbstractImplementation( get() = true var isPublic = false + var putImplementationOptInInConstructor = true + + var constructorParameterOrderOverride: List? = null + override fun get(fieldName: String): Field? { return allFields.firstOrNull { it.name == fieldName } } @@ -92,4 +96,7 @@ abstract class AbstractImplementation( } var builder: LeafBuilder? = null + + open val doPrint: Boolean + get() = true } diff --git a/generators/tree-generator-common/src/org/jetbrains/kotlin/generators/tree/AbstractImplementationPrinter.kt b/generators/tree-generator-common/src/org/jetbrains/kotlin/generators/tree/AbstractImplementationPrinter.kt index 6d9267c01d1..8862ba6932b 100644 --- a/generators/tree-generator-common/src/org/jetbrains/kotlin/generators/tree/AbstractImplementationPrinter.kt +++ b/generators/tree-generator-common/src/org/jetbrains/kotlin/generators/tree/AbstractImplementationPrinter.kt @@ -25,11 +25,13 @@ abstract class AbstractImplementationPrinter + protected open val separateFieldsWithBlankLine: Boolean + get() = false + protected abstract fun makeFieldPrinter(printer: SmartPrinter): AbstractFieldPrinter context(ImportCollector) - protected open fun SmartPrinter.printAdditionalMethods(implementation: Implementation) { - } + protected open fun SmartPrinter.printAdditionalMethods(implementation: Implementation) {} context(ImportCollector) fun printImplementation(implementation: Implementation) { @@ -63,19 +65,21 @@ abstract class AbstractImplementationPrinter - if (field.isParameter) { - print(field.name, ": ", field.typeRef.render()) - println(",") - } else if (!field.isFinal) { - fieldPrinter.printField(field, inImplementation = true, override = true, inConstructor = true) + implementation.fieldsInConstructor + .reorderFieldsIfNecessary(implementation.constructorParameterOrderOverride) + .forEachIndexed { _, field -> + if (field.isParameter) { + print(field.name, ": ", field.typeRef.render()) + println(",") + } else if (!field.isFinal) { + fieldPrinter.printField(field, inImplementation = true, override = true, inConstructor = true) + } } - } } print(")") } @@ -86,23 +90,18 @@ abstract class AbstractImplementationPrinter + if (index > 0 && separateFieldsWithBlankLine) { + println() } + fieldPrinter.printField( + field, + inImplementation = true, + override = true, + modality = Modality.ABSTRACT.takeIf { isAbstract } + ) } printAdditionalMethods(implementation) diff --git a/generators/tree-generator-common/src/org/jetbrains/kotlin/generators/tree/config/AbstractImplementationConfigurator.kt b/generators/tree-generator-common/src/org/jetbrains/kotlin/generators/tree/config/AbstractImplementationConfigurator.kt index 49eaf74419f..ca2cff0185b 100644 --- a/generators/tree-generator-common/src/org/jetbrains/kotlin/generators/tree/config/AbstractImplementationConfigurator.kt +++ b/generators/tree-generator-common/src/org/jetbrains/kotlin/generators/tree/config/AbstractImplementationConfigurator.kt @@ -80,14 +80,14 @@ abstract class AbstractImplementationConfigurator Boolean = { true }, fieldPredicate: (ImplementationField) -> Boolean = { true }, config: ImplementationContext.(field: String) -> Unit, @@ -95,9 +95,17 @@ abstract class AbstractImplementationConfigurator generateTree( pureAbstractElement: ClassRef<*>, createElementPrinter: (SmartPrinter) -> AbstractElementPrinter, createVisitorPrinters: List, (SmartPrinter, ClassRef<*>) -> AbstractVisitorPrinter>>, - implementationConfigurator: AbstractImplementationConfigurator? = null, + implementationConfigurator: AbstractImplementationConfigurator, builderConfigurator: AbstractBuilderConfigurator? = null, - createImplementationPrinter: ((SmartPrinter) -> AbstractImplementationPrinter)? = null, + createImplementationPrinter: (SmartPrinter) -> AbstractImplementationPrinter, createBuilderPrinter: ((SmartPrinter) -> AbstractBuilderPrinter)? = null, enableBaseTransformerTypeDetection: Boolean = true, addFiles: MutableList.() -> Unit = {}, @@ -98,7 +98,7 @@ fun generateTree( detectBaseTransformerTypes(model) } initializeSubElements(model.elements) - implementationConfigurator?.configureImplementations(model) + implementationConfigurator.configureImplementations(model) val implementations = model.elements.flatMap { it.implementations } InterfaceAndAbstractClassConfigurator((model.elements + implementations)) .configureInterfacesAndAbstractClasses() @@ -117,17 +117,15 @@ fun generateTree( } } - if (createImplementationPrinter != null) { - implementations.mapTo(generatedFiles) { implementation -> - printGeneratedType( - generationPath, - treeGeneratorReadme, - implementation.packageName, - implementation.typeName, - fileSuppressions = listOf("DuplicatedCode", "unused"), - ) { - createImplementationPrinter(this).printImplementation(implementation) - } + implementations.filter { it.doPrint }.mapTo(generatedFiles) { implementation -> + printGeneratedType( + generationPath, + treeGeneratorReadme, + implementation.packageName, + implementation.typeName, + fileSuppressions = listOf("DuplicatedCode", "unused"), + ) { + createImplementationPrinter(this).printImplementation(implementation) } } diff --git a/native/swift/sir/tree-generator/src/org/jetbrains/kotlin/sir/tree/generator/ImplementationConfigurator.kt b/native/swift/sir/tree-generator/src/org/jetbrains/kotlin/sir/tree/generator/ImplementationConfigurator.kt index 5c2cfcf60e0..1725b492a26 100644 --- a/native/swift/sir/tree-generator/src/org/jetbrains/kotlin/sir/tree/generator/ImplementationConfigurator.kt +++ b/native/swift/sir/tree-generator/src/org/jetbrains/kotlin/sir/tree/generator/ImplementationConfigurator.kt @@ -16,7 +16,7 @@ object ImplementationConfigurator : AbstractSwiftIrTreeImplementationConfigurato override fun configureAllImplementations(model: Model) { // Use configureFieldInAllImplementations to customize certain fields in all implementation classes configureFieldInAllImplementations( - field = "parent", + fieldName = "parent", ) { isMutable(it) isLateinit(it)