Skip to content

Commit 7784d6c

Browse files
committed
Factor _format generation into smaller functions
1 parent c4b9b51 commit 7784d6c

File tree

1 file changed

+105
-92
lines changed

1 file changed

+105
-92
lines changed

Sources/generate-swift-syntax-builder/Templates/FormatFile.swift

Lines changed: 105 additions & 92 deletions
Original file line numberDiff line numberDiff line change
@@ -109,106 +109,119 @@ let formatFile = SourceFile {
109109

110110
ExtensionDecl(extendedType: "Format") {
111111
for node in SYNTAX_NODES {
112-
let type = node.type
113-
let signature = FunctionSignature(
114-
input: ParameterClause {
115-
FunctionParameter(
116-
firstName: .identifier("syntax"),
117-
colon: .colon,
118-
type: type.syntaxBaseName
119-
)
120-
},
121-
output: type.syntaxBaseName
122-
)
123112
if node.isBuildable {
124-
FunctionDecl(
125-
modifiers: [TokenSyntax.public],
126-
identifier: .identifier("_format"),
127-
signature: signature
128-
) {
129-
VariableDecl(
130-
.var,
131-
name: "result",
132-
initializer: node.children
133-
.filter(\.requiresLeadingNewline)
134-
.reduce("syntax") { base, child in
135-
FunctionCallExpr(MemberAccessExpr(base: base, name: "with\(child.name)")) {
136-
let childExpr = MemberAccessExpr(base: "syntax", name: child.swiftName)
137-
TupleExprElement(expression: FunctionCallExpr(MemberAccessExpr(base: childExpr, name: "withLeadingTrivia")) {
138-
TupleExprElement(expression: SequenceExpr {
139-
"indentedNewline"
140-
BinaryOperatorExpr("+")
141-
TupleExpr {
142-
SequenceExpr {
143-
MemberAccessExpr(base: childExpr, name: "leadingTrivia")
144-
BinaryOperatorExpr("??")
145-
ArrayExpr()
146-
}
147-
}
148-
})
149-
})
113+
createBuildableNodeFormatFunction(node: node)
114+
} else if node.isSyntaxCollection {
115+
createBuildableCollectionNodeFormatFunction(node: node)
116+
}
117+
}
118+
}
119+
}
120+
121+
private func createFormatFunctionSignature(type: SyntaxBuildableType) -> FunctionSignature {
122+
FunctionSignature(
123+
input: ParameterClause {
124+
FunctionParameter(
125+
firstName: .identifier("syntax"),
126+
colon: .colon,
127+
type: type.syntaxBaseName
128+
)
129+
},
130+
output: type.syntaxBaseName
131+
)
132+
}
133+
134+
/// Generate the _format implementation for a buildable node.
135+
private func createBuildableNodeFormatFunction(node: Node) -> FunctionDecl {
136+
FunctionDecl(
137+
modifiers: [TokenSyntax.public],
138+
identifier: .identifier("_format"),
139+
signature: createFormatFunctionSignature(type: node.type)
140+
) {
141+
VariableDecl(
142+
.var,
143+
name: "result",
144+
initializer: node.children
145+
.filter(\.requiresLeadingNewline)
146+
.reduce("syntax") { base, child in
147+
FunctionCallExpr(MemberAccessExpr(base: base, name: "with\(child.name)")) {
148+
let childExpr = MemberAccessExpr(base: "syntax", name: child.swiftName)
149+
TupleExprElement(expression: FunctionCallExpr(MemberAccessExpr(base: childExpr, name: "withLeadingTrivia")) {
150+
TupleExprElement(expression: SequenceExpr {
151+
"indentedNewline"
152+
BinaryOperatorExpr("+")
153+
TupleExpr {
154+
SequenceExpr {
155+
MemberAccessExpr(base: childExpr, name: "leadingTrivia")
156+
BinaryOperatorExpr("??")
157+
ArrayExpr()
158+
}
150159
}
151-
}
152-
)
153-
VariableDecl(
154-
.let,
155-
name: "leadingTrivia",
156-
initializer: SequenceExpr {
157-
MemberAccessExpr(base: "result", name: "leadingTrivia")
158-
BinaryOperatorExpr("??")
159-
ArrayExpr()
160-
}
161-
)
162-
IfStmt(conditions: ExprList {
163-
PrefixOperatorExpr("!", MemberAccessExpr(base: "leadingTrivia", name: "isEmpty"))
164-
}) {
165-
SequenceExpr {
166-
"result"
167-
AssignmentExpr()
168-
FunctionCallExpr(MemberAccessExpr(base: "result", name: "withLeadingTrivia")) {
169-
TupleExprElement(expression: FunctionCallExpr(MemberAccessExpr(base: "leadingTrivia", name: "addingSpacingAfterNewlinesIfNeeded")))
170-
}
171-
}
160+
})
161+
})
172162
}
173-
ReturnStmt(expression: "result")
163+
}
164+
)
165+
VariableDecl(
166+
.let,
167+
name: "leadingTrivia",
168+
initializer: SequenceExpr {
169+
MemberAccessExpr(base: "result", name: "leadingTrivia")
170+
BinaryOperatorExpr("??")
171+
ArrayExpr()
172+
}
173+
)
174+
IfStmt(conditions: ExprList {
175+
PrefixOperatorExpr("!", MemberAccessExpr(base: "leadingTrivia", name: "isEmpty"))
176+
}) {
177+
SequenceExpr {
178+
"result"
179+
AssignmentExpr()
180+
FunctionCallExpr(MemberAccessExpr(base: "result", name: "withLeadingTrivia")) {
181+
TupleExprElement(expression: FunctionCallExpr(MemberAccessExpr(base: "leadingTrivia", name: "addingSpacingAfterNewlinesIfNeeded")))
174182
}
175-
} else if node.isSyntaxCollection {
176-
FunctionDecl(
177-
modifiers: [TokenSyntax.public],
178-
identifier: .identifier("_format"),
179-
signature: signature
180-
) {
181-
if node.elementsSeparatedByNewline {
182-
FunctionCallExpr(type.syntaxBaseName) {
183-
TupleExprElement(expression: FunctionCallExpr(
184-
MemberAccessExpr(base: "syntax", name: "map"),
185-
trailingClosure: ClosureExpr {
186-
FunctionCallExpr(MemberAccessExpr(base: "$0", name: "withLeadingTrivia")) {
187-
TupleExprElement(expression: FunctionCallExpr(MemberAccessExpr(
188-
base: TupleExpr {
189-
SequenceExpr {
190-
"indentedNewline"
191-
BinaryOperatorExpr("+")
192-
TupleExpr {
193-
SequenceExpr {
194-
MemberAccessExpr(base: "$0", name: "leadingTrivia")
195-
BinaryOperatorExpr("??")
196-
ArrayExpr()
197-
}
198-
}
199-
}
200-
},
201-
name: "addingSpacingAfterNewlinesIfNeeded"
202-
)))
183+
}
184+
}
185+
ReturnStmt(expression: "result")
186+
}
187+
}
188+
189+
/// Generate the _format implementation for a collection node.
190+
/// The implementation updates the leading trivia of the elements with their indentation.
191+
private func createBuildableCollectionNodeFormatFunction(node: Node) -> FunctionDecl {
192+
FunctionDecl(
193+
modifiers: [TokenSyntax.public],
194+
identifier: .identifier("_format"),
195+
signature: createFormatFunctionSignature(type: node.type)
196+
) {
197+
if node.elementsSeparatedByNewline {
198+
FunctionCallExpr(node.type.syntaxBaseName) {
199+
TupleExprElement(expression: FunctionCallExpr(
200+
MemberAccessExpr(base: "syntax", name: "map"),
201+
trailingClosure: ClosureExpr {
202+
FunctionCallExpr(MemberAccessExpr(base: "$0", name: "withLeadingTrivia")) {
203+
TupleExprElement(expression: FunctionCallExpr(MemberAccessExpr(
204+
base: TupleExpr {
205+
SequenceExpr {
206+
"indentedNewline"
207+
BinaryOperatorExpr("+")
208+
TupleExpr {
209+
SequenceExpr {
210+
MemberAccessExpr(base: "$0", name: "leadingTrivia")
211+
BinaryOperatorExpr("??")
212+
ArrayExpr()
213+
}
214+
}
203215
}
204-
}
205-
))
216+
},
217+
name: "addingSpacingAfterNewlinesIfNeeded"
218+
)))
206219
}
207-
} else {
208-
"syntax"
209220
}
210-
}
221+
))
211222
}
223+
} else {
224+
"syntax"
212225
}
213226
}
214227
}

0 commit comments

Comments
 (0)