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 23namespace panda::es2panda::ir { 24class AstNode; 25class ScriptFunction; 26class TSInterfaceDeclaration; 27class TSModuleDeclaration; 28class TSEnumDeclaration; 29class ImportDeclaration; 30} // namespace panda::es2panda::ir 31 32namespace panda::es2panda::binder { 33 34class Scope; 35class LocalScope; 36class TSEnumScope; 37 38#define DECLARE_CLASSES(decl_kind, className) class className; 39DECLARATION_KINDS(DECLARE_CLASSES) 40#undef DECLARE_CLASSES 41 42class Decl { 43public: 44 virtual ~Decl() = default; 45 NO_COPY_SEMANTIC(Decl); 46 NO_MOVE_SEMANTIC(Decl); 47 48 virtual DeclType Type() const = 0; 49 50 const util::StringView &Name() const 51 { 52 return name_; 53 } 54 55 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 78 void BindNode(const ir::AstNode *node) 79 { 80 node_ = node; 81 } 82 83 bool IsLetOrConstOrClassDecl() const 84 { 85 return IsLetDecl() || IsConstDecl() || IsClassDecl(); 86 } 87 88 DeclarationFlags Flags() const 89 { 90 return flags_; 91 } 92 93 void AddFlag(DeclarationFlags flag) 94 { 95 flags_ |= flag; 96 } 97 98 bool HasFlag(DeclarationFlags flag) const 99 { 100 return (flags_ & flag) != 0; 101 } 102 103 bool IsImportDecl() const 104 { 105 return HasFlag(DeclarationFlags::IMPORT); 106 } 107 108 bool IsImportOrExportDecl() const 109 { 110 return HasFlag(DeclarationFlags::IMPORT | DeclarationFlags::EXPORT); 111 } 112 113 bool IsExportDeclInTsModule() const 114 { 115 return HasFlag(DeclarationFlags::EXPORT_IN_TSMODULE); 116 } 117 118 void SetDeclare(bool isDeclare) 119 { 120 isDeclare_ = isDeclare; 121 } 122 123 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 134protected: 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 143template <typename T> 144class MultiDecl : public Decl { 145public: 146 explicit MultiDecl(ArenaAllocator *allocator, util::StringView name) 147 : Decl(name), declarations_(allocator->Adapter()) 148 { 149 } 150 151 const ArenaVector<T *> &Decls() const 152 { 153 return declarations_; 154 } 155 156 void Add(T *decl) 157 { 158 declarations_.push_back(decl); 159 } 160 161private: 162 ArenaVector<T *> declarations_; 163}; 164 165class EnumLiteralDecl : public MultiDecl<ir::TSEnumDeclaration> { 166public: 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 175 bool IsExport() const 176 { 177 return isExport_; 178 } 179 180 bool IsConst() const 181 { 182 return isConst_; 183 } 184 185 void BindScope(TSEnumScope *scope) 186 { 187 scope_ = scope; 188 } 189 190 TSEnumScope *Scope() 191 { 192 return scope_; 193 } 194 195private: 196 TSEnumScope *scope_ {nullptr}; 197 bool isExport_ {}; 198 bool isConst_ {}; 199}; 200 201class InterfaceDecl : public MultiDecl<ir::TSInterfaceDeclaration> { 202public: 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 211class TypeParameterDecl : public Decl { 212public: 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 221class PropertyDecl : public Decl { 222public: 223 explicit PropertyDecl(util::StringView name) : Decl(name) {} 224 225 DeclType Type() const override 226 { 227 return DeclType::PROPERTY; 228 } 229}; 230 231class MethodDecl : public Decl { 232public: 233 explicit MethodDecl(util::StringView name) : Decl(name) {} 234 235 DeclType Type() const override 236 { 237 return DeclType::METHOD; 238 } 239}; 240 241class EnumDecl : public Decl { 242public: 243 explicit EnumDecl(util::StringView name) : Decl(name) {} 244 245 DeclType Type() const override 246 { 247 return DeclType::ENUM; 248 } 249}; 250 251class TypeAliasDecl : public Decl { 252public: 253 explicit TypeAliasDecl(util::StringView name) : Decl(name) {} 254 255 DeclType Type() const override 256 { 257 return DeclType::TYPE_ALIAS; 258 } 259}; 260 261class NamespaceDecl : public MultiDecl<ir::TSModuleDeclaration> { 262public: 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 276class VarDecl : public Decl { 277public: 278 explicit VarDecl(util::StringView name) : Decl(name) {} 279 280 DeclType Type() const override 281 { 282 return DeclType::VAR; 283 } 284}; 285 286class LetDecl : public Decl { 287public: 288 explicit LetDecl(util::StringView name) : Decl(name) {} 289 290 DeclType Type() const override 291 { 292 return DeclType::LET; 293 } 294}; 295 296class ConstDecl : public Decl { 297public: 298 explicit ConstDecl(util::StringView name) : Decl(name) {} 299 300 DeclType Type() const override 301 { 302 return DeclType::CONST; 303 } 304}; 305 306class ClassDecl : public Decl { 307public: 308 explicit ClassDecl(util::StringView name) : Decl(name) {} 309 310 DeclType Type() const override 311 { 312 return DeclType::CLASS; 313 } 314}; 315 316class FunctionDecl : public MultiDecl<ir::ScriptFunction> { 317public: 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 329 void SetDeclClass(ClassDecl *declClass) 330 { 331 declClass_ = declClass; 332 } 333 334 ClassDecl *GetDeclClass() 335 { 336 return declClass_; 337 } 338 339private: 340 ClassDecl *declClass_ {nullptr}; 341}; 342 343class ParameterDecl : public Decl { 344public: 345 explicit ParameterDecl(util::StringView name) : Decl(name) {} 346 347 DeclType Type() const override 348 { 349 return DeclType::PARAM; 350 } 351}; 352 353class ImportEqualsDecl : public Decl { 354public: 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