From 1bed6a063f03da9cc860b330b3370f6c98ba3b52 Mon Sep 17 00:00:00 2001 From: Sergej Jaskiewicz Date: Mon, 11 Dec 2023 19:41:19 +0100 Subject: [PATCH] [SIR] Add SirTransformerVoid class This is convenient for cases when the transformer has no context to pass to each method --- .../generator/print/TransformerVoidPrinter.kt | 12 +- .../tree/AbstractTransformerVoidPrinter.kt | 84 ++++++++++++++ .../generators/tree/printer/printUtils.kt | 104 ++++++++++++++---- .../org/jetbrains/kotlin/sir/SirElement.kt | 22 ++++ .../kotlin/sir/visitors/SirTransformerVoid.kt | 82 ++++++++++++++ .../kotlin/sir/tree/generator/Main.kt | 1 + .../kotlin/sir/tree/generator/Types.kt | 1 + .../tree/generator/printer/ElementPrinter.kt | 9 +- .../printer/TransformerVoidPrinter.kt | 23 ++++ 9 files changed, 304 insertions(+), 34 deletions(-) create mode 100644 generators/tree-generator-common/src/org/jetbrains/kotlin/generators/tree/AbstractTransformerVoidPrinter.kt create mode 100644 native/swift/sir/gen/org/jetbrains/kotlin/sir/visitors/SirTransformerVoid.kt create mode 100644 native/swift/sir/tree-generator/src/org/jetbrains/kotlin/sir/tree/generator/printer/TransformerVoidPrinter.kt 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 ecd3dbf38cf..89c83b7e64d 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 @@ -20,16 +20,10 @@ import org.jetbrains.kotlin.utils.withIndent internal class TransformerVoidPrinter( printer: SmartPrinter, override val visitorType: ClassRef<*>, -) : AbstractTransformerPrinter(printer) { +) : AbstractTransformerVoidPrinter(printer) { - override val visitorTypeParameters: List - get() = emptyList() - - override val visitorSuperType: ClassRef - get() = elementTransformerType.withArgs(visitorDataType) - - override val visitorDataType: TypeRef - get() = StandardTypes.nothing.copy(nullable = true) + override val transformerSuperClass: ClassRef + get() = elementTransformerType // IrPackageFragment is treated as transformByChildren in IrElementTransformerVoid for historical reasons. private val Element.isPackageFragment: Boolean diff --git a/generators/tree-generator-common/src/org/jetbrains/kotlin/generators/tree/AbstractTransformerVoidPrinter.kt b/generators/tree-generator-common/src/org/jetbrains/kotlin/generators/tree/AbstractTransformerVoidPrinter.kt new file mode 100644 index 00000000000..dc3a9842f78 --- /dev/null +++ b/generators/tree-generator-common/src/org/jetbrains/kotlin/generators/tree/AbstractTransformerVoidPrinter.kt @@ -0,0 +1,84 @@ +/* + * Copyright 2010-2023 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.generators.tree + +import org.jetbrains.kotlin.descriptors.Modality +import org.jetbrains.kotlin.generators.tree.printer.FunctionParameter +import org.jetbrains.kotlin.generators.tree.printer.printFunctionDeclaration +import org.jetbrains.kotlin.utils.SmartPrinter +import org.jetbrains.kotlin.utils.withIndent + +abstract class AbstractTransformerVoidPrinter, Field : AbstractField>( + printer: SmartPrinter +) : AbstractTransformerPrinter(printer) { + + final override val visitorTypeParameters: List + get() = emptyList() + + final override val visitorDataType: TypeRef + get() = StandardTypes.nothing.copy(nullable = true) + + abstract val transformerSuperClass: ClassRef + + override val visitorSuperType: ClassRef? + get() = transformerSuperClass.withArgs(visitorDataType) + + context(ImportCollector) + override fun printMethodsForElement(element: Element) { + printer.run { + val elementParameterName = element.visitorParameterName + val dataParameter = FunctionParameter("data", visitorDataType) + val methodName = "transform" + element.name + if (element.isRootElement) { + println() + val elementTP = TypeVariable("E", listOf(element)) + printFunctionDeclaration( + name = methodName, + parameters = listOf(FunctionParameter(elementParameterName, elementTP)), + returnType = elementTP, + typeParameters = listOf(elementTP), + modality = Modality.ABSTRACT, + ) + println() + println() + printFunctionDeclaration( + name = methodName, + parameters = listOf(FunctionParameter(elementParameterName, elementTP), dataParameter), + returnType = elementTP, + typeParameters = listOf(elementTP), + modality = Modality.FINAL, + override = true, + ) + } else { + val parentInVisitor = parentInVisitor(element) ?: return + val returnType = visitMethodReturnType(element) + println() + printFunctionDeclaration( + name = methodName, + parameters = listOf(FunctionParameter(elementParameterName, element)), + returnType = returnType, + modality = Modality.OPEN, + ) + println(" =") + withIndent { + println("transform", parentInVisitor.name, "(", elementParameterName, ")") + } + println() + printFunctionDeclaration( + name = methodName, + parameters = listOf(FunctionParameter(elementParameterName, element), dataParameter), + returnType = returnType, + modality = Modality.FINAL, + override = true, + ) + } + println(" =") + withIndent { + println(methodName, "(", elementParameterName, ")") + } + } + } +} \ No newline at end of file diff --git a/generators/tree-generator-common/src/org/jetbrains/kotlin/generators/tree/printer/printUtils.kt b/generators/tree-generator-common/src/org/jetbrains/kotlin/generators/tree/printer/printUtils.kt index 376bdd9b087..c68547f5b66 100644 --- a/generators/tree-generator-common/src/org/jetbrains/kotlin/generators/tree/printer/printUtils.kt +++ b/generators/tree-generator-common/src/org/jetbrains/kotlin/generators/tree/printer/printUtils.kt @@ -237,6 +237,27 @@ fun SmartPrinter.printAcceptMethod( println() } +private fun transformMethodKDoc( + transformerParameter: FunctionParameter, + dataParameter: FunctionParameter?, + treeName: String, +) = buildString { + append("Runs the provided [") + append(transformerParameter.name) + append("] on the $treeName subtree with the root at this node.\n\n") + append("@param ") + append(transformerParameter.name) + append(" The transformer to use.") + if (dataParameter != null) { + append("\n@param ") + append(dataParameter.name) + append(" An arbitrary context to pass to each invocation of [") + append(transformerParameter.name) + append("]'s methods.") + } + append("\n@return The transformed node.") +} + context(ImportCollector) fun SmartPrinter.printTransformMethod( element: AbstractElement<*, *, *>, @@ -249,15 +270,7 @@ fun SmartPrinter.printTransformMethod( println() val transformerParameter = FunctionParameter("transformer", transformerClass.withArgs(dataTP)) if (element.isRootElement) { - printKDoc( - """ - Runs the provided [${transformerParameter.name}] on the $treeName subtree with the root at this node. - - @param ${transformerParameter.name} The transformer to use. - @param ${dataParameter.name} An arbitrary context to pass to each invocation of [${transformerParameter.name}]'s methods. - @return The transformed node. - """.trimIndent() - ) + printKDoc(transformMethodKDoc(transformerParameter, dataParameter, treeName)) } if (returnType is TypeParameterRef && implementation != null) { println("@Suppress(\"UNCHECKED_CAST\")") @@ -313,6 +326,36 @@ fun SmartPrinter.printAcceptChildrenMethod( ) } +private fun transformChildrenMethodKDoc(transformerParameter: FunctionParameter, dataParameter: FunctionParameter?, returnType: TypeRef) = + buildString { + append("Recursively transforms this node's children *in place* using [") + append(transformerParameter.name) + append("].\n\n") + append("Basically, executes `this.child = this.child.transform(") + append(transformerParameter.name) + if (dataParameter != null) { + append(", ") + append(dataParameter.name) + } + append(")` for each child of this node.\n\n") + append("Does **not** run [") + append(transformerParameter.name) + append("] on this node itself.\n\n") + append("@param ") + append(transformerParameter.name) + append(" The transformer to use for transforming the children.") + if (dataParameter != null) { + append("\n@param ") + append(dataParameter.name) + append(" An arbitrary context to pass to each invocation of [") + append(transformerParameter.name) + append("]'s methods.") + } + if (returnType != StandardTypes.unit) { + append("\n@return `this`") + } + } + context(ImportCollector) fun SmartPrinter.printTransformChildrenMethod( element: FieldContainer<*>, @@ -325,18 +368,7 @@ fun SmartPrinter.printTransformChildrenMethod( println() val transformerParameter = FunctionParameter("transformer", transformerClass.withArgs(dataTP)) if (!override) { - printKDoc( - """ - Recursively transforms this node's children *in place* using [${transformerParameter.name}]. - - Basically, executes `this.child = this.child.transform(${transformerParameter.name}, ${dataParameter.name})` for each child of this node. - - Does **not** run [${transformerParameter.name}] on this node itself. - - @param ${transformerParameter.name} The transformer to use for transforming the children. - @param ${dataParameter.name} An arbitrary context to pass to each invocation of [${transformerParameter.name}]'s methods. - """.trimIndent() + (if (returnType == StandardTypes.unit) "" else "\n@return `this`") - ) + printKDoc(transformChildrenMethodKDoc(transformerParameter, dataParameter, returnType)) } printFunctionDeclaration( name = "transformChildren", @@ -362,4 +394,34 @@ fun SmartPrinter.printAcceptChildrenVoidMethod(visitorType: ClassRef<*>) { println(" = acceptChildren(", visitorParameter.name, ", null)") } +context(ImportCollector) +fun SmartPrinter.printTransformVoidMethod(element: AbstractElement<*, *, *>, transformerType: ClassRef<*>, treeName: String) { + assert(element.isRootElement) { "Expected root element" } + val transformerParameter = FunctionParameter("transformer", transformerType) + val elementTP = TypeVariable("E", listOf(element)) + printKDoc(transformMethodKDoc(transformerParameter, null, treeName)) + printFunctionDeclaration( + name = "transform", + parameters = listOf(transformerParameter), + returnType = elementTP, + typeParameters = listOf(elementTP) + ) + println(" =") + withIndent { + println("transform(", transformerParameter.name, ", null)") + } +} + +context(ImportCollector) +fun SmartPrinter.printTransformChildrenVoidMethod(element: AbstractElement<*, *, *>, visitorType: ClassRef<*>, returnType: TypeRef) { + assert(element.isRootElement) { "Expected root element" } + val transformerParameter = FunctionParameter("transformer", visitorType) + printKDoc(transformChildrenMethodKDoc(transformerParameter, null, returnType)) + printFunctionDeclaration("transformChildren", listOf(transformerParameter), returnType) + println(" =") + withIndent { + println("transformChildren(", transformerParameter.name, ", null)") + } +} + fun AbstractField<*>.call(): String = if (nullable) "?." else "." diff --git a/native/swift/sir/gen/org/jetbrains/kotlin/sir/SirElement.kt b/native/swift/sir/gen/org/jetbrains/kotlin/sir/SirElement.kt index 31b0fbd60c6..62c2cd44631 100644 --- a/native/swift/sir/gen/org/jetbrains/kotlin/sir/SirElement.kt +++ b/native/swift/sir/gen/org/jetbrains/kotlin/sir/SirElement.kt @@ -9,6 +9,7 @@ package org.jetbrains.kotlin.sir import org.jetbrains.kotlin.sir.visitors.SirTransformer +import org.jetbrains.kotlin.sir.visitors.SirTransformerVoid import org.jetbrains.kotlin.sir.visitors.SirVisitor import org.jetbrains.kotlin.sir.visitors.SirVisitorVoid @@ -54,6 +55,15 @@ sealed interface SirElement { fun acceptChildren(visitor: SirVisitorVoid) = acceptChildren(visitor, null) + /** + * Runs the provided [transformer] on the Swift IR subtree with the root at this node. + * + * @param transformer The transformer to use. + * @return The transformed node. + */ + fun transform(transformer: SirTransformerVoid): E = + transform(transformer, null) + /** * Recursively transforms this node's children *in place* using [transformer]. * @@ -65,4 +75,16 @@ sealed interface SirElement { * @param data An arbitrary context to pass to each invocation of [transformer]'s methods. */ fun transformChildren(transformer: SirTransformer, data: D) + + /** + * Recursively transforms this node's children *in place* using [transformer]. + * + * Basically, executes `this.child = this.child.transform(transformer)` for each child of this node. + * + * Does **not** run [transformer] on this node itself. + * + * @param transformer The transformer to use for transforming the children. + */ + fun transformChildren(transformer: SirTransformerVoid) = + transformChildren(transformer, null) } diff --git a/native/swift/sir/gen/org/jetbrains/kotlin/sir/visitors/SirTransformerVoid.kt b/native/swift/sir/gen/org/jetbrains/kotlin/sir/visitors/SirTransformerVoid.kt new file mode 100644 index 00000000000..766e6b2efa8 --- /dev/null +++ b/native/swift/sir/gen/org/jetbrains/kotlin/sir/visitors/SirTransformerVoid.kt @@ -0,0 +1,82 @@ +/* + * Copyright 2010-2023 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. + */ + +// This file was generated automatically. See native/swift/sir/tree-generator/Readme.md. +// DO NOT MODIFY IT MANUALLY. + +package org.jetbrains.kotlin.sir.visitors + +import org.jetbrains.kotlin.sir.* + +/** + * Auto-generated by [org.jetbrains.kotlin.sir.tree.generator.printer.TransformerVoidPrinter] + */ +abstract class SirTransformerVoid : SirTransformer() { + + abstract fun transformElement(element: E): E + + final override fun transformElement(element: E, data: Nothing?): E = + transformElement(element) + + open fun transformModule(module: SirModule): SirModule = + transformElement(module) + + final override fun transformModule(module: SirModule, data: Nothing?): SirModule = + transformModule(module) + + open fun transformDeclarationContainer(declarationContainer: SirDeclarationContainer): SirDeclarationContainer = + transformElement(declarationContainer) + + final override fun transformDeclarationContainer(declarationContainer: SirDeclarationContainer, data: Nothing?): SirDeclarationContainer = + transformDeclarationContainer(declarationContainer) + + open fun transformDeclaration(declaration: SirDeclaration): SirDeclaration = + transformElement(declaration) + + final override fun transformDeclaration(declaration: SirDeclaration, data: Nothing?): SirDeclaration = + transformDeclaration(declaration) + + open fun transformForeignDeclaration(foreignDeclaration: SirForeignDeclaration): SirDeclaration = + transformDeclaration(foreignDeclaration) + + final override fun transformForeignDeclaration(foreignDeclaration: SirForeignDeclaration, data: Nothing?): SirDeclaration = + transformForeignDeclaration(foreignDeclaration) + + open fun transformNamedDeclaration(namedDeclaration: SirNamedDeclaration): SirDeclaration = + transformDeclaration(namedDeclaration) + + final override fun transformNamedDeclaration(namedDeclaration: SirNamedDeclaration, data: Nothing?): SirDeclaration = + transformNamedDeclaration(namedDeclaration) + + open fun transformEnum(enum: SirEnum): SirDeclaration = + transformNamedDeclaration(enum) + + final override fun transformEnum(enum: SirEnum, data: Nothing?): SirDeclaration = + transformEnum(enum) + + open fun transformStruct(struct: SirStruct): SirDeclaration = + transformNamedDeclaration(struct) + + final override fun transformStruct(struct: SirStruct, data: Nothing?): SirDeclaration = + transformStruct(struct) + + open fun transformCallable(callable: SirCallable): SirDeclaration = + transformDeclaration(callable) + + final override fun transformCallable(callable: SirCallable, data: Nothing?): SirDeclaration = + transformCallable(callable) + + open fun transformFunction(function: SirFunction): SirDeclaration = + transformCallable(function) + + final override fun transformFunction(function: SirFunction, data: Nothing?): SirDeclaration = + transformFunction(function) + + open fun transformForeignFunction(foreignFunction: SirForeignFunction): SirDeclaration = + transformCallable(foreignFunction) + + final override fun transformForeignFunction(foreignFunction: SirForeignFunction, data: Nothing?): SirDeclaration = + transformForeignFunction(foreignFunction) +} diff --git a/native/swift/sir/tree-generator/src/org/jetbrains/kotlin/sir/tree/generator/Main.kt b/native/swift/sir/tree-generator/src/org/jetbrains/kotlin/sir/tree/generator/Main.kt index e0abdc47f4d..929a5ba9051 100644 --- a/native/swift/sir/tree-generator/src/org/jetbrains/kotlin/sir/tree/generator/Main.kt +++ b/native/swift/sir/tree-generator/src/org/jetbrains/kotlin/sir/tree/generator/Main.kt @@ -29,6 +29,7 @@ fun main(args: Array) { elementVisitorType to ::VisitorPrinter, elementVisitorVoidType to ::VisitorVoidPrinter, elementTransformerType to ::TransformerPrinter.bind(model.rootElement), + elementTransformerVoidType to ::TransformerVoidPrinter, ), ImplementationConfigurator, BuilderConfigurator(model.elements), diff --git a/native/swift/sir/tree-generator/src/org/jetbrains/kotlin/sir/tree/generator/Types.kt b/native/swift/sir/tree-generator/src/org/jetbrains/kotlin/sir/tree/generator/Types.kt index c5838e7f42a..38a3bcc84ef 100644 --- a/native/swift/sir/tree-generator/src/org/jetbrains/kotlin/sir/tree/generator/Types.kt +++ b/native/swift/sir/tree-generator/src/org/jetbrains/kotlin/sir/tree/generator/Types.kt @@ -20,6 +20,7 @@ private const val VISITORS_PACKAGE = "$BASE_PACKAGE.visitors" val elementVisitorType = type(VISITORS_PACKAGE, "SirVisitor", TypeKind.Class) val elementVisitorVoidType = type(VISITORS_PACKAGE, "SirVisitorVoid", TypeKind.Class) val elementTransformerType = type(VISITORS_PACKAGE, "SirTransformer", TypeKind.Class) +val elementTransformerVoidType = type(VISITORS_PACKAGE, "SirTransformerVoid", TypeKind.Class) val swiftIrImplementationDetailAnnotation = type(BASE_PACKAGE, "SirImplementationDetail", TypeKind.Class) val swiftIrBuilderDslAnnotation = type(BASE_PACKAGE, "SirBuilderDsl", TypeKind.Class) diff --git a/native/swift/sir/tree-generator/src/org/jetbrains/kotlin/sir/tree/generator/printer/ElementPrinter.kt b/native/swift/sir/tree-generator/src/org/jetbrains/kotlin/sir/tree/generator/printer/ElementPrinter.kt index aedf925188b..84790311c3f 100644 --- a/native/swift/sir/tree-generator/src/org/jetbrains/kotlin/sir/tree/generator/printer/ElementPrinter.kt +++ b/native/swift/sir/tree-generator/src/org/jetbrains/kotlin/sir/tree/generator/printer/ElementPrinter.kt @@ -7,10 +7,7 @@ package org.jetbrains.kotlin.sir.tree.generator.printer import org.jetbrains.kotlin.generators.tree.* import org.jetbrains.kotlin.generators.tree.printer.* -import org.jetbrains.kotlin.sir.tree.generator.SwiftIrTree -import org.jetbrains.kotlin.sir.tree.generator.elementTransformerType -import org.jetbrains.kotlin.sir.tree.generator.elementVisitorType -import org.jetbrains.kotlin.sir.tree.generator.elementVisitorVoidType +import org.jetbrains.kotlin.sir.tree.generator.* import org.jetbrains.kotlin.sir.tree.generator.model.Element import org.jetbrains.kotlin.sir.tree.generator.model.Field import org.jetbrains.kotlin.utils.SmartPrinter @@ -42,8 +39,12 @@ internal class ElementPrinter(printer: SmartPrinter) : AbstractElementPrinter, +) : AbstractTransformerVoidPrinter(printer) { + + override val transformerSuperClass: ClassRef + get() = elementTransformerType +} \ No newline at end of file