13af6ab5fSopenharmony_ci/** 23af6ab5fSopenharmony_ci * Copyright (c) 2021 Huawei Device Co., Ltd. 33af6ab5fSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 43af6ab5fSopenharmony_ci * you may not use this file except in compliance with the License. 53af6ab5fSopenharmony_ci * You may obtain a copy of the License at 63af6ab5fSopenharmony_ci * 73af6ab5fSopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 83af6ab5fSopenharmony_ci * 93af6ab5fSopenharmony_ci * Unless required by applicable law or agreed to in writing, software 103af6ab5fSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 113af6ab5fSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 123af6ab5fSopenharmony_ci * See the License for the specific language governing permissions and 133af6ab5fSopenharmony_ci * limitations under the License. 143af6ab5fSopenharmony_ci */ 153af6ab5fSopenharmony_ci 163af6ab5fSopenharmony_ci#ifndef ES2PANDA_COMPILER_SCOPES_VARIABLE_H 173af6ab5fSopenharmony_ci#define ES2PANDA_COMPILER_SCOPES_VARIABLE_H 183af6ab5fSopenharmony_ci 193af6ab5fSopenharmony_ci#include <binder/enumMemberResult.h> 203af6ab5fSopenharmony_ci#include <binder/variableFlags.h> 213af6ab5fSopenharmony_ci#include <ir/irnode.h> 223af6ab5fSopenharmony_ci#include <macros.h> 233af6ab5fSopenharmony_ci#include <util/patchFix.h> 243af6ab5fSopenharmony_ci#include <util/ustring.h> 253af6ab5fSopenharmony_ci 263af6ab5fSopenharmony_ci#include <limits> 273af6ab5fSopenharmony_ci 283af6ab5fSopenharmony_cinamespace panda::es2panda::checker { 293af6ab5fSopenharmony_ciclass Type; 303af6ab5fSopenharmony_ci} // namespace panda::es2panda::checker 313af6ab5fSopenharmony_ci 323af6ab5fSopenharmony_cinamespace panda::es2panda::binder { 333af6ab5fSopenharmony_ci 343af6ab5fSopenharmony_ciclass Decl; 353af6ab5fSopenharmony_ciclass Scope; 363af6ab5fSopenharmony_ciclass VariableScope; 373af6ab5fSopenharmony_ciclass ExportBindings; 383af6ab5fSopenharmony_ciclass Variable; 393af6ab5fSopenharmony_ci 403af6ab5fSopenharmony_ciusing VariableMap = ArenaMap<util::StringView, Variable *>; 413af6ab5fSopenharmony_ci 423af6ab5fSopenharmony_ci#define DECLARE_CLASSES(type, className) class className; 433af6ab5fSopenharmony_ciVARIABLE_TYPES(DECLARE_CLASSES) 443af6ab5fSopenharmony_ci#undef DECLARE_CLASSES 453af6ab5fSopenharmony_ci 463af6ab5fSopenharmony_ciclass Variable { 473af6ab5fSopenharmony_cipublic: 483af6ab5fSopenharmony_ci virtual ~Variable() = default; 493af6ab5fSopenharmony_ci NO_COPY_SEMANTIC(Variable); 503af6ab5fSopenharmony_ci NO_MOVE_SEMANTIC(Variable); 513af6ab5fSopenharmony_ci 523af6ab5fSopenharmony_ci virtual VariableType Type() const = 0; 533af6ab5fSopenharmony_ci 543af6ab5fSopenharmony_ci#define DECLARE_CHECKS_CASTS(variableType, className) \ 553af6ab5fSopenharmony_ci bool Is##className() const \ 563af6ab5fSopenharmony_ci { \ 573af6ab5fSopenharmony_ci return Type() == VariableType::variableType; \ 583af6ab5fSopenharmony_ci } \ 593af6ab5fSopenharmony_ci className *As##className() \ 603af6ab5fSopenharmony_ci { \ 613af6ab5fSopenharmony_ci ASSERT(Is##className()); \ 623af6ab5fSopenharmony_ci return reinterpret_cast<className *>(this); \ 633af6ab5fSopenharmony_ci } \ 643af6ab5fSopenharmony_ci const className *As##className() const \ 653af6ab5fSopenharmony_ci { \ 663af6ab5fSopenharmony_ci ASSERT(Is##className()); \ 673af6ab5fSopenharmony_ci return reinterpret_cast<const className *>(this); \ 683af6ab5fSopenharmony_ci } 693af6ab5fSopenharmony_ci VARIABLE_TYPES(DECLARE_CHECKS_CASTS) 703af6ab5fSopenharmony_ci#undef DECLARE_CHECKS_CASTS 713af6ab5fSopenharmony_ci 723af6ab5fSopenharmony_ci Decl *Declaration() const 733af6ab5fSopenharmony_ci { 743af6ab5fSopenharmony_ci return decl_; 753af6ab5fSopenharmony_ci } 763af6ab5fSopenharmony_ci 773af6ab5fSopenharmony_ci VariableFlags Flags() const 783af6ab5fSopenharmony_ci { 793af6ab5fSopenharmony_ci return flags_; 803af6ab5fSopenharmony_ci } 813af6ab5fSopenharmony_ci 823af6ab5fSopenharmony_ci checker::Type *TsType() const 833af6ab5fSopenharmony_ci { 843af6ab5fSopenharmony_ci return tsType_; 853af6ab5fSopenharmony_ci } 863af6ab5fSopenharmony_ci 873af6ab5fSopenharmony_ci void SetTsType(checker::Type *tsType) 883af6ab5fSopenharmony_ci { 893af6ab5fSopenharmony_ci tsType_ = tsType; 903af6ab5fSopenharmony_ci } 913af6ab5fSopenharmony_ci 923af6ab5fSopenharmony_ci void AddFlag(VariableFlags flag) 933af6ab5fSopenharmony_ci { 943af6ab5fSopenharmony_ci flags_ |= flag; 953af6ab5fSopenharmony_ci } 963af6ab5fSopenharmony_ci 973af6ab5fSopenharmony_ci bool HasFlag(VariableFlags flag) const 983af6ab5fSopenharmony_ci { 993af6ab5fSopenharmony_ci return (flags_ & flag) != 0; 1003af6ab5fSopenharmony_ci } 1013af6ab5fSopenharmony_ci 1023af6ab5fSopenharmony_ci void RemoveFlag(VariableFlags flag) 1033af6ab5fSopenharmony_ci { 1043af6ab5fSopenharmony_ci flags_ &= ~flag; 1053af6ab5fSopenharmony_ci } 1063af6ab5fSopenharmony_ci 1073af6ab5fSopenharmony_ci void Reset(Decl *decl, VariableFlags flags) 1083af6ab5fSopenharmony_ci { 1093af6ab5fSopenharmony_ci decl_ = decl; 1103af6ab5fSopenharmony_ci flags_ = flags; 1113af6ab5fSopenharmony_ci } 1123af6ab5fSopenharmony_ci 1133af6ab5fSopenharmony_ci bool LexicalBound() const 1143af6ab5fSopenharmony_ci { 1153af6ab5fSopenharmony_ci return HasFlag(VariableFlags::LEXICAL_BOUND); 1163af6ab5fSopenharmony_ci } 1173af6ab5fSopenharmony_ci 1183af6ab5fSopenharmony_ci bool InSendableEnv() const 1193af6ab5fSopenharmony_ci { 1203af6ab5fSopenharmony_ci return HasFlag(VariableFlags::IN_SENDABLE_ENV); 1213af6ab5fSopenharmony_ci } 1223af6ab5fSopenharmony_ci 1233af6ab5fSopenharmony_ci const util::StringView &Name() const; 1243af6ab5fSopenharmony_ci virtual void SetLexical(Scope *scope, util::PatchFix *patchFixHelper = nullptr) = 0; 1253af6ab5fSopenharmony_ci 1263af6ab5fSopenharmony_ciprotected: 1273af6ab5fSopenharmony_ci explicit Variable(Decl *decl, VariableFlags flags) : decl_(decl), flags_(flags) {} 1283af6ab5fSopenharmony_ci 1293af6ab5fSopenharmony_ci Decl *decl_; 1303af6ab5fSopenharmony_ci VariableFlags flags_ {}; 1313af6ab5fSopenharmony_ci checker::Type *tsType_ {}; 1323af6ab5fSopenharmony_ci}; 1333af6ab5fSopenharmony_ci 1343af6ab5fSopenharmony_ciclass LocalVariable : public Variable { 1353af6ab5fSopenharmony_cipublic: 1363af6ab5fSopenharmony_ci explicit LocalVariable(Decl *decl, VariableFlags flags); 1373af6ab5fSopenharmony_ci 1383af6ab5fSopenharmony_ci VariableType Type() const override 1393af6ab5fSopenharmony_ci { 1403af6ab5fSopenharmony_ci return VariableType::LOCAL; 1413af6ab5fSopenharmony_ci } 1423af6ab5fSopenharmony_ci 1433af6ab5fSopenharmony_ci void BindVReg(compiler::VReg vreg) 1443af6ab5fSopenharmony_ci { 1453af6ab5fSopenharmony_ci ASSERT(!LexicalBound()); 1463af6ab5fSopenharmony_ci vreg_ = vreg; 1473af6ab5fSopenharmony_ci } 1483af6ab5fSopenharmony_ci 1493af6ab5fSopenharmony_ci void BindLexEnvSlot(uint32_t slot) 1503af6ab5fSopenharmony_ci { 1513af6ab5fSopenharmony_ci ASSERT(!LexicalBound()); 1523af6ab5fSopenharmony_ci AddFlag(VariableFlags::LEXICAL_BOUND); 1533af6ab5fSopenharmony_ci vreg_ = slot; 1543af6ab5fSopenharmony_ci } 1553af6ab5fSopenharmony_ci 1563af6ab5fSopenharmony_ci compiler::VReg Vreg() const 1573af6ab5fSopenharmony_ci { 1583af6ab5fSopenharmony_ci return vreg_; 1593af6ab5fSopenharmony_ci } 1603af6ab5fSopenharmony_ci 1613af6ab5fSopenharmony_ci uint32_t LexIdx() const 1623af6ab5fSopenharmony_ci { 1633af6ab5fSopenharmony_ci ASSERT(LexicalBound()); 1643af6ab5fSopenharmony_ci return vreg_; 1653af6ab5fSopenharmony_ci } 1663af6ab5fSopenharmony_ci 1673af6ab5fSopenharmony_ci void SetLexical([[maybe_unused]] Scope *scope, [[maybe_unused]] util::PatchFix *patchFixHelper = nullptr) override; 1683af6ab5fSopenharmony_ci LocalVariable *Copy(ArenaAllocator *allocator, Decl *decl) const; 1693af6ab5fSopenharmony_ci 1703af6ab5fSopenharmony_ciprivate: 1713af6ab5fSopenharmony_ci uint32_t vreg_ {}; 1723af6ab5fSopenharmony_ci}; 1733af6ab5fSopenharmony_ci 1743af6ab5fSopenharmony_ciclass GlobalVariable : public Variable { 1753af6ab5fSopenharmony_cipublic: 1763af6ab5fSopenharmony_ci explicit GlobalVariable(Decl *decl, VariableFlags flags) : Variable(decl, flags) {} 1773af6ab5fSopenharmony_ci 1783af6ab5fSopenharmony_ci VariableType Type() const override 1793af6ab5fSopenharmony_ci { 1803af6ab5fSopenharmony_ci return VariableType::GLOBAL; 1813af6ab5fSopenharmony_ci } 1823af6ab5fSopenharmony_ci 1833af6ab5fSopenharmony_ci void SetLexical([[maybe_unused]] Scope *scope, [[maybe_unused]] util::PatchFix *patchFixHelper = nullptr) override; 1843af6ab5fSopenharmony_ci}; 1853af6ab5fSopenharmony_ci 1863af6ab5fSopenharmony_ciclass ModuleVariable : public Variable { 1873af6ab5fSopenharmony_cipublic: 1883af6ab5fSopenharmony_ci explicit ModuleVariable(Decl *decl, VariableFlags flags) : Variable(decl, flags) {} 1893af6ab5fSopenharmony_ci 1903af6ab5fSopenharmony_ci VariableType Type() const override 1913af6ab5fSopenharmony_ci { 1923af6ab5fSopenharmony_ci return VariableType::MODULE; 1933af6ab5fSopenharmony_ci } 1943af6ab5fSopenharmony_ci 1953af6ab5fSopenharmony_ci void SetLexical([[maybe_unused]] Scope *scope, [[maybe_unused]] util::PatchFix *patchFixHelper = nullptr) override; 1963af6ab5fSopenharmony_ci 1973af6ab5fSopenharmony_ci void AssignIndex(uint32_t index) 1983af6ab5fSopenharmony_ci { 1993af6ab5fSopenharmony_ci index_ = index; 2003af6ab5fSopenharmony_ci } 2013af6ab5fSopenharmony_ci 2023af6ab5fSopenharmony_ci uint32_t Index() const 2033af6ab5fSopenharmony_ci { 2043af6ab5fSopenharmony_ci return index_; 2053af6ab5fSopenharmony_ci } 2063af6ab5fSopenharmony_ci 2073af6ab5fSopenharmony_ciprivate: 2083af6ab5fSopenharmony_ci uint32_t index_ {0}; 2093af6ab5fSopenharmony_ci}; 2103af6ab5fSopenharmony_ci 2113af6ab5fSopenharmony_ciclass EnumVariable : public Variable { 2123af6ab5fSopenharmony_cipublic: 2133af6ab5fSopenharmony_ci explicit EnumVariable(Decl *decl, bool backReference = false) 2143af6ab5fSopenharmony_ci : Variable(decl, VariableFlags::NONE), backReference_(backReference) 2153af6ab5fSopenharmony_ci { 2163af6ab5fSopenharmony_ci } 2173af6ab5fSopenharmony_ci 2183af6ab5fSopenharmony_ci VariableType Type() const override 2193af6ab5fSopenharmony_ci { 2203af6ab5fSopenharmony_ci return VariableType::ENUM; 2213af6ab5fSopenharmony_ci } 2223af6ab5fSopenharmony_ci 2233af6ab5fSopenharmony_ci void SetValue(EnumMemberResult value) 2243af6ab5fSopenharmony_ci { 2253af6ab5fSopenharmony_ci value_ = value; 2263af6ab5fSopenharmony_ci } 2273af6ab5fSopenharmony_ci 2283af6ab5fSopenharmony_ci const EnumMemberResult &Value() const 2293af6ab5fSopenharmony_ci { 2303af6ab5fSopenharmony_ci return value_; 2313af6ab5fSopenharmony_ci } 2323af6ab5fSopenharmony_ci 2333af6ab5fSopenharmony_ci bool BackReference() const 2343af6ab5fSopenharmony_ci { 2353af6ab5fSopenharmony_ci return backReference_; 2363af6ab5fSopenharmony_ci } 2373af6ab5fSopenharmony_ci 2383af6ab5fSopenharmony_ci void SetBackReference() 2393af6ab5fSopenharmony_ci { 2403af6ab5fSopenharmony_ci backReference_ = true; 2413af6ab5fSopenharmony_ci } 2423af6ab5fSopenharmony_ci 2433af6ab5fSopenharmony_ci bool IsVisited() const 2443af6ab5fSopenharmony_ci { 2453af6ab5fSopenharmony_ci return isVisited_; 2463af6ab5fSopenharmony_ci } 2473af6ab5fSopenharmony_ci 2483af6ab5fSopenharmony_ci void SetVisited() 2493af6ab5fSopenharmony_ci { 2503af6ab5fSopenharmony_ci isVisited_ = true; 2513af6ab5fSopenharmony_ci } 2523af6ab5fSopenharmony_ci 2533af6ab5fSopenharmony_ci bool StringInit() const 2543af6ab5fSopenharmony_ci { 2553af6ab5fSopenharmony_ci return isStringInit_; 2563af6ab5fSopenharmony_ci } 2573af6ab5fSopenharmony_ci 2583af6ab5fSopenharmony_ci void SetStringInit() 2593af6ab5fSopenharmony_ci { 2603af6ab5fSopenharmony_ci isStringInit_ = true; 2613af6ab5fSopenharmony_ci } 2623af6ab5fSopenharmony_ci 2633af6ab5fSopenharmony_ci void ResetDecl(Decl *decl); 2643af6ab5fSopenharmony_ci 2653af6ab5fSopenharmony_ci void SetLexical([[maybe_unused]] Scope *scope, [[maybe_unused]] util::PatchFix *patchFixHelper = nullptr) override; 2663af6ab5fSopenharmony_ci 2673af6ab5fSopenharmony_ciprivate: 2683af6ab5fSopenharmony_ci EnumMemberResult value_ {false}; 2693af6ab5fSopenharmony_ci bool backReference_ {}; 2703af6ab5fSopenharmony_ci bool isVisited_ {false}; 2713af6ab5fSopenharmony_ci bool isStringInit_ {false}; 2723af6ab5fSopenharmony_ci}; 2733af6ab5fSopenharmony_ci 2743af6ab5fSopenharmony_ciclass NamespaceVariable : public Variable { 2753af6ab5fSopenharmony_cipublic: 2763af6ab5fSopenharmony_ci explicit NamespaceVariable(Decl *decl, VariableFlags flags) : Variable(decl, flags) {} 2773af6ab5fSopenharmony_ci 2783af6ab5fSopenharmony_ci VariableType Type() const override 2793af6ab5fSopenharmony_ci { 2803af6ab5fSopenharmony_ci return VariableType::NAMESPACE; 2813af6ab5fSopenharmony_ci } 2823af6ab5fSopenharmony_ci 2833af6ab5fSopenharmony_ci void SetLexical([[maybe_unused]] Scope *scope, [[maybe_unused]] util::PatchFix *patchFixHelper = nullptr) override; 2843af6ab5fSopenharmony_ci 2853af6ab5fSopenharmony_ci ExportBindings *GetExportBindings() 2863af6ab5fSopenharmony_ci { 2873af6ab5fSopenharmony_ci return exportBindings_; 2883af6ab5fSopenharmony_ci } 2893af6ab5fSopenharmony_ci 2903af6ab5fSopenharmony_ci const ExportBindings *GetExportBindings() const 2913af6ab5fSopenharmony_ci { 2923af6ab5fSopenharmony_ci return exportBindings_; 2933af6ab5fSopenharmony_ci } 2943af6ab5fSopenharmony_ci 2953af6ab5fSopenharmony_ci void SetExportBindings(ExportBindings *exportBindings) 2963af6ab5fSopenharmony_ci { 2973af6ab5fSopenharmony_ci exportBindings_ = exportBindings; 2983af6ab5fSopenharmony_ci } 2993af6ab5fSopenharmony_ci 3003af6ab5fSopenharmony_ciprivate: 3013af6ab5fSopenharmony_ci ExportBindings *exportBindings_ {nullptr}; 3023af6ab5fSopenharmony_ci}; 3033af6ab5fSopenharmony_ci 3043af6ab5fSopenharmony_ciclass EnumLiteralVariable : public Variable { 3053af6ab5fSopenharmony_cipublic: 3063af6ab5fSopenharmony_ci explicit EnumLiteralVariable(Decl *decl, VariableFlags flags) : Variable(decl, flags) {} 3073af6ab5fSopenharmony_ci 3083af6ab5fSopenharmony_ci VariableType Type() const override 3093af6ab5fSopenharmony_ci { 3103af6ab5fSopenharmony_ci return VariableType::ENUMLITERAL; 3113af6ab5fSopenharmony_ci } 3123af6ab5fSopenharmony_ci 3133af6ab5fSopenharmony_ci void SetLexical([[maybe_unused]] Scope *scope, [[maybe_unused]] util::PatchFix *patchFixHelper = nullptr) override; 3143af6ab5fSopenharmony_ci 3153af6ab5fSopenharmony_ci VariableMap *GetEnumMembers() const 3163af6ab5fSopenharmony_ci { 3173af6ab5fSopenharmony_ci return enumMemberBindings_; 3183af6ab5fSopenharmony_ci } 3193af6ab5fSopenharmony_ci 3203af6ab5fSopenharmony_ci Variable *FindEnumMemberVariable(const util::StringView &name) const 3213af6ab5fSopenharmony_ci { 3223af6ab5fSopenharmony_ci auto res = enumMemberBindings_->find(name); 3233af6ab5fSopenharmony_ci if (res == enumMemberBindings_->end()) { 3243af6ab5fSopenharmony_ci return nullptr; 3253af6ab5fSopenharmony_ci } 3263af6ab5fSopenharmony_ci return res->second; 3273af6ab5fSopenharmony_ci } 3283af6ab5fSopenharmony_ci 3293af6ab5fSopenharmony_ci void SetEnumMembers(VariableMap *enumMemberBindings) 3303af6ab5fSopenharmony_ci { 3313af6ab5fSopenharmony_ci enumMemberBindings_ = enumMemberBindings; 3323af6ab5fSopenharmony_ci } 3333af6ab5fSopenharmony_ci 3343af6ab5fSopenharmony_ciprivate: 3353af6ab5fSopenharmony_ci VariableMap *enumMemberBindings_ {nullptr}; 3363af6ab5fSopenharmony_ci}; 3373af6ab5fSopenharmony_ci 3383af6ab5fSopenharmony_ciclass ImportEqualsVariable : public Variable { 3393af6ab5fSopenharmony_cipublic: 3403af6ab5fSopenharmony_ci explicit ImportEqualsVariable(Decl *decl, VariableFlags flags) : Variable(decl, flags) {} 3413af6ab5fSopenharmony_ci 3423af6ab5fSopenharmony_ci VariableType Type() const override 3433af6ab5fSopenharmony_ci { 3443af6ab5fSopenharmony_ci return VariableType::IMPORT_EQUALS; 3453af6ab5fSopenharmony_ci } 3463af6ab5fSopenharmony_ci 3473af6ab5fSopenharmony_ci void SetLexical([[maybe_unused]] Scope *scope, [[maybe_unused]] util::PatchFix *patchFixHelper = nullptr) override; 3483af6ab5fSopenharmony_ci 3493af6ab5fSopenharmony_ci Scope *GetScope() 3503af6ab5fSopenharmony_ci { 3513af6ab5fSopenharmony_ci return scope_; 3523af6ab5fSopenharmony_ci } 3533af6ab5fSopenharmony_ci 3543af6ab5fSopenharmony_ci void SetScope(Scope *scope) 3553af6ab5fSopenharmony_ci { 3563af6ab5fSopenharmony_ci scope_ = scope; 3573af6ab5fSopenharmony_ci } 3583af6ab5fSopenharmony_ci 3593af6ab5fSopenharmony_ciprivate: 3603af6ab5fSopenharmony_ci Scope *scope_ {nullptr}; 3613af6ab5fSopenharmony_ci}; 3623af6ab5fSopenharmony_ci 3633af6ab5fSopenharmony_ci} // namespace panda::es2panda::binder 3643af6ab5fSopenharmony_ci#endif 365