Skip to content

Commit 7b87b12

Browse files
committed
[CodeGeneration] Minimize per-type parse(from:) code
Use a delegating function `SyntaxProtocol.parse(from:parse:)` similar to the collection node version `SyntaxCollection.parse(from:parse:makeMissing`.
1 parent da8362a commit 7b87b12

File tree

2 files changed

+86
-290
lines changed

2 files changed

+86
-290
lines changed

CodeGeneration/Sources/generate-swift-syntax/templates/swiftparser/LayoutNodesParsableFile.swift

Lines changed: 25 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -25,23 +25,38 @@ let layoutNodesParsableFile = SourceFileSyntax(leadingTrivia: copyrightHeader) {
2525
}
2626
"""
2727
)
28+
DeclSyntax(
29+
"""
30+
extension SyntaxParseable {
31+
fileprivate static func parse(
32+
from parser: inout Parser,
33+
parse: (_ parser: inout Parser) -> some RawSyntaxNodeProtocol
34+
) -> Self {
35+
// Keep the parser alive so that the arena in which `raw` is allocated
36+
// doesn’t get deallocated before we have a chance to create a syntax node
37+
// from it. We can’t use `parser.arena` as the parameter to
38+
// `Syntax(raw:arena:)` because the node might have been re-used during an
39+
// incremental parse and would then live in a different arena than
40+
// `parser.arena`.
41+
defer {
42+
withExtendedLifetime(self) {
43+
}
44+
}
45+
let node = parse(&parser)
46+
let raw = RawSyntax(parser.parseRemainder(into: node))
47+
return Syntax(raw: raw, rawNodeArena: raw.arena).cast(Self.self)
48+
}
49+
}
50+
"""
51+
)
2852

2953
for node in SYNTAX_NODES {
3054
if let parserFunction = node.parserFunction {
3155
DeclSyntax(
3256
"""
3357
extension \(node.kind.syntaxType): SyntaxParseable {
3458
public static func parse(from parser: inout Parser) -> Self {
35-
// Keep the parser alive so that the arena in which `raw` is allocated
36-
// doesn’t get deallocated before we have a chance to create a syntax node
37-
// from it. We can’t use `parser.arena` as the parameter to
38-
// `Syntax(raw:arena:)` because the node might have been re-used during an
39-
// incremental parse and would then live in a different arena than
40-
// `parser.arena`.
41-
defer { withExtendedLifetime(parser) {} }
42-
let node = parser.\(parserFunction)()
43-
let raw = RawSyntax(parser.parseRemainder(into: node))
44-
return Syntax(raw: raw, rawNodeArena: raw.arena).cast(Self.self)
59+
parse(from: &parser) { $0.\(parserFunction)() }
4560
}
4661
}
4762
"""

0 commit comments

Comments
 (0)