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 : uint8_t {
56 NO_OPTS = 0,
57 STRICT = (1U << 0U),
58 PARAMETER = (1U << 1U),
59 };
60
61 DEFINE_BITOPS(AstNodeFlags)
62
63 enum class ModifierFlags : uint16_t {
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 ACCESSOR = 1 << 10,
76 OVERRIDE = 1 << 11,
77 ACCESS = PUBLIC | PROTECTED | PRIVATE,
78 ALL = STATIC | ASYNC | ACCESS | DECLARE | READONLY | ABSTRACT | ACCESSOR | OVERRIDE,
79 ALLOWED_IN_CTOR_PARAMETER = ACCESS | READONLY | OVERRIDE,
80 };
81
82 DEFINE_BITOPS(ModifierFlags)
83
84 enum class ScriptFunctionFlags : uint16_t {
85 NONE = 0,
86 GENERATOR = 1 << 0,
87 ASYNC = 1 << 1,
88 ARROW = 1 << 2,
89 EXPRESSION = 1 << 3,
90 OVERLOAD = 1 << 4,
91 CONSTRUCTOR = 1 << 5,
92 METHOD = 1 << 6,
93 CONCURRENT = 1 << 7,
94 STATIC_INITIALIZER = 1 << 8,
95 INSTANCE_INITIALIZER = 1 << 9,
96 GENERATED_CONSTRUCTOR = 1 << 10,
97 SENDABLE = 1 << 11,
98 };
99
100 DEFINE_BITOPS(ScriptFunctionFlags)
101
102 enum class TSOperatorType { READONLY, KEYOF, UNIQUE };
103 enum class MappedOption { NO_OPTS, PLUS, MINUS };
104
105 // Predefinitions
106 class AstDumper;
107 class Expression;
108 class Statement;
109
110 #define DECLARE_CLASSES(nodeType, className) class className;
111 AST_NODE_MAPPING(DECLARE_CLASSES)
112 #undef DECLARE_CLASSES
113
114 #define DECLARE_CLASSES(nodeType1, nodeType2, baseClass, reinterpretClass) class baseClass;
AST_NODE_REINTERPRET_MAPPING(DECLARE_CLASSES)115 AST_NODE_REINTERPRET_MAPPING(DECLARE_CLASSES)
116 #undef DECLARE_CLASSES
117
118 class AstNode {
119 public:
120 explicit AstNode(AstNodeType type) : type_(type) {};
121 virtual ~AstNode() = default;
122 NO_COPY_SEMANTIC(AstNode);
123 NO_MOVE_SEMANTIC(AstNode);
124
125 bool IsProgram() const
126 {
127 return parent_ == nullptr;
128 }
129
130 #define DECLARE_IS_CHECKS(nodeType, className) \
131 bool Is##className() const \
132 { \
133 return type_ == AstNodeType::nodeType; \
134 }
135 AST_NODE_MAPPING(DECLARE_IS_CHECKS)
136 #undef DECLARE_IS_CHECKS
137
138 #define DECLARE_IS_CHECKS(nodeType1, nodeType2, baseClass, reinterpretClass) \
139 bool Is##baseClass() const \
140 { \
141 return type_ == AstNodeType::nodeType1; \
142 } \
143 bool Is##reinterpretClass() const \
144 { \
145 return type_ == AstNodeType::nodeType2; \
146 }
147 AST_NODE_REINTERPRET_MAPPING(DECLARE_IS_CHECKS)
148 #undef DECLARE_IS_CHECKS
149
150 virtual bool IsStatement() const
151 {
152 return false;
153 }
154
155 virtual bool IsExpression() const
156 {
157 return false;
158 }
159
160 #define DECLARE_AS_CASTS(nodeType, className) \
161 className *As##className() \
162 { \
163 ASSERT(Is##className()); \
164 return reinterpret_cast<className *>(this); \
165 } \
166 const className *As##className() const \
167 { \
168 ASSERT(Is##className()); \
169 return reinterpret_cast<const className *>(this); \
170 }
171 AST_NODE_MAPPING(DECLARE_AS_CASTS)
172 #undef DECLARE_AS_CASTS
173
174 #define DECLARE_AS_CASTS(nodeType1, nodeType2, baseClass, reinterpretClass) \
175 baseClass *As##baseClass() \
176 { \
177 ASSERT(Is##baseClass()); \
178 return reinterpret_cast<baseClass *>(this); \
179 } \
180 baseClass *As##reinterpretClass() \
181 { \
182 ASSERT(Is##reinterpretClass()); \
183 return reinterpret_cast<baseClass *>(this); \
184 } \
185 const baseClass *As##baseClass() const \
186 { \
187 ASSERT(Is##baseClass()); \
188 return reinterpret_cast<const baseClass *>(this); \
189 } \
190 const baseClass *As##reinterpretClass() const \
191 { \
192 ASSERT(Is##reinterpretClass()); \
193 return reinterpret_cast<const baseClass *>(this); \
194 }
195 AST_NODE_REINTERPRET_MAPPING(DECLARE_AS_CASTS)
196 #undef DECLARE_AS_CASTS
197
198 Expression *AsExpression()
199 {
200 ASSERT(IsExpression());
201 return reinterpret_cast<Expression *>(this);
202 }
203
204 const Expression *AsExpression() const
205 {
206 ASSERT(IsExpression());
207 return reinterpret_cast<const Expression *>(this);
208 }
209
210 Statement *AsStatement()
211 {
212 ASSERT(IsStatement());
213 return reinterpret_cast<Statement *>(this);
214 }
215
216 const Statement *AsStatement() const
217 {
218 ASSERT(IsStatement());
219 return reinterpret_cast<const Statement *>(this);
220 }
221
222 void SetRange(const lexer::SourceRange &loc)
223 {
224 range_ = loc;
225 }
226
227 void SetStart(const lexer::SourcePosition &start)
228 {
229 range_.start = start;
230 }
231
232 void SetEnd(const lexer::SourcePosition &end)
233 {
234 range_.end = end;
235 }
236
237 const lexer::SourcePosition &Start() const
238 {
239 return range_.start;
240 }
241
242 const lexer::SourcePosition &End() const
243 {
244 return range_.end;
245 }
246
247 const lexer::SourceRange &Range() const
248 {
249 return range_;
250 }
251
252 AstNodeType Type() const
253 {
254 return type_;
255 }
256
257 AstNode *Parent()
258 {
259 return const_cast<AstNode*>(parent_);
260 }
261
262 const AstNode *Parent() const
263 {
264 return parent_;
265 }
266
267 void SetParent(const AstNode *parent)
268 {
269 parent_ = parent;
270 }
271
272 const AstNode *Original() const
273 {
274 return original_;
275 }
276
277 void SetOriginal(const AstNode *original)
278 {
279 original_ = original;
280 }
281
282 binder::Variable *Variable() const
283 {
284 return variable_;
285 }
286
287 void SetVariable(binder::Variable *variable)
288 {
289 variable_ = variable;
290 }
291
292 virtual void Iterate(const NodeTraverser &cb) const = 0;
293 virtual void Dump(ir::AstDumper *dumper) const = 0;
294 virtual void Compile([[maybe_unused]] compiler::PandaGen *pg) const = 0;
295 virtual checker::Type *Check([[maybe_unused]] checker::Checker *checker) const = 0;
296 virtual void UpdateSelf([[maybe_unused]] const NodeUpdater &cb, [[maybe_unused]] binder::Binder *binder) = 0;
297
298 protected:
299 void SetType(AstNodeType type)
300 {
301 type_ = type;
302 }
303
304 const AstNode *parent_ {};
305 lexer::SourceRange range_ {};
306 AstNodeType type_;
307 binder::Variable *variable_ {nullptr};
308 const AstNode *original_ {nullptr};
309 };
310
311 } // namespace panda::es2panda::ir
312 #endif
313