1 /* 2 * Copyright (c) 2021-2024 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_COMPILER_SCOPES_DECLARATION_H 17 #define ES2PANDA_COMPILER_SCOPES_DECLARATION_H 18 19 #include "varbinder/variableFlags.h" 20 #include "macros.h" 21 #include "util/ustring.h" 22 23 namespace ark::es2panda::ir { 24 class AstNode; 25 class ScriptFunction; 26 class TSInterfaceDeclaration; 27 class ImportDeclaration; 28 class ETSImportDeclaration; 29 } // namespace ark::es2panda::ir 30 31 namespace ark::es2panda::varbinder { 32 class Scope; 33 class LocalScope; 34 35 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage) 36 #define DECLARE_CLASSES(decl_kind, className) class className; 37 DECLARATION_KINDS(DECLARE_CLASSES) 38 #undef DECLARE_CLASSES 39 40 class Decl { 41 public: 42 virtual ~Decl() = default; 43 NO_COPY_SEMANTIC(Decl); 44 NO_MOVE_SEMANTIC(Decl); 45 46 virtual DeclType Type() const = 0; 47 Name() const48 const util::StringView &Name() const 49 { 50 return name_; 51 } 52 Node()53 ir::AstNode *Node() 54 { 55 return node_; 56 } 57 Node() const58 const ir::AstNode *Node() const 59 { 60 return node_; 61 } 62 63 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage) 64 #define DECLARE_CHECKS_CASTS(declKind, className) \ 65 bool Is##className() const \ 66 { \ 67 return Type() == DeclType::declKind; \ 68 } \ 69 className *As##className() \ 70 { \ 71 ASSERT(Is##className()); \ 72 return reinterpret_cast<className *>(this); \ 73 } \ 74 const className *As##className() const \ 75 { \ 76 ASSERT(Is##className()); \ 77 return reinterpret_cast<const className *>(this); \ 78 } 79 DECLARATION_KINDS(DECLARE_CHECKS_CASTS) 80 #undef DECLARE_CHECKS_CASTS 81 BindNode(ir::AstNode *node)82 void BindNode(ir::AstNode *node) 83 { 84 node_ = node; 85 } 86 IsLetOrConstDecl() const87 bool IsLetOrConstDecl() const 88 { 89 return IsLetDecl() || IsConstDecl(); 90 } 91 PossibleTDZ() const92 bool PossibleTDZ() const 93 { 94 return IsLetOrConstDecl() || IsParameterDecl(); 95 } 96 97 protected: Decl(util::StringView name)98 explicit Decl(util::StringView name) : name_(name) {} Decl(util::StringView name, ir::AstNode *declNode)99 explicit Decl(util::StringView name, ir::AstNode *declNode) : name_(name), node_(declNode) {} 100 101 // NOLINTBEGIN(misc-non-private-member-variables-in-classes) 102 util::StringView name_; 103 ir::AstNode *node_ {}; 104 // NOLINTEND(misc-non-private-member-variables-in-classes) 105 }; 106 107 template <typename T> 108 class MultiDecl : public Decl { 109 public: MultiDecl(ArenaAllocator *allocator, util::StringView name)110 explicit MultiDecl(ArenaAllocator *allocator, util::StringView name) 111 : Decl(name), declarations_(allocator->Adapter()) 112 { 113 } 114 MultiDecl(ArenaAllocator *allocator, util::StringView name, ir::AstNode *declNode)115 explicit MultiDecl(ArenaAllocator *allocator, util::StringView name, ir::AstNode *declNode) 116 : Decl(name, declNode), declarations_(allocator->Adapter()) 117 { 118 } 119 Decls() const120 const ArenaVector<T *> &Decls() const 121 { 122 return declarations_; 123 } 124 Add(T *decl)125 void Add(T *decl) 126 { 127 declarations_.push_back(decl); 128 } 129 130 private: 131 ArenaVector<T *> declarations_; 132 }; 133 134 class EnumLiteralDecl : public Decl { 135 public: EnumLiteralDecl(util::StringView name, bool isConst)136 explicit EnumLiteralDecl(util::StringView name, bool isConst) : Decl(name), isConst_(isConst) {} EnumLiteralDecl(util::StringView name, ir::AstNode *declNode, bool isConst)137 explicit EnumLiteralDecl(util::StringView name, ir::AstNode *declNode, bool isConst) 138 : Decl(name, declNode), isConst_(isConst) 139 { 140 } 141 142 DeclType Type() const override 143 { 144 return DeclType::ENUM_LITERAL; 145 } 146 IsConst() const147 bool IsConst() const 148 { 149 return isConst_; 150 } 151 BindScope(LocalScope *scope)152 void BindScope(LocalScope *scope) 153 { 154 scope_ = scope; 155 } 156 Scope()157 LocalScope *Scope() 158 { 159 return scope_; 160 } 161 162 private: 163 LocalScope *scope_ {}; 164 bool isConst_ {}; 165 }; 166 167 class InterfaceDecl : public MultiDecl<ir::TSInterfaceDeclaration> { 168 public: InterfaceDecl(ArenaAllocator *allocator, util::StringView name)169 explicit InterfaceDecl(ArenaAllocator *allocator, util::StringView name) : MultiDecl(allocator, name) {} InterfaceDecl(ArenaAllocator *allocator, util::StringView name, ir::AstNode *declNode)170 explicit InterfaceDecl(ArenaAllocator *allocator, util::StringView name, ir::AstNode *declNode) 171 : MultiDecl(allocator, name, declNode) 172 { 173 } 174 175 DeclType Type() const override 176 { 177 return DeclType::INTERFACE; 178 } 179 }; 180 181 class ClassDecl : public Decl { 182 public: ClassDecl(util::StringView name)183 explicit ClassDecl(util::StringView name) : Decl(name) {} ClassDecl(util::StringView name, ir::AstNode *node)184 explicit ClassDecl(util::StringView name, ir::AstNode *node) : Decl(name, node) {} 185 186 DeclType Type() const override 187 { 188 return DeclType::CLASS; 189 } 190 }; 191 192 class FunctionDecl : public MultiDecl<ir::ScriptFunction> { 193 public: FunctionDecl(ArenaAllocator *allocator, util::StringView name, ir::AstNode *node)194 explicit FunctionDecl(ArenaAllocator *allocator, util::StringView name, ir::AstNode *node) 195 : MultiDecl(allocator, name) 196 { 197 node_ = node; 198 } 199 200 DeclType Type() const override 201 { 202 return DeclType::FUNC; 203 } 204 }; 205 206 class TypeParameterDecl : public Decl { 207 public: TypeParameterDecl(util::StringView name)208 explicit TypeParameterDecl(util::StringView name) : Decl(name) {} 209 210 DeclType Type() const override 211 { 212 return DeclType::TYPE_PARAMETER; 213 } 214 }; 215 216 class PropertyDecl : public Decl { 217 public: PropertyDecl(util::StringView name)218 explicit PropertyDecl(util::StringView name) : Decl(name) {} 219 220 DeclType Type() const override 221 { 222 return DeclType::PROPERTY; 223 } 224 }; 225 226 class MethodDecl : public Decl { 227 public: MethodDecl(util::StringView name)228 explicit MethodDecl(util::StringView name) : Decl(name) {} 229 230 DeclType Type() const override 231 { 232 return DeclType::METHOD; 233 } 234 }; 235 236 class EnumDecl : public Decl { 237 public: EnumDecl(util::StringView name)238 explicit EnumDecl(util::StringView name) : Decl(name) {} 239 240 DeclType Type() const override 241 { 242 return DeclType::ENUM; 243 } 244 }; 245 246 class TypeAliasDecl : public Decl { 247 public: TypeAliasDecl(util::StringView name)248 explicit TypeAliasDecl(util::StringView name) : Decl(name) {} TypeAliasDecl(util::StringView name, ir::AstNode *node)249 explicit TypeAliasDecl(util::StringView name, ir::AstNode *node) : Decl(name, node) {} 250 251 DeclType Type() const override 252 { 253 return DeclType::TYPE_ALIAS; 254 } 255 }; 256 257 class NameSpaceDecl : public Decl { 258 public: NameSpaceDecl(util::StringView name)259 explicit NameSpaceDecl(util::StringView name) : Decl(name) {} 260 261 DeclType Type() const override 262 { 263 return DeclType::NAMESPACE; 264 } 265 }; 266 267 class VarDecl : public Decl { 268 public: VarDecl(util::StringView name)269 explicit VarDecl(util::StringView name) : Decl(name) {} 270 271 DeclType Type() const override 272 { 273 return DeclType::VAR; 274 } 275 }; 276 277 class LetDecl : public Decl { 278 public: LetDecl(util::StringView name)279 explicit LetDecl(util::StringView name) : Decl(name) {} LetDecl(util::StringView name, ir::AstNode *declNode)280 explicit LetDecl(util::StringView name, ir::AstNode *declNode) : Decl(name, declNode) {} 281 282 DeclType Type() const override 283 { 284 return DeclType::LET; 285 } 286 }; 287 288 class ConstDecl : public Decl { 289 public: ConstDecl(util::StringView name)290 explicit ConstDecl(util::StringView name) : Decl(name) {} ConstDecl(util::StringView name, ir::AstNode *declNode)291 explicit ConstDecl(util::StringView name, ir::AstNode *declNode) : Decl(name, declNode) {} 292 293 DeclType Type() const override 294 { 295 return DeclType::CONST; 296 } 297 }; 298 299 class LabelDecl : public Decl { 300 public: LabelDecl(util::StringView name)301 explicit LabelDecl(util::StringView name) : Decl(name) {} LabelDecl(util::StringView name, ir::AstNode *declNode)302 explicit LabelDecl(util::StringView name, ir::AstNode *declNode) : Decl(name, declNode) {} 303 304 DeclType Type() const override 305 { 306 return DeclType::LABEL; 307 } 308 }; 309 310 class ReadonlyDecl : public Decl { 311 public: ReadonlyDecl(util::StringView name)312 explicit ReadonlyDecl(util::StringView name) : Decl(name) {} ReadonlyDecl(util::StringView name, ir::AstNode *declNode)313 explicit ReadonlyDecl(util::StringView name, ir::AstNode *declNode) : Decl(name, declNode) {} 314 315 DeclType Type() const override 316 { 317 return DeclType::READONLY; 318 } 319 }; 320 321 class ParameterDecl : public Decl { 322 public: ParameterDecl(util::StringView name)323 explicit ParameterDecl(util::StringView name) : Decl(name) {} 324 325 DeclType Type() const override 326 { 327 return DeclType::PARAM; 328 } 329 }; 330 331 class ImportDecl : public Decl { 332 public: ImportDecl(util::StringView importName, util::StringView localName)333 explicit ImportDecl(util::StringView importName, util::StringView localName) 334 : Decl(localName), importName_(importName) 335 { 336 } 337 ImportDecl(util::StringView importName, util::StringView localName, ir::AstNode *node)338 explicit ImportDecl(util::StringView importName, util::StringView localName, ir::AstNode *node) 339 : Decl(localName), importName_(importName) 340 { 341 BindNode(node); 342 } 343 ImportName() const344 const util::StringView &ImportName() const 345 { 346 return importName_; 347 } 348 LocalName() const349 const util::StringView &LocalName() const 350 { 351 return name_; 352 } 353 354 DeclType Type() const override 355 { 356 return DeclType::IMPORT; 357 } 358 359 private: 360 util::StringView importName_; 361 }; 362 363 class ExportDecl : public Decl { 364 public: ExportDecl(util::StringView exportName, util::StringView localName)365 explicit ExportDecl(util::StringView exportName, util::StringView localName) 366 : Decl(localName), exportName_(exportName) 367 { 368 } 369 ExportDecl(util::StringView exportName, util::StringView localName, ir::AstNode *node)370 explicit ExportDecl(util::StringView exportName, util::StringView localName, ir::AstNode *node) 371 : Decl(localName), exportName_(exportName) 372 { 373 BindNode(node); 374 } 375 ExportName() const376 const util::StringView &ExportName() const 377 { 378 return exportName_; 379 } 380 LocalName() const381 const util::StringView &LocalName() const 382 { 383 return name_; 384 } 385 386 DeclType Type() const override 387 { 388 return DeclType::EXPORT; 389 } 390 391 private: 392 util::StringView exportName_; 393 }; 394 } // namespace ark::es2panda::varbinder 395 396 #endif 397