Skip to content

Commit 4bab48e

Browse files
committed
Use a dedicated Token type in SwiftSyntaxBuilder
At the moment, tokens were a little bit of an oddity in SwiftSyntaxBuilder: All nodes were represented by dedicated types in SwiftSyntaxBuilder but tokens were represented by the `TokenSyntax` from the SwiftSyntax module. This has lead to a few problems: - We needed to add extensions on `TokenSyntax` to add convienience properties that are only designed for SwiftSyntaxBuilder - `TokenSyntax` was not `SyntaxBuildable` and thus couldn’t be used as elements in unexpected node collections In general, it seems cleaner if we just add a custom `Token` type in SwiftSyntaxBuilder. rdar://99030016
1 parent 6fdc148 commit 4bab48e

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

42 files changed

+1613
-1588
lines changed

Package.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,7 @@ let package = Package(
140140
"PatternNodes.swift.gyb",
141141
"StmtNodes.swift.gyb",
142142
"SyntaxBaseKinds.swift.gyb",
143-
"Tokens.swift.gyb",
143+
"TokenSpec.swift.gyb",
144144
"Traits.swift.gyb",
145145
"Trivia.swift.gyb",
146146
"TypeNodes.swift.gyb"

Sources/SwiftSyntaxBuilder/Convenience Initializers/CatchClauseConvenienceInitializer.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ extension CatchClause {
2121
) {
2222
self.init(
2323
leadingTrivia: leadingTrivia,
24-
catchKeyword: .catchKeyword(trailingTrivia: catchItems.elements.isEmpty ? [] : .space),
24+
catchKeyword: .catch.withTrailingTrivia(catchItems.elements.isEmpty ? [] : .space),
2525
catchItems: catchItems,
2626
body: bodyBuilder()
2727
)

Sources/SwiftSyntaxBuilder/Convenience Initializers/DictionaryExprConvenienceInitializers.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,14 @@ extension DictionaryExpr {
1616
/// A convenience initializer that allows passing in members using a result builder
1717
/// instead of having to wrap them in a `DictionaryElementList`.
1818
public init(
19-
leftSquare: TokenSyntax = .`leftSquareBracket`,
20-
rightSquare: TokenSyntax = .`rightSquareBracket`,
19+
leftSquare: Token = .`leftSquareBracket`,
20+
rightSquare: Token = .`rightSquareBracket`,
2121
@DictionaryElementListBuilder contentBuilder: () -> ExpressibleAsDictionaryElementList = { [] }
2222
) {
2323
let elementList = contentBuilder().createDictionaryElementList()
2424
self.init(
2525
leftSquare: leftSquare,
26-
content: elementList.elements.isEmpty ? TokenSyntax.colonToken(trailingTrivia: []) : elementList,
26+
content: elementList.elements.isEmpty ? Token.colon.withTrailingTrivia([]) : elementList,
2727
rightSquare: rightSquare
2828
)
2929
}

Sources/SwiftSyntaxBuilder/Convenience Initializers/IfStmtConvenienceInitializers.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ public extension IfStmt {
2727
leadingTrivia: leadingTrivia,
2828
conditions: conditions,
2929
body: body(),
30-
elseKeyword: generatedElseBody == nil ? nil : TokenSyntax.elseKeyword(leadingTrivia: .space, trailingTrivia: []),
30+
elseKeyword: generatedElseBody == nil ? nil : Token.else.withLeadingTrivia(.space).withTrailingTrivia([]),
3131
elseBody: generatedElseBody.map { CodeBlock(statements: $0) }
3232
)
3333
}

Sources/SwiftSyntaxBuilder/Convenience Initializers/MemberAccessExprConvenienceInitializers.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ extension MemberAccessExpr {
1616
/// Creates a `MemberAccessExpr` using the provided parameters.
1717
public init(
1818
base: ExpressibleAsExprBuildable? = nil,
19-
dot: TokenSyntax = .period,
19+
dot: Token = .period,
2020
name: String,
2121
declNameArguments: ExpressibleAsDeclNameArguments? = nil
2222
) {

Sources/SwiftSyntaxBuilder/Convenience Initializers/StringLiteralExprConvenienceInitializers.swift

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -26,13 +26,13 @@ private let rawStringPotentialEscapesPattern = try! NSRegularExpression(
2626
extension StringLiteralExpr {
2727
/// Creates a string literal, optionally specifying quotes and delimiters.
2828
public init(
29-
openDelimiter: TokenSyntax? = nil,
30-
openQuote: TokenSyntax = .stringQuote,
29+
openDelimiter: Token? = nil,
30+
openQuote: Token = .stringQuote,
3131
_ value: String,
32-
closeQuote: TokenSyntax = .stringQuote,
33-
closeDelimiter: TokenSyntax? = nil
32+
closeQuote: Token = .stringQuote,
33+
closeDelimiter: Token? = nil
3434
) {
35-
let content = TokenSyntax.stringSegment(value)
35+
let content = Token.stringSegment(value)
3636
let segment = StringSegment(content: content)
3737
let segments = StringLiteralSegments([segment])
3838

@@ -57,7 +57,7 @@ extension StringLiteralExpr {
5757
.max() ?? 0
5858

5959
// Use a delimiter that is exactly one longer
60-
let delimiter = TokenSyntax.rawStringDelimiter(String(repeating: "#", count: 1 + maxPoundCount))
60+
let delimiter = Token.rawStringDelimiter(String(repeating: "#", count: 1 + maxPoundCount))
6161

6262
self.init(
6363
openDelimiter: delimiter,

Sources/SwiftSyntaxBuilder/Convenience Initializers/TernaryExprConvenienceInitializers.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,9 @@ extension TernaryExpr {
2020
) {
2121
self.init(
2222
conditionExpression: condition,
23-
questionMark: .infixQuestionMarkToken(leadingTrivia: .space, trailingTrivia: .space),
23+
questionMark: .infixQuestionMark.withLeadingTrivia(.space).withTrailingTrivia(.space),
2424
firstChoice: firstChoice,
25-
colonMark: .colonToken(leadingTrivia: .space),
25+
colonMark: .colon.withLeadingTrivia(.space),
2626
secondChoice: secondChoice
2727
)
2828
}

Sources/SwiftSyntaxBuilder/Convenience Initializers/TupleExprElementConvenienceInitializers.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,6 @@ public extension TupleExprElement {
1717
/// The presence of the colon will be inferred based on the presence of the label.
1818
init(label: String? = nil, expression: ExpressibleAsExprBuildable) {
1919
self.init(
20-
label: label.map { TokenSyntax.identifier($0) }, colon: label == nil ? nil : .colon, expression: expression)
20+
label: label.map { Token.identifier($0) }, colon: label == nil ? nil : Token.colon, expression: expression)
2121
}
2222
}

Sources/SwiftSyntaxBuilder/Convenience Initializers/VariableDeclConvenienceInitializers.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ extension VariableDecl {
1717
public init(
1818
leadingTrivia: Trivia = [],
1919
modifiers: ModifierList? = nil,
20-
_ letOrVarKeyword: TokenSyntax,
20+
_ letOrVarKeyword: Token,
2121
name: ExpressibleAsIdentifierPattern,
2222
type: ExpressibleAsTypeAnnotation? = nil,
2323
initializer: ExpressibleAsInitializerClause? = nil

Sources/SwiftSyntaxBuilder/HasTrailingComma.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
import SwiftSyntax
1414

1515
protocol HasTrailingComma {
16-
var trailingComma: TokenSyntax? { get }
16+
var trailingComma: Token? { get }
1717

1818
/// Returns this node overriding presence of the trailing comma
1919
func withTrailingComma(_ withComma: Bool) -> Self

Sources/SwiftSyntaxBuilder/generated/TokenSyntax.swift renamed to Sources/SwiftSyntaxBuilder/Token.swift

Lines changed: 35 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,3 @@
1-
2-
//// Automatically Generated by generate-swift-syntax-builder
3-
//// Do Not Edit Directly!
41
//===----------------------------------------------------------------------===//
52
//
63
// This source file is part of the Swift.org open source project
@@ -14,34 +11,65 @@
1411
//===----------------------------------------------------------------------===//
1512

1613
import SwiftSyntax
17-
extension TokenSyntax: ExpressibleAsTokenList, ExpressibleAsNonEmptyTokenList, ExpressibleAsBinaryOperatorExpr, ExpressibleAsDeclModifier, ExpressibleAsIdentifierExpr {
14+
15+
/// Represents `TokenSyntax` in `SwiftSyntaxBuilder`.
16+
/// At the moment, this just wraps `TokenSyntax`, but we can make it store just the information necessary to build a `TokenSyntax` in the future.
17+
public struct Token: SyntaxBuildable, ExpressibleAsTokenList, ExpressibleAsNonEmptyTokenList, ExpressibleAsBinaryOperatorExpr, ExpressibleAsDeclModifier, ExpressibleAsIdentifierExpr {
18+
let tokenSyntax: TokenSyntax
19+
20+
var text: String {
21+
return tokenSyntax.text
22+
}
23+
24+
init(tokenSyntax: TokenSyntax) {
25+
self.tokenSyntax = tokenSyntax
26+
}
27+
28+
public func withLeadingTrivia(_ leadingTrivia: Trivia) -> Token {
29+
return Token(tokenSyntax: tokenSyntax.withLeadingTrivia(leadingTrivia))
30+
}
31+
32+
public func withTrailingTrivia(_ leadingTrivia: Trivia) -> Token {
33+
return Token(tokenSyntax: tokenSyntax.withTrailingTrivia(leadingTrivia))
34+
}
35+
36+
public func buildToken() -> TokenSyntax {
37+
return tokenSyntax
38+
}
39+
40+
public func buildSyntax(format: Format, leadingTrivia: Trivia?) -> Syntax {
41+
return Syntax(tokenSyntax)
42+
}
43+
1844
/// Conformance to ExpressibleAsTokenList
1945
public func createTokenList() -> TokenList {
2046
return TokenList([self])
2147
}
48+
2249
/// Conformance to ExpressibleAsNonEmptyTokenList
2350
public func createNonEmptyTokenList() -> NonEmptyTokenList {
2451
return NonEmptyTokenList([self])
2552
}
53+
2654
/// Conformance to ExpressibleAsBinaryOperatorExpr
2755
public func createBinaryOperatorExpr() -> BinaryOperatorExpr {
2856
return BinaryOperatorExpr(operatorToken: self)
2957
}
58+
3059
/// Conformance to ExpressibleAsDeclModifier
3160
public func createDeclModifier() -> DeclModifier {
3261
return DeclModifier(name: self)
3362
}
63+
3464
/// Conformance to ExpressibleAsIdentifierExpr
3565
public func createIdentifierExpr() -> IdentifierExpr {
3666
return IdentifierExpr(identifier: self)
3767
}
38-
}
3968

40-
/// `TokenSyntax` conforms to `SyntaxBuildable` and `ExprBuildable` via different paths, so we need to pick one default conversion path to create an `ExprSyntax` (and `Syntax`) from a `String`. We choose `IdentifierExpr`.
41-
extension TokenSyntax {
4269
public func createSyntaxBuildable() -> SyntaxBuildable {
4370
return createIdentifierExpr()
4471
}
72+
4573
public func createExprBuildable() -> ExprBuildable {
4674
return createIdentifierExpr()
4775
}

Sources/SwiftSyntaxBuilder/generated/BuildableCollectionNodes.swift

Lines changed: 27 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1039,13 +1039,13 @@ extension Array: ExpressibleAsEnumCaseElementList where Element == ExpressibleAs
10391039
return EnumCaseElementList(self)
10401040
}
10411041
}
1042-
/// `IdentifierList` represents a collection of `TokenSyntax`
1042+
/// `IdentifierList` represents a collection of `Token`
10431043
public struct IdentifierList: ExpressibleByArrayLiteral, SyntaxBuildable, ExpressibleAsIdentifierList {
1044-
let elements: [TokenSyntax]
1044+
let elements: [Token]
10451045
/// Creates a `IdentifierList` with the provided list of elements.
10461046
/// - Parameters:
1047-
/// - elements: A list of `TokenSyntax`
1048-
public init (_ elements: [TokenSyntax]) {
1047+
/// - elements: A list of `Token`
1048+
public init (_ elements: [Token]) {
10491049
self.elements = elements
10501050
}
10511051
/// Creates a new `IdentifierList` by flattening the elements in `lists`
@@ -1054,11 +1054,13 @@ public struct IdentifierList: ExpressibleByArrayLiteral, SyntaxBuildable, Expres
10541054
$0.createIdentifierList().elements
10551055
}
10561056
}
1057-
public init (arrayLiteral elements: TokenSyntax...) {
1057+
public init (arrayLiteral elements: Token...) {
10581058
self.init(elements)
10591059
}
10601060
public func buildIdentifierList(format: Format, leadingTrivia: Trivia? = nil) -> IdentifierListSyntax {
1061-
let result = IdentifierListSyntax(elements)
1061+
let result = IdentifierListSyntax(elements.map {
1062+
$0.buildToken()
1063+
})
10621064
if let leadingTrivia = leadingTrivia {
10631065
return result.withLeadingTrivia((leadingTrivia + (result.leadingTrivia ?? [])).addingSpacingAfterNewlinesIfNeeded())
10641066
} else {
@@ -1080,7 +1082,7 @@ public struct IdentifierList: ExpressibleByArrayLiteral, SyntaxBuildable, Expres
10801082
return self
10811083
}
10821084
}
1083-
extension Array: ExpressibleAsIdentifierList where Element == TokenSyntax {
1085+
extension Array: ExpressibleAsIdentifierList where Element == Token {
10841086
public func createIdentifierList() -> IdentifierList {
10851087
return IdentifierList(self)
10861088
}
@@ -1185,13 +1187,13 @@ extension Array: ExpressibleAsPrecedenceGroupNameList where Element == Expressib
11851187
return PrecedenceGroupNameList(self)
11861188
}
11871189
}
1188-
/// `TokenList` represents a collection of `TokenSyntax`
1190+
/// `TokenList` represents a collection of `Token`
11891191
public struct TokenList: ExpressibleByArrayLiteral, SyntaxBuildable, ExpressibleAsTokenList {
1190-
let elements: [TokenSyntax]
1192+
let elements: [Token]
11911193
/// Creates a `TokenList` with the provided list of elements.
11921194
/// - Parameters:
1193-
/// - elements: A list of `TokenSyntax`
1194-
public init (_ elements: [TokenSyntax]) {
1195+
/// - elements: A list of `Token`
1196+
public init (_ elements: [Token]) {
11951197
self.elements = elements
11961198
}
11971199
/// Creates a new `TokenList` by flattening the elements in `lists`
@@ -1200,11 +1202,13 @@ public struct TokenList: ExpressibleByArrayLiteral, SyntaxBuildable, Expressible
12001202
$0.createTokenList().elements
12011203
}
12021204
}
1203-
public init (arrayLiteral elements: TokenSyntax...) {
1205+
public init (arrayLiteral elements: Token...) {
12041206
self.init(elements)
12051207
}
12061208
public func buildTokenList(format: Format, leadingTrivia: Trivia? = nil) -> TokenListSyntax {
1207-
let result = TokenListSyntax(elements)
1209+
let result = TokenListSyntax(elements.map {
1210+
$0.buildToken()
1211+
})
12081212
if let leadingTrivia = leadingTrivia {
12091213
return result.withLeadingTrivia((leadingTrivia + (result.leadingTrivia ?? [])).addingSpacingAfterNewlinesIfNeeded())
12101214
} else {
@@ -1226,18 +1230,18 @@ public struct TokenList: ExpressibleByArrayLiteral, SyntaxBuildable, Expressible
12261230
return self
12271231
}
12281232
}
1229-
extension Array: ExpressibleAsTokenList where Element == TokenSyntax {
1233+
extension Array: ExpressibleAsTokenList where Element == Token {
12301234
public func createTokenList() -> TokenList {
12311235
return TokenList(self)
12321236
}
12331237
}
1234-
/// `NonEmptyTokenList` represents a collection of `TokenSyntax`
1238+
/// `NonEmptyTokenList` represents a collection of `Token`
12351239
public struct NonEmptyTokenList: ExpressibleByArrayLiteral, SyntaxBuildable, ExpressibleAsNonEmptyTokenList {
1236-
let elements: [TokenSyntax]
1240+
let elements: [Token]
12371241
/// Creates a `NonEmptyTokenList` with the provided list of elements.
12381242
/// - Parameters:
1239-
/// - elements: A list of `TokenSyntax`
1240-
public init (_ elements: [TokenSyntax]) {
1243+
/// - elements: A list of `Token`
1244+
public init (_ elements: [Token]) {
12411245
self.elements = elements
12421246
}
12431247
/// Creates a new `NonEmptyTokenList` by flattening the elements in `lists`
@@ -1246,11 +1250,13 @@ public struct NonEmptyTokenList: ExpressibleByArrayLiteral, SyntaxBuildable, Exp
12461250
$0.createNonEmptyTokenList().elements
12471251
}
12481252
}
1249-
public init (arrayLiteral elements: TokenSyntax...) {
1253+
public init (arrayLiteral elements: Token...) {
12501254
self.init(elements)
12511255
}
12521256
public func buildNonEmptyTokenList(format: Format, leadingTrivia: Trivia? = nil) -> NonEmptyTokenListSyntax {
1253-
let result = NonEmptyTokenListSyntax(elements)
1257+
let result = NonEmptyTokenListSyntax(elements.map {
1258+
$0.buildToken()
1259+
})
12541260
if let leadingTrivia = leadingTrivia {
12551261
return result.withLeadingTrivia((leadingTrivia + (result.leadingTrivia ?? [])).addingSpacingAfterNewlinesIfNeeded())
12561262
} else {
@@ -1272,7 +1278,7 @@ public struct NonEmptyTokenList: ExpressibleByArrayLiteral, SyntaxBuildable, Exp
12721278
return self
12731279
}
12741280
}
1275-
extension Array: ExpressibleAsNonEmptyTokenList where Element == TokenSyntax {
1281+
extension Array: ExpressibleAsNonEmptyTokenList where Element == Token {
12761282
public func createNonEmptyTokenList() -> NonEmptyTokenList {
12771283
return NonEmptyTokenList(self)
12781284
}

0 commit comments

Comments
 (0)