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_COMPILER_SCOPES_DECLARATION_H 17 #define ES2PANDA_COMPILER_SCOPES_DECLARATION_H 18 19 #include <binder/variableFlags.h> 20 #include <macros.h> 21 #include <util/ustring.h> 22 23 namespace panda::es2panda::ir { 24 class AstNode; 25 class ScriptFunction; 26 class TSInterfaceDeclaration; 27 class TSModuleDeclaration; 28 class TSEnumDeclaration; 29 class ImportDeclaration; 30 } // namespace panda::es2panda::ir 31 32 namespace panda::es2panda::binder { 33 34 class Scope; 35 class LocalScope; 36 class TSEnumScope; 37 38 #define DECLARE_CLASSES(decl_kind, className) class className; 39 DECLARATION_KINDS(DECLARE_CLASSES) 40 #undef DECLARE_CLASSES 41 42 class Decl { 43 public: 44 virtual ~Decl() = default; 45 NO_COPY_SEMANTIC(Decl); 46 NO_MOVE_SEMANTIC(Decl); 47 48 virtual DeclType Type() const = 0; 49 Name() const50 const util::StringView &Name() const 51 { 52 return name_; 53 } 54 Node() const55 const ir::AstNode *Node() const 56 { 57 return node_; 58 } 59 60 #define DECLARE_CHECKS_CASTS(declKind, className) \ 61 bool Is##className() const \ 62 { \ 63 return Type() == DeclType::declKind; \ 64 } \ 65 className *As##className() \ 66 { \ 67 ASSERT(Is##className()); \ 68 return reinterpret_cast<className *>(this); \ 69 } \ 70 const className *As##className() const \ 71 { \ 72 ASSERT(Is##className()); \ 73 return reinterpret_cast<const className *>(this); \ 74 } 75 DECLARATION_KINDS(DECLARE_CHECKS_CASTS) 76 #undef DECLARE_CHECKS_CASTS 77 BindNode(const ir::AstNode *node)78 void BindNode(const ir::AstNode *node) 79 { 80 node_ = node; 81 } 82 IsLetOrConstOrClassDecl() const83 bool IsLetOrConstOrClassDecl() const 84 { 85 return IsLetDecl() || IsConstDecl() || IsClassDecl(); 86 } 87 Flags() const88 DeclarationFlags Flags() const 89 { 90 return flags_; 91 } 92 AddFlag(DeclarationFlags flag)93 void AddFlag(DeclarationFlags flag) 94 { 95 flags_ |= flag; 96 } 97 HasFlag(DeclarationFlags flag) const98 bool HasFlag(DeclarationFlags flag) const 99 { 100 return (flags_ & flag) != 0; 101 } 102 IsImportDecl() const103 bool IsImportDecl() const 104 { 105 return HasFlag(DeclarationFlags::IMPORT); 106 } 107 IsImportOrExportDecl() const108 bool IsImportOrExportDecl() const 109 { 110 return HasFlag(DeclarationFlags::IMPORT | DeclarationFlags::EXPORT); 111 } 112 IsExportDeclInTsModule() const113 bool IsExportDeclInTsModule() const 114 { 115 return HasFlag(DeclarationFlags::EXPORT_IN_TSMODULE); 116 } 117 SetDeclare(bool isDeclare)118 void SetDeclare(bool isDeclare) 119 { 120 isDeclare_ = isDeclare; 121 } 122 IsDeclare() const123 bool IsDeclare() const 124 { 125 return isDeclare_; 126 } 127 128 bool IsSendableClassDecl() const; 129 130 bool IsSendableFunctionDecl() const; 131 132 bool NeedSetInSendableEnv(Scope *scope) const; 133 134 protected: Decl(util::StringView name)135 explicit Decl(util::StringView name) : name_(name) {} 136 137 util::StringView name_; 138 DeclarationFlags flags_ {}; 139 const ir::AstNode *node_ {}; 140 bool isDeclare_ {false}; 141 }; 142 143 template <typename T> 144 class MultiDecl : public Decl { 145 public: MultiDecl(ArenaAllocator *allocator, util::StringView name)146 explicit MultiDecl(ArenaAllocator *allocator, util::StringView name) 147 : Decl(name), declarations_(allocator->Adapter()) 148 { 149 } 150 Decls() const151 const ArenaVector<T *> &Decls() const 152 { 153 return declarations_; 154 } 155 Add(T *decl)156 void Add(T *decl) 157 { 158 declarations_.push_back(decl); 159 } 160 161 private: 162 ArenaVector<T *> declarations_; 163 }; 164 165 class EnumLiteralDecl : public MultiDecl<ir::TSEnumDeclaration> { 166 public: EnumLiteralDecl(ArenaAllocator *allocator, util::StringView name, bool isExport, bool isConst)167 explicit EnumLiteralDecl(ArenaAllocator *allocator, util::StringView name, bool isExport, bool isConst) 168 : MultiDecl(allocator, name), isExport_(isExport), isConst_(isConst) {} 169 170 DeclType Type() const override 171 { 172 return DeclType::ENUM_LITERAL; 173 } 174 IsExport() const175 bool IsExport() const 176 { 177 return isExport_; 178 } 179 IsConst() const180 bool IsConst() const 181 { 182 return isConst_; 183 } 184 BindScope(TSEnumScope *scope)185 void BindScope(TSEnumScope *scope) 186 { 187 scope_ = scope; 188 } 189 Scope()190 TSEnumScope *Scope() 191 { 192 return scope_; 193 } 194 195 private: 196 TSEnumScope *scope_ {nullptr}; 197 bool isExport_ {}; 198 bool isConst_ {}; 199 }; 200 201 class InterfaceDecl : public MultiDecl<ir::TSInterfaceDeclaration> { 202 public: InterfaceDecl(ArenaAllocator *allocator, util::StringView name)203 explicit InterfaceDecl(ArenaAllocator *allocator, util::StringView name) : MultiDecl(allocator, name) {} 204 205 DeclType Type() const override 206 { 207 return DeclType::INTERFACE; 208 } 209 }; 210 211 class TypeParameterDecl : public Decl { 212 public: 213 explicit TypeParameterDecl(util::StringView name, const ir::AstNode *node); 214 215 DeclType Type() const override 216 { 217 return DeclType::TYPE_PARAMETER; 218 } 219 }; 220 221 class PropertyDecl : public Decl { 222 public: PropertyDecl(util::StringView name)223 explicit PropertyDecl(util::StringView name) : Decl(name) {} 224 225 DeclType Type() const override 226 { 227 return DeclType::PROPERTY; 228 } 229 }; 230 231 class MethodDecl : public Decl { 232 public: MethodDecl(util::StringView name)233 explicit MethodDecl(util::StringView name) : Decl(name) {} 234 235 DeclType Type() const override 236 { 237 return DeclType::METHOD; 238 } 239 }; 240 241 class EnumDecl : public Decl { 242 public: EnumDecl(util::StringView name)243 explicit EnumDecl(util::StringView name) : Decl(name) {} 244 245 DeclType Type() const override 246 { 247 return DeclType::ENUM; 248 } 249 }; 250 251 class TypeAliasDecl : public Decl { 252 public: TypeAliasDecl(util::StringView name)253 explicit TypeAliasDecl(util::StringView name) : Decl(name) {} 254 255 DeclType Type() const override 256 { 257 return DeclType::TYPE_ALIAS; 258 } 259 }; 260 261 class NamespaceDecl : public MultiDecl<ir::TSModuleDeclaration> { 262 public: NamespaceDecl(ArenaAllocator *allocator, util::StringView name)263 explicit NamespaceDecl(ArenaAllocator *allocator, util::StringView name) 264 : MultiDecl(allocator, name) 265 { 266 } 267 268 DeclType Type() const override 269 { 270 return DeclType::NAMESPACE; 271 } 272 273 bool IsInstantiated() const; 274 }; 275 276 class VarDecl : public Decl { 277 public: VarDecl(util::StringView name)278 explicit VarDecl(util::StringView name) : Decl(name) {} 279 280 DeclType Type() const override 281 { 282 return DeclType::VAR; 283 } 284 }; 285 286 class LetDecl : public Decl { 287 public: LetDecl(util::StringView name)288 explicit LetDecl(util::StringView name) : Decl(name) {} 289 290 DeclType Type() const override 291 { 292 return DeclType::LET; 293 } 294 }; 295 296 class ConstDecl : public Decl { 297 public: ConstDecl(util::StringView name)298 explicit ConstDecl(util::StringView name) : Decl(name) {} 299 300 DeclType Type() const override 301 { 302 return DeclType::CONST; 303 } 304 }; 305 306 class ClassDecl : public Decl { 307 public: ClassDecl(util::StringView name)308 explicit ClassDecl(util::StringView name) : Decl(name) {} 309 310 DeclType Type() const override 311 { 312 return DeclType::CLASS; 313 } 314 }; 315 316 class FunctionDecl : public MultiDecl<ir::ScriptFunction> { 317 public: FunctionDecl(ArenaAllocator *allocator, util::StringView name, const ir::AstNode *node)318 explicit FunctionDecl(ArenaAllocator *allocator, util::StringView name, const ir::AstNode *node) 319 : MultiDecl(allocator, name) 320 { 321 node_ = node; 322 } 323 324 DeclType Type() const override 325 { 326 return DeclType::FUNC; 327 } 328 SetDeclClass(ClassDecl *declClass)329 void SetDeclClass(ClassDecl *declClass) 330 { 331 declClass_ = declClass; 332 } 333 GetDeclClass()334 ClassDecl *GetDeclClass() 335 { 336 return declClass_; 337 } 338 339 private: 340 ClassDecl *declClass_ {nullptr}; 341 }; 342 343 class ParameterDecl : public Decl { 344 public: ParameterDecl(util::StringView name)345 explicit ParameterDecl(util::StringView name) : Decl(name) {} 346 347 DeclType Type() const override 348 { 349 return DeclType::PARAM; 350 } 351 }; 352 353 class ImportEqualsDecl : public Decl { 354 public: ImportEqualsDecl(util::StringView name)355 explicit ImportEqualsDecl(util::StringView name) : Decl(name) {} 356 357 DeclType Type() const override 358 { 359 return DeclType::IMPORT_EQUALS; 360 } 361 }; 362 363 } // namespace panda::es2panda::binder 364 365 #endif 366