# Announcing SwiftSyntaxBuilder

**URL:** <https://forums.swift.org/t/announcing-swiftsyntaxbuilder/56565>\
**Category:** Source Tooling\
**Tags:** swift-syntax\
**Created:** [April 6, 2022, 9:25am UTC](https://forums.swift.org/t/announcing-swiftsyntaxbuilder/56565 "2022-04-06T09:25:05Z")\
**Posts on this page:** 13\
**Page:** 1

<div class="post-metadata">

**Author:** ![kimdv](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/kimdv/32/22771_2.png) [@kimdv](https://forums.swift.org/u/kimdv)\
**Post date:** [April 6, 2022, 9:25am UTC](https://forums.swift.org/t/announcing-swiftsyntaxbuilder/56565/1 "2022-04-06T09:25:05Z")

</div>

Hi Swift Community!

[SwiftSyntaxBuilder](https://github.com/apple/swift-syntax/tree/main/Sources/SwiftSyntaxBuilder) a new library that makes it possible to generate Swift code in a declarative way using result builders. 🎉

The library contains everything to get started generating Swift code with a nice and convenient API, but there is space for improvements!

I would like to encourage everyone interested to give SwiftSyntaxBuilder a try, report any feedback you have or contribute to the library. Any contributions would be amazing and this is a community driven library so if you want to get involved, please do! 🙏

Based on your feedback, we will be working on finding the missing parts and implementing them.

If you find a bug or have a suggestion to improve the API, you can find the guide to report them [here](https://github.com/apple/swift-syntax#reporting-issues).

Thanks to [Akio Yasui](https://github.com/akkyie) for the initial version.

Thanks!

Kim

---

<div class="post-metadata">

**Author:** ![kiel](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/kiel/32/1392_2.png) [@kiel](https://forums.swift.org/u/kiel)\
**Post date:** [April 6, 2022, 11:19am UTC](https://forums.swift.org/t/announcing-swiftsyntaxbuilder/56565/2 "2022-04-06T11:19:14Z")

</div>

I think I found an example of this new library here: [swift-syntax/CodeGenerationUsingSwiftSyntaxBuilder.swift at main · apple/swift-syntax · GitHub](https://github.com/apple/swift-syntax/blob/main/Examples/CodeGenerationUsingSwiftSyntaxBuilder.swift)

Looks pretty neat!

---

<div class="post-metadata">

**Author:** ![ktoso](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/ktoso/32/44526_2.png) [@ktoso](https://forums.swift.org/u/ktoso)\
**Post date:** [April 6, 2022, 11:37am UTC](https://forums.swift.org/t/announcing-swiftsyntaxbuilder/56565/3 "2022-04-06T11:37:00Z")

</div>

Congratulations on the initial take on the lib! This is awesome and really a lifesaver for source generation plugins 👏 I've been cheering on this effort from the sidelines ever since 😃

For better or worse, for my current work we moved away from source generation but the shape of the lib and APIs looks excellent, exactly what one would have hoped for - congrats and thanks for your work!

---

<div class="post-metadata">

**Author:** ![Devarshi](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/devarshi/32/27825_2.png) [@Devarshi](https://forums.swift.org/u/Devarshi)\
**Post date:** [December 18, 2022, 10:36am UTC](https://forums.swift.org/t/announcing-swiftsyntaxbuilder/56565/4 "2022-12-18T10:36:36Z")

</div>

This looks great, thank you for sharing!

I wish we had more documentation for it. This is what I found apart from the link shared by Kiel:  
[https://speakerdeck.com/akkyie/swiftsyntaxbuilder-equals-swiftsyntax-x-function-builders?slide=25](https://speakerdeck.com/akkyie/swiftsyntaxbuilder-equals-swiftsyntax-x-function-builders?slide=25) (in Japanese)

Is there any way to manipulate `SourceFile` from some other part of code other than `main`?

In other words as per the shared example the complete `structure` is generated within `main` function:

```swift
@main
struct Main {
var source = SourceFile

  static func main() {
    let properties = [
      "firstName": "String",
      "lastName": "String",
      "age": "Int",
    ]

    source = SourceFile {
      StructDecl(identifier: "Person") {
        for (propertyName, propertyType) in properties {
          VariableDecl("var \(propertyName): \(propertyType)")

          FunctionDecl("""
            func with\(propertyName.withFirstLetterUppercased())(_ \(propertyName): \(propertyType)) -> Person {
              var result = self
              result.\(propertyName) = \(propertyName)
              return result
            }
            """
          )
        }
      }
    }

    print(source.formatted().description)
  }
}

```

Is it possible to modify it say on tap of button:

```swift
@IBAction func addAddressProperty() {
   // add address property to source

print(source.formatted().description) // prints updated structure
}

```

---

<div class="post-metadata">

**Author:** ![SimplyDanny](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/simplydanny/32/25114_2.png) [@SimplyDanny](https://forums.swift.org/u/SimplyDanny)\
**Post date:** [December 18, 2022, 6:16pm UTC](https://forums.swift.org/t/announcing-swiftsyntaxbuilder/56565/5 "2022-12-18T18:16:54Z")

</div>

You can perform this kind of code generation anywhere in your application. It is not bound to a `main` function. The examples in the `swift-syntax` repository are supposed to be readily executable. That's why they perform all the generation and transformation steps right in the `main` function.

Speaking about transformations, you can also rewrite an existing piece of code implementing a `SyntaxRewriter` (available in the `SwiftSyntax` module). [AddOneToIntegerLiterals.swift](https://github.com/apple/swift-syntax/blob/main/Examples/AddOneToIntegerLiterals.swift) is an example for that. To get from source code to an AST you want to use the `Parser` provided by `SwiftParser`.

---

<div class="post-metadata">

**Author:** ![kimdv](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/kimdv/32/22771_2.png) [@kimdv](https://forums.swift.org/u/kimdv)\
**Post date:** [December 18, 2022, 7:06pm UTC](https://forums.swift.org/t/announcing-swiftsyntaxbuilder/56565/6 "2022-12-18T19:06:32Z")

</div>

You should also be able to find documentation here: [SwiftSyntax – Swift Package Index](https://swiftpackageindex.com/apple/swift-syntax)

If there is any kind of specific documention you need feel free to ask here 🥳

---

<div class="post-metadata">

**Author:** ![sebsto](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/sebsto/32/27165_2.png) [@sebsto](https://forums.swift.org/u/sebsto)\
**Post date:** [May 30, 2024, 10:08am UTC](https://forums.swift.org/t/announcing-swiftsyntaxbuilder/56565/7 "2024-05-30T10:08:00Z")

</div>

Is there some doc available beyond the code sample?

Using the syntax builder library is quite difficult at the moment without doc and the compiler errors for ResultBuilder are not always very clear,

For example: how to add protocol conformance to a struct.

I think I'm close, but this still doesn't compile

```swift
            StructDeclSyntax(name: "MyStruct") {

                InheritanceClauseSyntax(inheritedTypes: InheritedTypeListSyntax {
                    DeclSyntax("Sendable")
                    DeclSyntax("Codable")
                })

```

`Static method 'buildExpression' requires that 'InheritanceClauseSyntax' conform to 'DeclSyntaxProtocol'`

I have the same question for adding `public` or `private` modifiers

I would love a couple of additional code examples for common use cases : declaring struct with modifiers, protocol and generics, functions, control statements (if, switch, loops). Declaring and using enums

---

<div class="post-metadata">

**Author:** ![SimplyDanny](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/simplydanny/32/25114_2.png) [@SimplyDanny](https://forums.swift.org/u/SimplyDanny)\
**Post date:** [May 30, 2024, 10:19am UTC](https://forums.swift.org/t/announcing-swiftsyntaxbuilder/56565/8 "2024-05-30T10:19:09Z")

</div>

The block can only contain members of the structs. Other details must be specified in the initializer for `StructDeclSyntax`. For example, it has a parameter `inheritanceClause` which you need to pass the inheritance clause to. Members can only be declarations. That’s somehow what the compiler mentions: `InheritanceClauseSyntax` is not a `DeclSyntax`.

Regarding examples: The SwiftSyntax repository uses SwiftSyntaxBuilder intensively to generate code.

---

<div class="post-metadata">

**Author:** ![sebsto](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/sebsto/32/27165_2.png) [@sebsto](https://forums.swift.org/u/sebsto)\
**Post date:** [May 30, 2024, 10:24am UTC](https://forums.swift.org/t/announcing-swiftsyntaxbuilder/56565/9 "2024-05-30T10:24:51Z")

</div>

Thank you Danny. I'll continue to search the source code and the Tests to figure out the correct syntax

---

<div class="post-metadata">

**Author:** ![SimplyDanny](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/simplydanny/32/25114_2.png) [@SimplyDanny](https://forums.swift.org/u/SimplyDanny)\
**Post date:** [May 30, 2024, 10:28am UTC](https://forums.swift.org/t/announcing-swiftsyntaxbuilder/56565/10 "2024-05-30T10:28:45Z")

</div>

Sorry, but I’m only typing on a phone. Otherwise I’d have given you a full working example. Perhaps check [the initializer](https://github.com/apple/swift-syntax/blob/83ee689360c79a350a10e628208266313ad71f6c/Sources/SwiftSyntaxBuilder/generated/BuildableNodes.swift#L1240) to get an idea of all possible parameters.

---

<div class="post-metadata">

**Author:** ![sebsto](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/sebsto/32/27165_2.png) [@sebsto](https://forums.swift.org/u/sebsto)\
**Post date:** [May 30, 2024, 10:33am UTC](https://forums.swift.org/t/announcing-swiftsyntaxbuilder/56565/11 "2024-05-30T10:33:06Z")

</div>

No worries :-) I found a few examples.

Here is what I have so far

```swift
let defaultInheritance = InheritanceClauseSyntax {
            InheritedTypeSyntax(type: TypeSyntax("Codable"))
            InheritedTypeSyntax(type: TypeSyntax("Sendable"))
        }
        
let source = SourceFileSyntax {
            //TODO: is there a result builder for DeclModifierSyntax?
            StructDeclSyntax(modifiers: DeclModifierListSyntax { DeclModifierSyntax(name: .keyword(.public)) },
                             name: "MyStruct",
                             inheritanceClause: defaultInheritance) {

```

---

<div class="post-metadata">

**Author:** ![alessioburatti](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/alessioburatti/32/7545_2.png) [@alessioburatti](https://forums.swift.org/u/alessioburatti)\
**Post date:** [May 30, 2024, 4:42pm UTC](https://forums.swift.org/t/announcing-swiftsyntaxbuilder/56565/12 "2024-05-30T16:42:22Z")

</div>

Hi @sebsto. I would suggest to use the SyntaxBuilder initializers, they should be those with the header parameter if I remember correctly (typing from my phone as well so I can’t check). Then you can simply do

```swift
StructDeclSyntax("struct MyStruct: Codable, Sendable") {
  "let myProp: Int"
}

```

Basically the brackets of the trailing closure represents the brackets of the declaration you will get as output.

Another example:

```swift
let source = try SourceFileSyntax {
    try StructDeclSyntax("struct MyStruct: Codable, Sendable") {
        "let myArray: [Int]"
        "let myEnum: MyNestedEnum"
        
        try FunctionDeclSyntax("func bar() async throws -> Int") {
            "var result = 0"
            try ForStmtSyntax("for elem in myArray") {
                "result += elem"
            }
            "return result"
        }
        
        try EnumDeclSyntax("enum MyNestedEnum: String, Codable, Sendable") {
            "case a"
            "case b"
            for other in ["c", "d", "e"] {
                "case \(raw: other)"
            }
        }
    }
}

print(source.formatted())

```

Output:

```swift
struct MyStruct: Codable, Sendable {
    let myArray: [Int]
    let myEnum: MyNestedEnum
    func bar() async throws -> Int {
        var result = 0
        for elem in myArray {
            result += elem
        }
        return result
    }
    enum MyNestedEnum: String, Codable, Sendable {
        case a
        case b
        case c
        case d
        case e
    }
}

```

**EDIT:**  
For this specific example, you can skip the whole `FunctionDeclSyntax` and just write the following as a multi line string

```swift
"""
func bar() async throws -> Int {
        var result = 0
        for elem in myArray {
            result += elem
        }
        return result
    }
"""

```

but once you need to add custom logic, swift-syntax will emit warnings and format the output with the wrong indentation if a parsed string isn't a valid declaration, so for example the following would emit warnings and the result would probably be wrongly formatted:

```swift
"for elem in myArray {"
if someCondition {
  "result += elem"
} else {
  "result -= elem"
"}"

```

This happens because when swift-syntax parses `"for elem in myArray {"` it expects to find a closing bracket in the same string, but it doesn't

---

<div class="post-metadata">

**Author:** ![sebsto](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/sebsto/32/27165_2.png) [@sebsto](https://forums.swift.org/u/sebsto)\
**Post date:** [May 30, 2024, 7:21pm UTC](https://forums.swift.org/t/announcing-swiftsyntaxbuilder/56565/13 "2024-05-30T19:21:35Z")

</div>

Thank you Alessio - that helps.  
I like the strong typing provided by

```swift
StructDeclSyntax(modifiers: DeclModifierListSyntax { DeclModifierSyntax(name: .keyword(.public)) },
                             name: "MyStruct",
                             inheritanceClause: defaultInheritance) {

```

But your way of doing things helped me to progress
