Skip to content
Newer
Older
100644 190 lines (173 sloc) 6.61 KB
c235a01 @laverdet NodeWalker and removal of reduce()
laverdet authored
1 #pragma once
2 #include <memory>
3 #include <utility>
4 #include <boost/ptr_container/ptr_vector.hpp>
5 #include "node.hpp"
6
7 #define NODE_WALKER_VISIT_IMPL(TYPE, FALLBACK) \
8 virtual void visit(TYPE& node) { \
9 visit(static_cast<FALLBACK&>(node)); \
10 }
11
12 #define NODE_WALKER_ACCEPT_IMPL(TYPE, FALLBACK) \
13 void TYPE::accept(NodeWalker& walker) { \
14 walker.visit(*this); \
15 }
16
17 namespace fbjs {
18 class NodeWalker {
19 private:
20 NodeWalker* _parent;
21 Node* _node;
22 bool _remove;
23 bool _skip_delete;
24
25 protected:
26 typedef boost::ptr_vector<NodeWalker> ptr_vector;
27
28 public:
29 typedef std::auto_ptr<NodeWalker> ptr;
30
31 NodeWalker() : _parent(NULL), _node(NULL), _remove(false),
32 _skip_delete(false) {};
33 virtual ~NodeWalker() {};
34 virtual NodeWalker* clone() const = 0;
35 virtual Node* walk(Node* root) {
36 replaceAndVisit(root);
37 return _node;
38 }
39
40 NodeWalker* parent() const {
41 return _parent;
42 }
43
44 Node* node() const {
45 return _node;
46 }
47
48 protected:
1c11917 @laverdet Add convenience casting for NodeWalker
laverdet authored
49 template<class T>
50 static T& cast(NodeWalker& node) {
51 T* tmp = dynamic_cast<T*>(&node);
52 if (tmp) {
53 return *tmp;
54 } else {
55 throw std::runtime_error("invalid NodeWalker");
56 }
57 }
58
59 template<class T>
60 static std::auto_ptr<T> cast(NodeWalker::ptr node) {
61 std::auto_ptr<T> casted(&cast<T>(*node));
62 node.release();
63 return casted;
64 }
65
c235a01 @laverdet NodeWalker and removal of reduce()
laverdet authored
66 void remove(bool skip_delete = false) {
67 _remove = true;
68 _skip_delete = skip_delete;
69 }
70
71 void replace(Node* new_node, bool skip_delete = false) {
72 if (new_node && _node) {
73 new_node->setLineno(_node->lineno());
74 }
75 _node = new_node;
76 _remove = false;
77 _skip_delete = skip_delete;
78 }
79
80 void replaceAndVisit(Node* new_node) {
81 replace(new_node);
82 if (new_node == NULL) {
83 visit();
84 } else {
85 new_node->accept(*this);
86 }
87 if (new_node != _node && new_node) {
88 delete new_node;
89 }
90 }
91
92 std::auto_ptr<ptr_vector> visitChildren() {
93 ptr_vector ret;
94 node_list_t::iterator ii = _node->childNodes().begin();
95 while (ii != _node->childNodes().end()) {
96 ret.push_back(visitChild(ii++).release());
97 }
98 return ret.release();
99 }
100
101 ptr visitChild(node_list_t::iterator ii) {
102 ptr walker(clone());
103 walker->_parent = this;
104 walker->_node = *ii;
105 if (*ii == NULL) {
106 visit();
107 } else {
108 (*ii)->accept(*walker);
109 }
110 if (_remove) {
111 if (!_skip_delete) {
112 delete _node->removeChild(ii);
113 }
114 } else if (*ii != walker->_node) {
115 Node* old_node = _node->replaceChild(walker->_node, ii);
116 if (!_skip_delete && old_node) {
117 delete old_node;
118 }
119 }
120 return walker;
121 }
122
123 public:
124 virtual void visit() {}
125 virtual void visit(Node& _node) {
126 visitChildren();
127 }
128 NODE_WALKER_VISIT_IMPL(NodeProgram, Node);
129 NODE_WALKER_VISIT_IMPL(NodeStatementList, Node);
130 NODE_WALKER_VISIT_IMPL(NodeExpression, Node);
131 NODE_WALKER_VISIT_IMPL(NodeNumericLiteral, NodeExpression);
132 NODE_WALKER_VISIT_IMPL(NodeStringLiteral, NodeExpression);
133 NODE_WALKER_VISIT_IMPL(NodeRegexLiteral, NodeExpression);
134 NODE_WALKER_VISIT_IMPL(NodeBooleanLiteral, NodeExpression);
135 NODE_WALKER_VISIT_IMPL(NodeNullLiteral, NodeExpression);
136 NODE_WALKER_VISIT_IMPL(NodeThis, NodeExpression);
137 NODE_WALKER_VISIT_IMPL(NodeEmptyExpression, NodeExpression);
138 NODE_WALKER_VISIT_IMPL(NodeOperator, NodeExpression);
139 NODE_WALKER_VISIT_IMPL(NodeConditionalExpression, NodeExpression);
140 NODE_WALKER_VISIT_IMPL(NodeParenthetical, NodeExpression);
141 NODE_WALKER_VISIT_IMPL(NodeAssignment, NodeExpression);
142 NODE_WALKER_VISIT_IMPL(NodeUnary, NodeExpression);
143 NODE_WALKER_VISIT_IMPL(NodePostfix, NodeExpression);
144 NODE_WALKER_VISIT_IMPL(NodeIdentifier, NodeExpression);
145 NODE_WALKER_VISIT_IMPL(NodeFunctionCall, NodeExpression);
146 NODE_WALKER_VISIT_IMPL(NodeFunctionConstructor, NodeExpression);
147 NODE_WALKER_VISIT_IMPL(NodeObjectLiteral, NodeExpression);
148 NODE_WALKER_VISIT_IMPL(NodeArrayLiteral, NodeExpression);
149 NODE_WALKER_VISIT_IMPL(NodeStaticMemberExpression, NodeExpression);
150 NODE_WALKER_VISIT_IMPL(NodeDynamicMemberExpression, NodeExpression);
151 NODE_WALKER_VISIT_IMPL(NodeStatement, Node);
152 NODE_WALKER_VISIT_IMPL(NodeStatementWithExpression, NodeStatement);
153 NODE_WALKER_VISIT_IMPL(NodeVarDeclaration, NodeStatement);
bd9ed38 @laverdet Support for typehints and object literal elisons
laverdet authored
154 NODE_WALKER_VISIT_IMPL(NodeTypehint, Node);
c235a01 @laverdet NodeWalker and removal of reduce()
laverdet authored
155 NODE_WALKER_VISIT_IMPL(NodeFunctionDeclaration, Node);
156 NODE_WALKER_VISIT_IMPL(NodeFunctionExpression, NodeExpression);
157 NODE_WALKER_VISIT_IMPL(NodeArgList, Node);
158 NODE_WALKER_VISIT_IMPL(NodeIf, Node);
159 NODE_WALKER_VISIT_IMPL(NodeWith, Node);
160 NODE_WALKER_VISIT_IMPL(NodeTry, Node);
161 NODE_WALKER_VISIT_IMPL(NodeLabel, Node);
162 NODE_WALKER_VISIT_IMPL(NodeCaseClause, Node);
163 NODE_WALKER_VISIT_IMPL(NodeSwitch, Node);
164 NODE_WALKER_VISIT_IMPL(NodeDefaultClause, NodeCaseClause);
165 NODE_WALKER_VISIT_IMPL(NodeObjectLiteralProperty, Node);
166 NODE_WALKER_VISIT_IMPL(NodeForLoop, Node);
167 NODE_WALKER_VISIT_IMPL(NodeForIn, Node);
9a77508 @laverdet E4X parsing support
laverdet authored
168 NODE_WALKER_VISIT_IMPL(NodeForEachIn, Node);
c235a01 @laverdet NodeWalker and removal of reduce()
laverdet authored
169 NODE_WALKER_VISIT_IMPL(NodeWhile, Node);
170 NODE_WALKER_VISIT_IMPL(NodeDoWhile, NodeStatement);
9a77508 @laverdet E4X parsing support
laverdet authored
171 NODE_WALKER_VISIT_IMPL(NodeXMLDefaultNamespace, NodeStatement);
172 NODE_WALKER_VISIT_IMPL(NodeXMLName, Node);
173 NODE_WALKER_VISIT_IMPL(NodeXMLElement, NodeExpression);
174 NODE_WALKER_VISIT_IMPL(NodeXMLComment, Node);
175 NODE_WALKER_VISIT_IMPL(NodeXMLPI, Node);
176 NODE_WALKER_VISIT_IMPL(NodeXMLContentList, Node);
177 NODE_WALKER_VISIT_IMPL(NodeXMLTextData, Node);
178 NODE_WALKER_VISIT_IMPL(NodeXMLEmbeddedExpression, Node);
179 NODE_WALKER_VISIT_IMPL(NodeXMLAttributeList, Node);
180 NODE_WALKER_VISIT_IMPL(NodeXMLAttribute, Node);
181 NODE_WALKER_VISIT_IMPL(NodeWildcardIdentifier, NodeExpression);
182 NODE_WALKER_VISIT_IMPL(NodeStaticAttributeIdentifier, NodeExpression);
183 NODE_WALKER_VISIT_IMPL(NodeDynamicAttributeIdentifier, NodeExpression);
184 NODE_WALKER_VISIT_IMPL(NodeStaticQualifiedIdentifier, NodeExpression);
185 NODE_WALKER_VISIT_IMPL(NodeDynamicQualifiedIdentifier, NodeExpression);
186 NODE_WALKER_VISIT_IMPL(NodeFilteringPredicate, NodeExpression);
187 NODE_WALKER_VISIT_IMPL(NodeDescendantExpression, NodeExpression);
c235a01 @laverdet NodeWalker and removal of reduce()
laverdet authored
188 };
189 }
Something went wrong with that request. Please try again.