Skip to content

Commit b26a19e

Browse files
committed
Move raw syntax nodes from gyb to code gen
1 parent 09a7b24 commit b26a19e

File tree

6 files changed

+8883
-6580
lines changed

6 files changed

+8883
-6580
lines changed

CodeGeneration/Sources/SyntaxSupport/Child.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ public class Child {
7575
case .node(kind: let kind):
7676
return kind
7777
case .nodeChoices:
78-
return "syntax"
78+
return "Syntax"
7979
case .collection(kind: let kind, collectionElementName: _):
8080
return kind
8181
case .token(choices: let choices, requiresLeadingSpace: _, requiresTrailingSpace: _):

CodeGeneration/Sources/generate-swiftsyntax/GenerateSwiftSyntax.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ struct GenerateSwiftSyntax: ParsableCommand {
7171
// SwiftSyntax
7272
TemplateSpec(sourceFile: keywordFile, module: swiftSyntaxDir, filename: "Keyword.swift"),
7373
TemplateSpec(sourceFile: miscFile, module: swiftSyntaxDir, filename: "Misc.swift"),
74+
TemplateSpec(sourceFile: rawSyntaxNodesFile, module: swiftSyntaxDir, filename: "raw/RawSyntaxNodes.swift"),
7475
TemplateSpec(sourceFile: syntaxAnyVisitorFile, module: swiftSyntaxDir, filename: "SyntaxAnyVisitor.swift"),
7576
TemplateSpec(sourceFile: syntaxBaseNodesFile, module: swiftSyntaxDir, filename: "SyntaxBaseNodes.swift"),
7677
TemplateSpec(sourceFile: syntaxCollectionsFile, module: swiftSyntaxDir, filename: "SyntaxCollections.swift"),
Lines changed: 271 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,271 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2014 - 2022 Apple Inc. and the Swift project authors
6+
// Licensed under Apache License v2.0 with Runtime Library Exception
7+
//
8+
// See https://swift.org/LICENSE.txt for license information
9+
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10+
//
11+
//===----------------------------------------------------------------------===//
12+
13+
import SwiftSyntax
14+
import SwiftSyntaxBuilder
15+
import SyntaxSupport
16+
import Utils
17+
18+
let rawSyntaxNodesFile = SourceFileSyntax(leadingTrivia: "\(generateCopyrightHeader(for: "generate-swiftsyntax"))" + .newline) {
19+
for node in SYNTAX_NODES where node.isBase {
20+
DeclSyntax(
21+
"""
22+
@_spi(RawSyntax)
23+
public protocol Raw\(raw: node.name)NodeProtocol: Raw\(raw: node.baseType.syntaxKind)NodeProtocol {}
24+
"""
25+
)
26+
}
27+
28+
for node in SYNTAX_NODES {
29+
try! StructDeclSyntax(
30+
"""
31+
@_spi(RawSyntax)
32+
public struct Raw\(raw: node.name): Raw\(raw: (node.isBase ? node.name : node.baseType.syntaxBaseName))NodeProtocol
33+
"""
34+
) {
35+
let enums: [(String, [(swiftName: String, typeName: String)])] =
36+
node.children.compactMap { child -> (String, [(String, String)])? in
37+
switch child.kind {
38+
case .nodeChoices(let choices):
39+
return (child.name, choices.map { ($0.swiftName, $0.typeName) })
40+
default:
41+
return nil
42+
}
43+
}
44+
+ (node.collectionElementChoices?.isEmpty == false
45+
? [("Element", node.collectionElementChoices!.map { choice -> (String, String) in (SYNTAX_NODE_MAP[choice]!.swiftSyntaxKind, SYNTAX_NODE_MAP[choice]!.name) })]
46+
: [])
47+
48+
for (name, choices) in enums {
49+
try EnumDeclSyntax(
50+
"""
51+
@frozen // FIXME: Not actually stable, works around a miscompile
52+
public enum \(raw: name): RawSyntaxNodeProtocol
53+
"""
54+
) {
55+
for (swiftName, typeName) in choices {
56+
DeclSyntax("case `\(raw: swiftName)`(Raw\(raw: typeName))")
57+
}
58+
59+
DeclSyntax(
60+
"""
61+
public static func isKindOf(_ raw: RawSyntax) -> Bool {
62+
return \(raw: choices.map { "Raw\($0.typeName).isKindOf(raw)" }.joined(separator: " || "))
63+
}
64+
"""
65+
)
66+
67+
try VariableDeclSyntax("public var raw: RawSyntax") {
68+
try SwitchExprSyntax("switch self") {
69+
for (swiftName, _) in choices {
70+
SwitchCaseSyntax("case .\(raw: swiftName)(let node): return node.raw")
71+
}
72+
}
73+
}
74+
75+
try InitializerDeclSyntax("public init?<T>(_ other: T) where T : RawSyntaxNodeProtocol") {
76+
for (swiftName, typeName) in choices {
77+
StmtSyntax(
78+
"""
79+
if let node = Raw\(raw: typeName)(other) {
80+
self = .\(raw: swiftName)(node)
81+
return
82+
}
83+
"""
84+
)
85+
}
86+
87+
StmtSyntax("return nil")
88+
}
89+
}
90+
}
91+
92+
DeclSyntax(
93+
"""
94+
@_spi(RawSyntax)
95+
public var layoutView: RawSyntaxLayoutView {
96+
return raw.layoutView!
97+
}
98+
"""
99+
)
100+
101+
try FunctionDeclSyntax("public static func isKindOf(_ raw: RawSyntax) -> Bool") {
102+
if node.isBase {
103+
104+
let cases = CaseItemListSyntax {
105+
for n in SYNTAX_NODES where n.baseKind == node.syntaxKind {
106+
CaseItemSyntax(
107+
pattern: ExpressionPatternSyntax(
108+
expression: ExprSyntax(".\(raw: n.swiftSyntaxKind)")))
109+
}
110+
}
111+
112+
ExprSyntax(
113+
"""
114+
switch raw.kind {
115+
case \(cases): return true
116+
default: return false
117+
}
118+
"""
119+
)
120+
} else {
121+
StmtSyntax("return raw.kind == .\(raw: node.swiftSyntaxKind)")
122+
}
123+
}
124+
125+
DeclSyntax("public var raw: RawSyntax")
126+
127+
DeclSyntax(
128+
"""
129+
init(raw: RawSyntax) {
130+
assert(Self.isKindOf(raw))
131+
self.raw = raw
132+
}
133+
"""
134+
)
135+
136+
DeclSyntax(
137+
"""
138+
public init?<Node: RawSyntaxNodeProtocol>(_ other: Node) {
139+
guard Self.isKindOf(other.raw) else { return nil }
140+
self.init(raw: other.raw)
141+
}
142+
"""
143+
)
144+
145+
if node.isBase {
146+
DeclSyntax(
147+
"""
148+
public init<Node: Raw\(raw: node.name)NodeProtocol>(_ other: Node) {
149+
self.init(raw: other.raw)
150+
}
151+
"""
152+
)
153+
}
154+
155+
if node.isSyntaxCollection {
156+
let element = node.collectionElementChoices?.isEmpty == false ? "Element" : "Raw\(node.collectionElementType.syntaxBaseName)"
157+
DeclSyntax(
158+
"""
159+
public init(elements: [\(raw: element)], arena: __shared SyntaxArena) {
160+
let raw = RawSyntax.makeLayout(
161+
kind: .\(raw: node.swiftSyntaxKind), uninitializedCount: elements.count, arena: arena) { layout in
162+
guard var ptr = layout.baseAddress else { return }
163+
for elem in elements {
164+
ptr.initialize(to: elem.raw)
165+
ptr += 1
166+
}
167+
}
168+
self.init(raw: raw)
169+
}
170+
"""
171+
)
172+
173+
DeclSyntax(
174+
"""
175+
public var elements: [Raw\(raw: node.collectionElementType.syntaxBaseName)] {
176+
layoutView.children.map { Raw\(raw: node.collectionElementType.syntaxBaseName)(raw: $0!) }
177+
}
178+
"""
179+
)
180+
}
181+
182+
if node.isBuildable || node.isMissing {
183+
let params = FunctionParameterListSyntax {
184+
for child in node.children {
185+
FunctionParameterSyntax(
186+
firstName: child.isUnexpectedNodes ? .wildcardToken(trailingTrivia: .space) : nil,
187+
secondName: .identifier(child.swiftName),
188+
colon: .colonToken(),
189+
type: child.rawParameterType,
190+
defaultArgument: child.isUnexpectedNodes ? child.defaultInitialization.map { InitializerClauseSyntax(value: $0) } : nil
191+
)
192+
}
193+
194+
FunctionParameterSyntax("arena: __shared SyntaxArena", for: .functionParameters)
195+
}
196+
try InitializerDeclSyntax("public init(\(params))") {
197+
if !node.children.isEmpty {
198+
for child in node.children {
199+
if child.typeName == "TokenSyntax", case .token(let tokenChoices, _, _) = child.kind, !child.swiftName.contains("async"), !child.swiftName.contains("throw") {
200+
let choices = tokenChoices.map { token -> (String, String) in
201+
switch token {
202+
case .keyword(let text):
203+
if text == "init" {
204+
return ("", ".keyword(.`init`")
205+
} else {
206+
return ("", ".keyword(.\(text))")
207+
}
208+
case .token(let tokenKind):
209+
return (".base", tokenKind)
210+
}
211+
}
212+
if child.isOptional {
213+
// FIXME: Assert disabled because normal CI doesn't have assertions enabled and debug CI seems to fail in a variety of places with this assertion
214+
// assert(${child.swift_name} == nil || ${' || '.join([f'{child.swift_name}?.tokenKind{base} == {choice}' for (base, choice) in choices])}, "Received \(String(describing: ${child.swift_name}?.tokenKind))")
215+
} else {
216+
// FIXME: Assert disabled because normal CI doesn't have assertions enabled and debug CI seems to fail in a variety of places with this assertion
217+
// assert(${' || '.join([f'{child.swift_name}.tokenKind{base} == {choice}' for (base, choice) in choices])}, "Received \(${child.swift_name}.tokenKind)")
218+
}
219+
}
220+
}
221+
let list = ExprListSyntax {
222+
ExprSyntax("layout.initialize(repeating: nil)")
223+
for (index, child) in node.children.enumerated() {
224+
let optionalMark = child.isOptional ? "?" : ""
225+
ExprSyntax("layout[\(raw: index)] = \(raw: child.swiftName)\(raw: optionalMark).raw")
226+
.with(\.leadingTrivia, .newline)
227+
}
228+
}
229+
230+
DeclSyntax(
231+
"""
232+
let raw = RawSyntax.makeLayout(
233+
kind: .\(raw: node.swiftSyntaxKind), uninitializedCount: \(raw: node.children.count), arena: arena) { layout in
234+
\(list)
235+
}
236+
"""
237+
)
238+
} else {
239+
DeclSyntax("let raw = RawSyntax.makeEmptyLayout(kind: .\(raw: node.swiftSyntaxKind), arena: arena)")
240+
}
241+
ExprSyntax("self.init(raw: raw)")
242+
}
243+
244+
for (index, child) in node.children.enumerated() {
245+
try VariableDeclSyntax("public var \(raw: child.swiftName): Raw\(raw: child.type.buildable)") {
246+
let iuoMark = child.isOptional ? "" : "!"
247+
248+
if child.typeName == "Syntax" {
249+
ExprSyntax("layoutView.children[\(raw: index)]\(raw: iuoMark)")
250+
} else {
251+
ExprSyntax("layoutView.children[\(raw: index)].map(Raw\(raw: child.typeName).init(raw:))\(raw: iuoMark)")
252+
}
253+
}
254+
}
255+
}
256+
}
257+
}
258+
}
259+
260+
fileprivate extension Child {
261+
var rawParameterType: TypeSyntax {
262+
let paramType: String
263+
if case ChildKind.nodeChoices = kind {
264+
paramType = name
265+
} else {
266+
paramType = "Raw\(typeName)"
267+
}
268+
269+
return type.optionalWrapped(type: SimpleTypeIdentifierSyntax(name: .identifier(paramType)))
270+
}
271+
}

Package.swift

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,6 @@ let package = Package(
6565
dependencies: [],
6666
exclude: [
6767
"CMakeLists.txt",
68-
"Raw/RawSyntaxNodes.swift.gyb",
6968
"Raw/RawSyntaxValidation.swift.gyb",
7069
],
7170
swiftSettings: swiftSyntaxSwiftSettings

0 commit comments

Comments
 (0)