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 23namespace ark::es2panda::ir { 24class AstNode; 25class ScriptFunction; 26class TSInterfaceDeclaration; 27class ImportDeclaration; 28class ETSImportDeclaration; 29} // namespace ark::es2panda::ir 30 31namespace ark::es2panda::varbinder { 32class Scope; 33class LocalScope; 34 35// NOLINTNEXTLINE(cppcoreguidelines-macro-usage) 36#define DECLARE_CLASSES(decl_kind, className) class className; 37DECLARATION_KINDS(DECLARE_CLASSES) 38#undef DECLARE_CLASSES 39 40class Decl { 41public: 42 virtual ~Decl() = default; 43 NO_COPY_SEMANTIC(Decl); 44 NO_MOVE_SEMANTIC(Decl); 45 46 virtual DeclType Type() const = 0; 47 48 const util::StringView &Name() const 49 { 50 return name_; 51 } 52 53 ir::AstNode *Node() 54 { 55 return node_; 56 } 57 58 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 82 void BindNode(ir::AstNode *node) 83 { 84 node_ = node; 85 } 86 87 bool IsLetOrConstDecl() const 88 { 89 return IsLetDecl() || IsConstDecl(); 90 } 91 92 bool PossibleTDZ() const 93 { 94 return IsLetOrConstDecl() || IsParameterDecl(); 95 } 96 97protected: 98 explicit Decl(util::StringView name) : name_(name) {} 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 107template <typename T> 108class MultiDecl : public Decl { 109public: 110 explicit MultiDecl(ArenaAllocator *allocator, util::StringView name) 111 : Decl(name), declarations_(allocator->Adapter()) 112 { 113 } 114 115 explicit MultiDecl(ArenaAllocator *allocator, util::StringView name, ir::AstNode *declNode) 116 : Decl(name, declNode), declarations_(allocator->Adapter()) 117 { 118 } 119 120 const ArenaVector<T *> &Decls() const 121 { 122 return declarations_; 123 } 124 125 void Add(T *decl) 126 { 127 declarations_.push_back(decl); 128 } 129 130private: 131 ArenaVector<T *> declarations_; 132}; 133 134class EnumLiteralDecl : public Decl { 135public: 136 explicit EnumLiteralDecl(util::StringView name, bool isConst) : Decl(name), isConst_(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 147 bool IsConst() const 148 { 149 return isConst_; 150 } 151 152 void BindScope(LocalScope *scope) 153 { 154 scope_ = scope; 155 } 156 157 LocalScope *Scope() 158 { 159 return scope_; 160 } 161 162private: 163 LocalScope *scope_ {}; 164 bool isConst_ {}; 165}; 166 167class InterfaceDecl : public MultiDecl<ir::TSInterfaceDeclaration> { 168public: 169 explicit InterfaceDecl(ArenaAllocator *allocator, util::StringView name) : MultiDecl(allocator, name) {} 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 181class ClassDecl : public Decl { 182public: 183 explicit ClassDecl(util::StringView name) : Decl(name) {} 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 192class FunctionDecl : public MultiDecl<ir::ScriptFunction> { 193public: 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 206class TypeParameterDecl : public Decl { 207public: 208 explicit TypeParameterDecl(util::StringView name) : Decl(name) {} 209 210 DeclType Type() const override 211 { 212 return DeclType::TYPE_PARAMETER; 213 } 214}; 215 216class PropertyDecl : public Decl { 217public: 218 explicit PropertyDecl(util::StringView name) : Decl(name) {} 219 220 DeclType Type() const override 221 { 222 return DeclType::PROPERTY; 223 } 224}; 225 226class MethodDecl : public Decl { 227public: 228 explicit MethodDecl(util::StringView name) : Decl(name) {} 229 230 DeclType Type() const override 231 { 232 return DeclType::METHOD; 233 } 234}; 235 236class EnumDecl : public Decl { 237public: 238 explicit EnumDecl(util::StringView name) : Decl(name) {} 239 240 DeclType Type() const override 241 { 242 return DeclType::ENUM; 243 } 244}; 245 246class TypeAliasDecl : public Decl { 247public: 248 explicit TypeAliasDecl(util::StringView name) : Decl(name) {} 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 257class NameSpaceDecl : public Decl { 258public: 259 explicit NameSpaceDecl(util::StringView name) : Decl(name) {} 260 261 DeclType Type() const override 262 { 263 return DeclType::NAMESPACE; 264 } 265}; 266 267class VarDecl : public Decl { 268public: 269 explicit VarDecl(util::StringView name) : Decl(name) {} 270 271 DeclType Type() const override 272 { 273 return DeclType::VAR; 274 } 275}; 276 277class LetDecl : public Decl { 278public: 279 explicit LetDecl(util::StringView name) : Decl(name) {} 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 288class ConstDecl : public Decl { 289public: 290 explicit ConstDecl(util::StringView name) : Decl(name) {} 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 299class LabelDecl : public Decl { 300public: 301 explicit LabelDecl(util::StringView name) : Decl(name) {} 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 310class ReadonlyDecl : public Decl { 311public: 312 explicit ReadonlyDecl(util::StringView name) : Decl(name) {} 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 321class ParameterDecl : public Decl { 322public: 323 explicit ParameterDecl(util::StringView name) : Decl(name) {} 324 325 DeclType Type() const override 326 { 327 return DeclType::PARAM; 328 } 329}; 330 331class ImportDecl : public Decl { 332public: 333 explicit ImportDecl(util::StringView importName, util::StringView localName) 334 : Decl(localName), importName_(importName) 335 { 336 } 337 338 explicit ImportDecl(util::StringView importName, util::StringView localName, ir::AstNode *node) 339 : Decl(localName), importName_(importName) 340 { 341 BindNode(node); 342 } 343 344 const util::StringView &ImportName() const 345 { 346 return importName_; 347 } 348 349 const util::StringView &LocalName() const 350 { 351 return name_; 352 } 353 354 DeclType Type() const override 355 { 356 return DeclType::IMPORT; 357 } 358 359private: 360 util::StringView importName_; 361}; 362 363class ExportDecl : public Decl { 364public: 365 explicit ExportDecl(util::StringView exportName, util::StringView localName) 366 : Decl(localName), exportName_(exportName) 367 { 368 } 369 370 explicit ExportDecl(util::StringView exportName, util::StringView localName, ir::AstNode *node) 371 : Decl(localName), exportName_(exportName) 372 { 373 BindNode(node); 374 } 375 376 const util::StringView &ExportName() const 377 { 378 return exportName_; 379 } 380 381 const util::StringView &LocalName() const 382 { 383 return name_; 384 } 385 386 DeclType Type() const override 387 { 388 return DeclType::EXPORT; 389 } 390 391private: 392 util::StringView exportName_; 393}; 394} // namespace ark::es2panda::varbinder 395 396#endif 397