13af6ab5fSopenharmony_ci/** 23af6ab5fSopenharmony_ci * Copyright (c) 2021-2024 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_SCOPE_H 173af6ab5fSopenharmony_ci#define ES2PANDA_COMPILER_SCOPES_SCOPE_H 183af6ab5fSopenharmony_ci 193af6ab5fSopenharmony_ci#include "varbinder/declaration.h" 203af6ab5fSopenharmony_ci#include "varbinder/variable.h" 213af6ab5fSopenharmony_ci#include "es2panda.h" 223af6ab5fSopenharmony_ci#include "util/enumbitops.h" 233af6ab5fSopenharmony_ci#include "util/ustring.h" 243af6ab5fSopenharmony_ci 253af6ab5fSopenharmony_ci#include <map> 263af6ab5fSopenharmony_ci#include <unordered_map> 273af6ab5fSopenharmony_ci#include <vector> 283af6ab5fSopenharmony_ci 293af6ab5fSopenharmony_cinamespace ark::es2panda::public_lib { 303af6ab5fSopenharmony_cistruct Context; 313af6ab5fSopenharmony_ci} // namespace ark::es2panda::public_lib 323af6ab5fSopenharmony_ci 333af6ab5fSopenharmony_cinamespace ark::es2panda::compiler { 343af6ab5fSopenharmony_ciclass IRNode; 353af6ab5fSopenharmony_ci} // namespace ark::es2panda::compiler 363af6ab5fSopenharmony_ci 373af6ab5fSopenharmony_cinamespace ark::es2panda::varbinder { 383af6ab5fSopenharmony_ci// NOLINTNEXTLINE(cppcoreguidelines-macro-usage) 393af6ab5fSopenharmony_ci#define DECLARE_CLASSES(type, className) class className; 403af6ab5fSopenharmony_ciSCOPE_TYPES(DECLARE_CLASSES) 413af6ab5fSopenharmony_ci#undef DECLARE_CLASSES 423af6ab5fSopenharmony_ci 433af6ab5fSopenharmony_ciclass Scope; 443af6ab5fSopenharmony_ciclass VariableScope; 453af6ab5fSopenharmony_ciclass Variable; 463af6ab5fSopenharmony_ci 473af6ab5fSopenharmony_citemplate <typename ScopeT, 483af6ab5fSopenharmony_ci std::enable_if_t<std::is_pointer_v<ScopeT> && std::is_base_of_v<Scope, std::remove_pointer_t<ScopeT>>, bool> = 493af6ab5fSopenharmony_ci true> 503af6ab5fSopenharmony_ciclass ScopeFindResultT { 513af6ab5fSopenharmony_cipublic: 523af6ab5fSopenharmony_ci ScopeFindResultT() = default; 533af6ab5fSopenharmony_ci ScopeFindResultT(util::StringView n, ScopeT s, uint32_t l, Variable *v) : ScopeFindResultT(n, s, l, l, v) {} 543af6ab5fSopenharmony_ci ScopeFindResultT(ScopeT s, uint32_t l, uint32_t ll, Variable *v) : scope(s), level(l), lexLevel(ll), variable(v) {} 553af6ab5fSopenharmony_ci ScopeFindResultT(util::StringView n, ScopeT s, uint32_t l, uint32_t ll, Variable *v) 563af6ab5fSopenharmony_ci : name(n), scope(s), level(l), lexLevel(ll), variable(v) 573af6ab5fSopenharmony_ci { 583af6ab5fSopenharmony_ci } 593af6ab5fSopenharmony_ci 603af6ab5fSopenharmony_ci // NOLINTBEGIN(misc-non-private-member-variables-in-classes) 613af6ab5fSopenharmony_ci util::StringView name {}; 623af6ab5fSopenharmony_ci ScopeT scope {}; 633af6ab5fSopenharmony_ci uint32_t level {}; 643af6ab5fSopenharmony_ci uint32_t lexLevel {}; 653af6ab5fSopenharmony_ci Variable *variable {}; 663af6ab5fSopenharmony_ci // NOLINTEND(misc-non-private-member-variables-in-classes) 673af6ab5fSopenharmony_ci}; 683af6ab5fSopenharmony_ci 693af6ab5fSopenharmony_ciusing ConstScopeFindResult = ScopeFindResultT<const Scope *>; 703af6ab5fSopenharmony_ciusing ScopeFindResult = ScopeFindResultT<Scope *>; 713af6ab5fSopenharmony_ci 723af6ab5fSopenharmony_ciclass Scope { 733af6ab5fSopenharmony_cipublic: 743af6ab5fSopenharmony_ci virtual ~Scope() = default; 753af6ab5fSopenharmony_ci NO_COPY_SEMANTIC(Scope); 763af6ab5fSopenharmony_ci NO_MOVE_SEMANTIC(Scope); 773af6ab5fSopenharmony_ci 783af6ab5fSopenharmony_ci using VariableMap = ArenaUnorderedMap<util::StringView, Variable *>; 793af6ab5fSopenharmony_ci using InsertResult = std::pair<VariableMap::const_iterator, bool>; 803af6ab5fSopenharmony_ci 813af6ab5fSopenharmony_ci virtual ScopeType Type() const = 0; 823af6ab5fSopenharmony_ci 833af6ab5fSopenharmony_ci// NOLINTNEXTLINE(cppcoreguidelines-macro-usage) 843af6ab5fSopenharmony_ci#define DECLARE_CHECKS_CASTS(scopeType, className) \ 853af6ab5fSopenharmony_ci bool Is##className() const \ 863af6ab5fSopenharmony_ci { \ 873af6ab5fSopenharmony_ci return Type() == ScopeType::scopeType; \ 883af6ab5fSopenharmony_ci } \ 893af6ab5fSopenharmony_ci className *As##className() \ 903af6ab5fSopenharmony_ci { \ 913af6ab5fSopenharmony_ci ASSERT(Is##className()); \ 923af6ab5fSopenharmony_ci return reinterpret_cast<className *>(this); \ 933af6ab5fSopenharmony_ci } \ 943af6ab5fSopenharmony_ci const className *As##className() const \ 953af6ab5fSopenharmony_ci { \ 963af6ab5fSopenharmony_ci ASSERT(Is##className()); \ 973af6ab5fSopenharmony_ci return reinterpret_cast<const className *>(this); \ 983af6ab5fSopenharmony_ci } 993af6ab5fSopenharmony_ci SCOPE_TYPES(DECLARE_CHECKS_CASTS) 1003af6ab5fSopenharmony_ci#undef DECLARE_CHECKS_CASTS 1013af6ab5fSopenharmony_ci 1023af6ab5fSopenharmony_ci bool IsVariableScope() const 1033af6ab5fSopenharmony_ci { 1043af6ab5fSopenharmony_ci return Type() > ScopeType::LOCAL; 1053af6ab5fSopenharmony_ci } 1063af6ab5fSopenharmony_ci 1073af6ab5fSopenharmony_ci bool IsFunctionVariableScope() const 1083af6ab5fSopenharmony_ci { 1093af6ab5fSopenharmony_ci return Type() >= ScopeType::FUNCTION; 1103af6ab5fSopenharmony_ci } 1113af6ab5fSopenharmony_ci 1123af6ab5fSopenharmony_ci FunctionScope *AsFunctionVariableScope() 1133af6ab5fSopenharmony_ci { 1143af6ab5fSopenharmony_ci ASSERT(IsFunctionVariableScope()); 1153af6ab5fSopenharmony_ci return reinterpret_cast<FunctionScope *>(this); 1163af6ab5fSopenharmony_ci } 1173af6ab5fSopenharmony_ci 1183af6ab5fSopenharmony_ci const FunctionScope *AsFunctionVariableScope() const 1193af6ab5fSopenharmony_ci { 1203af6ab5fSopenharmony_ci ASSERT(IsFunctionVariableScope()); 1213af6ab5fSopenharmony_ci return reinterpret_cast<const FunctionScope *>(this); 1223af6ab5fSopenharmony_ci } 1233af6ab5fSopenharmony_ci 1243af6ab5fSopenharmony_ci VariableScope *AsVariableScope() 1253af6ab5fSopenharmony_ci { 1263af6ab5fSopenharmony_ci ASSERT(IsVariableScope()); 1273af6ab5fSopenharmony_ci return reinterpret_cast<VariableScope *>(this); 1283af6ab5fSopenharmony_ci } 1293af6ab5fSopenharmony_ci 1303af6ab5fSopenharmony_ci const VariableScope *AsVariableScope() const 1313af6ab5fSopenharmony_ci { 1323af6ab5fSopenharmony_ci ASSERT(IsVariableScope()); 1333af6ab5fSopenharmony_ci return reinterpret_cast<const VariableScope *>(this); 1343af6ab5fSopenharmony_ci } 1353af6ab5fSopenharmony_ci 1363af6ab5fSopenharmony_ci VariableScope *EnclosingVariableScope(); 1373af6ab5fSopenharmony_ci 1383af6ab5fSopenharmony_ci const VariableScope *EnclosingVariableScope() const; 1393af6ab5fSopenharmony_ci 1403af6ab5fSopenharmony_ci ClassScope *EnclosingClassScope(); 1413af6ab5fSopenharmony_ci const ClassScope *EnclosingClassScope() const; 1423af6ab5fSopenharmony_ci 1433af6ab5fSopenharmony_ci void AddFlag(ScopeFlags flag) 1443af6ab5fSopenharmony_ci { 1453af6ab5fSopenharmony_ci flags_ |= flag; 1463af6ab5fSopenharmony_ci } 1473af6ab5fSopenharmony_ci 1483af6ab5fSopenharmony_ci void ClearFlag(ScopeFlags flag) 1493af6ab5fSopenharmony_ci { 1503af6ab5fSopenharmony_ci flags_ &= ~flag; 1513af6ab5fSopenharmony_ci } 1523af6ab5fSopenharmony_ci 1533af6ab5fSopenharmony_ci bool HasFlag(ScopeFlags flag) const 1543af6ab5fSopenharmony_ci { 1553af6ab5fSopenharmony_ci return (flags_ & flag) != 0; 1563af6ab5fSopenharmony_ci } 1573af6ab5fSopenharmony_ci 1583af6ab5fSopenharmony_ci ArenaVector<Decl *> &Decls() 1593af6ab5fSopenharmony_ci { 1603af6ab5fSopenharmony_ci return decls_; 1613af6ab5fSopenharmony_ci } 1623af6ab5fSopenharmony_ci 1633af6ab5fSopenharmony_ci const ArenaVector<Decl *> &Decls() const 1643af6ab5fSopenharmony_ci { 1653af6ab5fSopenharmony_ci return decls_; 1663af6ab5fSopenharmony_ci } 1673af6ab5fSopenharmony_ci 1683af6ab5fSopenharmony_ci void SetParent(Scope *parent) 1693af6ab5fSopenharmony_ci { 1703af6ab5fSopenharmony_ci parent_ = parent; 1713af6ab5fSopenharmony_ci } 1723af6ab5fSopenharmony_ci 1733af6ab5fSopenharmony_ci Scope *Parent() 1743af6ab5fSopenharmony_ci { 1753af6ab5fSopenharmony_ci return parent_; 1763af6ab5fSopenharmony_ci } 1773af6ab5fSopenharmony_ci 1783af6ab5fSopenharmony_ci const Scope *Parent() const 1793af6ab5fSopenharmony_ci { 1803af6ab5fSopenharmony_ci return parent_; 1813af6ab5fSopenharmony_ci } 1823af6ab5fSopenharmony_ci 1833af6ab5fSopenharmony_ci const compiler::IRNode *ScopeStart() const 1843af6ab5fSopenharmony_ci { 1853af6ab5fSopenharmony_ci return startIns_; 1863af6ab5fSopenharmony_ci } 1873af6ab5fSopenharmony_ci 1883af6ab5fSopenharmony_ci const compiler::IRNode *ScopeEnd() const 1893af6ab5fSopenharmony_ci { 1903af6ab5fSopenharmony_ci return endIns_; 1913af6ab5fSopenharmony_ci } 1923af6ab5fSopenharmony_ci 1933af6ab5fSopenharmony_ci void SetScopeStart(const compiler::IRNode *ins) 1943af6ab5fSopenharmony_ci { 1953af6ab5fSopenharmony_ci startIns_ = ins; 1963af6ab5fSopenharmony_ci } 1973af6ab5fSopenharmony_ci 1983af6ab5fSopenharmony_ci void SetScopeEnd(const compiler::IRNode *ins) 1993af6ab5fSopenharmony_ci { 2003af6ab5fSopenharmony_ci endIns_ = ins; 2013af6ab5fSopenharmony_ci } 2023af6ab5fSopenharmony_ci 2033af6ab5fSopenharmony_ci ir::AstNode *Node() 2043af6ab5fSopenharmony_ci { 2053af6ab5fSopenharmony_ci return node_; 2063af6ab5fSopenharmony_ci } 2073af6ab5fSopenharmony_ci 2083af6ab5fSopenharmony_ci const ir::AstNode *Node() const 2093af6ab5fSopenharmony_ci { 2103af6ab5fSopenharmony_ci return node_; 2113af6ab5fSopenharmony_ci } 2123af6ab5fSopenharmony_ci 2133af6ab5fSopenharmony_ci void BindNode(ir::AstNode *node) 2143af6ab5fSopenharmony_ci { 2153af6ab5fSopenharmony_ci node_ = node; 2163af6ab5fSopenharmony_ci } 2173af6ab5fSopenharmony_ci 2183af6ab5fSopenharmony_ci Variable *AddDecl(ArenaAllocator *allocator, Decl *decl, [[maybe_unused]] ScriptExtension extension) 2193af6ab5fSopenharmony_ci { 2203af6ab5fSopenharmony_ci decls_.push_back(decl); 2213af6ab5fSopenharmony_ci auto options = decl->IsTypeAliasDecl() ? varbinder::ResolveBindingOptions::TYPE_ALIASES 2223af6ab5fSopenharmony_ci : varbinder::ResolveBindingOptions::BINDINGS; 2233af6ab5fSopenharmony_ci return AddBinding(allocator, FindLocal(decl->Name(), options), decl, extension); 2243af6ab5fSopenharmony_ci } 2253af6ab5fSopenharmony_ci 2263af6ab5fSopenharmony_ci Variable *AddTsDecl(ArenaAllocator *allocator, Decl *decl, [[maybe_unused]] ScriptExtension extension) 2273af6ab5fSopenharmony_ci { 2283af6ab5fSopenharmony_ci decls_.push_back(decl); 2293af6ab5fSopenharmony_ci return AddBinding(allocator, FindLocal(decl->Name(), ResolveBindingOptions::ALL), decl, extension); 2303af6ab5fSopenharmony_ci } 2313af6ab5fSopenharmony_ci 2323af6ab5fSopenharmony_ci template <typename T, typename... Args> 2333af6ab5fSopenharmony_ci T *NewDecl(ArenaAllocator *allocator, Args &&...args); 2343af6ab5fSopenharmony_ci 2353af6ab5fSopenharmony_ci template <typename DeclType, typename VariableType> 2363af6ab5fSopenharmony_ci VariableType *AddDecl(ArenaAllocator *allocator, util::StringView name, VariableFlags flags); 2373af6ab5fSopenharmony_ci 2383af6ab5fSopenharmony_ci template <typename DeclType = varbinder::LetDecl, typename VariableType = varbinder::LocalVariable> 2393af6ab5fSopenharmony_ci static VariableType *CreateVar(ArenaAllocator *allocator, util::StringView name, VariableFlags flags, 2403af6ab5fSopenharmony_ci ir::AstNode *node); 2413af6ab5fSopenharmony_ci 2423af6ab5fSopenharmony_ci template <typename T, typename... Args> 2433af6ab5fSopenharmony_ci Variable *PropagateBinding(ArenaAllocator *allocator, util::StringView name, Args &&...args); 2443af6ab5fSopenharmony_ci 2453af6ab5fSopenharmony_ci virtual InsertResult InsertBinding(const util::StringView &name, Variable *var); 2463af6ab5fSopenharmony_ci virtual InsertResult TryInsertBinding(const util::StringView &name, Variable *var); 2473af6ab5fSopenharmony_ci virtual void MergeBindings(VariableMap const &bindings); 2483af6ab5fSopenharmony_ci virtual VariableMap::size_type EraseBinding(const util::StringView &name); 2493af6ab5fSopenharmony_ci 2503af6ab5fSopenharmony_ci const VariableMap &Bindings() const 2513af6ab5fSopenharmony_ci { 2523af6ab5fSopenharmony_ci return bindings_; 2533af6ab5fSopenharmony_ci } 2543af6ab5fSopenharmony_ci 2553af6ab5fSopenharmony_ci ArenaMap<util::StringView, Variable *> OrderedBindings(ArenaAllocator *allocator) const 2563af6ab5fSopenharmony_ci { 2573af6ab5fSopenharmony_ci ArenaMap<util::StringView, Variable *> result(allocator->Adapter()); 2583af6ab5fSopenharmony_ci result.insert(bindings_.begin(), bindings_.end()); 2593af6ab5fSopenharmony_ci return result; 2603af6ab5fSopenharmony_ci } 2613af6ab5fSopenharmony_ci 2623af6ab5fSopenharmony_ci virtual Variable *AddBinding(ArenaAllocator *allocator, Variable *currentVariable, Decl *newDecl, 2633af6ab5fSopenharmony_ci [[maybe_unused]] ScriptExtension extension) = 0; 2643af6ab5fSopenharmony_ci 2653af6ab5fSopenharmony_ci virtual Variable *FindLocal(const util::StringView &name, ResolveBindingOptions options) const; 2663af6ab5fSopenharmony_ci 2673af6ab5fSopenharmony_ci bool IsSuperscopeOf(const varbinder::Scope *subscope) const; 2683af6ab5fSopenharmony_ci 2693af6ab5fSopenharmony_ci ConstScopeFindResult Find(const util::StringView &name, 2703af6ab5fSopenharmony_ci ResolveBindingOptions options = ResolveBindingOptions::BINDINGS) const; 2713af6ab5fSopenharmony_ci 2723af6ab5fSopenharmony_ci ScopeFindResult Find(const util::StringView &name, ResolveBindingOptions options = ResolveBindingOptions::BINDINGS); 2733af6ab5fSopenharmony_ci 2743af6ab5fSopenharmony_ci ConstScopeFindResult FindInGlobal(const util::StringView &name, 2753af6ab5fSopenharmony_ci ResolveBindingOptions options = ResolveBindingOptions::BINDINGS) const; 2763af6ab5fSopenharmony_ci 2773af6ab5fSopenharmony_ci ConstScopeFindResult FindInFunctionScope(const util::StringView &name, 2783af6ab5fSopenharmony_ci ResolveBindingOptions options = ResolveBindingOptions::BINDINGS) const; 2793af6ab5fSopenharmony_ci 2803af6ab5fSopenharmony_ci Decl *FindDecl(const util::StringView &name) const; 2813af6ab5fSopenharmony_ci 2823af6ab5fSopenharmony_ciprotected: 2833af6ab5fSopenharmony_ci explicit Scope(ArenaAllocator *allocator, Scope *parent) 2843af6ab5fSopenharmony_ci : parent_(parent), decls_(allocator->Adapter()), bindings_(allocator->Adapter()) 2853af6ab5fSopenharmony_ci { 2863af6ab5fSopenharmony_ci } 2873af6ab5fSopenharmony_ci 2883af6ab5fSopenharmony_ci explicit Scope(ArenaAllocator *allocator, Scope *parent, ScopeFlags flags) 2893af6ab5fSopenharmony_ci : parent_(parent), decls_(allocator->Adapter()), bindings_(allocator->Adapter()), flags_(flags) 2903af6ab5fSopenharmony_ci { 2913af6ab5fSopenharmony_ci } 2923af6ab5fSopenharmony_ci 2933af6ab5fSopenharmony_ci /** 2943af6ab5fSopenharmony_ci * @return true - if the variable is shadowed 2953af6ab5fSopenharmony_ci * false - otherwise 2963af6ab5fSopenharmony_ci */ 2973af6ab5fSopenharmony_ci using VariableVisitor = std::function<bool(const Variable *)>; 2983af6ab5fSopenharmony_ci 2993af6ab5fSopenharmony_ci /** 3003af6ab5fSopenharmony_ci * @return true - if the variable is shadowed 3013af6ab5fSopenharmony_ci * false - otherwise 3023af6ab5fSopenharmony_ci */ 3033af6ab5fSopenharmony_ci std::tuple<Scope *, bool> IterateShadowedVariables(const util::StringView &name, const VariableVisitor &visitor); 3043af6ab5fSopenharmony_ci 3053af6ab5fSopenharmony_ci Variable *AddLocal(ArenaAllocator *allocator, Variable *currentVariable, Decl *newDecl, 3063af6ab5fSopenharmony_ci [[maybe_unused]] ScriptExtension extension); 3073af6ab5fSopenharmony_ci 3083af6ab5fSopenharmony_ci Variable *AddLocalVar(ArenaAllocator *allocator, Decl *newDecl); 3093af6ab5fSopenharmony_ci 3103af6ab5fSopenharmony_ciprivate: 3113af6ab5fSopenharmony_ci template < 3123af6ab5fSopenharmony_ci typename ResultT, typename ScopeT, 3133af6ab5fSopenharmony_ci std::enable_if_t<std::is_same_v<ResultT, ConstScopeFindResult> || std::is_same_v<ResultT, ScopeFindResult>, 3143af6ab5fSopenharmony_ci bool> = true, 3153af6ab5fSopenharmony_ci std::enable_if_t<std::is_pointer_v<ScopeT> && std::is_base_of_v<Scope, std::remove_pointer_t<ScopeT>>, bool> = 3163af6ab5fSopenharmony_ci true> 3173af6ab5fSopenharmony_ci static ResultT FindImpl(ScopeT &&scope, const util::StringView &name, const ResolveBindingOptions options) 3183af6ab5fSopenharmony_ci { 3193af6ab5fSopenharmony_ci uint32_t level = 0; 3203af6ab5fSopenharmony_ci uint32_t lexLevel = 0; 3213af6ab5fSopenharmony_ci // iter will be the EXACT type of scope with cv-qualifiers 3223af6ab5fSopenharmony_ci auto &&iter = scope; 3233af6ab5fSopenharmony_ci 3243af6ab5fSopenharmony_ci if (iter->IsFunctionParamScope()) { 3253af6ab5fSopenharmony_ci auto *const v = iter->FindLocal(name, options); 3263af6ab5fSopenharmony_ci 3273af6ab5fSopenharmony_ci if (v != nullptr) { 3283af6ab5fSopenharmony_ci return {name, iter, level, lexLevel, v}; 3293af6ab5fSopenharmony_ci } 3303af6ab5fSopenharmony_ci 3313af6ab5fSopenharmony_ci level++; 3323af6ab5fSopenharmony_ci const auto *const funcVariableScope = iter->AsFunctionParamScope()->GetFunctionScope(); 3333af6ab5fSopenharmony_ci 3343af6ab5fSopenharmony_ci if (funcVariableScope != nullptr && funcVariableScope->NeedLexEnv()) { 3353af6ab5fSopenharmony_ci lexLevel++; 3363af6ab5fSopenharmony_ci } 3373af6ab5fSopenharmony_ci 3383af6ab5fSopenharmony_ci iter = iter->Parent(); 3393af6ab5fSopenharmony_ci } 3403af6ab5fSopenharmony_ci 3413af6ab5fSopenharmony_ci while (iter != nullptr) { 3423af6ab5fSopenharmony_ci auto *const v = iter->FindLocal(name, options); 3433af6ab5fSopenharmony_ci 3443af6ab5fSopenharmony_ci if (v != nullptr) { 3453af6ab5fSopenharmony_ci return {name, iter, level, lexLevel, v}; 3463af6ab5fSopenharmony_ci } 3473af6ab5fSopenharmony_ci 3483af6ab5fSopenharmony_ci if (iter->IsVariableScope()) { 3493af6ab5fSopenharmony_ci level++; 3503af6ab5fSopenharmony_ci 3513af6ab5fSopenharmony_ci if (iter->AsVariableScope()->NeedLexEnv()) { 3523af6ab5fSopenharmony_ci lexLevel++; 3533af6ab5fSopenharmony_ci } 3543af6ab5fSopenharmony_ci } 3553af6ab5fSopenharmony_ci 3563af6ab5fSopenharmony_ci iter = iter->Parent(); 3573af6ab5fSopenharmony_ci } 3583af6ab5fSopenharmony_ci 3593af6ab5fSopenharmony_ci return {name, nullptr, 0, 0, nullptr}; 3603af6ab5fSopenharmony_ci } 3613af6ab5fSopenharmony_ci 3623af6ab5fSopenharmony_ci Scope *parent_ {}; 3633af6ab5fSopenharmony_ci ArenaVector<Decl *> decls_; 3643af6ab5fSopenharmony_ci VariableMap bindings_; 3653af6ab5fSopenharmony_ci ir::AstNode *node_ {}; 3663af6ab5fSopenharmony_ci ScopeFlags flags_ {}; 3673af6ab5fSopenharmony_ci const compiler::IRNode *startIns_ {}; 3683af6ab5fSopenharmony_ci const compiler::IRNode *endIns_ {}; 3693af6ab5fSopenharmony_ci}; 3703af6ab5fSopenharmony_ci 3713af6ab5fSopenharmony_ciclass VariableScope : public Scope { 3723af6ab5fSopenharmony_cipublic: 3733af6ab5fSopenharmony_ci ~VariableScope() override = default; 3743af6ab5fSopenharmony_ci NO_COPY_SEMANTIC(VariableScope); 3753af6ab5fSopenharmony_ci NO_MOVE_SEMANTIC(VariableScope); 3763af6ab5fSopenharmony_ci 3773af6ab5fSopenharmony_ci uint32_t NextSlot() 3783af6ab5fSopenharmony_ci { 3793af6ab5fSopenharmony_ci return slotIndex_++; 3803af6ab5fSopenharmony_ci } 3813af6ab5fSopenharmony_ci 3823af6ab5fSopenharmony_ci uint32_t LexicalSlots() const 3833af6ab5fSopenharmony_ci { 3843af6ab5fSopenharmony_ci return slotIndex_; 3853af6ab5fSopenharmony_ci } 3863af6ab5fSopenharmony_ci 3873af6ab5fSopenharmony_ci bool NeedLexEnv() const 3883af6ab5fSopenharmony_ci { 3893af6ab5fSopenharmony_ci return slotIndex_ != 0; 3903af6ab5fSopenharmony_ci } 3913af6ab5fSopenharmony_ci 3923af6ab5fSopenharmony_ci uint32_t EvalBindings() const 3933af6ab5fSopenharmony_ci { 3943af6ab5fSopenharmony_ci return evalBindings_; 3953af6ab5fSopenharmony_ci } 3963af6ab5fSopenharmony_ci 3973af6ab5fSopenharmony_ci void CheckDirectEval(public_lib::Context *context); 3983af6ab5fSopenharmony_ci 3993af6ab5fSopenharmony_ciprotected: 4003af6ab5fSopenharmony_ci explicit VariableScope(ArenaAllocator *allocator, Scope *parent) : Scope(allocator, parent) {} 4013af6ab5fSopenharmony_ci 4023af6ab5fSopenharmony_ci template <typename T> 4033af6ab5fSopenharmony_ci Variable *AddVar(ArenaAllocator *allocator, Variable *currentVariable, Decl *newDecl); 4043af6ab5fSopenharmony_ci 4053af6ab5fSopenharmony_ci template <typename T> 4063af6ab5fSopenharmony_ci Variable *AddFunction(ArenaAllocator *allocator, Variable *currentVariable, Decl *newDecl, 4073af6ab5fSopenharmony_ci [[maybe_unused]] ScriptExtension extension); 4083af6ab5fSopenharmony_ci 4093af6ab5fSopenharmony_ci template <typename T> 4103af6ab5fSopenharmony_ci Variable *AddTSBinding(ArenaAllocator *allocator, Variable *currentVariable, Decl *newDecl, VariableFlags flags); 4113af6ab5fSopenharmony_ci 4123af6ab5fSopenharmony_ci template <typename T> 4133af6ab5fSopenharmony_ci Variable *AddLexical(ArenaAllocator *allocator, Variable *currentVariable, Decl *newDecl); 4143af6ab5fSopenharmony_ci 4153af6ab5fSopenharmony_ci // NOLINTBEGIN(misc-non-private-member-variables-in-classes) 4163af6ab5fSopenharmony_ci uint32_t evalBindings_ {}; 4173af6ab5fSopenharmony_ci uint32_t slotIndex_ {}; 4183af6ab5fSopenharmony_ci // NOLINTEND(misc-non-private-member-variables-in-classes) 4193af6ab5fSopenharmony_ci}; 4203af6ab5fSopenharmony_ci 4213af6ab5fSopenharmony_ciclass ParamScope : public Scope { 4223af6ab5fSopenharmony_cipublic: 4233af6ab5fSopenharmony_ci ScopeType Type() const override 4243af6ab5fSopenharmony_ci { 4253af6ab5fSopenharmony_ci return ScopeType::PARAM; 4263af6ab5fSopenharmony_ci } 4273af6ab5fSopenharmony_ci 4283af6ab5fSopenharmony_ci ArenaVector<LocalVariable *> &Params() 4293af6ab5fSopenharmony_ci { 4303af6ab5fSopenharmony_ci return params_; 4313af6ab5fSopenharmony_ci } 4323af6ab5fSopenharmony_ci 4333af6ab5fSopenharmony_ci const ArenaVector<LocalVariable *> &Params() const 4343af6ab5fSopenharmony_ci { 4353af6ab5fSopenharmony_ci return params_; 4363af6ab5fSopenharmony_ci } 4373af6ab5fSopenharmony_ci 4383af6ab5fSopenharmony_ci std::tuple<ParameterDecl *, ir::AstNode *, Variable *> AddParamDecl(ArenaAllocator *allocator, ir::AstNode *param); 4393af6ab5fSopenharmony_ci 4403af6ab5fSopenharmony_ciprotected: 4413af6ab5fSopenharmony_ci explicit ParamScope(ArenaAllocator *allocator, Scope *parent) 4423af6ab5fSopenharmony_ci : Scope(allocator, parent), params_(allocator->Adapter()) 4433af6ab5fSopenharmony_ci { 4443af6ab5fSopenharmony_ci } 4453af6ab5fSopenharmony_ci 4463af6ab5fSopenharmony_ci Variable *AddParam(ArenaAllocator *allocator, Variable *currentVariable, Decl *newDecl, VariableFlags flags); 4473af6ab5fSopenharmony_ci 4483af6ab5fSopenharmony_ci // NOLINTNEXTLINE(misc-non-private-member-variables-in-classes) 4493af6ab5fSopenharmony_ci ArenaVector<LocalVariable *> params_; 4503af6ab5fSopenharmony_ci}; 4513af6ab5fSopenharmony_ci 4523af6ab5fSopenharmony_ciclass FunctionScope; 4533af6ab5fSopenharmony_ci 4543af6ab5fSopenharmony_ciclass FunctionParamScope : public ParamScope { 4553af6ab5fSopenharmony_cipublic: 4563af6ab5fSopenharmony_ci explicit FunctionParamScope(ArenaAllocator *allocator, Scope *parent) : ParamScope(allocator, parent) {} 4573af6ab5fSopenharmony_ci 4583af6ab5fSopenharmony_ci FunctionScope *GetFunctionScope() const 4593af6ab5fSopenharmony_ci { 4603af6ab5fSopenharmony_ci return functionScope_; 4613af6ab5fSopenharmony_ci } 4623af6ab5fSopenharmony_ci 4633af6ab5fSopenharmony_ci void BindFunctionScope(FunctionScope *funcScope) 4643af6ab5fSopenharmony_ci { 4653af6ab5fSopenharmony_ci functionScope_ = funcScope; 4663af6ab5fSopenharmony_ci } 4673af6ab5fSopenharmony_ci 4683af6ab5fSopenharmony_ci LocalVariable *NameVar() const 4693af6ab5fSopenharmony_ci { 4703af6ab5fSopenharmony_ci return nameVar_; 4713af6ab5fSopenharmony_ci } 4723af6ab5fSopenharmony_ci 4733af6ab5fSopenharmony_ci void BindName(ArenaAllocator *allocator, util::StringView name); 4743af6ab5fSopenharmony_ci 4753af6ab5fSopenharmony_ci ScopeType Type() const override 4763af6ab5fSopenharmony_ci { 4773af6ab5fSopenharmony_ci return ScopeType::FUNCTION_PARAM; 4783af6ab5fSopenharmony_ci } 4793af6ab5fSopenharmony_ci 4803af6ab5fSopenharmony_ci Variable *AddBinding(ArenaAllocator *allocator, Variable *currentVariable, Decl *newDecl, 4813af6ab5fSopenharmony_ci [[maybe_unused]] ScriptExtension extension) override; 4823af6ab5fSopenharmony_ci 4833af6ab5fSopenharmony_ci friend class FunctionScope; 4843af6ab5fSopenharmony_ci template <typename E, typename T> 4853af6ab5fSopenharmony_ci friend class ScopeWithParamScope; 4863af6ab5fSopenharmony_ci 4873af6ab5fSopenharmony_ciprivate: 4883af6ab5fSopenharmony_ci FunctionScope *functionScope_ {}; 4893af6ab5fSopenharmony_ci LocalVariable *nameVar_ {}; 4903af6ab5fSopenharmony_ci}; 4913af6ab5fSopenharmony_ci 4923af6ab5fSopenharmony_citemplate <typename E, typename T> 4933af6ab5fSopenharmony_ciclass ScopeWithParamScope : public E { 4943af6ab5fSopenharmony_cipublic: 4953af6ab5fSopenharmony_ci explicit ScopeWithParamScope(ArenaAllocator *allocator, Scope *parent) : E(allocator, parent), paramScope_(nullptr) 4963af6ab5fSopenharmony_ci { 4973af6ab5fSopenharmony_ci } 4983af6ab5fSopenharmony_ci 4993af6ab5fSopenharmony_ci void BindParamScope(T *paramScope) 5003af6ab5fSopenharmony_ci { 5013af6ab5fSopenharmony_ci AssignParamScope(paramScope); 5023af6ab5fSopenharmony_ci this->MergeBindings(paramScope->Bindings()); 5033af6ab5fSopenharmony_ci } 5043af6ab5fSopenharmony_ci 5053af6ab5fSopenharmony_ci void AssignParamScope(T *paramScope) 5063af6ab5fSopenharmony_ci { 5073af6ab5fSopenharmony_ci ASSERT(this->Parent() == paramScope); 5083af6ab5fSopenharmony_ci paramScope_ = paramScope; 5093af6ab5fSopenharmony_ci } 5103af6ab5fSopenharmony_ci 5113af6ab5fSopenharmony_ci T *ParamScope() 5123af6ab5fSopenharmony_ci { 5133af6ab5fSopenharmony_ci return paramScope_; 5143af6ab5fSopenharmony_ci } 5153af6ab5fSopenharmony_ci 5163af6ab5fSopenharmony_ci const T *ParamScope() const 5173af6ab5fSopenharmony_ci { 5183af6ab5fSopenharmony_ci return paramScope_; 5193af6ab5fSopenharmony_ci } 5203af6ab5fSopenharmony_ci 5213af6ab5fSopenharmony_ciprotected: 5223af6ab5fSopenharmony_ci // NOLINTNEXTLINE(misc-non-private-member-variables-in-classes) 5233af6ab5fSopenharmony_ci T *paramScope_; 5243af6ab5fSopenharmony_ci}; 5253af6ab5fSopenharmony_ci 5263af6ab5fSopenharmony_ciclass LocalScope : public Scope { 5273af6ab5fSopenharmony_cipublic: 5283af6ab5fSopenharmony_ci explicit LocalScope(ArenaAllocator *allocator, Scope *parent) : Scope(allocator, parent) {} 5293af6ab5fSopenharmony_ci explicit LocalScope(ArenaAllocator *allocator, Scope *parent, ScopeFlags flags) : Scope(allocator, parent, flags) {} 5303af6ab5fSopenharmony_ci 5313af6ab5fSopenharmony_ci ScopeType Type() const override 5323af6ab5fSopenharmony_ci { 5333af6ab5fSopenharmony_ci return ScopeType::LOCAL; 5343af6ab5fSopenharmony_ci } 5353af6ab5fSopenharmony_ci 5363af6ab5fSopenharmony_ci Variable *AddBinding(ArenaAllocator *allocator, Variable *currentVariable, Decl *newDecl, 5373af6ab5fSopenharmony_ci [[maybe_unused]] ScriptExtension extension) override; 5383af6ab5fSopenharmony_ci}; 5393af6ab5fSopenharmony_ci 5403af6ab5fSopenharmony_ciclass LocalScopeWithTypeAlias : public LocalScope { 5413af6ab5fSopenharmony_cipublic: 5423af6ab5fSopenharmony_ci explicit LocalScopeWithTypeAlias(ArenaAllocator *allocator, Scope *parent) 5433af6ab5fSopenharmony_ci : LocalScope(allocator, parent), 5443af6ab5fSopenharmony_ci typeAliasScope_(allocator->New<LocalScope>(allocator, this, ScopeFlags::TYPE_ALIAS)) 5453af6ab5fSopenharmony_ci { 5463af6ab5fSopenharmony_ci } 5473af6ab5fSopenharmony_ci explicit LocalScopeWithTypeAlias(ArenaAllocator *allocator, Scope *parent, ScopeFlags flags) 5483af6ab5fSopenharmony_ci : LocalScope(allocator, parent, flags), 5493af6ab5fSopenharmony_ci typeAliasScope_(allocator->New<LocalScope>(allocator, this, ScopeFlags::TYPE_ALIAS)) 5503af6ab5fSopenharmony_ci { 5513af6ab5fSopenharmony_ci } 5523af6ab5fSopenharmony_ci 5533af6ab5fSopenharmony_ci Variable *FindLocal(const util::StringView &name, ResolveBindingOptions options) const override; 5543af6ab5fSopenharmony_ci 5553af6ab5fSopenharmony_ci Variable *AddBinding(ArenaAllocator *allocator, Variable *currentVariable, Decl *newDecl, 5563af6ab5fSopenharmony_ci [[maybe_unused]] ScriptExtension extension) override; 5573af6ab5fSopenharmony_ci 5583af6ab5fSopenharmony_ci const LocalScope *TypeAliasScope() const 5593af6ab5fSopenharmony_ci { 5603af6ab5fSopenharmony_ci return typeAliasScope_; 5613af6ab5fSopenharmony_ci } 5623af6ab5fSopenharmony_ci 5633af6ab5fSopenharmony_ci LocalScope *TypeAliasScope() 5643af6ab5fSopenharmony_ci { 5653af6ab5fSopenharmony_ci return typeAliasScope_; 5663af6ab5fSopenharmony_ci } 5673af6ab5fSopenharmony_ci 5683af6ab5fSopenharmony_ciprivate: 5693af6ab5fSopenharmony_ci LocalScope *typeAliasScope_; 5703af6ab5fSopenharmony_ci}; 5713af6ab5fSopenharmony_ci 5723af6ab5fSopenharmony_ciclass FunctionScope : public ScopeWithParamScope<VariableScope, FunctionParamScope> { 5733af6ab5fSopenharmony_cipublic: 5743af6ab5fSopenharmony_ci explicit FunctionScope(ArenaAllocator *allocator, Scope *parent) 5753af6ab5fSopenharmony_ci : ScopeWithParamScope(allocator, parent), 5763af6ab5fSopenharmony_ci typeAliasScope_(allocator->New<LocalScope>(allocator, this, ScopeFlags::TYPE_ALIAS)) 5773af6ab5fSopenharmony_ci { 5783af6ab5fSopenharmony_ci } 5793af6ab5fSopenharmony_ci 5803af6ab5fSopenharmony_ci ScopeType Type() const override 5813af6ab5fSopenharmony_ci { 5823af6ab5fSopenharmony_ci return ScopeType::FUNCTION; 5833af6ab5fSopenharmony_ci } 5843af6ab5fSopenharmony_ci 5853af6ab5fSopenharmony_ci void BindName(util::StringView name) 5863af6ab5fSopenharmony_ci { 5873af6ab5fSopenharmony_ci name_ = name; 5883af6ab5fSopenharmony_ci } 5893af6ab5fSopenharmony_ci 5903af6ab5fSopenharmony_ci void BindInternalName(util::StringView internalName) 5913af6ab5fSopenharmony_ci { 5923af6ab5fSopenharmony_ci internalName_ = internalName; 5933af6ab5fSopenharmony_ci } 5943af6ab5fSopenharmony_ci 5953af6ab5fSopenharmony_ci const util::StringView &Name() const 5963af6ab5fSopenharmony_ci { 5973af6ab5fSopenharmony_ci return name_; 5983af6ab5fSopenharmony_ci } 5993af6ab5fSopenharmony_ci 6003af6ab5fSopenharmony_ci const util::StringView &InternalName() const 6013af6ab5fSopenharmony_ci { 6023af6ab5fSopenharmony_ci return internalName_; 6033af6ab5fSopenharmony_ci } 6043af6ab5fSopenharmony_ci 6053af6ab5fSopenharmony_ci const LocalScope *TypeAliasScope() const 6063af6ab5fSopenharmony_ci { 6073af6ab5fSopenharmony_ci return typeAliasScope_; 6083af6ab5fSopenharmony_ci } 6093af6ab5fSopenharmony_ci 6103af6ab5fSopenharmony_ci Variable *FindLocal(const util::StringView &name, ResolveBindingOptions options) const override; 6113af6ab5fSopenharmony_ci 6123af6ab5fSopenharmony_ci Variable *AddBinding(ArenaAllocator *allocator, Variable *currentVariable, Decl *newDecl, 6133af6ab5fSopenharmony_ci [[maybe_unused]] ScriptExtension extension) override; 6143af6ab5fSopenharmony_ci 6153af6ab5fSopenharmony_ciprivate: 6163af6ab5fSopenharmony_ci util::StringView name_ {}; 6173af6ab5fSopenharmony_ci util::StringView internalName_ {}; 6183af6ab5fSopenharmony_ci LocalScope *typeAliasScope_; 6193af6ab5fSopenharmony_ci}; 6203af6ab5fSopenharmony_ci 6213af6ab5fSopenharmony_ciclass ClassScope : public LocalScopeWithTypeAlias { 6223af6ab5fSopenharmony_cipublic: 6233af6ab5fSopenharmony_ci explicit ClassScope(ArenaAllocator *allocator, Scope *parent) 6243af6ab5fSopenharmony_ci : LocalScopeWithTypeAlias(allocator, parent), 6253af6ab5fSopenharmony_ci staticDeclScope_(allocator->New<LocalScope>(allocator, this, ScopeFlags::STATIC_DECL_SCOPE)), 6263af6ab5fSopenharmony_ci staticFieldScope_(allocator->New<LocalScope>(allocator, staticDeclScope_, ScopeFlags::STATIC_FIELD_SCOPE)), 6273af6ab5fSopenharmony_ci staticMethodScope_(allocator->New<LocalScope>(allocator, staticFieldScope_, ScopeFlags::STATIC_METHOD_SCOPE)), 6283af6ab5fSopenharmony_ci instanceDeclScope_(allocator->New<LocalScope>(allocator, staticMethodScope_, ScopeFlags::DECL_SCOPE)), 6293af6ab5fSopenharmony_ci instanceFieldScope_(allocator->New<LocalScope>(allocator, instanceDeclScope_, ScopeFlags::FIELD_SCOPE)), 6303af6ab5fSopenharmony_ci instanceMethodScope_(allocator->New<LocalScope>(allocator, instanceFieldScope_, ScopeFlags::METHOD_SCOPE)) 6313af6ab5fSopenharmony_ci { 6323af6ab5fSopenharmony_ci } 6333af6ab5fSopenharmony_ci 6343af6ab5fSopenharmony_ci ScopeType Type() const override 6353af6ab5fSopenharmony_ci { 6363af6ab5fSopenharmony_ci return ScopeType::CLASS; 6373af6ab5fSopenharmony_ci } 6383af6ab5fSopenharmony_ci 6393af6ab5fSopenharmony_ci LocalScope *StaticDeclScope() 6403af6ab5fSopenharmony_ci { 6413af6ab5fSopenharmony_ci return staticDeclScope_; 6423af6ab5fSopenharmony_ci } 6433af6ab5fSopenharmony_ci 6443af6ab5fSopenharmony_ci const LocalScope *StaticDeclScope() const 6453af6ab5fSopenharmony_ci { 6463af6ab5fSopenharmony_ci return staticDeclScope_; 6473af6ab5fSopenharmony_ci } 6483af6ab5fSopenharmony_ci 6493af6ab5fSopenharmony_ci LocalScope *StaticFieldScope() 6503af6ab5fSopenharmony_ci { 6513af6ab5fSopenharmony_ci return staticFieldScope_; 6523af6ab5fSopenharmony_ci } 6533af6ab5fSopenharmony_ci 6543af6ab5fSopenharmony_ci const LocalScope *StaticFieldScope() const 6553af6ab5fSopenharmony_ci { 6563af6ab5fSopenharmony_ci return staticFieldScope_; 6573af6ab5fSopenharmony_ci } 6583af6ab5fSopenharmony_ci 6593af6ab5fSopenharmony_ci LocalScope *StaticMethodScope() 6603af6ab5fSopenharmony_ci { 6613af6ab5fSopenharmony_ci return staticMethodScope_; 6623af6ab5fSopenharmony_ci } 6633af6ab5fSopenharmony_ci 6643af6ab5fSopenharmony_ci const LocalScope *StaticMethodScope() const 6653af6ab5fSopenharmony_ci { 6663af6ab5fSopenharmony_ci return staticMethodScope_; 6673af6ab5fSopenharmony_ci } 6683af6ab5fSopenharmony_ci 6693af6ab5fSopenharmony_ci LocalScope *InstanceFieldScope() 6703af6ab5fSopenharmony_ci { 6713af6ab5fSopenharmony_ci return instanceFieldScope_; 6723af6ab5fSopenharmony_ci } 6733af6ab5fSopenharmony_ci 6743af6ab5fSopenharmony_ci const LocalScope *InstanceFieldScope() const 6753af6ab5fSopenharmony_ci { 6763af6ab5fSopenharmony_ci return instanceFieldScope_; 6773af6ab5fSopenharmony_ci } 6783af6ab5fSopenharmony_ci 6793af6ab5fSopenharmony_ci LocalScope *InstanceMethodScope() 6803af6ab5fSopenharmony_ci { 6813af6ab5fSopenharmony_ci return instanceMethodScope_; 6823af6ab5fSopenharmony_ci } 6833af6ab5fSopenharmony_ci 6843af6ab5fSopenharmony_ci const LocalScope *InstanceMethodScope() const 6853af6ab5fSopenharmony_ci { 6863af6ab5fSopenharmony_ci return instanceMethodScope_; 6873af6ab5fSopenharmony_ci } 6883af6ab5fSopenharmony_ci 6893af6ab5fSopenharmony_ci LocalScope *InstanceDeclScope() 6903af6ab5fSopenharmony_ci { 6913af6ab5fSopenharmony_ci return instanceDeclScope_; 6923af6ab5fSopenharmony_ci } 6933af6ab5fSopenharmony_ci 6943af6ab5fSopenharmony_ci const LocalScope *InstanceDeclScope() const 6953af6ab5fSopenharmony_ci { 6963af6ab5fSopenharmony_ci return instanceDeclScope_; 6973af6ab5fSopenharmony_ci } 6983af6ab5fSopenharmony_ci 6993af6ab5fSopenharmony_ci uint32_t GetAndIncrementAnonymousClassIdx() const 7003af6ab5fSopenharmony_ci { 7013af6ab5fSopenharmony_ci return anonymousClassIdx_++; 7023af6ab5fSopenharmony_ci } 7033af6ab5fSopenharmony_ci 7043af6ab5fSopenharmony_ci Variable *FindLocal(const util::StringView &name, ResolveBindingOptions options) const override; 7053af6ab5fSopenharmony_ci 7063af6ab5fSopenharmony_ci Variable *AddBinding(ArenaAllocator *allocator, Variable *currentVariable, Decl *newDecl, 7073af6ab5fSopenharmony_ci [[maybe_unused]] ScriptExtension extension) override; 7083af6ab5fSopenharmony_ci 7093af6ab5fSopenharmony_ci class BindingProps { 7103af6ab5fSopenharmony_ci public: 7113af6ab5fSopenharmony_ci BindingProps() = default; 7123af6ab5fSopenharmony_ci 7133af6ab5fSopenharmony_ci void SetFlagsType(VariableFlags flagsType) 7143af6ab5fSopenharmony_ci { 7153af6ab5fSopenharmony_ci flags_ |= flagsType; 7163af6ab5fSopenharmony_ci } 7173af6ab5fSopenharmony_ci void SetBindingProps(VariableFlags flags, ir::Identifier *ident, LocalScope *targetScope) 7183af6ab5fSopenharmony_ci { 7193af6ab5fSopenharmony_ci flags_ |= flags; 7203af6ab5fSopenharmony_ci ident_ = ident; 7213af6ab5fSopenharmony_ci targetScope_ = targetScope; 7223af6ab5fSopenharmony_ci } 7233af6ab5fSopenharmony_ci VariableFlags GetFlags() const 7243af6ab5fSopenharmony_ci { 7253af6ab5fSopenharmony_ci return flags_; 7263af6ab5fSopenharmony_ci } 7273af6ab5fSopenharmony_ci ir::Identifier *GetIdent() 7283af6ab5fSopenharmony_ci { 7293af6ab5fSopenharmony_ci return ident_; 7303af6ab5fSopenharmony_ci } 7313af6ab5fSopenharmony_ci LocalScope *GetTargetScope() 7323af6ab5fSopenharmony_ci { 7333af6ab5fSopenharmony_ci return targetScope_; 7343af6ab5fSopenharmony_ci } 7353af6ab5fSopenharmony_ci 7363af6ab5fSopenharmony_ci private: 7373af6ab5fSopenharmony_ci VariableFlags flags_ = VariableFlags::NONE; 7383af6ab5fSopenharmony_ci ir::Identifier *ident_ {}; 7393af6ab5fSopenharmony_ci LocalScope *targetScope_ {}; 7403af6ab5fSopenharmony_ci }; 7413af6ab5fSopenharmony_ci 7423af6ab5fSopenharmony_ci void SetBindingProps(Decl *newDecl, BindingProps *props, bool isStatic); 7433af6ab5fSopenharmony_ci 7443af6ab5fSopenharmony_ciprivate: 7453af6ab5fSopenharmony_ci LocalScope *staticDeclScope_; 7463af6ab5fSopenharmony_ci LocalScope *staticFieldScope_; 7473af6ab5fSopenharmony_ci LocalScope *staticMethodScope_; 7483af6ab5fSopenharmony_ci LocalScope *instanceDeclScope_; 7493af6ab5fSopenharmony_ci LocalScope *instanceFieldScope_; 7503af6ab5fSopenharmony_ci LocalScope *instanceMethodScope_; 7513af6ab5fSopenharmony_ci mutable uint32_t anonymousClassIdx_ {1}; 7523af6ab5fSopenharmony_ci}; 7533af6ab5fSopenharmony_ci 7543af6ab5fSopenharmony_ciclass CatchParamScope : public ParamScope { 7553af6ab5fSopenharmony_cipublic: 7563af6ab5fSopenharmony_ci explicit CatchParamScope(ArenaAllocator *allocator, Scope *parent) : ParamScope(allocator, parent) {} 7573af6ab5fSopenharmony_ci 7583af6ab5fSopenharmony_ci ScopeType Type() const override 7593af6ab5fSopenharmony_ci { 7603af6ab5fSopenharmony_ci return ScopeType::CATCH_PARAM; 7613af6ab5fSopenharmony_ci } 7623af6ab5fSopenharmony_ci 7633af6ab5fSopenharmony_ci Variable *AddBinding(ArenaAllocator *allocator, Variable *currentVariable, Decl *newDecl, 7643af6ab5fSopenharmony_ci [[maybe_unused]] ScriptExtension extension) override; 7653af6ab5fSopenharmony_ci 7663af6ab5fSopenharmony_ci friend class CatchScope; 7673af6ab5fSopenharmony_ci}; 7683af6ab5fSopenharmony_ci 7693af6ab5fSopenharmony_ciclass CatchScope : public ScopeWithParamScope<LocalScopeWithTypeAlias, CatchParamScope> { 7703af6ab5fSopenharmony_cipublic: 7713af6ab5fSopenharmony_ci explicit CatchScope(ArenaAllocator *allocator, Scope *parent) : ScopeWithParamScope(allocator, parent) {} 7723af6ab5fSopenharmony_ci 7733af6ab5fSopenharmony_ci ScopeType Type() const override 7743af6ab5fSopenharmony_ci { 7753af6ab5fSopenharmony_ci return ScopeType::CATCH; 7763af6ab5fSopenharmony_ci } 7773af6ab5fSopenharmony_ci 7783af6ab5fSopenharmony_ci Variable *AddBinding(ArenaAllocator *allocator, Variable *currentVariable, Decl *newDecl, 7793af6ab5fSopenharmony_ci [[maybe_unused]] ScriptExtension extension) override; 7803af6ab5fSopenharmony_ci}; 7813af6ab5fSopenharmony_ci 7823af6ab5fSopenharmony_ciclass LoopScope; 7833af6ab5fSopenharmony_ci 7843af6ab5fSopenharmony_ciclass LoopDeclarationScope : public VariableScope { 7853af6ab5fSopenharmony_cipublic: 7863af6ab5fSopenharmony_ci explicit LoopDeclarationScope(ArenaAllocator *allocator, Scope *parent) : VariableScope(allocator, parent) {} 7873af6ab5fSopenharmony_ci 7883af6ab5fSopenharmony_ci ScopeType Type() const override 7893af6ab5fSopenharmony_ci { 7903af6ab5fSopenharmony_ci return loopType_; 7913af6ab5fSopenharmony_ci } 7923af6ab5fSopenharmony_ci 7933af6ab5fSopenharmony_ci Variable *AddBinding(ArenaAllocator *allocator, Variable *currentVariable, Decl *newDecl, 7943af6ab5fSopenharmony_ci [[maybe_unused]] ScriptExtension extension) override 7953af6ab5fSopenharmony_ci { 7963af6ab5fSopenharmony_ci return AddLocal(allocator, currentVariable, newDecl, extension); 7973af6ab5fSopenharmony_ci } 7983af6ab5fSopenharmony_ci 7993af6ab5fSopenharmony_ci Scope *InitScope() 8003af6ab5fSopenharmony_ci { 8013af6ab5fSopenharmony_ci if (NeedLexEnv()) { 8023af6ab5fSopenharmony_ci return initScope_; 8033af6ab5fSopenharmony_ci } 8043af6ab5fSopenharmony_ci 8053af6ab5fSopenharmony_ci return this; 8063af6ab5fSopenharmony_ci } 8073af6ab5fSopenharmony_ci 8083af6ab5fSopenharmony_ci void ConvertToVariableScope(ArenaAllocator *allocator); 8093af6ab5fSopenharmony_ci 8103af6ab5fSopenharmony_ciprivate: 8113af6ab5fSopenharmony_ci friend class LoopScope; 8123af6ab5fSopenharmony_ci LoopScope *loopScope_ {}; 8133af6ab5fSopenharmony_ci LocalScope *initScope_ {}; 8143af6ab5fSopenharmony_ci ScopeType loopType_ {ScopeType::LOCAL}; 8153af6ab5fSopenharmony_ci}; 8163af6ab5fSopenharmony_ci 8173af6ab5fSopenharmony_ciclass LoopScope : public VariableScope { 8183af6ab5fSopenharmony_cipublic: 8193af6ab5fSopenharmony_ci explicit LoopScope(ArenaAllocator *allocator, Scope *parent) : VariableScope(allocator, parent) 8203af6ab5fSopenharmony_ci { 8213af6ab5fSopenharmony_ci // NOTE(kkonkuznetsov): currently LoopScope type has ScopeType::LOCAL 8223af6ab5fSopenharmony_ci // therefore it does not respond to IsLoopScope() because it checks for type. 8233af6ab5fSopenharmony_ci // This LOOP_SCOPE flag can be used to check that scope is actually a loop scope. 8243af6ab5fSopenharmony_ci AddFlag(ScopeFlags::LOOP_SCOPE); 8253af6ab5fSopenharmony_ci } 8263af6ab5fSopenharmony_ci 8273af6ab5fSopenharmony_ci LoopDeclarationScope *DeclScope() 8283af6ab5fSopenharmony_ci { 8293af6ab5fSopenharmony_ci return declScope_; 8303af6ab5fSopenharmony_ci } 8313af6ab5fSopenharmony_ci 8323af6ab5fSopenharmony_ci void BindDecls(LoopDeclarationScope *declScope) 8333af6ab5fSopenharmony_ci { 8343af6ab5fSopenharmony_ci declScope_ = declScope; 8353af6ab5fSopenharmony_ci declScope_->loopScope_ = this; 8363af6ab5fSopenharmony_ci } 8373af6ab5fSopenharmony_ci 8383af6ab5fSopenharmony_ci ScopeType Type() const override 8393af6ab5fSopenharmony_ci { 8403af6ab5fSopenharmony_ci return loopType_; 8413af6ab5fSopenharmony_ci } 8423af6ab5fSopenharmony_ci 8433af6ab5fSopenharmony_ci void ConvertToVariableScope(ArenaAllocator *allocator); 8443af6ab5fSopenharmony_ci 8453af6ab5fSopenharmony_ci Variable *AddBinding(ArenaAllocator *allocator, Variable *currentVariable, Decl *newDecl, 8463af6ab5fSopenharmony_ci [[maybe_unused]] ScriptExtension extension) override 8473af6ab5fSopenharmony_ci { 8483af6ab5fSopenharmony_ci return AddLocal(allocator, currentVariable, newDecl, extension); 8493af6ab5fSopenharmony_ci } 8503af6ab5fSopenharmony_ci 8513af6ab5fSopenharmony_ciprotected: 8523af6ab5fSopenharmony_ci // NOLINTBEGIN(misc-non-private-member-variables-in-classes) 8533af6ab5fSopenharmony_ci LoopDeclarationScope *declScope_ {}; 8543af6ab5fSopenharmony_ci ScopeType loopType_ {ScopeType::LOCAL}; 8553af6ab5fSopenharmony_ci // NOLINTEND(misc-non-private-member-variables-in-classes) 8563af6ab5fSopenharmony_ci}; 8573af6ab5fSopenharmony_ci 8583af6ab5fSopenharmony_ciclass GlobalScope : public FunctionScope { 8593af6ab5fSopenharmony_cipublic: 8603af6ab5fSopenharmony_ci explicit GlobalScope(ArenaAllocator *allocator) 8613af6ab5fSopenharmony_ci : FunctionScope(allocator, nullptr), foreignBindings_(allocator->Adapter()) 8623af6ab5fSopenharmony_ci { 8633af6ab5fSopenharmony_ci auto *paramScope = allocator->New<FunctionParamScope>(allocator, this); 8643af6ab5fSopenharmony_ci paramScope_ = paramScope; 8653af6ab5fSopenharmony_ci paramScope_->BindFunctionScope(this); 8663af6ab5fSopenharmony_ci } 8673af6ab5fSopenharmony_ci 8683af6ab5fSopenharmony_ci ScopeType Type() const override 8693af6ab5fSopenharmony_ci { 8703af6ab5fSopenharmony_ci return ScopeType::GLOBAL; 8713af6ab5fSopenharmony_ci } 8723af6ab5fSopenharmony_ci 8733af6ab5fSopenharmony_ci Variable *AddBinding(ArenaAllocator *allocator, Variable *currentVariable, Decl *newDecl, 8743af6ab5fSopenharmony_ci [[maybe_unused]] ScriptExtension extension) override; 8753af6ab5fSopenharmony_ci 8763af6ab5fSopenharmony_ci InsertResult InsertBinding(const util::StringView &name, Variable *var) override; 8773af6ab5fSopenharmony_ci InsertResult TryInsertBinding(const util::StringView &name, Variable *var) override; 8783af6ab5fSopenharmony_ci void MergeBindings(VariableMap const &bindings) override; 8793af6ab5fSopenharmony_ci VariableMap::size_type EraseBinding(const util::StringView &name) override; 8803af6ab5fSopenharmony_ci 8813af6ab5fSopenharmony_ci InsertResult InsertForeignBinding(const util::StringView &name, Variable *var); 8823af6ab5fSopenharmony_ci [[nodiscard]] bool IsForeignBinding(const util::StringView &name) const; 8833af6ab5fSopenharmony_ci 8843af6ab5fSopenharmony_ci InsertResult InsertDynamicBinding(const util::StringView &name, Variable *var); 8853af6ab5fSopenharmony_ci 8863af6ab5fSopenharmony_ciprivate: 8873af6ab5fSopenharmony_ci InsertResult InsertImpl(const util::StringView &name, Variable *var, bool isForeign, bool isDynamic); 8883af6ab5fSopenharmony_ci 8893af6ab5fSopenharmony_ci ArenaUnorderedMap<util::StringView, bool> foreignBindings_; 8903af6ab5fSopenharmony_ci}; 8913af6ab5fSopenharmony_ci 8923af6ab5fSopenharmony_ciclass ModuleScope : public GlobalScope { 8933af6ab5fSopenharmony_cipublic: 8943af6ab5fSopenharmony_ci template <typename K, typename V> 8953af6ab5fSopenharmony_ci using ModuleEntry = ArenaVector<std::pair<K, V>>; 8963af6ab5fSopenharmony_ci using ImportDeclList = ArenaVector<ImportDecl *>; 8973af6ab5fSopenharmony_ci using ExportDeclList = ArenaVector<ExportDecl *>; 8983af6ab5fSopenharmony_ci using LocalExportNameMap = ArenaMultiMap<varbinder::Variable *, util::StringView>; 8993af6ab5fSopenharmony_ci 9003af6ab5fSopenharmony_ci explicit ModuleScope(ArenaAllocator *allocator) 9013af6ab5fSopenharmony_ci : GlobalScope(allocator), 9023af6ab5fSopenharmony_ci allocator_(allocator), 9033af6ab5fSopenharmony_ci imports_(allocator_->Adapter()), 9043af6ab5fSopenharmony_ci exports_(allocator_->Adapter()), 9053af6ab5fSopenharmony_ci localExports_(allocator_->Adapter()) 9063af6ab5fSopenharmony_ci { 9073af6ab5fSopenharmony_ci } 9083af6ab5fSopenharmony_ci 9093af6ab5fSopenharmony_ci ScopeType Type() const override 9103af6ab5fSopenharmony_ci { 9113af6ab5fSopenharmony_ci return ScopeType::MODULE; 9123af6ab5fSopenharmony_ci } 9133af6ab5fSopenharmony_ci 9143af6ab5fSopenharmony_ci const ModuleEntry<ir::ImportDeclaration *, ImportDeclList> &Imports() const 9153af6ab5fSopenharmony_ci { 9163af6ab5fSopenharmony_ci return imports_; 9173af6ab5fSopenharmony_ci } 9183af6ab5fSopenharmony_ci 9193af6ab5fSopenharmony_ci const ModuleEntry<ir::AstNode *, ExportDeclList> &Exports() const 9203af6ab5fSopenharmony_ci { 9213af6ab5fSopenharmony_ci return exports_; 9223af6ab5fSopenharmony_ci } 9233af6ab5fSopenharmony_ci 9243af6ab5fSopenharmony_ci const LocalExportNameMap &LocalExports() const 9253af6ab5fSopenharmony_ci { 9263af6ab5fSopenharmony_ci return localExports_; 9273af6ab5fSopenharmony_ci } 9283af6ab5fSopenharmony_ci 9293af6ab5fSopenharmony_ci void AddImportDecl(ir::ImportDeclaration *importDecl, ImportDeclList &&decls); 9303af6ab5fSopenharmony_ci 9313af6ab5fSopenharmony_ci void AddExportDecl(ir::AstNode *exportDecl, ExportDecl *decl); 9323af6ab5fSopenharmony_ci 9333af6ab5fSopenharmony_ci void AddExportDecl(ir::AstNode *exportDecl, ExportDeclList &&decls); 9343af6ab5fSopenharmony_ci 9353af6ab5fSopenharmony_ci Variable *AddBinding(ArenaAllocator *allocator, Variable *currentVariable, Decl *newDecl, 9363af6ab5fSopenharmony_ci [[maybe_unused]] ScriptExtension extension) override; 9373af6ab5fSopenharmony_ci 9383af6ab5fSopenharmony_ci bool ExportAnalysis(); 9393af6ab5fSopenharmony_ci 9403af6ab5fSopenharmony_ciprivate: 9413af6ab5fSopenharmony_ci Variable *AddImport(ArenaAllocator *allocator, Variable *currentVariable, Decl *newDecl); 9423af6ab5fSopenharmony_ci 9433af6ab5fSopenharmony_ci ArenaAllocator *allocator_; 9443af6ab5fSopenharmony_ci ModuleEntry<ir::ImportDeclaration *, ImportDeclList> imports_; 9453af6ab5fSopenharmony_ci ModuleEntry<ir::AstNode *, ExportDeclList> exports_; 9463af6ab5fSopenharmony_ci LocalExportNameMap localExports_; 9473af6ab5fSopenharmony_ci}; 9483af6ab5fSopenharmony_ci 9493af6ab5fSopenharmony_citemplate <typename T> 9503af6ab5fSopenharmony_ciVariable *VariableScope::AddVar(ArenaAllocator *allocator, Variable *currentVariable, Decl *newDecl) 9513af6ab5fSopenharmony_ci{ 9523af6ab5fSopenharmony_ci if (!currentVariable) { 9533af6ab5fSopenharmony_ci return InsertBinding(newDecl->Name(), allocator->New<T>(newDecl, VariableFlags::HOIST_VAR)).first->second; 9543af6ab5fSopenharmony_ci } 9553af6ab5fSopenharmony_ci 9563af6ab5fSopenharmony_ci switch (currentVariable->Declaration()->Type()) { 9573af6ab5fSopenharmony_ci case DeclType::VAR: { 9583af6ab5fSopenharmony_ci currentVariable->Reset(newDecl, VariableFlags::HOIST_VAR); 9593af6ab5fSopenharmony_ci [[fallthrough]]; 9603af6ab5fSopenharmony_ci } 9613af6ab5fSopenharmony_ci case DeclType::PARAM: 9623af6ab5fSopenharmony_ci case DeclType::FUNC: { 9633af6ab5fSopenharmony_ci return currentVariable; 9643af6ab5fSopenharmony_ci } 9653af6ab5fSopenharmony_ci default: { 9663af6ab5fSopenharmony_ci return nullptr; 9673af6ab5fSopenharmony_ci } 9683af6ab5fSopenharmony_ci } 9693af6ab5fSopenharmony_ci} 9703af6ab5fSopenharmony_ci 9713af6ab5fSopenharmony_citemplate <typename T> 9723af6ab5fSopenharmony_ciVariable *VariableScope::AddFunction(ArenaAllocator *allocator, Variable *currentVariable, Decl *newDecl, 9733af6ab5fSopenharmony_ci [[maybe_unused]] ScriptExtension extension) 9743af6ab5fSopenharmony_ci{ 9753af6ab5fSopenharmony_ci VariableFlags flags = (extension == ScriptExtension::JS) ? VariableFlags::HOIST_VAR : VariableFlags::HOIST; 9763af6ab5fSopenharmony_ci 9773af6ab5fSopenharmony_ci if (!currentVariable) { 9783af6ab5fSopenharmony_ci return InsertBinding(newDecl->Name(), allocator->New<T>(newDecl, flags)).first->second; 9793af6ab5fSopenharmony_ci } 9803af6ab5fSopenharmony_ci 9813af6ab5fSopenharmony_ci if (extension != ScriptExtension::JS || IsModuleScope()) { 9823af6ab5fSopenharmony_ci return nullptr; 9833af6ab5fSopenharmony_ci } 9843af6ab5fSopenharmony_ci 9853af6ab5fSopenharmony_ci switch (currentVariable->Declaration()->Type()) { 9863af6ab5fSopenharmony_ci case DeclType::VAR: 9873af6ab5fSopenharmony_ci case DeclType::FUNC: { 9883af6ab5fSopenharmony_ci currentVariable->Reset(newDecl, VariableFlags::HOIST_VAR); 9893af6ab5fSopenharmony_ci return currentVariable; 9903af6ab5fSopenharmony_ci } 9913af6ab5fSopenharmony_ci default: { 9923af6ab5fSopenharmony_ci return nullptr; 9933af6ab5fSopenharmony_ci } 9943af6ab5fSopenharmony_ci } 9953af6ab5fSopenharmony_ci} 9963af6ab5fSopenharmony_ci 9973af6ab5fSopenharmony_citemplate <typename T> 9983af6ab5fSopenharmony_ciVariable *VariableScope::AddTSBinding(ArenaAllocator *allocator, [[maybe_unused]] Variable *currentVariable, 9993af6ab5fSopenharmony_ci Decl *newDecl, VariableFlags flags) 10003af6ab5fSopenharmony_ci{ 10013af6ab5fSopenharmony_ci ASSERT(!currentVariable); 10023af6ab5fSopenharmony_ci return InsertBinding(newDecl->Name(), allocator->New<T>(newDecl, flags)).first->second; 10033af6ab5fSopenharmony_ci} 10043af6ab5fSopenharmony_ci 10053af6ab5fSopenharmony_citemplate <typename T> 10063af6ab5fSopenharmony_ciVariable *VariableScope::AddLexical(ArenaAllocator *allocator, Variable *currentVariable, Decl *newDecl) 10073af6ab5fSopenharmony_ci{ 10083af6ab5fSopenharmony_ci if (currentVariable) { 10093af6ab5fSopenharmony_ci return nullptr; 10103af6ab5fSopenharmony_ci } 10113af6ab5fSopenharmony_ci 10123af6ab5fSopenharmony_ci return InsertBinding(newDecl->Name(), allocator->New<T>(newDecl, VariableFlags::NONE)).first->second; 10133af6ab5fSopenharmony_ci} 10143af6ab5fSopenharmony_ci 10153af6ab5fSopenharmony_citemplate <typename T, typename... Args> 10163af6ab5fSopenharmony_ciT *Scope::NewDecl(ArenaAllocator *allocator, Args &&...args) 10173af6ab5fSopenharmony_ci{ 10183af6ab5fSopenharmony_ci T *decl = allocator->New<T>(std::forward<Args>(args)...); 10193af6ab5fSopenharmony_ci decls_.push_back(decl); 10203af6ab5fSopenharmony_ci 10213af6ab5fSopenharmony_ci return decl; 10223af6ab5fSopenharmony_ci} 10233af6ab5fSopenharmony_ci 10243af6ab5fSopenharmony_citemplate <typename DeclType, typename VariableType> 10253af6ab5fSopenharmony_ciVariableType *Scope::AddDecl(ArenaAllocator *allocator, util::StringView name, VariableFlags flags) 10263af6ab5fSopenharmony_ci{ 10273af6ab5fSopenharmony_ci if (FindLocal(name, varbinder::ResolveBindingOptions::BINDINGS)) { 10283af6ab5fSopenharmony_ci return nullptr; 10293af6ab5fSopenharmony_ci } 10303af6ab5fSopenharmony_ci 10313af6ab5fSopenharmony_ci auto *decl = allocator->New<DeclType>(name); 10323af6ab5fSopenharmony_ci auto *variable = allocator->New<VariableType>(decl, flags); 10333af6ab5fSopenharmony_ci 10343af6ab5fSopenharmony_ci decls_.push_back(decl); 10353af6ab5fSopenharmony_ci bindings_.insert({decl->Name(), variable}); 10363af6ab5fSopenharmony_ci variable->SetScope(this); 10373af6ab5fSopenharmony_ci 10383af6ab5fSopenharmony_ci return variable; 10393af6ab5fSopenharmony_ci} 10403af6ab5fSopenharmony_ci 10413af6ab5fSopenharmony_citemplate <typename DeclType, typename VariableType> 10423af6ab5fSopenharmony_ciVariableType *Scope::CreateVar(ArenaAllocator *allocator, util::StringView name, VariableFlags flags, ir::AstNode *node) 10433af6ab5fSopenharmony_ci{ 10443af6ab5fSopenharmony_ci auto *decl = allocator->New<DeclType>(name); 10453af6ab5fSopenharmony_ci auto *variable = allocator->New<VariableType>(decl, flags); 10463af6ab5fSopenharmony_ci decl->BindNode(node); 10473af6ab5fSopenharmony_ci return variable; 10483af6ab5fSopenharmony_ci} 10493af6ab5fSopenharmony_ci 10503af6ab5fSopenharmony_citemplate <typename T, typename... Args> 10513af6ab5fSopenharmony_ciVariable *Scope::PropagateBinding(ArenaAllocator *allocator, util::StringView name, Args &&...args) 10523af6ab5fSopenharmony_ci{ 10533af6ab5fSopenharmony_ci auto res = bindings_.find(name); 10543af6ab5fSopenharmony_ci if (res == bindings_.end()) { 10553af6ab5fSopenharmony_ci return bindings_.insert({name, allocator->New<T>(std::forward<Args>(args)...)}).first->second; 10563af6ab5fSopenharmony_ci } 10573af6ab5fSopenharmony_ci 10583af6ab5fSopenharmony_ci res->second->Reset(std::forward<Args>(args)...); 10593af6ab5fSopenharmony_ci return res->second; 10603af6ab5fSopenharmony_ci} 10613af6ab5fSopenharmony_ci} // namespace ark::es2panda::varbinder 10623af6ab5fSopenharmony_ci 10633af6ab5fSopenharmony_ci#endif 1064