Skip to content

Commit 219fa33

Browse files
authored
Merge pull request swiftlang#2974 from rintaro/layout-parseable-impl
[CodeGeneration] Minimize per-type `parse(from:)` code
2 parents 60b01b7 + 2d3ba35 commit 219fa33

File tree

3 files changed

+87
-291
lines changed

3 files changed

+87
-291
lines changed

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

+25-10
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(parser) {
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
"""

Sources/SwiftParser/CollectionNodes+Parsable.swift

+2-2
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,8 @@
1616
@_spi(RawSyntax) import SwiftSyntax
1717
#endif
1818

19-
fileprivate extension SyntaxCollection {
20-
static func parse(
19+
extension SyntaxCollection where Self: SyntaxParseable {
20+
fileprivate static func parse(
2121
from parser: inout Parser,
2222
parse: (_ parser: inout Parser) -> some RawSyntaxNodeProtocol,
2323
makeMissing: (_ remainingTokens: [RawSyntax], _ arena: RawSyntaxArena) -> some RawSyntaxNodeProtocol

0 commit comments

Comments
 (0)