/** * Copyright (c) 2021 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef ES2PANDA_COMPILER_SCOPES_DECLARATION_H #define ES2PANDA_COMPILER_SCOPES_DECLARATION_H #include #include #include namespace panda::es2panda::ir { class AstNode; class ScriptFunction; class TSInterfaceDeclaration; class TSModuleDeclaration; class TSEnumDeclaration; class ImportDeclaration; } // namespace panda::es2panda::ir namespace panda::es2panda::binder { class Scope; class LocalScope; class TSEnumScope; #define DECLARE_CLASSES(decl_kind, className) class className; DECLARATION_KINDS(DECLARE_CLASSES) #undef DECLARE_CLASSES class Decl { public: virtual ~Decl() = default; NO_COPY_SEMANTIC(Decl); NO_MOVE_SEMANTIC(Decl); virtual DeclType Type() const = 0; const util::StringView &Name() const { return name_; } const ir::AstNode *Node() const { return node_; } #define DECLARE_CHECKS_CASTS(declKind, className) \ bool Is##className() const \ { \ return Type() == DeclType::declKind; \ } \ className *As##className() \ { \ ASSERT(Is##className()); \ return reinterpret_cast(this); \ } \ const className *As##className() const \ { \ ASSERT(Is##className()); \ return reinterpret_cast(this); \ } DECLARATION_KINDS(DECLARE_CHECKS_CASTS) #undef DECLARE_CHECKS_CASTS void BindNode(const ir::AstNode *node) { node_ = node; } bool IsLetOrConstOrClassDecl() const { return IsLetDecl() || IsConstDecl() || IsClassDecl(); } DeclarationFlags Flags() const { return flags_; } void AddFlag(DeclarationFlags flag) { flags_ |= flag; } bool HasFlag(DeclarationFlags flag) const { return (flags_ & flag) != 0; } bool IsImportDecl() const { return HasFlag(DeclarationFlags::IMPORT); } bool IsImportOrExportDecl() const { return HasFlag(DeclarationFlags::IMPORT | DeclarationFlags::EXPORT); } bool IsExportDeclInTsModule() const { return HasFlag(DeclarationFlags::EXPORT_IN_TSMODULE); } void SetDeclare(bool isDeclare) { isDeclare_ = isDeclare; } bool IsDeclare() const { return isDeclare_; } protected: explicit Decl(util::StringView name) : name_(name) {} util::StringView name_; DeclarationFlags flags_ {}; const ir::AstNode *node_ {}; bool isDeclare_ {false}; }; template class MultiDecl : public Decl { public: explicit MultiDecl(ArenaAllocator *allocator, util::StringView name) : Decl(name), declarations_(allocator->Adapter()) { } const ArenaVector &Decls() const { return declarations_; } void Add(T *decl) { declarations_.push_back(decl); } private: ArenaVector declarations_; }; class EnumLiteralDecl : public MultiDecl { public: explicit EnumLiteralDecl(ArenaAllocator *allocator, util::StringView name, bool isExport, bool isConst) : MultiDecl(allocator, name), isExport_(isExport), isConst_(isConst) {} DeclType Type() const override { return DeclType::ENUM_LITERAL; } bool IsExport() const { return isExport_; } bool IsConst() const { return isConst_; } void BindScope(TSEnumScope *scope) { scope_ = scope; } TSEnumScope *Scope() { return scope_; } private: TSEnumScope *scope_ {nullptr}; bool isExport_ {}; bool isConst_ {}; }; class InterfaceDecl : public MultiDecl { public: explicit InterfaceDecl(ArenaAllocator *allocator, util::StringView name) : MultiDecl(allocator, name) {} DeclType Type() const override { return DeclType::INTERFACE; } }; class TypeParameterDecl : public Decl { public: explicit TypeParameterDecl(util::StringView name, const ir::AstNode *node); DeclType Type() const override { return DeclType::TYPE_PARAMETER; } }; class PropertyDecl : public Decl { public: explicit PropertyDecl(util::StringView name) : Decl(name) {} DeclType Type() const override { return DeclType::PROPERTY; } }; class MethodDecl : public Decl { public: explicit MethodDecl(util::StringView name) : Decl(name) {} DeclType Type() const override { return DeclType::METHOD; } }; class EnumDecl : public Decl { public: explicit EnumDecl(util::StringView name) : Decl(name) {} DeclType Type() const override { return DeclType::ENUM; } }; class TypeAliasDecl : public Decl { public: explicit TypeAliasDecl(util::StringView name) : Decl(name) {} DeclType Type() const override { return DeclType::TYPE_ALIAS; } }; class NamespaceDecl : public MultiDecl { public: explicit NamespaceDecl(ArenaAllocator *allocator, util::StringView name) : MultiDecl(allocator, name) { } DeclType Type() const override { return DeclType::NAMESPACE; } bool IsInstantiated() const; }; class VarDecl : public Decl { public: explicit VarDecl(util::StringView name) : Decl(name) {} DeclType Type() const override { return DeclType::VAR; } }; class LetDecl : public Decl { public: explicit LetDecl(util::StringView name) : Decl(name) {} DeclType Type() const override { return DeclType::LET; } }; class ConstDecl : public Decl { public: explicit ConstDecl(util::StringView name) : Decl(name) {} DeclType Type() const override { return DeclType::CONST; } }; class ClassDecl : public Decl { public: explicit ClassDecl(util::StringView name) : Decl(name) {} DeclType Type() const override { return DeclType::CLASS; } }; class FunctionDecl : public MultiDecl { public: explicit FunctionDecl(ArenaAllocator *allocator, util::StringView name, const ir::AstNode *node) : MultiDecl(allocator, name) { node_ = node; } DeclType Type() const override { return DeclType::FUNC; } void SetDeclClass(ClassDecl *declClass) { declClass_ = declClass; } ClassDecl *GetDeclClass() { return declClass_; } private: ClassDecl *declClass_ {nullptr}; }; class ParameterDecl : public Decl { public: explicit ParameterDecl(util::StringView name) : Decl(name) {} DeclType Type() const override { return DeclType::PARAM; } }; class ImportEqualsDecl : public Decl { public: explicit ImportEqualsDecl(util::StringView name) : Decl(name) {} DeclType Type() const override { return DeclType::IMPORT_EQUALS; } }; } // namespace panda::es2panda::binder #endif