Skip to content

Commit 5692c16

Browse files
committed
Significantly improve performance of BasicFormat
In `visit(TokenSyntax)`, we were modifying the token in place, which caused the entire syntax tree to be rewritten to it’s root. It’s a lot (6x) faster to just modify `leadingTrivia` and `trailingTrivia` and create a new `TokenSyntax` that doesn’t have a parent.
1 parent 7e3dc35 commit 5692c16

File tree

2 files changed

+224
-206
lines changed

2 files changed

+224
-206
lines changed

CodeGeneration/Sources/generate-swiftbasicformat/BasicFormatFile.swift

Lines changed: 26 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -166,24 +166,25 @@ private func createTokenFormatFunction() -> FunctionDecl {
166166
output: "Syntax"
167167
)
168168
) {
169-
VariableDecl("var node = node")
169+
VariableDecl("var leadingTrivia = node.leadingTrivia")
170+
VariableDecl("var trailingTrivia = node.trailingTrivia")
170171
SwitchStmt(expression: MemberAccessExpr(base: "node", name: "tokenKind")) {
171172
for token in SYNTAX_TOKENS where token.name != "ContextualKeyword" {
172173
SwitchCase(label: SwitchCaseLabel(caseItems: CaseItem(pattern: ExpressionPattern(expression: MemberAccessExpr(name: token.swiftKind))))) {
173174
if token.requiresLeadingSpace {
174175
IfStmt(
175176
"""
176-
if node.leadingTrivia.isEmpty && lastRewrittenToken?.trailingTrivia.isEmpty != false {
177-
node.leadingTrivia += .space
177+
if leadingTrivia.isEmpty && lastRewrittenToken?.trailingTrivia.isEmpty != false {
178+
leadingTrivia += .space
178179
}
179180
"""
180181
)
181182
}
182183
if token.requiresTrailingSpace {
183184
IfStmt(
184185
"""
185-
if node.trailingTrivia.isEmpty {
186-
node.trailingTrivia += .space
186+
if trailingTrivia.isEmpty {
187+
trailingTrivia += .space
187188
}
188189
"""
189190
)
@@ -200,20 +201,30 @@ private func createTokenFormatFunction() -> FunctionDecl {
200201
SwitchStmt(
201202
"""
202203
switch node.text {
203-
case "async":
204-
if node.trailingTrivia.isEmpty {
205-
node.trailingTrivia += .space
206-
}
207-
default:
208-
break
204+
case "async":
205+
if trailingTrivia.isEmpty {
206+
trailingTrivia += .space
207+
}
208+
default:
209+
break
209210
}
210211
"""
211212
)
212213
}
213214
}
214-
SequenceExpr("node.leadingTrivia = node.leadingTrivia.indented(indentation: indentation)")
215-
SequenceExpr("node.trailingTrivia = node.trailingTrivia.indented(indentation: indentation)")
216-
SequenceExpr("lastRewrittenToken = node")
217-
ReturnStmt("return Syntax(node)")
215+
SequenceExpr("leadingTrivia = leadingTrivia.indented(indentation: indentation)")
216+
SequenceExpr("trailingTrivia = trailingTrivia.indented(indentation: indentation)")
217+
VariableDecl(
218+
"""
219+
let rewritten = TokenSyntax(
220+
node.tokenKind,
221+
leadingTrivia: leadingTrivia,
222+
trailingTrivia: trailingTrivia,
223+
presence: node.presence
224+
)
225+
"""
226+
)
227+
SequenceExpr("lastRewrittenToken = rewritten")
228+
ReturnStmt("return Syntax(rewritten)")
218229
}
219230
}

0 commit comments

Comments
 (0)