Skip to content

Commit 361a140

Browse files
authored
Merge pull request #2129 from ahoppen/ahoppen/kill-syntaxdata
Remove the SyntaxData abstraction layer
2 parents 86f50c2 + d2011cb commit 361a140

40 files changed

+6172
-8522
lines changed

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

Lines changed: 2 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -184,7 +184,7 @@ let syntaxBaseNodesFile = SourceFileSyntax(leadingTrivia: copyrightHeader) {
184184
// We know this cast is going to succeed. Go through init(_: SyntaxData)
185185
// to do a sanity check and verify the kind matches in debug builds and get
186186
// maximum performance in release builds.
187-
self.init(syntax._syntaxNode.data)
187+
self = Syntax(syntax).cast(Self.self)
188188
}
189189
"""
190190
)
@@ -205,7 +205,7 @@ let syntaxBaseNodesFile = SourceFileSyntax(leadingTrivia: copyrightHeader) {
205205
// We know this cast is going to succeed. Go through init(_: SyntaxData)
206206
// to do a sanity check and verify the kind matches in debug builds and get
207207
// maximum performance in release builds.
208-
self.init(syntax._syntaxNode.data)
208+
self = Syntax(syntax).cast(Self.self)
209209
}
210210
"""
211211
)
@@ -246,42 +246,6 @@ let syntaxBaseNodesFile = SourceFileSyntax(leadingTrivia: copyrightHeader) {
246246
}
247247
}
248248

249-
try InitializerDeclSyntax(
250-
"""
251-
/// Creates a ``\(node.kind.syntaxType)`` node from the given ``SyntaxData``.
252-
///
253-
/// - Warning: This assumes that the ``SyntaxData`` is of the correct kind.
254-
/// If it is not, the behaviour is undefined.
255-
internal init(_ data: SyntaxData)
256-
"""
257-
) {
258-
CodeBlockItemListSyntax {
259-
try! SwitchExprSyntax("switch data.raw.kind") {
260-
SwitchCaseSyntax(
261-
label: .case(
262-
SwitchCaseLabelSyntax {
263-
for childNode in SYNTAX_NODES where childNode.base == node.kind {
264-
SwitchCaseItemSyntax(
265-
pattern: ExpressionPatternSyntax(
266-
expression: ExprSyntax(".\(childNode.varOrCaseName)")
267-
)
268-
)
269-
}
270-
}
271-
)
272-
) {
273-
BreakStmtSyntax()
274-
}
275-
276-
SwitchCaseSyntax("default:") {
277-
ExprSyntax("preconditionFailure(\"Unable to create \(node.kind.syntaxType) from \\(data.raw.kind)\")")
278-
}
279-
}
280-
}
281-
282-
ExprSyntax("self._syntaxNode = Syntax(data)")
283-
}
284-
285249
DeclSyntax(
286250
"""
287251
/// Syntax nodes always conform to `\(node.kind.protocolType)`. This API is just

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

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,8 +61,6 @@ let syntaxCollectionsFile = SourceFileSyntax(leadingTrivia: copyrightHeader) {
6161
}
6262
}
6363

64-
DeclSyntax("init(_ data: SyntaxData) { self.init(Syntax(data))! }")
65-
6664
for choiceName in node.elementChoices {
6765
let choiceNode = SYNTAX_NODE_MAP[choiceName]!
6866
if choiceNode.kind.isBase {

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

Lines changed: 11 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -65,19 +65,6 @@ func syntaxNode(nodesStartingWith: [Character]) -> SourceFileSyntax {
6565
"""
6666
)
6767

68-
DeclSyntax(
69-
"""
70-
/// Creates a ``\(node.kind.syntaxType)`` node from the given ``SyntaxData``.
71-
///
72-
/// - Warning: This assumes that the `SyntaxData` is of the correct kind.
73-
/// If it is not, the behaviour is undefined.
74-
internal init(_ data: SyntaxData) {
75-
precondition(data.raw.kind == .\(node.varOrCaseName))
76-
self._syntaxNode = Syntax(data)
77-
}
78-
"""
79-
)
80-
8168
try! InitializerDeclSyntax(
8269
"""
8370
\(node.generateInitializerDocComment())
@@ -136,23 +123,20 @@ func syntaxNode(nodesStartingWith: [Character]) -> SourceFileSyntax {
136123
"""
137124
)
138125
}
139-
StmtSyntax("return SyntaxData.forRoot(raw, rawNodeArena: arena)")
126+
StmtSyntax("return Syntax.forRoot(raw, rawNodeArena: arena).cast(Self.self)")
140127
}
141128
)
142129

143-
VariableDeclSyntax(
130+
InfixOperatorExprSyntax(
144131
leadingTrivia: """
145132
// Extend the lifetime of all parameters so their arenas don't get destroyed
146133
// before they can be added as children of the new arena.
147134
148135
""",
149-
.let,
150-
name: PatternSyntax("data"),
151-
type: TypeAnnotationSyntax(type: TypeSyntax("SyntaxData")),
152-
initializer: InitializerClauseSyntax(value: initializer)
136+
leftOperand: ExprSyntax("self"),
137+
operator: ExprSyntax(AssignmentExprSyntax()),
138+
rightOperand: initializer
153139
)
154-
155-
ExprSyntax("self.init(data)")
156140
}
157141

158142
for (index, child) in node.children.enumerated() {
@@ -170,19 +154,14 @@ func syntaxNode(nodesStartingWith: [Character]) -> SourceFileSyntax {
170154
"""
171155
) {
172156
AccessorDeclSyntax(accessorSpecifier: .keyword(.get)) {
173-
if child.isOptional {
174-
StmtSyntax("return data.child(at: \(raw: index)).map(\(childType).init)")
175-
} else {
176-
StmtSyntax("return \(childType)(data.child(at: \(raw: index))!)")
177-
}
157+
let optionalityMarker: TokenSyntax = child.isOptional ? .infixQuestionMarkToken() : .exclamationMarkToken()
158+
StmtSyntax("return Syntax(self).child(at: \(raw: index))\(optionalityMarker).cast(\(childType).self)")
178159
}
179160

180-
let questionMark = child.isOptional ? TokenSyntax.postfixQuestionMarkToken() : nil
181-
182161
AccessorDeclSyntax(
183162
"""
184163
set(value) {
185-
self = \(node.kind.syntaxType)(data.replacingChild(at: \(raw: index), with: value\(questionMark).data, arena: SyntaxArena()))
164+
self = Syntax(self).replacingChild(at: \(raw: index), with: Syntax(value), arena: SyntaxArena()).cast(\(node.kind.syntaxType).self)
186165
}
187166
"""
188167
)
@@ -218,8 +197,9 @@ func syntaxNode(nodesStartingWith: [Character]) -> SourceFileSyntax {
218197
collection = RawSyntax.makeLayout(kind: SyntaxKind.\(childNode.varOrCaseName),
219198
from: [element.raw], arena: arena)
220199
}
221-
let newData = data.replacingChild(at: \(raw: index), with: collection, rawNodeArena: arena, allocationArena: arena)
222-
return \(node.kind.syntaxType)(newData)
200+
return Syntax(self)
201+
.replacingChild(at: \(raw: index), with: collection, rawNodeArena: arena, allocationArena: arena)
202+
.cast(\(node.kind.syntaxType).self)
223203
}
224204
"""
225205
)
@@ -262,8 +242,6 @@ private func generateSyntaxChildChoices(for child: Child) throws -> EnumDeclSynt
262242
}
263243
}
264244

265-
DeclSyntax("init(_ data: SyntaxData) { self.init(Syntax(data))! }")
266-
267245
for choice in choices {
268246
if let choiceNode = SYNTAX_NODE_MAP[choice.syntaxNodeKind], choiceNode.kind.isBase {
269247
DeclSyntax(

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

Lines changed: 22 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -44,13 +44,13 @@ let syntaxRewriterFile = SourceFileSyntax(leadingTrivia: copyrightHeader) {
4444
"""
4545
/// Rewrite `node`, keeping its parent unless `detach` is `true`.
4646
public func rewrite(_ node: some SyntaxProtocol, detach: Bool = false) -> Syntax {
47-
let rewritten = self.visit(node.data)
47+
let rewritten = self.dispatchVisit(Syntax(node))
4848
if detach {
4949
return rewritten
5050
}
5151
5252
return withExtendedLifetime(rewritten) {
53-
return Syntax(node.data.replacingSelf(rewritten.raw, rawNodeArena: rewritten.raw.arena, allocationArena: SyntaxArena()))
53+
return Syntax(node).replacingSelf(rewritten.raw, rawNodeArena: rewritten.raw.arena, allocationArena: SyntaxArena())
5454
}
5555
}
5656
"""
@@ -105,15 +105,15 @@ let syntaxRewriterFile = SourceFileSyntax(leadingTrivia: copyrightHeader) {
105105
/// - Returns: the rewritten node
106106
@available(*, deprecated, renamed: "rewrite(_:detach:)")
107107
public func visit(_ node: Syntax) -> Syntax {
108-
return visit(node.data)
108+
return dispatchVisit(node)
109109
}
110110
"""
111111
)
112112

113113
DeclSyntax(
114114
"""
115115
public func visit<T: SyntaxChildChoices>(_ node: T) -> T {
116-
return visit(node.data).cast(T.self)
116+
return dispatchVisit(Syntax(node)).cast(T.self)
117117
}
118118
"""
119119
)
@@ -155,31 +155,31 @@ let syntaxRewriterFile = SourceFileSyntax(leadingTrivia: copyrightHeader) {
155155
/// - Returns: the rewritten node
156156
\(baseNode.apiAttributes())\
157157
public func visit(_ node: \(baseKind.syntaxType)) -> \(baseKind.syntaxType) {
158-
return visit(node.data).cast(\(baseKind.syntaxType).self)
158+
return dispatchVisit(Syntax(node)).cast(\(baseKind.syntaxType).self)
159159
}
160160
"""
161161
)
162162
}
163163

164164
DeclSyntax(
165165
"""
166-
/// Interpret `data` as a node of type `nodeType`, visit it, calling
166+
/// Interpret `node` as a node of type `nodeType`, visit it, calling
167167
/// the `visit` to transform the node.
168168
private func visitImpl<NodeType: SyntaxProtocol>(
169-
_ data: SyntaxData,
169+
_ node: Syntax,
170170
_ nodeType: NodeType.Type,
171171
_ visit: (NodeType) -> some SyntaxProtocol
172172
) -> Syntax {
173-
let node = Syntax(data).cast(NodeType.self)
173+
let castedNode = node.cast(NodeType.self)
174174
// Accessing _syntaxNode directly is faster than calling Syntax(node)
175-
visitPre(node._syntaxNode)
175+
visitPre(node)
176176
defer {
177-
visitPost(node._syntaxNode)
177+
visitPost(node)
178178
}
179-
if let newNode = visitAny(node._syntaxNode) {
179+
if let newNode = visitAny(node) {
180180
return newNode
181181
}
182-
return Syntax(visit(node))
182+
return Syntax(visit(castedNode))
183183
}
184184
"""
185185
)
@@ -220,10 +220,10 @@ let syntaxRewriterFile = SourceFileSyntax(leadingTrivia: copyrightHeader) {
220220
/// that determines the correct visitation function will be popped of the
221221
/// stack before the function is being called, making the switch's stack
222222
/// space transient instead of having it linger in the call stack.
223-
private func visitationFunc(for data: SyntaxData) -> ((SyntaxData) -> Syntax)
223+
private func visitationFunc(for node: Syntax) -> ((Syntax) -> Syntax)
224224
"""
225225
) {
226-
try SwitchExprSyntax("switch data.raw.kind") {
226+
try SwitchExprSyntax("switch node.raw.kind") {
227227
SwitchCaseSyntax("case .token:") {
228228
StmtSyntax("return { self.visitImpl($0, TokenSyntax.self, self.visit) }")
229229
}
@@ -238,8 +238,8 @@ let syntaxRewriterFile = SourceFileSyntax(leadingTrivia: copyrightHeader) {
238238

239239
DeclSyntax(
240240
"""
241-
private func visit(_ data: SyntaxData) -> Syntax {
242-
return visitationFunc(for: data)(data)
241+
private func dispatchVisit(_ node: Syntax) -> Syntax {
242+
return visitationFunc(for: node)(node)
243243
}
244244
"""
245245
)
@@ -250,15 +250,15 @@ let syntaxRewriterFile = SourceFileSyntax(leadingTrivia: copyrightHeader) {
250250
poundKeyword: .poundElseToken(),
251251
elements: .statements(
252252
CodeBlockItemListSyntax {
253-
try! FunctionDeclSyntax("private func visit(_ data: SyntaxData) -> Syntax") {
254-
try SwitchExprSyntax("switch data.raw.kind") {
253+
try! FunctionDeclSyntax("private func dispatchVisit(_ node: Syntax) -> Syntax") {
254+
try SwitchExprSyntax("switch node.raw.kind") {
255255
SwitchCaseSyntax("case .token:") {
256-
StmtSyntax("return visitImpl(data, TokenSyntax.self, visit)")
256+
StmtSyntax("return visitImpl(node, TokenSyntax.self, visit)")
257257
}
258258

259259
for node in NON_BASE_SYNTAX_NODES {
260260
SwitchCaseSyntax("case .\(node.varOrCaseName):") {
261-
StmtSyntax("return visitImpl(data, \(node.kind.syntaxType).self, visit)")
261+
StmtSyntax("return visitImpl(node, \(node.kind.syntaxType).self, visit)")
262262
}
263263
}
264264
}
@@ -308,10 +308,9 @@ let syntaxRewriterFile = SourceFileSyntax(leadingTrivia: copyrightHeader) {
308308
309309
// Build the Syntax node to rewrite
310310
let absoluteRaw = AbsoluteRawSyntax(raw: child, info: info)
311-
let data = SyntaxData(absoluteRaw, parent: syntaxNode)
312311
313-
let rewritten = visit(data)
314-
if rewritten.data.nodeId != info.nodeId {
312+
let rewritten = dispatchVisit(Syntax(absoluteRaw, parent: syntaxNode))
313+
if rewritten.id != info.nodeId {
315314
// The node was rewritten, let's handle it
316315
if newLayout == nil {
317316
// We have not yet collected any previous rewritten nodes. Initialize

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@ let syntaxTransformFile = SourceFileSyntax(leadingTrivia: copyrightHeader) {
115115
public func visitChildren(_ node: some SyntaxProtocol) -> [ResultType] {
116116
let syntaxNode = Syntax(node)
117117
return NonNilRawSyntaxChildren(syntaxNode, viewMode: .sourceAccurate).map { rawChild in
118-
let child = Syntax(SyntaxData(rawChild, parent: syntaxNode))
118+
let child = Syntax(rawChild, parent: syntaxNode)
119119
return visit(child)
120120
}
121121
}

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

Lines changed: 13 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ let syntaxVisitorFile = SourceFileSyntax(leadingTrivia: copyrightHeader) {
4545
/// Walk all nodes of the given syntax tree, calling the corresponding `visit`
4646
/// function for every node that is being visited.
4747
public func walk(_ node: some SyntaxProtocol) {
48-
visit(node.data)
48+
visit(Syntax(node))
4949
}
5050
"""
5151
)
@@ -97,12 +97,12 @@ let syntaxVisitorFile = SourceFileSyntax(leadingTrivia: copyrightHeader) {
9797
/// Interpret `data` as a node of type `nodeType`, visit it, calling
9898
/// the `visit` and `visitPost` functions during visitation.
9999
private func visitImpl<NodeType: SyntaxProtocol>(
100-
_ data: SyntaxData,
100+
_ node: Syntax,
101101
_ nodeType: NodeType.Type,
102102
_ visit: (NodeType) -> SyntaxVisitorContinueKind,
103103
_ visitPost: (NodeType) -> Void
104104
) {
105-
let node = NodeType(Syntax(data))!
105+
let node = node.cast(NodeType.self)
106106
let needsChildren = (visit(node) == .visitChildren)
107107
// Avoid calling into visitChildren if possible.
108108
if needsChildren && !node.raw.layoutView!.children.isEmpty {
@@ -149,15 +149,15 @@ let syntaxVisitorFile = SourceFileSyntax(leadingTrivia: copyrightHeader) {
149149
/// that determines the correct visitation function will be popped of the
150150
/// stack before the function is being called, making the switch's stack
151151
/// space transient instead of having it linger in the call stack.
152-
private func visitationFunc(for data: SyntaxData) -> ((SyntaxData) -> Void)
152+
private func visitationFunc(for node: Syntax) -> ((Syntax) -> Void)
153153
"""
154154
) {
155-
try SwitchExprSyntax("switch data.raw.kind") {
155+
try SwitchExprSyntax("switch node.raw.kind") {
156156
SwitchCaseSyntax("case .token:") {
157157
StmtSyntax(
158158
"""
159159
return {
160-
let node = TokenSyntax($0)
160+
let node = $0.cast(TokenSyntax.self)
161161
_ = self.visit(node)
162162
// No children to visit.
163163
self.visitPost(node)
@@ -176,8 +176,8 @@ let syntaxVisitorFile = SourceFileSyntax(leadingTrivia: copyrightHeader) {
176176

177177
DeclSyntax(
178178
"""
179-
private func visit(_ data: SyntaxData) {
180-
return visitationFunc(for: data)(data)
179+
private func visit(_ node: Syntax) {
180+
return visitationFunc(for: node)(node)
181181
}
182182
"""
183183
)
@@ -188,11 +188,10 @@ let syntaxVisitorFile = SourceFileSyntax(leadingTrivia: copyrightHeader) {
188188
poundKeyword: .poundElseToken(),
189189
elements: .statements(
190190
CodeBlockItemListSyntax {
191-
try! FunctionDeclSyntax("private func visit(_ data: SyntaxData)") {
192-
try SwitchExprSyntax("switch data.raw.kind") {
191+
try! FunctionDeclSyntax("private func visit(_ node: Syntax)") {
192+
try SwitchExprSyntax("switch node.raw.kind") {
193193
SwitchCaseSyntax("case .token:") {
194-
DeclSyntax("let node = TokenSyntax(data)")
195-
194+
DeclSyntax("let node = node.cast(TokenSyntax.self)")
196195
ExprSyntax("_ = visit(node)")
197196
ExprSyntax(
198197
"""
@@ -204,7 +203,7 @@ let syntaxVisitorFile = SourceFileSyntax(leadingTrivia: copyrightHeader) {
204203

205204
for node in NON_BASE_SYNTAX_NODES {
206205
SwitchCaseSyntax("case .\(node.varOrCaseName):") {
207-
ExprSyntax("visitImpl(data, \(node.kind.syntaxType).self, visit, visitPost)")
206+
ExprSyntax("visitImpl(node, \(node.kind.syntaxType).self, visit, visitPost)")
208207
}
209208
}
210209
}
@@ -221,8 +220,7 @@ let syntaxVisitorFile = SourceFileSyntax(leadingTrivia: copyrightHeader) {
221220
private func visitChildren(_ node: some SyntaxProtocol) {
222221
let syntaxNode = Syntax(node)
223222
for childRaw in NonNilRawSyntaxChildren(syntaxNode, viewMode: viewMode) {
224-
let childData = SyntaxData(childRaw, parent: syntaxNode)
225-
visit(childData)
223+
visit(Syntax(childRaw, parent: syntaxNode))
226224
}
227225
}
228226
"""

0 commit comments

Comments
 (0)