Skip to content

Commit db4a2a4

Browse files
committed
[ASTGen] Generalize Optional node handling
Defining `generate(_: XXXSyntax?) -> BridgedXXX` for each node kind is too much boilerplate. self.generate(optional: optionalXXXNode).asNullable is now: self.map(optionalXXXNode, generate(xxx:))
1 parent 91fa051 commit db4a2a4

File tree

7 files changed

+94
-125
lines changed

7 files changed

+94
-125
lines changed

lib/ASTGen/Sources/ASTGen/ASTGen.swift

Lines changed: 19 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -209,79 +209,31 @@ extension ASTGenVisitor {
209209
}
210210
}
211211

212-
// Forwarding overloads that take optional syntax nodes. These are defined on demand to achieve a consistent
213-
// 'self.visit(<expr>)' recursion pattern between optional and non-optional inputs.
212+
// Optional node handling.
214213
extension ASTGenVisitor {
214+
/// Generate an AST node from an optional node using the generator function.
215+
///
216+
/// Usage:
217+
/// self.map(node.initializer, generate(expr:))
215218
@inline(__always)
216-
func generate(optional node: TypeSyntax?) -> BridgedTypeRepr? {
217-
guard let node else {
218-
return nil
219-
}
220-
221-
return self.generate(type: node)
222-
}
223-
224-
@inline(__always)
225-
func generate(optional node: ExprSyntax?) -> BridgedExpr? {
226-
guard let node else {
227-
return nil
228-
}
229-
230-
return self.generate(expr: node)
231-
}
232-
233-
@inline(__always)
234-
func generate(optional node: GenericParameterClauseSyntax?) -> BridgedGenericParamList? {
235-
guard let node else {
236-
return nil
237-
}
238-
239-
return self.generate(genericParameterClause: node)
240-
}
241-
242-
@inline(__always)
243-
func generate(optional node: GenericWhereClauseSyntax?) -> BridgedTrailingWhereClause? {
244-
guard let node else {
245-
return nil
246-
}
247-
248-
return self.generate(genericWhereClause: node)
249-
}
250-
251-
@inline(__always)
252-
func generate(optional node: EnumCaseParameterClauseSyntax?) -> BridgedParameterList? {
253-
guard let node else {
254-
return nil
255-
}
256-
257-
return self.generate(enumCaseParameterClause: node)
258-
}
259-
260-
@inline(__always)
261-
func generate(optional node: InheritedTypeListSyntax?) -> BridgedArrayRef {
262-
guard let node else {
263-
return .init()
264-
}
265-
266-
return self.generate(inheritedTypeList: node)
267-
}
268-
269-
@inline(__always)
270-
func generate(optional node: PrecedenceGroupNameListSyntax?) -> BridgedArrayRef {
271-
guard let node else {
272-
return .init()
273-
}
274-
275-
return self.generate(precedenceGroupNameList: node)
219+
func map<Node: SyntaxProtocol, Result: HasNullable>(
220+
_ node: Node?,
221+
_ body: (Node) -> Result
222+
) -> Result.Nullable {
223+
return Result.asNullable(node.map(body))
276224
}
277225

278-
/// Generate AST from an optional node.
279-
/// This is `node.map(body)` but with `self.generate(...)` syntax.
226+
/// Generate an AST node array from an optional collection node using the
227+
/// generator function. If `nil`, returns an empty array.
228+
///
280229
/// Usage:
281-
/// self.generate(optional: node.initializer, generate(expr:))
230+
/// self.map(node.genericWhereClasuse, generate(genericWhereClause:))
282231
@inline(__always)
283-
func generate<T: SyntaxProtocol, U>(optional node: T?, _ body: (T) -> U) -> U? {
284-
return node.map(body)
232+
func map<Node: SyntaxCollection>(
233+
_ node: Node?,
234+
_ body: (Node) -> BridgedArrayRef
235+
) -> BridgedArrayRef {
236+
return node.map(body) ?? .init()
285237
}
286238
}
287239

lib/ASTGen/Sources/ASTGen/Bridge.swift

Lines changed: 35 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -26,39 +26,56 @@ extension BridgedIdentifier: ExpressibleByNilLiteral {
2626
}
2727
}
2828

29-
extension BridgedStmt? {
30-
var asNullable: BridgedNullableStmt {
31-
.init(raw: self?.raw)
29+
/// Protocol that declares that there's a "Nullable" variation of the type.
30+
///
31+
/// E.g. BridgedExpr vs BridgedNullableExpr.
32+
protocol HasNullable {
33+
associatedtype Nullable
34+
35+
/// Convert an `Optional<Self>` to `Nullable`.
36+
static func asNullable(_ node: Self?) -> Nullable
37+
}
38+
39+
extension Optional where Wrapped: HasNullable {
40+
/// Convert an Optional to Nullable variation of the wrapped type.
41+
var asNullable: Wrapped.Nullable {
42+
Wrapped.asNullable(self)
43+
}
44+
}
45+
46+
extension BridgedStmt: HasNullable {
47+
static func asNullable(_ node: Self?) -> BridgedNullableStmt {
48+
.init(raw: node?.raw)
3249
}
3350
}
3451

35-
extension BridgedExpr? {
36-
var asNullable: BridgedNullableExpr {
37-
.init(raw: self?.raw)
52+
extension BridgedExpr: HasNullable {
53+
static func asNullable(_ node: Self?) -> BridgedNullableExpr {
54+
.init(raw: node?.raw)
3855
}
3956
}
4057

41-
extension BridgedTypeRepr? {
42-
var asNullable: BridgedNullableTypeRepr {
43-
.init(raw: self?.raw)
58+
extension BridgedTypeRepr: HasNullable {
59+
static func asNullable(_ node: Self?) -> BridgedNullableTypeRepr {
60+
.init(raw: node?.raw)
4461
}
4562
}
4663

47-
extension BridgedGenericParamList? {
48-
var asNullable: BridgedNullableGenericParamList {
49-
.init(raw: self?.raw)
64+
extension BridgedGenericParamList: HasNullable {
65+
static func asNullable(_ node: Self?) -> BridgedNullableGenericParamList {
66+
.init(raw: node?.raw)
5067
}
5168
}
5269

53-
extension BridgedTrailingWhereClause? {
54-
var asNullable: BridgedNullableTrailingWhereClause {
55-
.init(raw: self?.raw)
70+
extension BridgedTrailingWhereClause: HasNullable {
71+
static func asNullable(_ node: Self?) -> BridgedNullableTrailingWhereClause {
72+
.init(raw: node?.raw)
5673
}
5774
}
5875

59-
extension BridgedParameterList? {
60-
var asNullable: BridgedNullableParameterList {
61-
.init(raw: self?.raw)
76+
extension BridgedParameterList: HasNullable {
77+
static func asNullable(_ node: Self?) -> BridgedNullableParameterList {
78+
.init(raw: node?.raw)
6279
}
6380
}
6481

lib/ASTGen/Sources/ASTGen/Decls.swift

Lines changed: 32 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -81,10 +81,10 @@ extension ASTGenVisitor {
8181
typealiasKeywordLoc: node.typealiasKeyword.bridgedSourceLoc(in: self),
8282
name: name,
8383
nameLoc: nameLoc,
84-
genericParamList: self.generate(optional: node.genericParameterClause).asNullable,
84+
genericParamList: self.map(node.genericParameterClause, generate(genericParameterClause:)),
8585
equalLoc: node.initializer.equal.bridgedSourceLoc(in: self),
8686
underlyingType: self.generate(type: node.initializer.value),
87-
genericWhereClause: self.generate(optional: node.genericWhereClause).asNullable
87+
genericWhereClause: self.map(node.genericWhereClause, generate(genericWhereClause:))
8888
)
8989
}
9090

@@ -97,9 +97,9 @@ extension ASTGenVisitor {
9797
enumKeywordLoc: node.enumKeyword.bridgedSourceLoc(in: self),
9898
name: name,
9999
nameLoc: nameLoc,
100-
genericParamList: self.generate(optional: node.genericParameterClause).asNullable,
101-
inheritedTypes: self.generate(optional: node.inheritanceClause?.inheritedTypes),
102-
genericWhereClause: self.generate(optional: node.genericWhereClause).asNullable,
100+
genericParamList: self.map(node.genericParameterClause, generate(genericParameterClause:)),
101+
inheritedTypes: self.map(node.inheritanceClause?.inheritedTypes, generate(inheritedTypeList:)),
102+
genericWhereClause: self.map(node.genericWhereClause, generate(genericWhereClause:)),
103103
braceRange: BridgedSourceRange(
104104
startToken: node.memberBlock.leftBrace,
105105
endToken: node.memberBlock.rightBrace,
@@ -123,9 +123,9 @@ extension ASTGenVisitor {
123123
structKeywordLoc: node.structKeyword.bridgedSourceLoc(in: self),
124124
name: name,
125125
nameLoc: nameLoc,
126-
genericParamList: self.generate(optional: node.genericParameterClause).asNullable,
127-
inheritedTypes: self.generate(optional: node.inheritanceClause?.inheritedTypes),
128-
genericWhereClause: self.generate(optional: node.genericWhereClause).asNullable,
126+
genericParamList: self.map(node.genericParameterClause, generate(genericParameterClause:)),
127+
inheritedTypes: self.map(node.inheritanceClause?.inheritedTypes, generate(inheritedTypeList:)),
128+
genericWhereClause: self.map(node.genericWhereClause, generate(genericWhereClause:)),
129129
braceRange: BridgedSourceRange(
130130
startToken: node.memberBlock.leftBrace,
131131
endToken: node.memberBlock.rightBrace,
@@ -149,9 +149,9 @@ extension ASTGenVisitor {
149149
classKeywordLoc: node.classKeyword.bridgedSourceLoc(in: self),
150150
name: name,
151151
nameLoc: nameLoc,
152-
genericParamList: self.generate(optional: node.genericParameterClause).asNullable,
153-
inheritedTypes: self.generate(optional: node.inheritanceClause?.inheritedTypes),
154-
genericWhereClause: self.generate(optional: node.genericWhereClause).asNullable,
152+
genericParamList: self.map(node.genericParameterClause, generate(genericParameterClause:)),
153+
inheritedTypes: self.map(node.inheritanceClause?.inheritedTypes, generate(inheritedTypeList:)),
154+
genericWhereClause: self.map(node.genericWhereClause, generate(genericWhereClause:)),
155155
braceRange: BridgedSourceRange(
156156
startToken: node.memberBlock.leftBrace,
157157
endToken: node.memberBlock.rightBrace,
@@ -176,9 +176,9 @@ extension ASTGenVisitor {
176176
classKeywordLoc: node.actorKeyword.bridgedSourceLoc(in: self),
177177
name: name,
178178
nameLoc: nameLoc,
179-
genericParamList: self.generate(optional: node.genericParameterClause).asNullable,
180-
inheritedTypes: self.generate(optional: node.inheritanceClause?.inheritedTypes),
181-
genericWhereClause: self.generate(optional: node.genericWhereClause).asNullable,
179+
genericParamList: self.map(node.genericParameterClause, generate(genericParameterClause:)),
180+
inheritedTypes: self.map(node.inheritanceClause?.inheritedTypes, generate(inheritedTypeList:)),
181+
genericWhereClause: self.map(node.genericWhereClause, generate(genericWhereClause:)),
182182
braceRange: BridgedSourceRange(
183183
startToken: node.memberBlock.leftBrace,
184184
endToken: node.memberBlock.rightBrace,
@@ -207,8 +207,8 @@ extension ASTGenVisitor {
207207
name: name,
208208
nameLoc: nameLoc,
209209
primaryAssociatedTypeNames: primaryAssociatedTypeNames.bridgedArray(in: self),
210-
inheritedTypes: self.generate(optional: node.inheritanceClause?.inheritedTypes),
211-
genericWhereClause: self.generate(optional: node.genericWhereClause).asNullable,
210+
inheritedTypes: self.map(node.inheritanceClause?.inheritedTypes, generate(inheritedTypeList:)),
211+
genericWhereClause: self.map(node.genericWhereClause, generate(genericWhereClause:)),
212212
braceRange: BridgedSourceRange(
213213
startToken: node.memberBlock.leftBrace,
214214
endToken: node.memberBlock.rightBrace,
@@ -232,9 +232,9 @@ extension ASTGenVisitor {
232232
associatedtypeKeywordLoc: node.associatedtypeKeyword.bridgedSourceLoc(in: self),
233233
name: name,
234234
nameLoc: nameLoc,
235-
inheritedTypes: self.generate(optional: node.inheritanceClause?.inheritedTypes),
236-
defaultType: self.generate(optional: node.initializer?.value).asNullable,
237-
genericWhereClause: self.generate(optional: node.genericWhereClause).asNullable
235+
inheritedTypes: self.map(node.inheritanceClause?.inheritedTypes, generate(inheritedTypeList:)),
236+
defaultType: self.map(node.initializer?.value, generate(type:)),
237+
genericWhereClause: self.map(node.genericWhereClause, generate(genericWhereClause:))
238238
)
239239
}
240240
}
@@ -248,8 +248,8 @@ extension ASTGenVisitor {
248248
declContext: self.declContext,
249249
extensionKeywordLoc: node.extensionKeyword.bridgedSourceLoc(in: self),
250250
extendedType: self.generate(type: node.extendedType),
251-
inheritedTypes: self.generate(optional: node.inheritanceClause?.inheritedTypes),
252-
genericWhereClause: self.generate(optional: node.genericWhereClause).asNullable,
251+
inheritedTypes: self.map(node.inheritanceClause?.inheritedTypes, generate(inheritedTypeList:)),
252+
genericWhereClause: self.map(node.genericWhereClause, generate(genericWhereClause:)),
253253
braceRange: BridgedSourceRange(
254254
startToken: node.memberBlock.leftBrace,
255255
endToken: node.memberBlock.rightBrace,
@@ -276,9 +276,9 @@ extension ASTGenVisitor {
276276
declContext: self.declContext,
277277
name: name,
278278
nameLoc: nameLoc,
279-
parameterList: self.generate(optional: node.parameterClause).asNullable,
279+
parameterList: self.map(node.parameterClause, generate(enumCaseParameterClause:)),
280280
equalsLoc: (node.rawValue?.equal).bridgedSourceLoc(in: self),
281-
rawValue: self.generate(optional: node.rawValue?.value).asNullable
281+
rawValue: self.map(node.rawValue?.value, generate(expr:))
282282
)
283283
}
284284

@@ -329,13 +329,13 @@ extension ASTGenVisitor {
329329
funcKeywordLoc: node.funcKeyword.bridgedSourceLoc(in: self),
330330
name: name,
331331
nameLoc: nameLoc,
332-
genericParamList: self.generate(optional: node.genericParameterClause).asNullable,
332+
genericParamList: self.map(node.genericParameterClause, generate(genericParameterClause:)),
333333
parameterList: self.generate(functionParameterClause: node.signature.parameterClause),
334334
asyncSpecifierLoc: (node.signature.effectSpecifiers?.asyncSpecifier).bridgedSourceLoc(in: self),
335335
throwsSpecifierLoc: (node.signature.effectSpecifiers?.throwsSpecifier).bridgedSourceLoc(in: self),
336-
thrownType: self.generate(optional: node.signature.effectSpecifiers?.thrownError?.type).asNullable,
337-
returnType: self.generate(optional: node.signature.returnClause?.type).asNullable,
338-
genericWhereClause: self.generate(optional: node.genericWhereClause).asNullable
336+
thrownType: self.map(node.signature.effectSpecifiers?.thrownError?.type, generate(type:)),
337+
returnType: self.map(node.signature.returnClause?.type, generate(type:)),
338+
genericWhereClause: self.map(node.genericWhereClause, generate(genericWhereClause:))
339339
)
340340

341341
if let body = node.body {
@@ -354,12 +354,12 @@ extension ASTGenVisitor {
354354
initKeywordLoc: node.initKeyword.bridgedSourceLoc(in: self),
355355
failabilityMarkLoc: node.optionalMark.bridgedSourceLoc(in: self),
356356
isIUO: node.optionalMark?.tokenKind == .exclamationMark,
357-
genericParamList: self.generate(optional: node.genericParameterClause).asNullable,
357+
genericParamList: self.map(node.genericParameterClause, generate(genericParameterClause:)),
358358
parameterList: self.generate(functionParameterClause: node.signature.parameterClause),
359359
asyncSpecifierLoc: (node.signature.effectSpecifiers?.asyncSpecifier).bridgedSourceLoc(in: self),
360360
throwsSpecifierLoc: (node.signature.effectSpecifiers?.throwsSpecifier).bridgedSourceLoc(in: self),
361-
thrownType: self.generate(optional: node.signature.effectSpecifiers?.thrownError?.type).asNullable,
362-
genericWhereClause: self.generate(optional: node.genericWhereClause).asNullable
361+
thrownType: self.map(node.signature.effectSpecifiers?.thrownError?.type, generate(type:)),
362+
genericWhereClause: self.map(node.genericWhereClause, generate(genericWhereClause:))
363363
)
364364

365365
if let body = node.body {
@@ -533,9 +533,9 @@ extension ASTGenVisitor {
533533
assignmentValueLoc: (body.assignment?.value).bridgedSourceLoc(in: self),
534534
isAssignment: assignmentValue,
535535
higherThanKeywordLoc: (body.higherThanRelation?.higherThanOrLowerThanLabel).bridgedSourceLoc(in: self),
536-
higherThanNames: self.generate(optional: body.higherThanRelation?.precedenceGroups),
536+
higherThanNames: self.map(body.higherThanRelation?.precedenceGroups, generate(precedenceGroupNameList:)),
537537
lowerThanKeywordLoc: (body.lowerThanRelation?.higherThanOrLowerThanLabel).bridgedSourceLoc(in: self),
538-
lowerThanNames: self.generate(optional: body.lowerThanRelation?.precedenceGroups),
538+
lowerThanNames: self.map(body.lowerThanRelation?.precedenceGroups, generate(precedenceGroupNameList:)),
539539
rightBraceLoc: node.rightBrace.bridgedSourceLoc(in: self)
540540
)
541541
}

lib/ASTGen/Sources/ASTGen/Generics.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ extension ASTGenVisitor {
1919
self.ctx,
2020
leftAngleLoc: node.leftAngle.bridgedSourceLoc(in: self),
2121
parameters: node.parameters.lazy.map(self.generate).bridgedArray(in: self),
22-
genericWhereClause: self.generate(optional: node.genericWhereClause).asNullable,
22+
genericWhereClause: self.map(node.genericWhereClause, generate(genericWhereClause:)),
2323
rightAngleLoc: node.rightAngle.bridgedSourceLoc(in: self)
2424
)
2525
}
@@ -44,7 +44,7 @@ extension ASTGenVisitor {
4444
eachKeywordLoc: node.eachKeyword.bridgedSourceLoc(in: self),
4545
name: name,
4646
nameLoc: nameLoc,
47-
inheritedType: self.generate(optional: node.inheritedType).asNullable,
47+
inheritedType: self.map(node.inheritedType, generate(type:)),
4848
index: genericParameterIndex
4949
)
5050
}

lib/ASTGen/Sources/ASTGen/ParameterClause.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ extension ASTGenVisitor {
8383

8484
let (secondName, secondNameLoc) = node.secondName.bridgedIdentifierAndSourceLoc(in: self)
8585

86-
var type = self.generate(optional: node.optionalType)
86+
var type = node.optionalType.map(generate(type:))
8787
if let ellipsis = node.ellipsis, let base = type {
8888
type = BridgedVarargTypeRepr.createParsed(
8989
self.ctx,
@@ -101,7 +101,7 @@ extension ASTGenVisitor {
101101
secondName: secondName,
102102
secondNameLoc: secondNameLoc,
103103
type: type.asNullable,
104-
defaultValue: self.generate(optional: node.defaultValue?.value).asNullable
104+
defaultValue: self.map(node.defaultValue?.value, generate(expr:))
105105
)
106106
}
107107
}

lib/ASTGen/Sources/ASTGen/Stmts.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -75,14 +75,14 @@ extension ASTGenVisitor {
7575
condition: conditions.first!.castToExpr,
7676
thenStmt: self.generate(codeBlock: node.body).asStmt,
7777
elseLoc: node.elseKeyword.bridgedSourceLoc(in: self),
78-
elseStmt: self.generate(optional: node.elseBody) {
78+
elseStmt: self.map(node.elseBody) {
7979
switch $0 {
8080
case .codeBlock(let node):
8181
return self.generate(codeBlock: node).asStmt
8282
case .ifExpr(let node):
8383
return self.makeIfStmt(node).asStmt
8484
}
85-
}.asNullable
85+
}
8686
)
8787
}
8888

@@ -99,7 +99,7 @@ extension ASTGenVisitor {
9999
.createParsed(
100100
self.ctx,
101101
returnKeywordLoc: node.returnKeyword.bridgedSourceLoc(in: self),
102-
expr: self.generate(optional: node.expression).asNullable
102+
expr: self.map(node.expression, generate(expr:))
103103
)
104104
}
105105
}

0 commit comments

Comments
 (0)