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;
115 AST_NODE_REINTERPRET_MAPPING(DECLARE_CLASSES)
116 #undef DECLARE_CLASSES
117 
118 class AstNode {
119 public:
AstNode(AstNodeType type)120     explicit AstNode(AstNodeType type) : type_(type) {};
121     virtual ~AstNode() = default;
122     NO_COPY_SEMANTIC(AstNode);
123     NO_MOVE_SEMANTIC(AstNode);
124 
IsProgram() const125     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 
IsStatement() const150     virtual bool IsStatement() const
151     {
152         return false;
153     }
154 
IsExpression() const155     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 
AsExpression()198     Expression *AsExpression()
199     {
200         ASSERT(IsExpression());
201         return reinterpret_cast<Expression *>(this);
202     }
203 
AsExpression() const204     const Expression *AsExpression() const
205     {
206         ASSERT(IsExpression());
207         return reinterpret_cast<const Expression *>(this);
208     }
209 
AsStatement()210     Statement *AsStatement()
211     {
212         ASSERT(IsStatement());
213         return reinterpret_cast<Statement *>(this);
214     }
215 
AsStatement() const216     const Statement *AsStatement() const
217     {
218         ASSERT(IsStatement());
219         return reinterpret_cast<const Statement *>(this);
220     }
221 
SetRange(const lexer::SourceRange &loc)222     void SetRange(const lexer::SourceRange &loc)
223     {
224         range_ = loc;
225     }
226 
SetStart(const lexer::SourcePosition &start)227     void SetStart(const lexer::SourcePosition &start)
228     {
229         range_.start = start;
230     }
231 
SetEnd(const lexer::SourcePosition &end)232     void SetEnd(const lexer::SourcePosition &end)
233     {
234         range_.end = end;
235     }
236 
Start() const237     const lexer::SourcePosition &Start() const
238     {
239         return range_.start;
240     }
241 
End() const242     const lexer::SourcePosition &End() const
243     {
244         return range_.end;
245     }
246 
Range() const247     const lexer::SourceRange &Range() const
248     {
249         return range_;
250     }
251 
Type() const252     AstNodeType Type() const
253     {
254         return type_;
255     }
256 
Parent()257     AstNode *Parent()
258     {
259         return const_cast<AstNode*>(parent_);
260     }
261 
Parent() const262     const AstNode *Parent() const
263     {
264         return parent_;
265     }
266 
SetParent(const AstNode *parent)267     void SetParent(const AstNode *parent)
268     {
269         parent_ = parent;
270     }
271 
Original() const272     const AstNode *Original() const
273     {
274         return original_;
275     }
276 
SetOriginal(const AstNode *original)277     void SetOriginal(const AstNode *original)
278     {
279         original_ = original;
280     }
281 
Variable() const282     binder::Variable *Variable() const
283     {
284         return variable_;
285     }
286 
SetVariable(binder::Variable *variable)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:
SetType(AstNodeType type)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