Skip to content

Commit d689cae

Browse files
authored
Merge pull request #1326 from kimdv/kimdv/move-raw-syntax-nodes-from-gyb-to-code-gen
Move raw syntax nodes from gyb to code gen
2 parents b4c5149 + ac46401 commit d689cae

File tree

7 files changed

+13907
-11630
lines changed

7 files changed

+13907
-11630
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: 250 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,250 @@
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+
}
113+
114+
ExprSyntax(
115+
"""
116+
switch raw.kind {
117+
case \(cases): return true
118+
default: return false
119+
}
120+
"""
121+
)
122+
} else {
123+
StmtSyntax("return raw.kind == .\(raw: node.swiftSyntaxKind)")
124+
}
125+
}
126+
127+
DeclSyntax("public var raw: RawSyntax")
128+
129+
DeclSyntax(
130+
"""
131+
init(raw: RawSyntax) {
132+
assert(Self.isKindOf(raw))
133+
self.raw = raw
134+
}
135+
"""
136+
)
137+
138+
DeclSyntax(
139+
"""
140+
public init?<Node: RawSyntaxNodeProtocol>(_ other: Node) {
141+
guard Self.isKindOf(other.raw) else { return nil }
142+
self.init(raw: other.raw)
143+
}
144+
"""
145+
)
146+
147+
if node.isBase {
148+
DeclSyntax(
149+
"""
150+
public init<Node: Raw\(raw: node.name)NodeProtocol>(_ other: Node) {
151+
self.init(raw: other.raw)
152+
}
153+
"""
154+
)
155+
}
156+
157+
if node.isSyntaxCollection {
158+
let element = node.collectionElementChoices?.isEmpty == false ? "Element" : "Raw\(node.collectionElementType.syntaxBaseName)"
159+
DeclSyntax(
160+
"""
161+
public init(elements: [\(raw: element)], arena: __shared SyntaxArena) {
162+
let raw = RawSyntax.makeLayout(
163+
kind: .\(raw: node.swiftSyntaxKind), uninitializedCount: elements.count, arena: arena) { layout in
164+
guard var ptr = layout.baseAddress else { return }
165+
for elem in elements {
166+
ptr.initialize(to: elem.raw)
167+
ptr += 1
168+
}
169+
}
170+
self.init(raw: raw)
171+
}
172+
"""
173+
)
174+
175+
DeclSyntax(
176+
"""
177+
public var elements: [Raw\(raw: node.collectionElementType.syntaxBaseName)] {
178+
layoutView.children.map { Raw\(raw: node.collectionElementType.syntaxBaseName)(raw: $0!) }
179+
}
180+
"""
181+
)
182+
}
183+
184+
if node.isBuildable || node.isMissing {
185+
let params = FunctionParameterListSyntax {
186+
for child in node.children {
187+
FunctionParameterSyntax(
188+
firstName: child.isUnexpectedNodes ? .wildcardToken(trailingTrivia: .space) : nil,
189+
secondName: .identifier(child.swiftName),
190+
colon: .colonToken(),
191+
type: child.rawParameterType,
192+
defaultArgument: child.isUnexpectedNodes ? child.defaultInitialization.map { InitializerClauseSyntax(value: $0) } : nil
193+
)
194+
}
195+
196+
FunctionParameterSyntax("arena: __shared SyntaxArena", for: .functionParameters)
197+
}
198+
try InitializerDeclSyntax("public init(\(params))") {
199+
if !node.children.isEmpty {
200+
let list = ExprListSyntax {
201+
ExprSyntax("layout.initialize(repeating: nil)")
202+
for (index, child) in node.children.enumerated() {
203+
let optionalMark = child.isOptional ? "?" : ""
204+
ExprSyntax("layout[\(raw: index)] = \(raw: child.swiftName)\(raw: optionalMark).raw")
205+
.with(\.leadingTrivia, .newline)
206+
}
207+
}
208+
209+
DeclSyntax(
210+
"""
211+
let raw = RawSyntax.makeLayout(
212+
kind: .\(raw: node.swiftSyntaxKind), uninitializedCount: \(raw: node.children.count), arena: arena) { layout in
213+
\(list)
214+
}
215+
"""
216+
)
217+
} else {
218+
DeclSyntax("let raw = RawSyntax.makeEmptyLayout(kind: .\(raw: node.swiftSyntaxKind), arena: arena)")
219+
}
220+
ExprSyntax("self.init(raw: raw)")
221+
}
222+
223+
for (index, child) in node.children.enumerated() {
224+
try VariableDeclSyntax("public var \(raw: child.swiftName): Raw\(raw: child.type.buildable)") {
225+
let iuoMark = child.isOptional ? "" : "!"
226+
227+
if child.typeName == "Syntax" {
228+
ExprSyntax("layoutView.children[\(raw: index)]\(raw: iuoMark)")
229+
} else {
230+
ExprSyntax("layoutView.children[\(raw: index)].map(Raw\(raw: child.typeName).init(raw:))\(raw: iuoMark)")
231+
}
232+
}
233+
}
234+
}
235+
}
236+
}
237+
}
238+
239+
fileprivate extension Child {
240+
var rawParameterType: TypeSyntax {
241+
let paramType: String
242+
if case ChildKind.nodeChoices = kind {
243+
paramType = name
244+
} else {
245+
paramType = "Raw\(typeName)"
246+
}
247+
248+
return type.optionalWrapped(type: SimpleTypeIdentifierSyntax(name: .identifier(paramType)))
249+
}
250+
}

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

Sources/SwiftSyntax/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ add_swift_host_library(SwiftSyntax
2929
Raw/RawSyntaxNodeProtocol.swift
3030
Raw/RawSyntaxTokenView.swift
3131

32-
Raw/gyb_generated/RawSyntaxNodes.swift
32+
generated/raw/RawSyntaxNodes.swift
3333
Raw/gyb_generated/RawSyntaxValidation.swift
3434

3535
generated/Keyword.swift

0 commit comments

Comments
 (0)