Skip to content

Commit f34ec41

Browse files
committed
Move SyntaxVisitor from gyb to codegen
1 parent eb875f4 commit f34ec41

File tree

6 files changed

+3282
-2749
lines changed

6 files changed

+3282
-2749
lines changed

CodeGeneration/Sources/generate-swiftsyntax/GenerateSwiftSyntax.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ struct GenerateSwiftSyntax: ParsableCommand {
3333
(syntaxKindFile, "SyntaxKind.swift"),
3434
(syntaxTraitsFile, "SyntaxTraits.swift"),
3535
(syntaxTransformFile, "SyntaxTransform.swift"),
36+
(syntaxVisitorFile, "SyntaxVisitor.swift"),
3637
(tokenKindFile, "TokenKind.swift"),
3738
(tokensFile, "Tokens.swift")
3839
],
Lines changed: 139 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,139 @@
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 syntaxVisitorFile = SourceFile {
19+
EnumDecl("""
20+
/// The enum describes how the SyntaxVistor should continue after visiting
21+
/// the current node.
22+
public enum SyntaxVisitorContinueKind
23+
""") {
24+
EnumCaseDecl("""
25+
/// The visitor should visit the descendents of the current node.
26+
case visitChildren
27+
""")
28+
29+
EnumCaseDecl("""
30+
/// The visitor should avoid visiting the descendents of the current node.
31+
case skipChildren
32+
""")
33+
}
34+
35+
ClassDecl("open class SyntaxVisitor") {
36+
VariableDecl("public let viewMode: SyntaxTreeViewMode")
37+
38+
InitializerDecl("""
39+
@available(*, deprecated, message: "Use init(viewMode:) instead")
40+
public convenience init() {
41+
self.init(viewMode: .sourceAccurate)
42+
}
43+
""")
44+
45+
InitializerDecl("""
46+
public init(viewMode: SyntaxTreeViewMode) {
47+
self.viewMode = viewMode
48+
}
49+
""")
50+
51+
FunctionDecl("""
52+
/// Walk all nodes of the given syntax tree, calling the corresponding `visit`
53+
/// function for every node that is being visited.
54+
public func walk<SyntaxType: SyntaxProtocol>(_ node: SyntaxType) {
55+
visit(node.data)
56+
}
57+
""")
58+
59+
for node in SYNTAX_NODES where node.isVisitable {
60+
FunctionDecl("""
61+
/// Visiting `\(raw: node.name)` specifically.
62+
/// - Parameter node: the node we are visiting.
63+
/// - Returns: how should we continue visiting.
64+
open func visit(_ node: \(raw: node.name)) -> SyntaxVisitorContinueKind {
65+
return .visitChildren
66+
}
67+
""")
68+
69+
FunctionDecl("""
70+
/// The function called after visiting `\(raw: node.name)` and its descendents.
71+
/// - node: the node we just finished visiting.
72+
open func visitPost(_ node: \(raw: node.name)) {}
73+
""")
74+
}
75+
76+
FunctionDecl("""
77+
/// Visiting `TokenSyntax` specifically.
78+
/// - Parameter node: the node we are visiting.
79+
/// - Returns: how should we continue visiting.
80+
open func visit(_ token: TokenSyntax) -> SyntaxVisitorContinueKind {
81+
return .visitChildren
82+
}
83+
""")
84+
85+
FunctionDecl("""
86+
/// The function called after visiting the node and its descendents.
87+
/// - node: the node we just finished visiting.
88+
open func visitPost(_ node: TokenSyntax) {}
89+
""")
90+
91+
for node in NON_BASE_SYNTAX_NODES {
92+
FunctionDecl("""
93+
/// Implementation detail of doVisit(_:_:). Do not call directly.
94+
private func visitImpl\(raw: node.name)(_ data: SyntaxData) {
95+
let node = \(raw: node.name)(data)
96+
let needsChildren = (visit(node) == .visitChildren)
97+
// Avoid calling into visitChildren if possible.
98+
if needsChildren && !node.raw.layoutView!.children.isEmpty {
99+
visitChildren(node)
100+
}
101+
visitPost(node)
102+
}
103+
""")
104+
}
105+
106+
FunctionDecl("private func visit(_ data: SyntaxData)") {
107+
SwitchStmt(expression: Expr("data.raw.kind")) {
108+
SwitchCase("case .token:") {
109+
VariableDecl("let node = TokenSyntax(data)")
110+
111+
Expr("_ = visit(node)")
112+
FunctionCallExpr("""
113+
// No children to visit.
114+
visitPost(node)
115+
// The implementation of every generated case goes into its own function. This
116+
// circumvents an issue where the compiler allocates stack space for every
117+
// case statement next to each other in debug builds, causing it to allocate
118+
// ~50KB per call to this function. rdar://55929175
119+
""")
120+
}
121+
for node in NON_BASE_SYNTAX_NODES {
122+
SwitchCase("case .\(raw: node.swiftSyntaxKind):") {
123+
FunctionCallExpr("visitImpl\(raw: node.name)(data)")
124+
}
125+
}
126+
}
127+
}
128+
129+
FunctionDecl("""
130+
private func visitChildren<SyntaxType: SyntaxProtocol>(_ node: SyntaxType) {
131+
let syntaxNode = Syntax(node)
132+
for childRaw in NonNilRawSyntaxChildren(syntaxNode, viewMode: viewMode) {
133+
let childData = SyntaxData(childRaw, parent: syntaxNode)
134+
visit(childData)
135+
}
136+
}
137+
""")
138+
}
139+
}

Package.swift

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,6 @@ let package = Package(
6969
"SyntaxFactory.swift.gyb",
7070
"SyntaxNodes.swift.gyb.template",
7171
"SyntaxRewriter.swift.gyb",
72-
"SyntaxVisitor.swift.gyb",
7372
"Trivia.swift.gyb",
7473
],
7574
swiftSettings: swiftSyntaxSwiftSettings

Sources/SwiftSyntax/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ add_swift_host_library(SwiftSyntax
4141
gyb_generated/SyntaxRewriter.swift
4242
generated/SyntaxTraits.swift
4343
generated/SyntaxTransform.swift
44-
gyb_generated/SyntaxVisitor.swift
44+
generated/SyntaxVisitor.swift
4545
generated/TokenKind.swift
4646
generated/Tokens.swift
4747
gyb_generated/Trivia.swift

Sources/SwiftSyntax/SyntaxVisitor.swift.gyb

Lines changed: 0 additions & 114 deletions
This file was deleted.

0 commit comments

Comments
 (0)