From 0d2032f3ef01b178c8c29df8440986546c7c7826 Mon Sep 17 00:00:00 2001 From: Sergej Jaskiewicz Date: Wed, 6 Dec 2023 13:07:46 +0100 Subject: [PATCH] [SIR] Auto-generate the Swift IR tree Co-authored-by: Gleb Lukianets --- .../Generate_SwiftIR_tree.xml | 24 ++++ build.gradle.kts | 1 + .../kotlin/generators/tree/AbstractElement.kt | 6 +- .../generators/tree/AbstractVisitorPrinter.kt | 3 +- native/swift/sir/build.gradle.kts | 43 +++++++ .../kotlin/sir/builder/SirEnumBuilder.kt | 14 +++ .../sir/builder/SirForeignFunctionBuilder.kt | 11 ++ .../kotlin/sir/builder/SirFunctionBuilder.kt | 14 +++ .../kotlin/sir/builder/SirModuleBuilder.kt | 11 ++ .../kotlin/sir/builder/SirStructBuilder.kt | 13 +++ .../jetbrains/kotlin/sir/impl/SirEnumImpl.kt | 2 + .../kotlin/sir/impl/SirForeignFunctionImpl.kt | 2 + .../kotlin/sir/impl/SirFunctionImpl.kt | 2 + .../kotlin/sir/impl/SirModuleImpl.kt | 2 + .../kotlin/sir/impl/SirStructImpl.kt | 2 + native/swift/sir/tree-generator/Readme.md | 13 +++ .../swift/sir/tree-generator/build.gradle.kts | 24 ++++ .../sir/tree/generator/BuilderConfigurator.kt | 26 +++++ .../generator/ImplementationConfigurator.kt | 25 ++++ .../kotlin/sir/tree/generator/Main.kt | 38 ++++++ .../kotlin/sir/tree/generator/SwiftIrTree.kt | 90 ++++++++++++++ .../kotlin/sir/tree/generator/Types.kt | 24 ++++ .../config/AbstractSwiftIrTreeBuilder.kt | 110 ++++++++++++++++++ .../AbstractSwiftIrTreeBuilderConfigurator.kt | 25 ++++ ...ctSwiftIrTreeImplementationConfigurator.kt | 15 +++ .../sir/tree/generator/model/Element.kt | 61 ++++++++++ .../kotlin/sir/tree/generator/model/Field.kt | 74 ++++++++++++ .../tree/generator/model/Implementation.kt | 12 ++ .../tree/generator/printer/BuilderPrinter.kt | 24 ++++ .../tree/generator/printer/ElementPrinter.kt | 46 ++++++++ .../printer/ImplementationPrinter.kt | 96 +++++++++++++++ .../generator/printer/TransformerPrinter.kt | 88 ++++++++++++++ .../tree/generator/printer/VisitorPrinter.kt | 28 +++++ settings.gradle | 1 + 34 files changed, 968 insertions(+), 2 deletions(-) create mode 100644 .idea/runConfigurations/Generate_SwiftIR_tree.xml create mode 100644 native/swift/sir/tree-generator/Readme.md create mode 100644 native/swift/sir/tree-generator/build.gradle.kts create mode 100644 native/swift/sir/tree-generator/src/org/jetbrains/kotlin/sir/tree/generator/BuilderConfigurator.kt create mode 100644 native/swift/sir/tree-generator/src/org/jetbrains/kotlin/sir/tree/generator/ImplementationConfigurator.kt create mode 100644 native/swift/sir/tree-generator/src/org/jetbrains/kotlin/sir/tree/generator/Main.kt create mode 100644 native/swift/sir/tree-generator/src/org/jetbrains/kotlin/sir/tree/generator/SwiftIrTree.kt create mode 100644 native/swift/sir/tree-generator/src/org/jetbrains/kotlin/sir/tree/generator/Types.kt create mode 100644 native/swift/sir/tree-generator/src/org/jetbrains/kotlin/sir/tree/generator/config/AbstractSwiftIrTreeBuilder.kt create mode 100644 native/swift/sir/tree-generator/src/org/jetbrains/kotlin/sir/tree/generator/config/AbstractSwiftIrTreeBuilderConfigurator.kt create mode 100644 native/swift/sir/tree-generator/src/org/jetbrains/kotlin/sir/tree/generator/config/AbstractSwiftIrTreeImplementationConfigurator.kt create mode 100644 native/swift/sir/tree-generator/src/org/jetbrains/kotlin/sir/tree/generator/model/Element.kt create mode 100644 native/swift/sir/tree-generator/src/org/jetbrains/kotlin/sir/tree/generator/model/Field.kt create mode 100644 native/swift/sir/tree-generator/src/org/jetbrains/kotlin/sir/tree/generator/model/Implementation.kt create mode 100644 native/swift/sir/tree-generator/src/org/jetbrains/kotlin/sir/tree/generator/printer/BuilderPrinter.kt create mode 100644 native/swift/sir/tree-generator/src/org/jetbrains/kotlin/sir/tree/generator/printer/ElementPrinter.kt create mode 100644 native/swift/sir/tree-generator/src/org/jetbrains/kotlin/sir/tree/generator/printer/ImplementationPrinter.kt create mode 100644 native/swift/sir/tree-generator/src/org/jetbrains/kotlin/sir/tree/generator/printer/TransformerPrinter.kt create mode 100644 native/swift/sir/tree-generator/src/org/jetbrains/kotlin/sir/tree/generator/printer/VisitorPrinter.kt diff --git a/.idea/runConfigurations/Generate_SwiftIR_tree.xml b/.idea/runConfigurations/Generate_SwiftIR_tree.xml new file mode 100644 index 00000000000..b2301a3ceac --- /dev/null +++ b/.idea/runConfigurations/Generate_SwiftIR_tree.xml @@ -0,0 +1,24 @@ + + + + + + + true + true + false + false + + + \ No newline at end of file diff --git a/build.gradle.kts b/build.gradle.kts index 19e9d9c1720..c1abd58dea7 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -485,6 +485,7 @@ val projectsWithEnabledContextReceivers by extra { ":compiler:fir:raw-fir:light-tree2fir", ":compiler:fir:tree:tree-generator", ":compiler:ir.tree:tree-generator", + ":native:swift:sir:tree-generator", ":generators:tree-generator-common", ":kotlin-lombok-compiler-plugin.k1", ":kotlinx-serialization-compiler-plugin.k2", diff --git a/generators/tree-generator-common/src/org/jetbrains/kotlin/generators/tree/AbstractElement.kt b/generators/tree-generator-common/src/org/jetbrains/kotlin/generators/tree/AbstractElement.kt index bb506456cf9..ecd230b4afd 100644 --- a/generators/tree-generator-common/src/org/jetbrains/kotlin/generators/tree/AbstractElement.kt +++ b/generators/tree-generator-common/src/org/jetbrains/kotlin/generators/tree/AbstractElement.kt @@ -6,7 +6,11 @@ package org.jetbrains.kotlin.generators.tree /** - * A class representing a FIR or IR tree element. + * Represents an abstract class/interface for a tree node in the tree generator. + * + * Examples: `IrElement`, `FirRegularClass`. + * + * Subclasses may contain additional properties/logic specific to a particular tree. */ abstract class AbstractElement( val name: String, 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 33d03c60667..e387217f4b3 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 @@ -49,7 +49,8 @@ abstract class AbstractVisitorPrinter Unit): SirEnum { } return SirEnumBuilder().apply(init).build() } + +@OptIn(ExperimentalContracts::class) +inline fun buildEnumCopy(original: SirEnum, init: SirEnumBuilder.() -> Unit): SirEnum { + contract { + callsInPlace(init, InvocationKind.EXACTLY_ONCE) + } + val copyBuilder = SirEnumBuilder() + copyBuilder.origin = original.origin + copyBuilder.visibility = original.visibility + copyBuilder.name = original.name + copyBuilder.declarations.addAll(original.declarations) + copyBuilder.cases.addAll(original.cases) + return copyBuilder.apply(init).build() +} diff --git a/native/swift/sir/gen/org/jetbrains/kotlin/sir/builder/SirForeignFunctionBuilder.kt b/native/swift/sir/gen/org/jetbrains/kotlin/sir/builder/SirForeignFunctionBuilder.kt index 9b1cf087555..3dc451c89f1 100644 --- a/native/swift/sir/gen/org/jetbrains/kotlin/sir/builder/SirForeignFunctionBuilder.kt +++ b/native/swift/sir/gen/org/jetbrains/kotlin/sir/builder/SirForeignFunctionBuilder.kt @@ -37,3 +37,14 @@ inline fun buildForeignFunction(init: SirForeignFunctionBuilder.() -> Unit = {}) } return SirForeignFunctionBuilder().apply(init).build() } + +@OptIn(ExperimentalContracts::class) +inline fun buildForeignFunctionCopy(original: SirForeignFunction, init: SirForeignFunctionBuilder.() -> Unit = {}): SirForeignFunction { + contract { + callsInPlace(init, InvocationKind.EXACTLY_ONCE) + } + val copyBuilder = SirForeignFunctionBuilder() + copyBuilder.origin = original.origin + copyBuilder.visibility = original.visibility + return copyBuilder.apply(init).build() +} diff --git a/native/swift/sir/gen/org/jetbrains/kotlin/sir/builder/SirFunctionBuilder.kt b/native/swift/sir/gen/org/jetbrains/kotlin/sir/builder/SirFunctionBuilder.kt index 18ce1981189..f0c48cee89a 100644 --- a/native/swift/sir/gen/org/jetbrains/kotlin/sir/builder/SirFunctionBuilder.kt +++ b/native/swift/sir/gen/org/jetbrains/kotlin/sir/builder/SirFunctionBuilder.kt @@ -40,3 +40,17 @@ inline fun buildFunction(init: SirFunctionBuilder.() -> Unit): SirFunction { } return SirFunctionBuilder().apply(init).build() } + +@OptIn(ExperimentalContracts::class) +inline fun buildFunctionCopy(original: SirFunction, init: SirFunctionBuilder.() -> Unit): SirFunction { + contract { + callsInPlace(init, InvocationKind.EXACTLY_ONCE) + } + val copyBuilder = SirFunctionBuilder() + copyBuilder.origin = original.origin + copyBuilder.visibility = original.visibility + copyBuilder.name = original.name + copyBuilder.parameters.addAll(original.parameters) + copyBuilder.returnType = original.returnType + return copyBuilder.apply(init).build() +} diff --git a/native/swift/sir/gen/org/jetbrains/kotlin/sir/builder/SirModuleBuilder.kt b/native/swift/sir/gen/org/jetbrains/kotlin/sir/builder/SirModuleBuilder.kt index 382d22e1249..e2a841ee697 100644 --- a/native/swift/sir/gen/org/jetbrains/kotlin/sir/builder/SirModuleBuilder.kt +++ b/native/swift/sir/gen/org/jetbrains/kotlin/sir/builder/SirModuleBuilder.kt @@ -36,3 +36,14 @@ inline fun buildModule(init: SirModuleBuilder.() -> Unit): SirModule { } return SirModuleBuilder().apply(init).build() } + +@OptIn(ExperimentalContracts::class) +inline fun buildModuleCopy(original: SirModule, init: SirModuleBuilder.() -> Unit): SirModule { + contract { + callsInPlace(init, InvocationKind.EXACTLY_ONCE) + } + val copyBuilder = SirModuleBuilder() + copyBuilder.declarations.addAll(original.declarations) + copyBuilder.name = original.name + return copyBuilder.apply(init).build() +} diff --git a/native/swift/sir/gen/org/jetbrains/kotlin/sir/builder/SirStructBuilder.kt b/native/swift/sir/gen/org/jetbrains/kotlin/sir/builder/SirStructBuilder.kt index cc06c4aa611..aa7c0b383dc 100644 --- a/native/swift/sir/gen/org/jetbrains/kotlin/sir/builder/SirStructBuilder.kt +++ b/native/swift/sir/gen/org/jetbrains/kotlin/sir/builder/SirStructBuilder.kt @@ -38,3 +38,16 @@ inline fun buildStruct(init: SirStructBuilder.() -> Unit): SirStruct { } return SirStructBuilder().apply(init).build() } + +@OptIn(ExperimentalContracts::class) +inline fun buildStructCopy(original: SirStruct, init: SirStructBuilder.() -> Unit): SirStruct { + contract { + callsInPlace(init, InvocationKind.EXACTLY_ONCE) + } + val copyBuilder = SirStructBuilder() + copyBuilder.origin = original.origin + copyBuilder.visibility = original.visibility + copyBuilder.name = original.name + copyBuilder.declarations.addAll(original.declarations) + return copyBuilder.apply(init).build() +} diff --git a/native/swift/sir/gen/org/jetbrains/kotlin/sir/impl/SirEnumImpl.kt b/native/swift/sir/gen/org/jetbrains/kotlin/sir/impl/SirEnumImpl.kt index 908d28cfdcb..27b3bc1696e 100644 --- a/native/swift/sir/gen/org/jetbrains/kotlin/sir/impl/SirEnumImpl.kt +++ b/native/swift/sir/gen/org/jetbrains/kotlin/sir/impl/SirEnumImpl.kt @@ -6,6 +6,8 @@ // This file was generated automatically. See native/swift/sir/tree-generator/Readme.md. // DO NOT MODIFY IT MANUALLY. +@file:Suppress("DuplicatedCode", "unused") + package org.jetbrains.kotlin.sir.impl import org.jetbrains.kotlin.sir.* diff --git a/native/swift/sir/gen/org/jetbrains/kotlin/sir/impl/SirForeignFunctionImpl.kt b/native/swift/sir/gen/org/jetbrains/kotlin/sir/impl/SirForeignFunctionImpl.kt index c94482f9726..45a2ef67ddc 100644 --- a/native/swift/sir/gen/org/jetbrains/kotlin/sir/impl/SirForeignFunctionImpl.kt +++ b/native/swift/sir/gen/org/jetbrains/kotlin/sir/impl/SirForeignFunctionImpl.kt @@ -6,6 +6,8 @@ // This file was generated automatically. See native/swift/sir/tree-generator/Readme.md. // DO NOT MODIFY IT MANUALLY. +@file:Suppress("DuplicatedCode", "unused") + package org.jetbrains.kotlin.sir.impl import org.jetbrains.kotlin.sir.SirDeclarationParent diff --git a/native/swift/sir/gen/org/jetbrains/kotlin/sir/impl/SirFunctionImpl.kt b/native/swift/sir/gen/org/jetbrains/kotlin/sir/impl/SirFunctionImpl.kt index dca0db2331b..daeb75df6fd 100644 --- a/native/swift/sir/gen/org/jetbrains/kotlin/sir/impl/SirFunctionImpl.kt +++ b/native/swift/sir/gen/org/jetbrains/kotlin/sir/impl/SirFunctionImpl.kt @@ -6,6 +6,8 @@ // This file was generated automatically. See native/swift/sir/tree-generator/Readme.md. // DO NOT MODIFY IT MANUALLY. +@file:Suppress("DuplicatedCode", "unused") + package org.jetbrains.kotlin.sir.impl import org.jetbrains.kotlin.sir.* diff --git a/native/swift/sir/gen/org/jetbrains/kotlin/sir/impl/SirModuleImpl.kt b/native/swift/sir/gen/org/jetbrains/kotlin/sir/impl/SirModuleImpl.kt index 4376a9dee58..2d3a0b3c771 100644 --- a/native/swift/sir/gen/org/jetbrains/kotlin/sir/impl/SirModuleImpl.kt +++ b/native/swift/sir/gen/org/jetbrains/kotlin/sir/impl/SirModuleImpl.kt @@ -6,6 +6,8 @@ // This file was generated automatically. See native/swift/sir/tree-generator/Readme.md. // DO NOT MODIFY IT MANUALLY. +@file:Suppress("DuplicatedCode", "unused") + package org.jetbrains.kotlin.sir.impl import org.jetbrains.kotlin.sir.SirDeclaration diff --git a/native/swift/sir/gen/org/jetbrains/kotlin/sir/impl/SirStructImpl.kt b/native/swift/sir/gen/org/jetbrains/kotlin/sir/impl/SirStructImpl.kt index e0c641b48c3..acfb92cdead 100644 --- a/native/swift/sir/gen/org/jetbrains/kotlin/sir/impl/SirStructImpl.kt +++ b/native/swift/sir/gen/org/jetbrains/kotlin/sir/impl/SirStructImpl.kt @@ -6,6 +6,8 @@ // This file was generated automatically. See native/swift/sir/tree-generator/Readme.md. // DO NOT MODIFY IT MANUALLY. +@file:Suppress("DuplicatedCode", "unused") + package org.jetbrains.kotlin.sir.impl import org.jetbrains.kotlin.sir.* diff --git a/native/swift/sir/tree-generator/Readme.md b/native/swift/sir/tree-generator/Readme.md new file mode 100644 index 00000000000..55bf47e0179 --- /dev/null +++ b/native/swift/sir/tree-generator/Readme.md @@ -0,0 +1,13 @@ +# Swift IR tree generator + +This directory contains a code generator for generating Swift IR classes. +We reuse the infrastructure for tree generators that is also used for generating [IR](../../../../compiler/ir/ir.tree/tree-generator) and +[FIR](../../../../compiler/fir/tree/tree-generator) trees. + +- All tree elements are declared in [`SwiftIrTree.kt`](src/org/jetbrains/kotlin/sir/tree/generator/SwiftIrTree.kt) +- Types commonly used in configuration are listed in [`Types.kt`](src/org/jetbrains/kotlin/sir/tree/generator/Types.kt) +- If an element has no inheritors, then it will have a default implementation. + Otherwise, you should declare an implementation that you want in + [`ImplementationConfigurator.kt`](src/org/jetbrains/kotlin/sir/tree/generator/ImplementationConfigurator.kt). +- The same is true for builders. For each leaf element in the hierarchy, there is a corresponding builder class. +- Builders are configured in [`BuilderConfigurator.kt`](src/org/jetbrains/kotlin/sir/tree/generator/BuilderConfigurator.kt). diff --git a/native/swift/sir/tree-generator/build.gradle.kts b/native/swift/sir/tree-generator/build.gradle.kts new file mode 100644 index 00000000000..44808c6bc82 --- /dev/null +++ b/native/swift/sir/tree-generator/build.gradle.kts @@ -0,0 +1,24 @@ +plugins { + kotlin("jvm") + id("jps-compatible") + application +} + +val runtimeOnly by configurations +val compileOnly by configurations +runtimeOnly.extendsFrom(compileOnly) + +dependencies { + implementation(project(":generators:tree-generator-common")) +} + +application { + mainClass.set("org.jetbrains.kotlin.sir.tree.generator.MainKt") +} + +sourceSets { + "main" { + projectDefault() + } + "test" {} +} diff --git a/native/swift/sir/tree-generator/src/org/jetbrains/kotlin/sir/tree/generator/BuilderConfigurator.kt b/native/swift/sir/tree-generator/src/org/jetbrains/kotlin/sir/tree/generator/BuilderConfigurator.kt new file mode 100644 index 00000000000..c92eeb4f245 --- /dev/null +++ b/native/swift/sir/tree-generator/src/org/jetbrains/kotlin/sir/tree/generator/BuilderConfigurator.kt @@ -0,0 +1,26 @@ +/* + * 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.sir.tree.generator + +import org.jetbrains.kotlin.sir.tree.generator.config.AbstractSwiftIrTreeBuilderConfigurator +import org.jetbrains.kotlin.sir.tree.generator.model.Element + +class BuilderConfigurator(elements: List) : AbstractSwiftIrTreeBuilderConfigurator(elements) { + + override fun configureBuilders() = with(SwiftIrTree) { + configureAllLeafBuilders { + withCopy() + } + + configureFieldInAllLeafBuilders("origin") { + default(it, "SirOrigin.Unknown") + } + + configureFieldInAllLeafBuilders("visibility") { + default(it, "SirVisibility.PUBLIC") + } + } +} 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 new file mode 100644 index 00000000000..ca4a0ac11ea --- /dev/null +++ b/native/swift/sir/tree-generator/src/org/jetbrains/kotlin/sir/tree/generator/ImplementationConfigurator.kt @@ -0,0 +1,25 @@ +/* + * 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.sir.tree.generator + +import org.jetbrains.kotlin.sir.tree.generator.config.AbstractSwiftIrTreeImplementationConfigurator + +object ImplementationConfigurator : AbstractSwiftIrTreeImplementationConfigurator() { + + override fun configure() = with(SwiftIrTree) { + // Declare custom implementation classes, see org.jetbrains.kotlin.fir.tree.generator.ImplementationConfigurator + } + + override fun configureAllImplementations() { + // Use configureFieldInAllImplementations to customize certain fields in all implementation classes + configureFieldInAllImplementations( + field = "parent", + ) { + isMutable(it) + isLateinit(it) + } + } +} \ No newline at end of file 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 new file mode 100644 index 00000000000..8c706ac69df --- /dev/null +++ b/native/swift/sir/tree-generator/src/org/jetbrains/kotlin/sir/tree/generator/Main.kt @@ -0,0 +1,38 @@ +/* + * 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.sir.tree.generator + +import org.jetbrains.kotlin.generators.tree.bind +import org.jetbrains.kotlin.generators.tree.printer.generateTree +import org.jetbrains.kotlin.sir.tree.generator.model.Element +import org.jetbrains.kotlin.sir.tree.generator.printer.* +import java.io.File + +internal const val BASE_PACKAGE = "org.jetbrains.kotlin.sir" + +typealias Model = org.jetbrains.kotlin.generators.tree.Model + +fun main(args: Array) { + val generationPath = args.firstOrNull()?.let { File(it) } + ?: File("../../tree/gen").canonicalFile + val model = SwiftIrTree.build() + generateTree( + generationPath, + "native/swift/sir/tree-generator/Readme.md", + model, + pureAbstractElementType, + ::ElementPrinter, + listOf( + elementVisitorType to ::VisitorPrinter, + elementTransformerType to ::TransformerPrinter.bind(model.rootElement), + ), + ImplementationConfigurator, + BuilderConfigurator(model.elements), + ::ImplementationPrinter, + ::BuilderPrinter, + ) +} + diff --git a/native/swift/sir/tree-generator/src/org/jetbrains/kotlin/sir/tree/generator/SwiftIrTree.kt b/native/swift/sir/tree-generator/src/org/jetbrains/kotlin/sir/tree/generator/SwiftIrTree.kt new file mode 100644 index 00000000000..d20a591dcf4 --- /dev/null +++ b/native/swift/sir/tree-generator/src/org/jetbrains/kotlin/sir/tree/generator/SwiftIrTree.kt @@ -0,0 +1,90 @@ +/* + * 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. + */ + +@file:Suppress("unused", "MemberVisibilityCanBePrivate") + +package org.jetbrains.kotlin.sir.tree.generator + +import org.jetbrains.kotlin.generators.tree.StandardTypes.string +import org.jetbrains.kotlin.sir.tree.generator.config.AbstractSwiftIrTreeBuilder +import org.jetbrains.kotlin.sir.tree.generator.model.Element + +object SwiftIrTree : AbstractSwiftIrTreeBuilder() { + + override val rootElement by sealedElement(name = "Element") { + kDoc = "The root interface of the Swift IR tree." + } + + val module by element { + customParentInVisitor = rootElement + parent(declarationContainer) + parent(named) + } + + val declarationParent by sealedElement() + + val declarationContainer by sealedElement { + parent(declarationParent) + customParentInVisitor = rootElement + + +listField("declarations", declaration) + } + + val declaration by sealedElement { + customParentInVisitor = rootElement + +field("origin", originType) + +field("visibility", swiftVisibilityType) + +field("parent", declarationParent, mutable = true, isChild = false) { + useInBaseTransformerDetection = false + } + } + + val foreignDeclaration by sealedElement { + parent(declaration) + } + + val named by sealedElement { + +field("name", string) + } + + val namedDeclaration by sealedElement { + customParentInVisitor = declaration + parent(declaration) + parent(named) + } + + val enum: Element by element { + customParentInVisitor = namedDeclaration + parent(namedDeclaration) + parent(declarationContainer) + + +listField("cases", enumCaseType) + } + + val struct: Element by element { + customParentInVisitor = namedDeclaration + parent(namedDeclaration) + parent(declarationContainer) + } + + val callable by sealedElement { + parent(declaration) + } + + val function by element { + customParentInVisitor = callable + parent(callable) + + +field("name", string) + +listField("parameters", parameterType) + +field("returnType", typeType) + } + + val foreignFunction by element { + customParentInVisitor = callable + parent(callable) + parent(foreignDeclaration) + } +} \ No newline at end of file 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 new file mode 100644 index 00000000000..cd8434a8bc0 --- /dev/null +++ b/native/swift/sir/tree-generator/src/org/jetbrains/kotlin/sir/tree/generator/Types.kt @@ -0,0 +1,24 @@ +/* + * 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.sir.tree.generator + +import org.jetbrains.kotlin.generators.tree.TypeKind +import org.jetbrains.kotlin.generators.tree.type + +val pureAbstractElementType = type(BASE_PACKAGE, "SirElementBase", TypeKind.Class) +val swiftVisibilityType = type(BASE_PACKAGE, "SirVisibility", TypeKind.Class) +val originType = type(BASE_PACKAGE, "SirOrigin", TypeKind.Class) +val parameterType = type(BASE_PACKAGE, "SirParameter", TypeKind.Class) +val typeType = type(BASE_PACKAGE, "SirType", TypeKind.Class) +val enumCaseType = type(BASE_PACKAGE, "SirEnumCase", TypeKind.Class) + +private const val VISITORS_PACKAGE = "$BASE_PACKAGE.visitors" + +val elementVisitorType = type(VISITORS_PACKAGE, "SirVisitor", TypeKind.Class) +val elementTransformerType = type(VISITORS_PACKAGE, "SirTransformer", 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/config/AbstractSwiftIrTreeBuilder.kt b/native/swift/sir/tree-generator/src/org/jetbrains/kotlin/sir/tree/generator/config/AbstractSwiftIrTreeBuilder.kt new file mode 100644 index 00000000000..2af3671cc56 --- /dev/null +++ b/native/swift/sir/tree-generator/src/org/jetbrains/kotlin/sir/tree/generator/config/AbstractSwiftIrTreeBuilder.kt @@ -0,0 +1,110 @@ +/* + * 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.sir.tree.generator.config + +import org.jetbrains.kotlin.generators.tree.* +import org.jetbrains.kotlin.sir.tree.generator.Model +import org.jetbrains.kotlin.sir.tree.generator.model.Element +import org.jetbrains.kotlin.sir.tree.generator.model.Field +import org.jetbrains.kotlin.sir.tree.generator.model.ListField +import org.jetbrains.kotlin.sir.tree.generator.model.SimpleField +import org.jetbrains.kotlin.types.Variance +import kotlin.properties.PropertyDelegateProvider +import kotlin.properties.ReadOnlyProperty +import kotlin.reflect.KProperty + +// TODO: This class was copy-pasted from the IR tree generator. It'd be good to factor out common parts. +abstract class AbstractSwiftIrTreeBuilder { + private val configurationCallbacks = mutableListOf<() -> Element>() + + abstract val rootElement: Element + + private fun createElement(name: String? = null, isSealed: Boolean, initializer: Element.() -> Unit = {}): ElementDelegate { + val del = ElementDelegate(name, isSealed) + configurationCallbacks.add { + del.element!!.apply { + initializer() + if (elementParents.isEmpty() && this != rootElement) { + elementParents.add(ElementRef(rootElement)) + } + } + } + return del + } + + fun element(name: String? = null, initializer: Element.() -> Unit = {}) = + createElement(name, isSealed = false, initializer) + + fun sealedElement(name: String? = null, initializer: Element.() -> Unit = {}) = + createElement(name, isSealed = true, initializer) + + protected fun Element.parent(type: ClassRef<*>) { + otherParents.add(type) + } + + protected fun Element.parent(type: ElementOrRef) { + elementParents.add(ElementRef(type.element, type.args, type.nullable)) + } + + protected fun param(name: String, vararg bounds: TypeRef, variance: Variance = Variance.INVARIANT): TypeVariable { + return TypeVariable(name, bounds.toList(), variance) + } + + protected fun field( + name: String, + type: TypeRefWithNullability, + nullable: Boolean = false, + mutable: Boolean = false, + isChild: Boolean = true, + initializer: SimpleField.() -> Unit = {} + ): SimpleField { + return SimpleField(name, type.copy(nullable), mutable).apply { + this.isChild = isChild + initializer() + } + } + + protected fun listField( + name: String, + baseType: TypeRef, + isChild: Boolean = true, + initializer: ListField.() -> Unit = {} + ): ListField { + return ListField( + name = name, + baseType = baseType, + isMutable = false, + ).apply { + this.isChild = isChild + initializer() + } + } + + fun build(): Model { + val elements = configurationCallbacks.map { it() } + return Model(elements, rootElement) + } +} + +class ElementDelegate( + private val name: String?, + private val isSealed: Boolean, +) : ReadOnlyProperty, PropertyDelegateProvider { + var element: Element? = null + private set + + override fun getValue(thisRef: AbstractSwiftIrTreeBuilder, property: KProperty<*>): Element { + return element!! + } + + override fun provideDelegate(thisRef: AbstractSwiftIrTreeBuilder, property: KProperty<*>): ElementDelegate { + val path = thisRef.javaClass.name + "." + property.name + element = Element(name ?: property.name.replaceFirstChar(Char::uppercaseChar), path).also { + it.isSealed = isSealed + } + return this + } +} diff --git a/native/swift/sir/tree-generator/src/org/jetbrains/kotlin/sir/tree/generator/config/AbstractSwiftIrTreeBuilderConfigurator.kt b/native/swift/sir/tree-generator/src/org/jetbrains/kotlin/sir/tree/generator/config/AbstractSwiftIrTreeBuilderConfigurator.kt new file mode 100644 index 00000000000..0c5653792f4 --- /dev/null +++ b/native/swift/sir/tree-generator/src/org/jetbrains/kotlin/sir/tree/generator/config/AbstractSwiftIrTreeBuilderConfigurator.kt @@ -0,0 +1,25 @@ +/* + * 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.sir.tree.generator.config + +import org.jetbrains.kotlin.generators.tree.config.AbstractBuilderConfigurator +import org.jetbrains.kotlin.sir.tree.generator.BASE_PACKAGE +import org.jetbrains.kotlin.sir.tree.generator.model.Element +import org.jetbrains.kotlin.sir.tree.generator.model.Field +import org.jetbrains.kotlin.sir.tree.generator.model.Implementation + +abstract class AbstractSwiftIrTreeBuilderConfigurator( + elements: List +) : AbstractBuilderConfigurator(elements) { + + override val namePrefix: String + get() = "Sir" + + override val defaultBuilderPackage: String + get() = "$BASE_PACKAGE.builder" + + override fun builderFieldFromElementField(elementField: Field) = elementField.copy() +} \ No newline at end of file diff --git a/native/swift/sir/tree-generator/src/org/jetbrains/kotlin/sir/tree/generator/config/AbstractSwiftIrTreeImplementationConfigurator.kt b/native/swift/sir/tree-generator/src/org/jetbrains/kotlin/sir/tree/generator/config/AbstractSwiftIrTreeImplementationConfigurator.kt new file mode 100644 index 00000000000..f0a022a693c --- /dev/null +++ b/native/swift/sir/tree-generator/src/org/jetbrains/kotlin/sir/tree/generator/config/AbstractSwiftIrTreeImplementationConfigurator.kt @@ -0,0 +1,15 @@ +/* + * 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.sir.tree.generator.config + +import org.jetbrains.kotlin.generators.tree.config.AbstractImplementationConfigurator +import org.jetbrains.kotlin.sir.tree.generator.model.Element +import org.jetbrains.kotlin.sir.tree.generator.model.Field +import org.jetbrains.kotlin.sir.tree.generator.model.Implementation + +abstract class AbstractSwiftIrTreeImplementationConfigurator : AbstractImplementationConfigurator() { + override fun createImplementation(element: Element, name: String?) = Implementation(element, name) +} \ No newline at end of file diff --git a/native/swift/sir/tree-generator/src/org/jetbrains/kotlin/sir/tree/generator/model/Element.kt b/native/swift/sir/tree-generator/src/org/jetbrains/kotlin/sir/tree/generator/model/Element.kt new file mode 100644 index 00000000000..861a72e0874 --- /dev/null +++ b/native/swift/sir/tree-generator/src/org/jetbrains/kotlin/sir/tree/generator/model/Element.kt @@ -0,0 +1,61 @@ +/* + * 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.sir.tree.generator.model + +import org.jetbrains.kotlin.generators.tree.* +import org.jetbrains.kotlin.sir.tree.generator.BASE_PACKAGE + +class Element(name: String, override val propertyName: String) : AbstractElement(name) { + + override var kDoc: String? = null + + override val fields: MutableSet = mutableSetOf() + + override val params: MutableList = mutableListOf() + + override val elementParents: MutableList> = mutableListOf() + + override val otherParents: MutableList> = mutableListOf() + + override val visitorParameterName: String = when (val parameterName = name.replaceFirstChar(Char::lowercaseChar)) { + "class" -> "klass" + else -> parameterName + } + + override val hasAcceptMethod: Boolean + get() = true + + override val hasTransformMethod: Boolean + get() = true + + override val hasAcceptChildrenMethod: Boolean + get() = isRootElement + + override val hasTransformChildrenMethod: Boolean + get() = isRootElement + + override var kind: ImplementationKind? = null + + override val namePrefix: String + get() = "Sir" + + override val packageName: String + get() = BASE_PACKAGE + + override val element: Element + get() = this + + override val nullable: Boolean + get() = false + + override val args: Map + get() = emptyMap() + + operator fun Field.unaryPlus(): Field { + fields.add(this) + return this + } +} \ No newline at end of file diff --git a/native/swift/sir/tree-generator/src/org/jetbrains/kotlin/sir/tree/generator/model/Field.kt b/native/swift/sir/tree-generator/src/org/jetbrains/kotlin/sir/tree/generator/model/Field.kt new file mode 100644 index 00000000000..8eab45d2eb0 --- /dev/null +++ b/native/swift/sir/tree-generator/src/org/jetbrains/kotlin/sir/tree/generator/model/Field.kt @@ -0,0 +1,74 @@ +/* + * 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.sir.tree.generator.model + +import org.jetbrains.kotlin.generators.tree.* +import org.jetbrains.kotlin.generators.tree.ListField + +abstract class Field( + override val name: String, + override var isMutable: Boolean +) : AbstractField(), AbstractFieldWithDefaultValue { + + override val origin: Field + get() = this + + override var withGetter: Boolean = false + + override var customSetter: String? = null + + override var defaultValueInImplementation: String? = null + + override var defaultValueInBuilder: String? = null + + override val isVolatile: Boolean + get() = false + + override var isFinal: Boolean = false + + override val isParameter: Boolean + get() = false + + abstract fun internalCopy(): Field + + override fun copy() = internalCopy().also(::updateFieldsInCopy) + + override fun updateFieldsInCopy(copy: Field) { + super.updateFieldsInCopy(copy) + copy.withGetter = withGetter + copy.customSetter = customSetter + copy.defaultValueInImplementation = defaultValueInImplementation + copy.isFinal = isFinal + } +} + +class SimpleField( + name: String, + override val typeRef: TypeRefWithNullability, + isMutable: Boolean, +) : Field(name, isMutable) { + + override fun internalCopy() = SimpleField(name, typeRef, isMutable) + + override fun replaceType(newType: TypeRefWithNullability) = SimpleField(name, newType, isMutable).also(::updateFieldsInCopy) +} + +class ListField( + name: String, + override val baseType: TypeRef, + isMutable: Boolean, +) : Field(name, isMutable), ListField { + + override val typeRef: ClassRef + get() = super.typeRef + + override val listType: ClassRef + get() = StandardTypes.list + + override fun internalCopy() = ListField(name, baseType, isMutable) + + override fun replaceType(newType: TypeRefWithNullability) = internalCopy().also(::updateFieldsInCopy) +} diff --git a/native/swift/sir/tree-generator/src/org/jetbrains/kotlin/sir/tree/generator/model/Implementation.kt b/native/swift/sir/tree-generator/src/org/jetbrains/kotlin/sir/tree/generator/model/Implementation.kt new file mode 100644 index 00000000000..7875a697868 --- /dev/null +++ b/native/swift/sir/tree-generator/src/org/jetbrains/kotlin/sir/tree/generator/model/Implementation.kt @@ -0,0 +1,12 @@ +/* + * 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.sir.tree.generator.model + +import org.jetbrains.kotlin.generators.tree.AbstractImplementation + +class Implementation(element: Element, name: String?) : AbstractImplementation(element, name) { + override val allFields: List = element.allFields.map { it.copy() } +} diff --git a/native/swift/sir/tree-generator/src/org/jetbrains/kotlin/sir/tree/generator/printer/BuilderPrinter.kt b/native/swift/sir/tree-generator/src/org/jetbrains/kotlin/sir/tree/generator/printer/BuilderPrinter.kt new file mode 100644 index 00000000000..3c32e472faf --- /dev/null +++ b/native/swift/sir/tree-generator/src/org/jetbrains/kotlin/sir/tree/generator/printer/BuilderPrinter.kt @@ -0,0 +1,24 @@ +/* + * 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.sir.tree.generator.printer + +import org.jetbrains.kotlin.generators.tree.* +import org.jetbrains.kotlin.sir.tree.generator.model.Element +import org.jetbrains.kotlin.sir.tree.generator.model.Field +import org.jetbrains.kotlin.sir.tree.generator.model.Implementation +import org.jetbrains.kotlin.sir.tree.generator.model.ListField +import org.jetbrains.kotlin.sir.tree.generator.swiftIrBuilderDslAnnotation +import org.jetbrains.kotlin.sir.tree.generator.swiftIrImplementationDetailAnnotation +import org.jetbrains.kotlin.utils.SmartPrinter + +internal class BuilderPrinter(printer: SmartPrinter) : AbstractBuilderPrinter(printer) { + + override val implementationDetailAnnotation: ClassRef<*> + get() = swiftIrImplementationDetailAnnotation + + override val builderDslAnnotation: ClassRef<*> + get() = swiftIrBuilderDslAnnotation +} \ No newline at end of file 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 new file mode 100644 index 00000000000..96a9c46fa09 --- /dev/null +++ b/native/swift/sir/tree-generator/src/org/jetbrains/kotlin/sir/tree/generator/printer/ElementPrinter.kt @@ -0,0 +1,46 @@ +/* + * 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.sir.tree.generator.printer + +import org.jetbrains.kotlin.generators.tree.* +import org.jetbrains.kotlin.generators.tree.printer.* +import org.jetbrains.kotlin.sir.tree.generator.BASE_PACKAGE +import org.jetbrains.kotlin.sir.tree.generator.SwiftIrTree +import org.jetbrains.kotlin.sir.tree.generator.model.Element +import org.jetbrains.kotlin.sir.tree.generator.model.Field +import org.jetbrains.kotlin.sir.tree.generator.elementTransformerType +import org.jetbrains.kotlin.sir.tree.generator.elementVisitorType +import org.jetbrains.kotlin.sir.tree.generator.model.SimpleField +import org.jetbrains.kotlin.utils.SmartPrinter + +internal class ElementPrinter(printer: SmartPrinter) : AbstractElementPrinter(printer) { + + override fun makeFieldPrinter(printer: SmartPrinter) = object : AbstractFieldPrinter(printer) { + override fun forceMutable(field: Field): Boolean = field.isMutable + } + + context(ImportCollector) + override fun SmartPrinter.printAdditionalMethods(element: Element) { + val treeName = "Swift IR" + if (element.isRootElement || element.parentInVisitor != null) { + printAcceptMethod(element, elementVisitorType, hasImplementation = !element.isRootElement, treeName) + printTransformMethod( + element, + elementTransformerType, + implementation = "transformer.transform${element.name}(this, data)", + returnType = TypeVariable("E", listOf(SwiftIrTree.rootElement)), + treeName + ) + } + + if (element.isRootElement) { + printAcceptChildrenMethod(element, elementVisitorType, TypeVariable("R")) + println() + printTransformChildrenMethod(element, elementTransformerType, StandardTypes.unit) + println() + } + } +} \ No newline at end of file diff --git a/native/swift/sir/tree-generator/src/org/jetbrains/kotlin/sir/tree/generator/printer/ImplementationPrinter.kt b/native/swift/sir/tree-generator/src/org/jetbrains/kotlin/sir/tree/generator/printer/ImplementationPrinter.kt new file mode 100644 index 00000000000..5280cef7ee7 --- /dev/null +++ b/native/swift/sir/tree-generator/src/org/jetbrains/kotlin/sir/tree/generator/printer/ImplementationPrinter.kt @@ -0,0 +1,96 @@ +/* + * 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.sir.tree.generator.printer + +import org.jetbrains.kotlin.generators.tree.* +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.sir.tree.generator.BASE_PACKAGE +import org.jetbrains.kotlin.sir.tree.generator.elementTransformerType +import org.jetbrains.kotlin.sir.tree.generator.elementVisitorType +import org.jetbrains.kotlin.sir.tree.generator.model.* +import org.jetbrains.kotlin.sir.tree.generator.model.ListField +import org.jetbrains.kotlin.sir.tree.generator.swiftIrImplementationDetailAnnotation +import org.jetbrains.kotlin.utils.SmartPrinter + +internal class ImplementationPrinter(printer: SmartPrinter) : AbstractImplementationPrinter(printer) { + + companion object { + private val transformInPlace = ArbitraryImportable("$BASE_PACKAGE.util", "transformInPlace") + } + + override val implementationOptInAnnotation: ClassRef<*> + get() = swiftIrImplementationDetailAnnotation + + override val pureAbstractElementType: ClassRef<*> + get() = org.jetbrains.kotlin.sir.tree.generator.pureAbstractElementType + + override fun makeFieldPrinter(printer: SmartPrinter) = object : AbstractFieldPrinter(printer) { + + override fun forceMutable(field: Field) = field.isMutable + + override fun actualTypeOfField(field: Field): TypeRefWithNullability { + if (field is ListField) return StandardTypes.mutableList.withArgs(field.baseType) + return field.typeRef + } + } + + context(ImportCollector) + override fun SmartPrinter.printAdditionalMethods(implementation: Implementation) { + + if (implementation.hasAcceptChildrenMethod) { + printAcceptChildrenMethod(implementation, elementVisitorType, TypeVariable("R"), override = true) + printBlock { + // TODO: This is copy-pasted from the IR generator. Factor this out. + for (child in implementation.walkableChildren) { + print(child.name) + if (child.nullable) { + print("?") + } + when (child) { + is SimpleField -> println(".accept(visitor, data)") + is ListField -> { + print(".forEach { it") + if (child.baseType.nullable) { + print("?") + } + println(".accept(visitor, data) }") + } + } + } + } + } + + if (implementation.hasTransformChildrenMethod) { + printTransformChildrenMethod(implementation, elementTransformerType, StandardTypes.unit, override = true) + printBlock { + // TODO: This is copy-pasted from the IR generator. Factor this out. + for (child in implementation.transformableChildren) { + print(child.name) + when (child) { + is SimpleField -> { + print(" = ", child.name) + if (child.nullable) { + print("?") + } + print(".transform(transformer, data)") + val elementRef = child.typeRef as ElementRef<*> + if (!elementRef.element.hasTransformMethod) { + print(" as ", elementRef.render()) + } + println() + } + is ListField -> { + addImport(transformInPlace) + println(".transformInPlace(transformer, data)") + } + } + } + } + } + } +} \ No newline at end of file diff --git a/native/swift/sir/tree-generator/src/org/jetbrains/kotlin/sir/tree/generator/printer/TransformerPrinter.kt b/native/swift/sir/tree-generator/src/org/jetbrains/kotlin/sir/tree/generator/printer/TransformerPrinter.kt new file mode 100644 index 00000000000..31a3665d389 --- /dev/null +++ b/native/swift/sir/tree-generator/src/org/jetbrains/kotlin/sir/tree/generator/printer/TransformerPrinter.kt @@ -0,0 +1,88 @@ +/* + * 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.sir.tree.generator.printer + +import org.jetbrains.kotlin.descriptors.Modality +import org.jetbrains.kotlin.generators.tree.* +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.sir.tree.generator.elementVisitorType +import org.jetbrains.kotlin.sir.tree.generator.model.Element +import org.jetbrains.kotlin.sir.tree.generator.model.Field +import org.jetbrains.kotlin.utils.SmartPrinter + +internal class TransformerPrinter( + printer: SmartPrinter, + override val visitorType: ClassRef<*>, + private val rootElement: Element, +) : AbstractVisitorPrinter(printer) { + + override val visitorSuperType: ClassRef + get() = elementVisitorType.withArgs(rootElement, dataTypeVariable) + + override val visitorTypeParameters: List + get() = listOf(dataTypeVariable) + + override val visitorDataType: TypeRef + get() = dataTypeVariable + + override fun visitMethodReturnType(element: Element) = element.transformerClass + + context(ImportCollector) + override fun printMethodsForElement(element: Element) { + // FIXME: This code is copy-pasted from the FIR generator. Factor it out. + printer.run { + println() + val elementParameterName = element.visitorParameterName + if (element.isRootElement) { + val elementTP = TypeVariable("E", listOf(element)) + printFunctionDeclaration( + name = "transformElement", + parameters = listOf( + FunctionParameter(elementParameterName, elementTP), + FunctionParameter("data", dataTypeVariable) + ), + returnType = elementTP, + typeParameters = listOf(elementTP), + modality = Modality.ABSTRACT, + ) + println() + } else { + if (element.parentInVisitor == null) return + printFunctionWithBlockBody( + name = "transform" + element.name, + parameters = listOf( + FunctionParameter(elementParameterName, element), + FunctionParameter("data", dataTypeVariable) + ), + returnType = visitMethodReturnType(element), + typeParameters = element.params, + modality = Modality.OPEN, + ) { + println("return transformElement(", elementParameterName, ", data)") + } + } + println() + printVisitMethodDeclaration( + element = element, + modality = Modality.FINAL, + override = true, + ) + printBlock { + println( + "return transform", + element.name, + "(", + elementParameterName, + ", ", + "data)" + ) + } + } + } +} \ No newline at end of file diff --git a/native/swift/sir/tree-generator/src/org/jetbrains/kotlin/sir/tree/generator/printer/VisitorPrinter.kt b/native/swift/sir/tree-generator/src/org/jetbrains/kotlin/sir/tree/generator/printer/VisitorPrinter.kt new file mode 100644 index 00000000000..73bd2eec341 --- /dev/null +++ b/native/swift/sir/tree-generator/src/org/jetbrains/kotlin/sir/tree/generator/printer/VisitorPrinter.kt @@ -0,0 +1,28 @@ +/* + * 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.sir.tree.generator.printer + +import org.jetbrains.kotlin.generators.tree.* +import org.jetbrains.kotlin.sir.tree.generator.model.Element +import org.jetbrains.kotlin.sir.tree.generator.model.Field +import org.jetbrains.kotlin.utils.SmartPrinter + +internal class VisitorPrinter( + printer: SmartPrinter, + override val visitorType: ClassRef<*> +) : AbstractVisitorPrinter(printer) { + + override val visitorTypeParameters: List + get() = listOf(resultTypeVariable, dataTypeVariable) + + override val visitorDataType: TypeRef + get() = dataTypeVariable + + override fun visitMethodReturnType(element: Element) = resultTypeVariable + + override val visitorSuperType: ClassRef? + get() = null +} \ No newline at end of file diff --git a/settings.gradle b/settings.gradle index 7b20df9ed39..1be50a316cb 100644 --- a/settings.gradle +++ b/settings.gradle @@ -401,6 +401,7 @@ include ":plugins:compose-compiler-plugin:compiler", // Swift Export modules include ":native:swift:sir", + ":native:swift:sir:tree-generator", ":native:swift:sir-passes", ":native:swift:sir-printer", ":native:swift:sir-analysis-api",