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 28namespace panda::es2panda::compiler { 29class PandaGen; 30} // namespace panda::es2panda::compiler 31 32namespace panda::es2panda::checker { 33class Checker; 34class Type; 35} // namespace panda::es2panda::checker 36 37namespace panda::es2panda::ir { 38 39class AstNode; 40 41using NodeTraverser = std::function<void(AstNode *)>; 42 43using UpdateNodes = std::variant<AstNode *, std::vector<AstNode *>>; 44using NodeUpdater = std::function<UpdateNodes(AstNode *)>; 45 46enum 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 55enum class AstNodeFlags : uint8_t { 56 NO_OPTS = 0, 57 STRICT = (1U << 0U), 58 PARAMETER = (1U << 1U), 59}; 60 61DEFINE_BITOPS(AstNodeFlags) 62 63enum 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 82DEFINE_BITOPS(ModifierFlags) 83 84enum 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 100DEFINE_BITOPS(ScriptFunctionFlags) 101 102enum class TSOperatorType { READONLY, KEYOF, UNIQUE }; 103enum class MappedOption { NO_OPTS, PLUS, MINUS }; 104 105// Predefinitions 106class AstDumper; 107class Expression; 108class Statement; 109 110#define DECLARE_CLASSES(nodeType, className) class className; 111AST_NODE_MAPPING(DECLARE_CLASSES) 112#undef DECLARE_CLASSES 113 114#define DECLARE_CLASSES(nodeType1, nodeType2, baseClass, reinterpretClass) class baseClass; 115AST_NODE_REINTERPRET_MAPPING(DECLARE_CLASSES) 116#undef DECLARE_CLASSES 117 118class AstNode { 119public: 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 298protected: 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