Skip to content

Commit e8f2d02

Browse files
committed
Add struct declaration builder
1 parent edad18d commit e8f2d02

File tree

3 files changed

+98
-0
lines changed

3 files changed

+98
-0
lines changed
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2014 - 2019 Apple Inc. and the Swift project authors
6+
// Licensed under Apache License v2.0 with Runtime Library Exception
7+
//
8+
// See https://swift.org/LICENSE.txt for license information
9+
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10+
//
11+
//===----------------------------------------------------------------------===//
12+
13+
import SwiftSyntax
14+
15+
public struct Struct: DeclBuildable {
16+
let name: String
17+
let memberList: DeclListBuildable
18+
19+
public init(
20+
_ name: String,
21+
@DeclListBuilder buildMemberList: () -> DeclListBuildable = { DeclList.empty }
22+
) {
23+
self.name = name
24+
self.memberList = buildMemberList()
25+
}
26+
27+
public func buildDecl(format: Format, leadingTrivia: Trivia) -> DeclSyntax {
28+
let structKeyword = Tokens.struct.withLeadingTrivia(leadingTrivia + format.makeIndent())
29+
30+
let declList = memberList.buildDeclList(
31+
format: format.indented(),
32+
leadingTrivia: .newlines(1)
33+
)
34+
35+
return StructDeclSyntax {
36+
$0.useStructKeyword(structKeyword)
37+
$0.useIdentifier(SyntaxFactory.makeIdentifier(name))
38+
$0.useMembers(MemberDeclBlockSyntax {
39+
$0.useLeftBrace(Tokens.leftBrace.withLeadingTrivia(.spaces(1)))
40+
$0.useRightBrace(Tokens.rightBrace.withLeadingTrivia(.newlines(1) + format.makeIndent()))
41+
42+
for decl in declList {
43+
$0.addMember(SyntaxFactory.makeMemberDeclListItem(decl: decl, semicolon: nil))
44+
}
45+
})
46+
}
47+
}
48+
}

Sources/SwiftSyntaxBuilder/Tokens/Tokens.swift

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,9 @@ enum Tokens {
2222
/// `"var "`
2323
static let `var` = SyntaxFactory.makeVarKeyword().withTrailingTrivia(.spaces(1))
2424

25+
/// `"struct "`
26+
static let `struct` = SyntaxFactory.makeStructKeyword().withTrailingTrivia(.spaces(1))
27+
2528
// MARK: Punctuations and Signs
2629

2730
/// `":"`
@@ -30,4 +33,10 @@ enum Tokens {
3033
/// `" = "`
3134
static let equal = SyntaxFactory.makeEqualToken().withLeadingTrivia(.spaces(1))
3235
.withTrailingTrivia(.spaces(1))
36+
37+
/// `"{"`
38+
static let leftBrace = SyntaxFactory.makeLeftBraceToken()
39+
40+
/// `"}"`
41+
static let rightBrace = SyntaxFactory.makeRightBraceToken()
3342
}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
import XCTest
2+
import SwiftSyntax
3+
4+
@testable import SwiftSyntaxBuilder
5+
6+
final class StructTests: XCTestCase {
7+
let format = Format(indentWidth: 2).indented()
8+
9+
func testStruct() {
10+
let testCases: [UInt: (Struct, String)] = [
11+
#line: (
12+
Struct("TestStruct"),
13+
"""
14+
struct TestStruct {
15+
}
16+
"""
17+
),
18+
19+
#line: (
20+
Struct("TestStruct") {
21+
Let("name", of: "String")
22+
},
23+
"""
24+
struct TestStruct {
25+
let name: String
26+
}
27+
"""
28+
),
29+
]
30+
31+
for (line, testCase) in testCases {
32+
let (builder, expected) = testCase
33+
let syntax = builder.buildSyntax(format: format, leadingTrivia: .zero)
34+
35+
var text = ""
36+
syntax.write(to: &text)
37+
38+
XCTAssertEqual(text, expected, line: line)
39+
}
40+
}
41+
}

0 commit comments

Comments
 (0)