1 /**
2 * Copyright (c) 2021 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #ifndef ES2PANDA_IR_ASTNODE_H
17 #define ES2PANDA_IR_ASTNODE_H
18
19 #include <functional>
20 #include <macros.h>
21
22 #include <binder/binder.h>
23 #include <binder/scope.h>
24 #include <ir/astNodeMapping.h>
25 #include <lexer/token/sourceLocation.h>
26 #include <util/enumbitops.h>
27
28 namespace panda::es2panda::compiler {
29 class PandaGen;
30 } // namespace panda::es2panda::compiler
31
32 namespace panda::es2panda::checker {
33 class Checker;
34 class Type;
35 } // namespace panda::es2panda::checker
36
37 namespace panda::es2panda::ir {
38
39 class AstNode;
40
41 using NodeTraverser = std::function<void(AstNode *)>;
42
43 using UpdateNodes = std::variant<AstNode *, std::vector<AstNode *>>;
44 using NodeUpdater = std::function<UpdateNodes(AstNode *)>;
45
46 enum class AstNodeType {
47 #define DECLARE_NODE_TYPES(nodeType, className) nodeType,
48 AST_NODE_MAPPING(DECLARE_NODE_TYPES)
49 #undef DECLARE_NODE_TYPES
50 #define DECLARE_NODE_TYPES(nodeType1, nodeType2, baseClass, reinterpretClass) nodeType1, nodeType2,
51 AST_NODE_REINTERPRET_MAPPING(DECLARE_NODE_TYPES)
52 #undef DECLARE_NODE_TYPES
53 };
54
55 enum class AstNodeFlags {
56 NO_OPTS = 0,
57 STRICT = (1U << 0U),
58 PARAMETER = (1U << 1U),
59 };
60
61 DEFINE_BITOPS(AstNodeFlags)
62
63 enum class ModifierFlags {
64 NONE = 0,
65 STATIC = 1 << 0,
66 ASYNC = 1 << 1,
67 PUBLIC = 1 << 2,
68 PROTECTED = 1 << 3,
69 PRIVATE = 1 << 4,
70 DECLARE = 1 << 5,
71 READONLY = 1 << 6,
72 OPTIONAL = 1 << 7,
73 DEFINITE = 1 << 8,
74 ABSTRACT = 1 << 9,
75 ACCESS = PUBLIC | PROTECTED | PRIVATE,
76 ALL = STATIC | ASYNC | ACCESS | DECLARE | READONLY | ABSTRACT,
77 ALLOWED_IN_CTOR_PARAMETER = ACCESS | READONLY,
78 };
79
80 DEFINE_BITOPS(ModifierFlags)
81
82 enum class ScriptFunctionFlags {
83 NONE = 0,
84 GENERATOR = 1 << 0,
85 ASYNC = 1 << 1,
86 ARROW = 1 << 2,
87 EXPRESSION = 1 << 3,
88 OVERLOAD = 1 << 4,
89 CONSTRUCTOR = 1 << 5,
90 METHOD = 1 << 6,
91 CONCURRENT = 1 << 7
92 };
93
94 DEFINE_BITOPS(ScriptFunctionFlags)
95
96 enum class TSOperatorType { READONLY, KEYOF, UNIQUE };
97 enum class MappedOption { NO_OPTS, PLUS, MINUS };
98
99 // Predefinitions
100 class AstDumper;
101 class Expression;
102 class Statement;
103
104 #define DECLARE_CLASSES(nodeType, className) class className;
105 AST_NODE_MAPPING(DECLARE_CLASSES)
106 #undef DECLARE_CLASSES
107
108 #define DECLARE_CLASSES(nodeType1, nodeType2, baseClass, reinterpretClass) class baseClass;
AST_NODE_REINTERPRET_MAPPING(DECLARE_CLASSES)109 AST_NODE_REINTERPRET_MAPPING(DECLARE_CLASSES)
110 #undef DECLARE_CLASSES
111
112 class AstNode {
113 public:
114 explicit AstNode(AstNodeType type) : type_(type) {};
115 virtual ~AstNode() = default;
116 NO_COPY_SEMANTIC(AstNode);
117 NO_MOVE_SEMANTIC(AstNode);
118
119 bool IsProgram() const
120 {
121 return parent_ == nullptr;
122 }
123
124 #define DECLARE_IS_CHECKS(nodeType, className) \
125 bool Is##className() const \
126 { \
127 return type_ == AstNodeType::nodeType; \
128 }
129 AST_NODE_MAPPING(DECLARE_IS_CHECKS)
130 #undef DECLARE_IS_CHECKS
131
132 #define DECLARE_IS_CHECKS(nodeType1, nodeType2, baseClass, reinterpretClass) \
133 bool Is##baseClass() const \
134 { \
135 return type_ == AstNodeType::nodeType1; \
136 } \
137 bool Is##reinterpretClass() const \
138 { \
139 return type_ == AstNodeType::nodeType2; \
140 }
141 AST_NODE_REINTERPRET_MAPPING(DECLARE_IS_CHECKS)
142 #undef DECLARE_IS_CHECKS
143
144 virtual bool IsStatement() const
145 {
146 return false;
147 }
148
149 virtual bool IsExpression() const
150 {
151 return false;
152 }
153
154 #define DECLARE_AS_CASTS(nodeType, className) \
155 className *As##className() \
156 { \
157 ASSERT(Is##className()); \
158 return reinterpret_cast<className *>(this); \
159 } \
160 const className *As##className() const \
161 { \
162 ASSERT(Is##className()); \
163 return reinterpret_cast<const className *>(this); \
164 }
165 AST_NODE_MAPPING(DECLARE_AS_CASTS)
166 #undef DECLARE_AS_CASTS
167
168 #define DECLARE_AS_CASTS(nodeType1, nodeType2, baseClass, reinterpretClass) \
169 baseClass *As##baseClass() \
170 { \
171 ASSERT(Is##baseClass()); \
172 return reinterpret_cast<baseClass *>(this); \
173 } \
174 baseClass *As##reinterpretClass() \
175 { \
176 ASSERT(Is##reinterpretClass()); \
177 return reinterpret_cast<baseClass *>(this); \
178 } \
179 const baseClass *As##baseClass() const \
180 { \
181 ASSERT(Is##baseClass()); \
182 return reinterpret_cast<const baseClass *>(this); \
183 } \
184 const baseClass *As##reinterpretClass() const \
185 { \
186 ASSERT(Is##reinterpretClass()); \
187 return reinterpret_cast<const baseClass *>(this); \
188 }
189 AST_NODE_REINTERPRET_MAPPING(DECLARE_AS_CASTS)
190 #undef DECLARE_AS_CASTS
191
192 Expression *AsExpression()
193 {
194 ASSERT(IsExpression());
195 return reinterpret_cast<Expression *>(this);
196 }
197
198 const Expression *AsExpression() const
199 {
200 ASSERT(IsExpression());
201 return reinterpret_cast<const Expression *>(this);
202 }
203
204 Statement *AsStatement()
205 {
206 ASSERT(IsStatement());
207 return reinterpret_cast<Statement *>(this);
208 }
209
210 const Statement *AsStatement() const
211 {
212 ASSERT(IsStatement());
213 return reinterpret_cast<const Statement *>(this);
214 }
215
216 void SetRange(const lexer::SourceRange &loc)
217 {
218 range_ = loc;
219 }
220
221 void SetStart(const lexer::SourcePosition &start)
222 {
223 range_.start = start;
224 }
225
226 void SetEnd(const lexer::SourcePosition &end)
227 {
228 range_.end = end;
229 }
230
231 const lexer::SourcePosition &Start() const
232 {
233 return range_.start;
234 }
235
236 const lexer::SourcePosition &End() const
237 {
238 return range_.end;
239 }
240
241 const lexer::SourceRange &Range() const
242 {
243 return range_;
244 }
245
246 AstNodeType Type() const
247 {
248 return type_;
249 }
250
251 const AstNode *Parent()
252 {
253 return parent_;
254 }
255
256 const AstNode *Parent() const
257 {
258 return parent_;
259 }
260
261 void SetParent(const AstNode *parent)
262 {
263 parent_ = parent;
264 }
265
266 const AstNode *Original() const
267 {
268 return original_;
269 }
270
271 void SetOriginal(const AstNode *original)
272 {
273 original_ = original;
274 }
275
276 binder::Variable *Variable() const
277 {
278 return variable_;
279 }
280
281 void SetVariable(binder::Variable *variable)
282 {
283 variable_ = variable;
284 }
285
286 virtual void Iterate(const NodeTraverser &cb) const = 0;
287 virtual void Dump(ir::AstDumper *dumper) const = 0;
288 virtual void Compile([[maybe_unused]] compiler::PandaGen *pg) const = 0;
289 virtual checker::Type *Check([[maybe_unused]] checker::Checker *checker) const = 0;
290 virtual void UpdateSelf([[maybe_unused]] const NodeUpdater &cb, [[maybe_unused]] binder::Binder *binder) = 0;
291
292 protected:
293 void SetType(AstNodeType type)
294 {
295 type_ = type;
296 }
297
298 const AstNode *parent_ {};
299 lexer::SourceRange range_ {};
300 AstNodeType type_;
301 binder::Variable *variable_ {nullptr};
302 const AstNode *original_ {nullptr};
303 };
304
305 } // namespace panda::es2panda::ir
306 #endif
307