Skip to content

Commit ee80394

Browse files
committed
[SwiftParser] Move typed raw syntax nodes into SwiftParser
The typed `RawXXXSyntax` nodes and `RawSyntaxNodeProtocol` are only used while parsing, so move them from SwiftSyntax into SwiftParser as internal types. SwiftSyntax keeps only the untyped `RawSyntax`, exposing the handful of members the parser needs through the `@_spi(RawSyntax)` boundary. Making the raw nodes internal narrows SwiftSyntax's public surface and reduces compiled code size: the optimizer can drop the type metadata and protocol witness tables that public conformances must emit, and eliminate or specialize the raw node code that is no longer reachable across the module boundary. `validateLayout(layout:as:)` stays in SwiftSyntax and is still called from `RawSyntax.layout()`, but it no longer depends on the typed raw nodes. Validation is expressed against the public syntax types via a new `SyntaxProtocol.isKindOf(_ kind: SyntaxKind)` requirement, so it matches each child's `RawSyntax.kind` against the kinds allowed for the corresponding syntax type. Every generated syntax node, base node, collection, and child-choice enum implements `isKindOf`, and the two synthetic conformers in SwiftLexicalLookup implement it to mirror their `init?`. The code generator emits the raw node files into SwiftParser, and the `RawSyntaxNodesFile` template produces internal declarations.
1 parent 97ce779 commit ee80394

50 files changed

Lines changed: 7578 additions & 7096 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

CodeGeneration/Sources/generate-swift-syntax/ChildNodeChoices.swift

Lines changed: 23 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -48,16 +48,26 @@ struct ChildNodeChoices {
4848
let name: TypeSyntax
4949
let choices: [Choice]
5050

51-
func isKindOfFuncDecl(parameterName: TokenSyntax, parameterType: TypeSyntax) -> FunctionDeclSyntax {
52-
try! FunctionDeclSyntax("public static func isKindOf(_ \(parameterName): \(parameterType)) -> Bool") {
51+
func isKindOfFuncDecl(
52+
parameterName: TokenSyntax,
53+
parameterType: TypeSyntax,
54+
accessLevel: ImportAccessLevel? = .public
55+
) -> FunctionDeclSyntax {
56+
try! FunctionDeclSyntax(
57+
"\(accessLevel?.modifier) static func isKindOf(_ \(parameterName): \(parameterType)) -> Bool"
58+
) {
5359
ExprSyntax(
5460
"\(raw: self.choices.map { "\($0.syntaxType).isKindOf(\(parameterName))" }.joined(separator: " || "))"
5561
)
5662
}
5763
}
5864

59-
func syntaxGetter(propertyName: TokenSyntax, propertyType: TypeSyntax) -> VariableDeclSyntax {
60-
try! VariableDeclSyntax("public var \(propertyName.declNameOrVarCallName): \(propertyType)") {
65+
func syntaxGetter(
66+
propertyName: TokenSyntax,
67+
propertyType: TypeSyntax,
68+
accessLevel: ImportAccessLevel? = .public
69+
) -> VariableDeclSyntax {
70+
try! VariableDeclSyntax("\(accessLevel?.modifier) var \(propertyName.declNameOrVarCallName): \(propertyType)") {
6171
try! SwitchExprSyntax("switch self") {
6272
for choice in self.choices {
6373
SwitchCaseSyntax("case .\(choice.enumCaseCallName)(let node):") {
@@ -68,8 +78,8 @@ struct ChildNodeChoices {
6878
}
6979
}
7080

71-
func syntaxInitDecl(inputType: TypeSyntax) -> InitializerDeclSyntax {
72-
try! InitializerDeclSyntax("public init?(_ node: \(inputType))") {
81+
func syntaxInitDecl(inputType: TypeSyntax, accessLevel: ImportAccessLevel? = .public) -> InitializerDeclSyntax {
82+
try! InitializerDeclSyntax("\(accessLevel?.modifier) init?(_ node: \(inputType))") {
7383
self.choices.ifExpr
7484
}
7585
}
@@ -105,18 +115,18 @@ extension Node {
105115
}
106116

107117
extension ChildNodeChoices.Choice {
108-
var enumCaseDecl: EnumCaseDeclSyntax {
118+
func enumCaseDecl(internal isIntenral: Bool = false) -> EnumCaseDeclSyntax {
109119
try! EnumCaseDeclSyntax(
110120
"""
111-
\(self.documentation)\
112-
\(self.experimentalDocNote)\
113-
\(self.apiAttributes)\
121+
\(isIntenral ? "" : self.documentation)\
122+
\(isIntenral ? "" : self.experimentalDocNote)\
123+
\(isIntenral ? "" : self.apiAttributes)\
114124
case \(self.enumCaseDeclName)(\(self.syntaxType))
115125
"""
116126
)
117127
}
118128

119-
func baseTypeInitDecl(hasArgumentName: Bool) -> InitializerDeclSyntax? {
129+
func baseTypeInitDecl(hasArgumentName: Bool, accessLevel: ImportAccessLevel? = .public) -> InitializerDeclSyntax? {
120130
guard self.isBase else {
121131
return nil
122132
}
@@ -133,7 +143,8 @@ extension ChildNodeChoices.Choice {
133143
"""
134144
\(self.experimentalDocNote)\
135145
\(self.apiAttributes)\
136-
public init(\(firstName)\(secondName): some \(self.protocolType))
146+
\(accessLevel?.modifier) \
147+
init(\(firstName)\(secondName): some \(self.protocolType))
137148
"""
138149
) {
139150
ExprSyntax(

CodeGeneration/Sources/generate-swift-syntax/GenerateSwiftSyntax.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,7 @@ struct GenerateSwiftSyntax: AsyncParsableCommand {
162162
syntaxNode(nodesStartingWith: Array(letters))
163163
),
164164
GeneratedFileSpec(
165-
swiftSyntaxGeneratedDir + ["raw", "RawSyntaxNodes\(letters).swift"],
165+
swiftParserGeneratedDir + ["raw", "RawSyntaxNodes\(letters).swift"],
166166
rawSyntaxNodesFile(nodesStartingWith: Array(letters))
167167
),
168168
]

CodeGeneration/Sources/generate-swift-syntax/ImportSwiftSyntax.swift

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,15 @@ import SyntaxSupport
1717
enum ImportAccessLevel {
1818
case `public`
1919
case `internal`
20+
21+
var modifier: DeclModifierSyntax {
22+
switch self {
23+
case .internal:
24+
return DeclModifierSyntax(name: .keyword(.internal))
25+
case .public:
26+
return DeclModifierSyntax(name: .keyword(.public))
27+
}
28+
}
2029
}
2130

2231
func importSwiftSyntax(accessLevel: ImportAccessLevel = .internal) -> DeclSyntax {
@@ -31,18 +40,11 @@ func importSwiftSyntax(accessLevel: ImportAccessLevel = .internal) -> DeclSyntax
3140
}
3241
}
3342
}
34-
let visibilityKeyword: TokenSyntax
35-
switch accessLevel {
36-
case .internal:
37-
visibilityKeyword = "internal"
38-
case .public:
39-
visibilityKeyword = "public"
40-
}
4143

4244
return DeclSyntax(
4345
"""
4446
#if compiler(>=6)
45-
\(importingAttrs)\(visibilityKeyword) import SwiftSyntax
47+
\(importingAttrs)\(accessLevel.modifier) import SwiftSyntax
4648
#else
4749
\(importingAttrs)import SwiftSyntax
4850
#endif

CodeGeneration/Sources/generate-swift-syntax/templates/swiftsyntax/RawSyntaxNodesFile.swift renamed to CodeGeneration/Sources/generate-swift-syntax/templates/swiftparser/RawSyntaxNodesFile.swift

Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -17,15 +17,17 @@ import Utils
1717

1818
func rawSyntaxNodesFile(nodesStartingWith: [Character]) -> SourceFileSyntax {
1919
return SourceFileSyntax(leadingTrivia: copyrightHeader) {
20+
21+
DeclSyntax("@_spi(RawSyntax) @_spi(Compiler) @_spi(ExperimentalLanguageFeatures) internal import SwiftSyntax")
22+
2023
for node in SYNTAX_NODES
2124
where node.kind.isBase
2225
&& nodesStartingWith.contains(node.kind.syntaxType.description.droppingLeadingUnderscores.first!)
2326
&& !node.kind.isDeprecated
2427
{
2528
DeclSyntax(
2629
"""
27-
\(node.apiAttributes(forRaw: true))\
28-
public protocol \(node.kind.raw.protocolType): \(node.base.raw.protocolType) {}
30+
protocol \(node.kind.raw.protocolType): \(node.base.raw.protocolType) {}
2931
"""
3032
)
3133
}
@@ -34,8 +36,7 @@ func rawSyntaxNodesFile(nodesStartingWith: [Character]) -> SourceFileSyntax {
3436
where nodesStartingWith.contains(node.kind.syntaxType.description.droppingLeadingUnderscores.first!) {
3537
try! StructDeclSyntax(
3638
"""
37-
\(node.apiAttributes(forRaw: true))\
38-
public struct \(node.kind.raw.syntaxType): \(node.kind.isBase ? node.kind.raw.protocolType : node.base.raw.protocolType)
39+
struct \(node.kind.raw.syntaxType): \(node.kind.isBase ? node.kind.raw.protocolType : node.base.raw.protocolType)
3940
"""
4041
) {
4142
for childNodeChoices in node.childrenNodeChoices(forRaw: true) {
@@ -44,14 +45,13 @@ func rawSyntaxNodesFile(nodesStartingWith: [Character]) -> SourceFileSyntax {
4445

4546
DeclSyntax(
4647
"""
47-
@_spi(RawSyntax)
48-
public var layoutView: RawSyntaxLayoutView {
48+
var layoutView: RawSyntaxLayoutView {
4949
return raw.layoutView!
5050
}
5151
"""
5252
)
5353

54-
try FunctionDeclSyntax("public static func isKindOf(_ raw: RawSyntax) -> Bool") {
54+
try FunctionDeclSyntax("static func isKindOf(_ raw: RawSyntax) -> Bool") {
5555
if node.kind.isBase {
5656

5757
let cases = SwitchCaseItemListSyntax {
@@ -77,7 +77,7 @@ func rawSyntaxNodesFile(nodesStartingWith: [Character]) -> SourceFileSyntax {
7777
}
7878
}
7979

80-
DeclSyntax("public var raw: RawSyntax")
80+
DeclSyntax("var raw: RawSyntax")
8181

8282
DeclSyntax(
8383
"""
@@ -98,7 +98,7 @@ func rawSyntaxNodesFile(nodesStartingWith: [Character]) -> SourceFileSyntax {
9898

9999
DeclSyntax(
100100
"""
101-
public init?(_ other: some RawSyntaxNodeProtocol) {
101+
init?(_ other: some RawSyntaxNodeProtocol) {
102102
guard Self.isKindOf(other.raw) else { return nil }
103103
self.init(unchecked: other.raw)
104104
}
@@ -108,7 +108,7 @@ func rawSyntaxNodesFile(nodesStartingWith: [Character]) -> SourceFileSyntax {
108108
if node.kind.isBase {
109109
DeclSyntax(
110110
"""
111-
public init(_ other: some \(node.kind.raw.protocolType)) {
111+
init(_ other: some \(node.kind.raw.protocolType)) {
112112
self.init(unchecked: other.raw)
113113
}
114114
"""
@@ -119,7 +119,7 @@ func rawSyntaxNodesFile(nodesStartingWith: [Character]) -> SourceFileSyntax {
119119
let element = node.elementChoices.only != nil ? node.elementChoices.only!.raw.syntaxType : "Element"
120120
DeclSyntax(
121121
"""
122-
public init(elements: [\(element)], arena: __shared RawSyntaxArena) {
122+
init(elements: [\(element)], arena: __shared RawSyntaxArena) {
123123
let raw = RawSyntax.makeLayout(
124124
kind: .\(node.memberCallName), uninitializedCount: elements.count, arena: arena) { layout in
125125
guard var ptr = layout.baseAddress else { return }
@@ -135,7 +135,7 @@ func rawSyntaxNodesFile(nodesStartingWith: [Character]) -> SourceFileSyntax {
135135

136136
DeclSyntax(
137137
"""
138-
public var elements: [Raw\(node.collectionElementType.syntaxBaseName)] {
138+
var elements: [Raw\(node.collectionElementType.syntaxBaseName)] {
139139
layoutView.children.map { Raw\(node.collectionElementType.syntaxBaseName)(raw: $0!) }
140140
}
141141
"""
@@ -156,7 +156,7 @@ func rawSyntaxNodesFile(nodesStartingWith: [Character]) -> SourceFileSyntax {
156156

157157
FunctionParameterSyntax("arena: __shared RawSyntaxArena")
158158
}
159-
try InitializerDeclSyntax("public init(\(params))") {
159+
try InitializerDeclSyntax("init(\(params))") {
160160
if !node.children.isEmpty {
161161
let list = ExprListSyntax {
162162
ExprSyntax("layout.initialize(repeating: nil)")
@@ -186,7 +186,7 @@ func rawSyntaxNodesFile(nodesStartingWith: [Character]) -> SourceFileSyntax {
186186

187187
for (index, child) in node.children.enumerated() {
188188
try VariableDeclSyntax(
189-
"public var \(child.varDeclName): Raw\(child.buildableType.buildable)"
189+
"var \(child.varDeclName): Raw\(child.buildableType.buildable)"
190190
) {
191191
let exclamationMark = child.isOptional ? "" : "!"
192192

@@ -207,19 +207,19 @@ func rawSyntaxNodesFile(nodesStartingWith: [Character]) -> SourceFileSyntax {
207207

208208
private extension ChildNodeChoices {
209209
var rawEnumDecl: EnumDeclSyntax {
210-
try! EnumDeclSyntax("public enum \(self.name): RawSyntaxNodeProtocol") {
210+
try! EnumDeclSyntax("enum \(self.name): RawSyntaxNodeProtocol") {
211211
for choice in self.choices {
212-
choice.enumCaseDecl
212+
choice.enumCaseDecl(internal: true)
213213
}
214214

215-
self.isKindOfFuncDecl(parameterName: "raw", parameterType: "RawSyntax")
215+
self.isKindOfFuncDecl(parameterName: "raw", parameterType: "RawSyntax", accessLevel: nil)
216216

217-
self.syntaxGetter(propertyName: "raw", propertyType: "RawSyntax")
217+
self.syntaxGetter(propertyName: "raw", propertyType: "RawSyntax", accessLevel: nil)
218218

219-
self.syntaxInitDecl(inputType: "__shared some RawSyntaxNodeProtocol")
219+
self.syntaxInitDecl(inputType: "__shared some RawSyntaxNodeProtocol", accessLevel: nil)
220220

221221
for choice in self.choices {
222-
if let baseTypeInitDecl = choice.baseTypeInitDecl(hasArgumentName: true) {
222+
if let baseTypeInitDecl = choice.baseTypeInitDecl(hasArgumentName: true, accessLevel: nil) {
223223
baseTypeInitDecl
224224
}
225225
}

0 commit comments

Comments
 (0)