Skip to content

Commit 6be29a5

Browse files
authored
Merge pull request #2908 from ahoppen/rawsyntaxvalidation-stack-usage
Create local functions to validate the RawSyntax layout of nodes
2 parents b479382 + 704b199 commit 6be29a5

File tree

2 files changed

+1203
-343
lines changed

2 files changed

+1203
-343
lines changed

CodeGeneration/Sources/generate-swift-syntax/templates/swiftsyntax/RawSyntaxValidationFile.swift

Lines changed: 64 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -190,75 +190,83 @@ let rawSyntaxValidationFile = try! SourceFileSyntax(leadingTrivia: copyrightHead
190190
"""#
191191
)
192192

193-
try SwitchExprSyntax("switch kind") {
194-
SwitchCaseSyntax(
195-
"""
196-
case .token:
197-
assertionFailure("validateLayout for .token kind is not supported")
198-
"""
199-
)
200-
201-
for node in NON_BASE_SYNTAX_NODES {
202-
try SwitchCaseSyntax("case .\(node.enumCaseCallName):") {
203-
if let node = node.layoutNode {
204-
ExprSyntax("assert(layout.count == \(raw: node.children.count))")
205-
for (index, child) in node.children.enumerated() {
206-
switch child.kind {
207-
case .nodeChoices(let choices, _):
208-
let verifiedChoices = ArrayExprSyntax {
209-
ArrayElementSyntax(
210-
leadingTrivia: .newline,
211-
expression: ExprSyntax(
212-
"verify(layout[\(raw: index)], as: Raw\(child.buildableType.buildable).self)"
213-
)
193+
for node in NON_BASE_SYNTAX_NODES {
194+
try FunctionDeclSyntax(
195+
"func validate\(node.kind.syntaxType)(kind: SyntaxKind, layout: RawSyntaxBuffer)"
196+
) {
197+
if let node = node.layoutNode {
198+
ExprSyntax("assert(layout.count == \(raw: node.children.count))")
199+
for (index, child) in node.children.enumerated() {
200+
switch child.kind {
201+
case .nodeChoices(let choices, _):
202+
let verifiedChoices = ArrayExprSyntax {
203+
ArrayElementSyntax(
204+
leadingTrivia: .newline,
205+
expression: ExprSyntax(
206+
"verify(layout[\(raw: index)], as: Raw\(child.buildableType.buildable).self)"
214207
)
215-
}
208+
)
209+
}
216210

217-
ExprSyntax("assertAnyHasNoError(kind, \(raw: index), \(verifiedChoices))")
218-
case .token(choices: let choices, requiresLeadingSpace: _, requiresTrailingSpace: _):
219-
let choices = ArrayExprSyntax {
220-
for choice in choices {
221-
switch choice {
222-
case .keyword(let keyword):
223-
ArrayElementSyntax(expression: ExprSyntax(".keyword(\(literal: keyword.spec.name))"))
224-
case .token(let token):
225-
ArrayElementSyntax(expression: ExprSyntax(".tokenKind(.\(token.spec.memberCallName))"))
226-
}
211+
ExprSyntax("assertAnyHasNoError(kind, \(raw: index), \(verifiedChoices))")
212+
case .token(choices: let choices, requiresLeadingSpace: _, requiresTrailingSpace: _):
213+
let choices = ArrayExprSyntax {
214+
for choice in choices {
215+
switch choice {
216+
case .keyword(let keyword):
217+
ArrayElementSyntax(expression: ExprSyntax(".keyword(\(literal: keyword.spec.name))"))
218+
case .token(let token):
219+
ArrayElementSyntax(expression: ExprSyntax(".tokenKind(.\(token.spec.memberCallName))"))
227220
}
228221
}
229-
let verifyCall = ExprSyntax(
230-
"verify(layout[\(raw: index)], as: Raw\(child.buildableType.buildable).self, tokenChoices: \(choices))"
231-
)
232-
ExprSyntax("assertNoError(kind, \(raw: index), \(verifyCall))")
233-
default:
234-
ExprSyntax(
235-
"assertNoError(kind, \(raw: index), verify(layout[\(raw: index)], as: Raw\(child.buildableType.buildable).self))"
236-
)
237222
}
223+
let verifyCall = ExprSyntax(
224+
"verify(layout[\(raw: index)], as: Raw\(child.buildableType.buildable).self, tokenChoices: \(choices))"
225+
)
226+
ExprSyntax("assertNoError(kind, \(raw: index), \(verifyCall))")
227+
default:
228+
ExprSyntax(
229+
"assertNoError(kind, \(raw: index), verify(layout[\(raw: index)], as: Raw\(child.buildableType.buildable).self))"
230+
)
238231
}
239-
} else if let node = node.collectionNode {
240-
try ForStmtSyntax("for (index, element) in layout.enumerated()") {
241-
if let onlyElement = node.elementChoices.only {
242-
ExprSyntax(
243-
"assertNoError(kind, index, verify(element, as: \(onlyElement.raw.syntaxType).self))"
244-
)
245-
} else {
246-
let verifiedChoices = ArrayExprSyntax {
247-
for choiceName in node.elementChoices {
248-
let choice = SYNTAX_NODE_MAP[choiceName]!
249-
ArrayElementSyntax(
250-
leadingTrivia: .newline,
251-
expression: ExprSyntax("verify(element, as: \(choice.kind.raw.syntaxType).self)")
252-
)
253-
}
232+
}
233+
} else if let node = node.collectionNode {
234+
try ForStmtSyntax("for (index, element) in layout.enumerated()") {
235+
if let onlyElement = node.elementChoices.only {
236+
ExprSyntax(
237+
"assertNoError(kind, index, verify(element, as: \(onlyElement.raw.syntaxType).self))"
238+
)
239+
} else {
240+
let verifiedChoices = ArrayExprSyntax {
241+
for choiceName in node.elementChoices {
242+
let choice = SYNTAX_NODE_MAP[choiceName]!
243+
ArrayElementSyntax(
244+
leadingTrivia: .newline,
245+
expression: ExprSyntax("verify(element, as: \(choice.kind.raw.syntaxType).self)")
246+
)
254247
}
255-
ExprSyntax("assertAnyHasNoError(kind, index, \(verifiedChoices))")
256248
}
249+
ExprSyntax("assertAnyHasNoError(kind, index, \(verifiedChoices))")
257250
}
258251
}
259252
}
260253
}
261254
}
255+
256+
try SwitchExprSyntax("switch kind") {
257+
SwitchCaseSyntax(
258+
"""
259+
case .token:
260+
assertionFailure("validateLayout for .token kind is not supported")
261+
"""
262+
)
263+
264+
for node in NON_BASE_SYNTAX_NODES {
265+
SwitchCaseSyntax("case .\(node.enumCaseCallName):") {
266+
ExprSyntax("validate\(node.kind.syntaxType)(kind: kind, layout: layout)")
267+
}
268+
}
269+
}
262270
}
263271
)
264272
)

0 commit comments

Comments
 (0)