forked from swiftlang/swift-syntax
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathSyntaxRewriter.swift.gyb
134 lines (116 loc) · 4.18 KB
/
SyntaxRewriter.swift.gyb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
%{
from gyb_syntax_support import *
# -*- mode: Swift -*-
# Ignore the following admonition it applies to the resulting .swift file only
}%
//// Automatically Generated From SyntaxFactory.swift.gyb.
//// Do Not Edit Directly!
//===------------ SyntaxRewriter.swift - Syntax Rewriter class ------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//
//
// This file defines the SyntaxRewriter, a class that performs a standard walk
// and tree-rebuilding pattern.
//
// Subclassers of this class can override the walking behavior for any syntax
// node and transform nodes however they like.
//
//===----------------------------------------------------------------------===//
open class SyntaxRewriter {
public init() {}
% for node in SYNTAX_NODES:
% if is_visitable(node):
open func visit(_ node: ${node.name}) -> ${node.base_type} {
% cast = ('as! ' + node.base_type) if node.base_type != 'Syntax' else ''
return visitChildren(node) ${cast}
}
% end
% end
open func visit(_ token: TokenSyntax) -> Syntax {
return token
}
/// The function called before visiting the node and its descendents.
/// - node: the node we are about to visit.
open func visitPre(_ node: Syntax) {}
/// Override point to choose custom visitation dispatch instead of the
/// specialized `visit(_:)` methods. Use this instead of those methods if
/// you intend to dynamically dispatch rewriting behavior.
/// - note: If this method returns a non-nil result, the specialized
/// `visit(_:)` methods will not be called for this node.
open func visitAny(_ node: Syntax) -> Syntax? {
return nil
}
/// The function called after visting the node and its descendents.
/// - node: the node we just finished visiting.
open func visitPost(_ node: Syntax) {}
public func visit(_ node: Syntax) -> Syntax {
visitPre(node)
defer { visitPost(node) }
// If the global visitor returned non-nil, skip specialized dispatch.
if let newNode = visitAny(node) {
return newNode
}
switch node.raw.kind {
case .token: return visit(node as! TokenSyntax)
% for node in SYNTAX_NODES:
% if is_visitable(node):
case .${node.swift_syntax_kind}: return visit(node as! ${node.name})
% end
% end
default: return visitChildren(node)
}
}
func visitChildren(_ node: Syntax) -> Syntax {
// Visit all children of this node, returning `nil` if child is not
// present. This will ensure that there are always the same number
// of children after transforming.
let newLayout = (0..<node.numberOfChildren).map { (i: Int) -> RawSyntax? in
guard let child = node.child(at: i) else { return nil }
return visit(child).raw
}
// Sanity check, ensure the new children are the same length.
assert(newLayout.count == node.raw.layout.count)
return makeSyntax(node.raw.replacingLayout(newLayout))
}
}
open class SyntaxVisitor {
public init() {}
% for node in SYNTAX_NODES:
% if is_visitable(node):
open func visit(_ node: ${node.name}) {
visitChildren(node)
}
% end
% end
open func visit(_ token: TokenSyntax) {}
/// The function called before visiting the node and its descendents.
/// - node: the node we are about to visit.
open func visitPre(_ node: Syntax) {}
/// The function called after visting the node and its descendents.
/// - node: the node we just finished visiting.
open func visitPost(_ node: Syntax) {}
public func visit(_ node: Syntax) {
visitPre(node)
defer { visitPost(node) }
switch node.raw.kind {
case .token: visit(node as! TokenSyntax)
% for node in SYNTAX_NODES:
% if is_visitable(node):
case .${node.swift_syntax_kind}: visit(node as! ${node.name})
% end
% end
default: visitChildren(node)
}
}
func visitChildren(_ node: Syntax) {
node.children.forEach { visit($0) }
}
}