Skip to content

Commit e9024bc

Browse files
committed
Add SyntaxEnum per base syntax kind
Add DeclSyntaxEnum, StmtSyntaxEnum, ExprSyntaxEnum, TypeSyntaxEnum and PatternSyntaxEnum. These are useful for exhaustively enumerating specific syntax kind.
1 parent 86783bd commit e9024bc

File tree

3 files changed

+484
-0
lines changed

3 files changed

+484
-0
lines changed

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

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,4 +57,50 @@ let syntaxEnumFile = SourceFileSyntax(leadingTrivia: copyrightHeader) {
5757
}
5858
}
5959
}
60+
61+
for base in SYNTAX_NODES where base.kind.isBase {
62+
let baseKind = base.kind
63+
let baseName = baseKind.rawValue.withFirstCharacterUppercased;
64+
let enumType: TypeSyntax = "\(raw: baseName)SyntaxEnum"
65+
66+
try! EnumDeclSyntax(
67+
"""
68+
/// Enum to exhaustively switch over all different \(raw: baseName) syntax nodes.
69+
public enum \(enumType)
70+
"""
71+
) {
72+
for node in NON_BASE_SYNTAX_NODES where node.base == baseKind {
73+
DeclSyntax(
74+
"""
75+
\(node.apiAttributes())\
76+
case \(node.varOrCaseName)(\(node.kind.syntaxType))
77+
"""
78+
)
79+
}
80+
}
81+
82+
try! ExtensionDeclSyntax(
83+
"""
84+
public extension \(baseKind.syntaxType)
85+
"""
86+
) {
87+
try FunctionDeclSyntax(
88+
"""
89+
/// Get an enum that can be used to exhaustively switch over all \(raw: baseName) syntax nodes.
90+
func `as`(_: \(enumType).Type) -> \(enumType)
91+
"""
92+
) {
93+
try SwitchExprSyntax("switch raw.kind") {
94+
for node in NON_BASE_SYNTAX_NODES where node.base == baseKind {
95+
SwitchCaseSyntax("case .\(node.varOrCaseName):") {
96+
StmtSyntax("return .\(node.varOrCaseName)(\(node.kind.syntaxType)(self)!)")
97+
}
98+
}
99+
SwitchCaseSyntax("default:") {
100+
ExprSyntax(#"preconditionFailure("unknown \#(raw: baseName) syntax kind")"#)
101+
}
102+
}
103+
}
104+
}
105+
}
60106
}

0 commit comments

Comments
 (0)