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#include "scope.h" 173af6ab5fSopenharmony_ci 183af6ab5fSopenharmony_ci#include "varbinder/declaration.h" 193af6ab5fSopenharmony_ci#include "util/helpers.h" 203af6ab5fSopenharmony_ci#include "varbinder/tsBinding.h" 213af6ab5fSopenharmony_ci#include "varbinder/variable.h" 223af6ab5fSopenharmony_ci#include "varbinder/variableFlags.h" 233af6ab5fSopenharmony_ci#include "ir/astNode.h" 243af6ab5fSopenharmony_ci#include "ir/expressions/identifier.h" 253af6ab5fSopenharmony_ci#include "ir/statements/classDeclaration.h" 263af6ab5fSopenharmony_ci#include "ir/base/classDefinition.h" 273af6ab5fSopenharmony_ci#include "ir/base/scriptFunction.h" 283af6ab5fSopenharmony_ci#include "ir/base/classProperty.h" 293af6ab5fSopenharmony_ci#include "ir/base/methodDefinition.h" 303af6ab5fSopenharmony_ci#include "ir/module/exportAllDeclaration.h" 313af6ab5fSopenharmony_ci#include "ir/module/exportNamedDeclaration.h" 323af6ab5fSopenharmony_ci#include "ir/module/exportSpecifier.h" 333af6ab5fSopenharmony_ci#include "ir/module/importDeclaration.h" 343af6ab5fSopenharmony_ci#include "ir/expressions/literals/stringLiteral.h" 353af6ab5fSopenharmony_ci#include "ir/expressions/literals/booleanLiteral.h" 363af6ab5fSopenharmony_ci#include "ir/ts/tsInterfaceDeclaration.h" 373af6ab5fSopenharmony_ci#include "ir/ts/tsEnumDeclaration.h" 383af6ab5fSopenharmony_ci#include "ir/ts/tsTypeAliasDeclaration.h" 393af6ab5fSopenharmony_ci#include "compiler/base/literals.h" 403af6ab5fSopenharmony_ci#include "macros.h" 413af6ab5fSopenharmony_ci#include "util/ustring.h" 423af6ab5fSopenharmony_ci#include "generated/signatures.h" 433af6ab5fSopenharmony_ci#include "public/public.h" 443af6ab5fSopenharmony_ci 453af6ab5fSopenharmony_cinamespace ark::es2panda::varbinder { 463af6ab5fSopenharmony_ciVariableScope *Scope::EnclosingVariableScope() 473af6ab5fSopenharmony_ci{ 483af6ab5fSopenharmony_ci Scope *iter = this; 493af6ab5fSopenharmony_ci 503af6ab5fSopenharmony_ci while (iter != nullptr) { 513af6ab5fSopenharmony_ci if (iter->IsVariableScope()) { 523af6ab5fSopenharmony_ci return iter->AsVariableScope(); 533af6ab5fSopenharmony_ci } 543af6ab5fSopenharmony_ci 553af6ab5fSopenharmony_ci iter = iter->Parent(); 563af6ab5fSopenharmony_ci } 573af6ab5fSopenharmony_ci 583af6ab5fSopenharmony_ci return nullptr; 593af6ab5fSopenharmony_ci} 603af6ab5fSopenharmony_ci 613af6ab5fSopenharmony_ciconst VariableScope *Scope::EnclosingVariableScope() const 623af6ab5fSopenharmony_ci{ 633af6ab5fSopenharmony_ci const auto *iter = this; 643af6ab5fSopenharmony_ci 653af6ab5fSopenharmony_ci while (iter != nullptr) { 663af6ab5fSopenharmony_ci if (iter->IsVariableScope()) { 673af6ab5fSopenharmony_ci return iter->AsVariableScope(); 683af6ab5fSopenharmony_ci } 693af6ab5fSopenharmony_ci 703af6ab5fSopenharmony_ci iter = iter->Parent(); 713af6ab5fSopenharmony_ci } 723af6ab5fSopenharmony_ci 733af6ab5fSopenharmony_ci return nullptr; 743af6ab5fSopenharmony_ci} 753af6ab5fSopenharmony_ci 763af6ab5fSopenharmony_cibool Scope::IsSuperscopeOf(const varbinder::Scope *subscope) const 773af6ab5fSopenharmony_ci{ 783af6ab5fSopenharmony_ci while (subscope != nullptr) { 793af6ab5fSopenharmony_ci if (subscope == this) { 803af6ab5fSopenharmony_ci return true; 813af6ab5fSopenharmony_ci } 823af6ab5fSopenharmony_ci subscope = ir::AstNode::EnclosingScope(subscope->Node()->Parent()); 833af6ab5fSopenharmony_ci } 843af6ab5fSopenharmony_ci return false; 853af6ab5fSopenharmony_ci} 863af6ab5fSopenharmony_ci 873af6ab5fSopenharmony_ci// NOTE(psiket): Duplication 883af6ab5fSopenharmony_ciClassScope *Scope::EnclosingClassScope() 893af6ab5fSopenharmony_ci{ 903af6ab5fSopenharmony_ci Scope *iter = this; 913af6ab5fSopenharmony_ci 923af6ab5fSopenharmony_ci while (iter != nullptr) { 933af6ab5fSopenharmony_ci if (iter->IsClassScope()) { 943af6ab5fSopenharmony_ci return iter->AsClassScope(); 953af6ab5fSopenharmony_ci } 963af6ab5fSopenharmony_ci 973af6ab5fSopenharmony_ci iter = iter->Parent(); 983af6ab5fSopenharmony_ci } 993af6ab5fSopenharmony_ci 1003af6ab5fSopenharmony_ci return nullptr; 1013af6ab5fSopenharmony_ci} 1023af6ab5fSopenharmony_ci 1033af6ab5fSopenharmony_ciconst ClassScope *Scope::EnclosingClassScope() const 1043af6ab5fSopenharmony_ci{ 1053af6ab5fSopenharmony_ci const auto *iter = this; 1063af6ab5fSopenharmony_ci 1073af6ab5fSopenharmony_ci while (iter != nullptr) { 1083af6ab5fSopenharmony_ci if (iter->IsVariableScope()) { 1093af6ab5fSopenharmony_ci return iter->AsClassScope(); 1103af6ab5fSopenharmony_ci } 1113af6ab5fSopenharmony_ci 1123af6ab5fSopenharmony_ci iter = iter->Parent(); 1133af6ab5fSopenharmony_ci } 1143af6ab5fSopenharmony_ci 1153af6ab5fSopenharmony_ci return nullptr; 1163af6ab5fSopenharmony_ci} 1173af6ab5fSopenharmony_ci 1183af6ab5fSopenharmony_ciVariable *Scope::FindLocal(const util::StringView &name, ResolveBindingOptions options) const 1193af6ab5fSopenharmony_ci{ 1203af6ab5fSopenharmony_ci if ((options & ResolveBindingOptions::INTERFACES) != 0) { 1213af6ab5fSopenharmony_ci std::string tsBindingName = varbinder::TSBinding::ToTSBinding(name); 1223af6ab5fSopenharmony_ci util::StringView interfaceNameView(tsBindingName); 1233af6ab5fSopenharmony_ci 1243af6ab5fSopenharmony_ci auto res = bindings_.find(interfaceNameView); 1253af6ab5fSopenharmony_ci if (res != bindings_.end()) { 1263af6ab5fSopenharmony_ci return res->second; 1273af6ab5fSopenharmony_ci } 1283af6ab5fSopenharmony_ci 1293af6ab5fSopenharmony_ci if ((options & ResolveBindingOptions::BINDINGS) == 0) { 1303af6ab5fSopenharmony_ci return nullptr; 1313af6ab5fSopenharmony_ci } 1323af6ab5fSopenharmony_ci } 1333af6ab5fSopenharmony_ci 1343af6ab5fSopenharmony_ci auto res = bindings_.find(name); 1353af6ab5fSopenharmony_ci if (res == bindings_.end()) { 1363af6ab5fSopenharmony_ci return nullptr; 1373af6ab5fSopenharmony_ci } 1383af6ab5fSopenharmony_ci 1393af6ab5fSopenharmony_ci return res->second; 1403af6ab5fSopenharmony_ci} 1413af6ab5fSopenharmony_ci 1423af6ab5fSopenharmony_ciScope::InsertResult Scope::InsertBinding(const util::StringView &name, Variable *const var) 1433af6ab5fSopenharmony_ci{ 1443af6ab5fSopenharmony_ci ASSERT(var != nullptr); 1453af6ab5fSopenharmony_ci auto insertResult = bindings_.emplace(name, var); 1463af6ab5fSopenharmony_ci if (insertResult.second) { 1473af6ab5fSopenharmony_ci decls_.push_back(var->Declaration()); 1483af6ab5fSopenharmony_ci } 1493af6ab5fSopenharmony_ci 1503af6ab5fSopenharmony_ci return insertResult; 1513af6ab5fSopenharmony_ci} 1523af6ab5fSopenharmony_ci 1533af6ab5fSopenharmony_ciScope::InsertResult Scope::TryInsertBinding(const util::StringView &name, Variable *const var) 1543af6ab5fSopenharmony_ci{ 1553af6ab5fSopenharmony_ci ASSERT(var != nullptr); 1563af6ab5fSopenharmony_ci return bindings_.try_emplace(name, var); 1573af6ab5fSopenharmony_ci} 1583af6ab5fSopenharmony_ci 1593af6ab5fSopenharmony_civoid Scope::MergeBindings(VariableMap const &bindings) 1603af6ab5fSopenharmony_ci{ 1613af6ab5fSopenharmony_ci for (auto &[k, v] : bindings) { 1623af6ab5fSopenharmony_ci bindings_.try_emplace(k, v); 1633af6ab5fSopenharmony_ci } 1643af6ab5fSopenharmony_ci} 1653af6ab5fSopenharmony_ci 1663af6ab5fSopenharmony_ciScope::VariableMap::size_type Scope::EraseBinding(const util::StringView &name) 1673af6ab5fSopenharmony_ci{ 1683af6ab5fSopenharmony_ci if (auto toBeErased = bindings_.find(name); 1693af6ab5fSopenharmony_ci toBeErased == bindings_.end() || 1703af6ab5fSopenharmony_ci (toBeErased->second->IsLocalVariable() && 1713af6ab5fSopenharmony_ci toBeErased->second->AsLocalVariable()->Declaration()->Node()->IsImportNamespaceSpecifier())) { 1723af6ab5fSopenharmony_ci return 0; 1733af6ab5fSopenharmony_ci } 1743af6ab5fSopenharmony_ci 1753af6ab5fSopenharmony_ci return bindings_.erase(name); 1763af6ab5fSopenharmony_ci} 1773af6ab5fSopenharmony_ci 1783af6ab5fSopenharmony_ciConstScopeFindResult Scope::FindInGlobal(const util::StringView &name, const ResolveBindingOptions options) const 1793af6ab5fSopenharmony_ci{ 1803af6ab5fSopenharmony_ci const auto *scopeIter = this; 1813af6ab5fSopenharmony_ci const auto *scopeParent = this->Parent(); 1823af6ab5fSopenharmony_ci // One scope below true global is ETSGLOBAL 1833af6ab5fSopenharmony_ci while (scopeParent != nullptr && !scopeParent->IsGlobalScope()) { 1843af6ab5fSopenharmony_ci scopeIter = scopeParent; 1853af6ab5fSopenharmony_ci scopeParent = scopeIter->Parent(); 1863af6ab5fSopenharmony_ci } 1873af6ab5fSopenharmony_ci 1883af6ab5fSopenharmony_ci auto *resolved = scopeIter->FindLocal(name, options); 1893af6ab5fSopenharmony_ci if (resolved == nullptr && scopeParent != nullptr) { 1903af6ab5fSopenharmony_ci // If the variable cannot be found in the scope of the local ETSGLOBAL, than we still need to check the true 1913af6ab5fSopenharmony_ci // global scope which contains all the imported ETSGLOBALs 1923af6ab5fSopenharmony_ci resolved = scopeParent->FindLocal(name, options); 1933af6ab5fSopenharmony_ci } 1943af6ab5fSopenharmony_ci 1953af6ab5fSopenharmony_ci return {name, scopeIter, 0, 0, resolved}; 1963af6ab5fSopenharmony_ci} 1973af6ab5fSopenharmony_ci 1983af6ab5fSopenharmony_ciConstScopeFindResult Scope::FindInFunctionScope(const util::StringView &name, const ResolveBindingOptions options) const 1993af6ab5fSopenharmony_ci{ 2003af6ab5fSopenharmony_ci const auto *scopeIter = this; 2013af6ab5fSopenharmony_ci while (scopeIter != nullptr && !scopeIter->IsGlobalScope()) { 2023af6ab5fSopenharmony_ci if (!scopeIter->IsClassScope()) { 2033af6ab5fSopenharmony_ci if (auto *const resolved = scopeIter->FindLocal(name, options); resolved != nullptr) { 2043af6ab5fSopenharmony_ci return ConstScopeFindResult(name, scopeIter, 0, 0, resolved); 2053af6ab5fSopenharmony_ci } 2063af6ab5fSopenharmony_ci } 2073af6ab5fSopenharmony_ci scopeIter = scopeIter->Parent(); 2083af6ab5fSopenharmony_ci } 2093af6ab5fSopenharmony_ci 2103af6ab5fSopenharmony_ci return ConstScopeFindResult(name, scopeIter, 0, 0, nullptr); 2113af6ab5fSopenharmony_ci} 2123af6ab5fSopenharmony_ci 2133af6ab5fSopenharmony_ciScopeFindResult Scope::Find(const util::StringView &name, const ResolveBindingOptions options) 2143af6ab5fSopenharmony_ci{ 2153af6ab5fSopenharmony_ci return FindImpl<ScopeFindResult>(this, name, options); 2163af6ab5fSopenharmony_ci} 2173af6ab5fSopenharmony_ci 2183af6ab5fSopenharmony_ciConstScopeFindResult Scope::Find(const util::StringView &name, const ResolveBindingOptions options) const 2193af6ab5fSopenharmony_ci{ 2203af6ab5fSopenharmony_ci return FindImpl<ConstScopeFindResult>(this, name, options); 2213af6ab5fSopenharmony_ci} 2223af6ab5fSopenharmony_ci 2233af6ab5fSopenharmony_ciDecl *Scope::FindDecl(const util::StringView &name) const 2243af6ab5fSopenharmony_ci{ 2253af6ab5fSopenharmony_ci for (auto *it : decls_) { 2263af6ab5fSopenharmony_ci if (it->Name() == name) { 2273af6ab5fSopenharmony_ci return it; 2283af6ab5fSopenharmony_ci } 2293af6ab5fSopenharmony_ci } 2303af6ab5fSopenharmony_ci 2313af6ab5fSopenharmony_ci return nullptr; 2323af6ab5fSopenharmony_ci} 2333af6ab5fSopenharmony_ci 2343af6ab5fSopenharmony_cistd::tuple<Scope *, bool> Scope::IterateShadowedVariables(const util::StringView &name, const VariableVisitor &visitor) 2353af6ab5fSopenharmony_ci{ 2363af6ab5fSopenharmony_ci auto *iter = this; 2373af6ab5fSopenharmony_ci 2383af6ab5fSopenharmony_ci while (iter != nullptr) { 2393af6ab5fSopenharmony_ci auto *v = iter->FindLocal(name, varbinder::ResolveBindingOptions::BINDINGS); 2403af6ab5fSopenharmony_ci 2413af6ab5fSopenharmony_ci if (v != nullptr && visitor(v)) { 2423af6ab5fSopenharmony_ci return {iter, true}; 2433af6ab5fSopenharmony_ci } 2443af6ab5fSopenharmony_ci 2453af6ab5fSopenharmony_ci if (iter->IsFunctionVariableScope()) { 2463af6ab5fSopenharmony_ci break; 2473af6ab5fSopenharmony_ci } 2483af6ab5fSopenharmony_ci 2493af6ab5fSopenharmony_ci iter = iter->Parent(); 2503af6ab5fSopenharmony_ci } 2513af6ab5fSopenharmony_ci 2523af6ab5fSopenharmony_ci return {iter, false}; 2533af6ab5fSopenharmony_ci} 2543af6ab5fSopenharmony_ci 2553af6ab5fSopenharmony_ciVariable *Scope::AddLocalVar(ArenaAllocator *allocator, Decl *newDecl) 2563af6ab5fSopenharmony_ci{ 2573af6ab5fSopenharmony_ci auto [scope, shadowed] = 2583af6ab5fSopenharmony_ci IterateShadowedVariables(newDecl->Name(), [](const Variable *v) { return !v->HasFlag(VariableFlags::VAR); }); 2593af6ab5fSopenharmony_ci 2603af6ab5fSopenharmony_ci if (shadowed) { 2613af6ab5fSopenharmony_ci return nullptr; 2623af6ab5fSopenharmony_ci } 2633af6ab5fSopenharmony_ci 2643af6ab5fSopenharmony_ci VariableFlags varFlags = VariableFlags::HOIST_VAR | VariableFlags::LEXICAL_VAR; 2653af6ab5fSopenharmony_ci if (scope->IsGlobalScope()) { 2663af6ab5fSopenharmony_ci return scope->InsertBinding(newDecl->Name(), allocator->New<GlobalVariable>(newDecl, varFlags)).first->second; 2673af6ab5fSopenharmony_ci } 2683af6ab5fSopenharmony_ci 2693af6ab5fSopenharmony_ci return scope->PropagateBinding<LocalVariable>(allocator, newDecl->Name(), newDecl, varFlags); 2703af6ab5fSopenharmony_ci} 2713af6ab5fSopenharmony_ci 2723af6ab5fSopenharmony_ciVariable *Scope::AddLocal(ArenaAllocator *allocator, Variable *currentVariable, Decl *newDecl, 2733af6ab5fSopenharmony_ci [[maybe_unused]] ScriptExtension extension) 2743af6ab5fSopenharmony_ci{ 2753af6ab5fSopenharmony_ci VariableFlags flags = VariableFlags::LEXICAL; 2763af6ab5fSopenharmony_ci switch (newDecl->Type()) { 2773af6ab5fSopenharmony_ci case DeclType::VAR: { 2783af6ab5fSopenharmony_ci return AddLocalVar(allocator, newDecl); 2793af6ab5fSopenharmony_ci } 2803af6ab5fSopenharmony_ci case DeclType::ENUM: { 2813af6ab5fSopenharmony_ci return bindings_.insert({newDecl->Name(), allocator->New<EnumVariable>(newDecl, false)}).first->second; 2823af6ab5fSopenharmony_ci } 2833af6ab5fSopenharmony_ci case DeclType::ENUM_LITERAL: { 2843af6ab5fSopenharmony_ci return bindings_ 2853af6ab5fSopenharmony_ci .insert({newDecl->Name(), allocator->New<LocalVariable>(newDecl, VariableFlags::ENUM_LITERAL)}) 2863af6ab5fSopenharmony_ci .first->second; 2873af6ab5fSopenharmony_ci } 2883af6ab5fSopenharmony_ci case DeclType::INTERFACE: { 2893af6ab5fSopenharmony_ci return bindings_.insert({newDecl->Name(), allocator->New<LocalVariable>(newDecl, VariableFlags::INTERFACE)}) 2903af6ab5fSopenharmony_ci .first->second; 2913af6ab5fSopenharmony_ci } 2923af6ab5fSopenharmony_ci case DeclType::CLASS: { 2933af6ab5fSopenharmony_ci return bindings_.insert({newDecl->Name(), allocator->New<LocalVariable>(newDecl, VariableFlags::CLASS)}) 2943af6ab5fSopenharmony_ci .first->second; 2953af6ab5fSopenharmony_ci } 2963af6ab5fSopenharmony_ci case DeclType::TYPE_PARAMETER: { 2973af6ab5fSopenharmony_ci return bindings_ 2983af6ab5fSopenharmony_ci .insert({newDecl->Name(), allocator->New<LocalVariable>(newDecl, VariableFlags::TYPE_PARAMETER)}) 2993af6ab5fSopenharmony_ci .first->second; 3003af6ab5fSopenharmony_ci } 3013af6ab5fSopenharmony_ci case DeclType::FUNC: { 3023af6ab5fSopenharmony_ci flags = VariableFlags::HOIST; 3033af6ab5fSopenharmony_ci [[fallthrough]]; 3043af6ab5fSopenharmony_ci } 3053af6ab5fSopenharmony_ci default: { 3063af6ab5fSopenharmony_ci if (currentVariable != nullptr) { 3073af6ab5fSopenharmony_ci return nullptr; 3083af6ab5fSopenharmony_ci } 3093af6ab5fSopenharmony_ci 3103af6ab5fSopenharmony_ci auto [_, shadowed] = IterateShadowedVariables( 3113af6ab5fSopenharmony_ci newDecl->Name(), [](const Variable *v) { return v->HasFlag(VariableFlags::LEXICAL_VAR); }); 3123af6ab5fSopenharmony_ci (void)_; 3133af6ab5fSopenharmony_ci 3143af6ab5fSopenharmony_ci if (shadowed) { 3153af6ab5fSopenharmony_ci return nullptr; 3163af6ab5fSopenharmony_ci } 3173af6ab5fSopenharmony_ci 3183af6ab5fSopenharmony_ci return bindings_.insert({newDecl->Name(), allocator->New<LocalVariable>(newDecl, flags)}).first->second; 3193af6ab5fSopenharmony_ci } 3203af6ab5fSopenharmony_ci } 3213af6ab5fSopenharmony_ci} 3223af6ab5fSopenharmony_ci 3233af6ab5fSopenharmony_civoid VariableScope::CheckDirectEval(public_lib::Context *context) 3243af6ab5fSopenharmony_ci{ 3253af6ab5fSopenharmony_ci ASSERT(context); 3263af6ab5fSopenharmony_ci const auto &varMap = Bindings(); 3273af6ab5fSopenharmony_ci 3283af6ab5fSopenharmony_ci if (!HasFlag(ScopeFlags::NO_REG_STORE) || varMap.empty()) { 3293af6ab5fSopenharmony_ci evalBindings_ = compiler::INVALID_LITERAL_BUFFER_ID; 3303af6ab5fSopenharmony_ci return; 3313af6ab5fSopenharmony_ci } 3323af6ab5fSopenharmony_ci 3333af6ab5fSopenharmony_ci size_t constBindings = 0; 3343af6ab5fSopenharmony_ci for (const auto &[name, var] : varMap) { 3353af6ab5fSopenharmony_ci (void)name; 3363af6ab5fSopenharmony_ci var->SetLexical(this); 3373af6ab5fSopenharmony_ci 3383af6ab5fSopenharmony_ci if (var->LexicalBound() && var->Declaration()->IsConstDecl()) { 3393af6ab5fSopenharmony_ci constBindings++; 3403af6ab5fSopenharmony_ci } 3413af6ab5fSopenharmony_ci } 3423af6ab5fSopenharmony_ci 3433af6ab5fSopenharmony_ci std::vector<compiler::Literal> literals(LexicalSlots() + constBindings, compiler::Literal(util::StringView())); 3443af6ab5fSopenharmony_ci 3453af6ab5fSopenharmony_ci if (constBindings == 0U) { 3463af6ab5fSopenharmony_ci for (const auto &[name, variable] : varMap) { 3473af6ab5fSopenharmony_ci if (!variable->LexicalBound()) { 3483af6ab5fSopenharmony_ci continue; 3493af6ab5fSopenharmony_ci } 3503af6ab5fSopenharmony_ci 3513af6ab5fSopenharmony_ci literals[variable->AsLocalVariable()->LexIdx()] = compiler::Literal(name); 3523af6ab5fSopenharmony_ci } 3533af6ab5fSopenharmony_ci } else { 3543af6ab5fSopenharmony_ci std::vector<varbinder::Variable *> bindings(LexicalSlots()); 3553af6ab5fSopenharmony_ci 3563af6ab5fSopenharmony_ci for (const auto &[name, variable] : varMap) { 3573af6ab5fSopenharmony_ci (void)name; 3583af6ab5fSopenharmony_ci if (!variable->LexicalBound()) { 3593af6ab5fSopenharmony_ci continue; 3603af6ab5fSopenharmony_ci } 3613af6ab5fSopenharmony_ci 3623af6ab5fSopenharmony_ci bindings[variable->AsLocalVariable()->LexIdx()] = variable; 3633af6ab5fSopenharmony_ci } 3643af6ab5fSopenharmony_ci 3653af6ab5fSopenharmony_ci uint32_t buffIndex = 0; 3663af6ab5fSopenharmony_ci for (const auto *variable : bindings) { 3673af6ab5fSopenharmony_ci if (variable == nullptr) { 3683af6ab5fSopenharmony_ci ASSERT(literals[buffIndex].GetString().empty()); 3693af6ab5fSopenharmony_ci buffIndex++; 3703af6ab5fSopenharmony_ci continue; 3713af6ab5fSopenharmony_ci } 3723af6ab5fSopenharmony_ci if (variable->Declaration()->IsConstDecl()) { 3733af6ab5fSopenharmony_ci literals[buffIndex++] = compiler::Literal(true); 3743af6ab5fSopenharmony_ci } 3753af6ab5fSopenharmony_ci literals[buffIndex++] = compiler::Literal(variable->Name()); 3763af6ab5fSopenharmony_ci } 3773af6ab5fSopenharmony_ci } 3783af6ab5fSopenharmony_ci context->contextLiterals.emplace_back(literals); 3793af6ab5fSopenharmony_ci evalBindings_ = context->contextLiterals.size() - 1; 3803af6ab5fSopenharmony_ci} 3813af6ab5fSopenharmony_ci 3823af6ab5fSopenharmony_ciVariable *ParamScope::AddParam(ArenaAllocator *allocator, Variable *currentVariable, Decl *newDecl, VariableFlags flags) 3833af6ab5fSopenharmony_ci{ 3843af6ab5fSopenharmony_ci ASSERT(newDecl->IsParameterDecl()); 3853af6ab5fSopenharmony_ci 3863af6ab5fSopenharmony_ci if (currentVariable != nullptr) { 3873af6ab5fSopenharmony_ci return nullptr; 3883af6ab5fSopenharmony_ci } 3893af6ab5fSopenharmony_ci 3903af6ab5fSopenharmony_ci auto *param = allocator->New<LocalVariable>(newDecl, flags); 3913af6ab5fSopenharmony_ci param->SetScope(this); 3923af6ab5fSopenharmony_ci 3933af6ab5fSopenharmony_ci params_.push_back(param); 3943af6ab5fSopenharmony_ci InsertBinding(newDecl->Name(), param); 3953af6ab5fSopenharmony_ci return param; 3963af6ab5fSopenharmony_ci} 3973af6ab5fSopenharmony_ci 3983af6ab5fSopenharmony_cistd::tuple<ParameterDecl *, ir::AstNode *, Variable *> ParamScope::AddParamDecl(ArenaAllocator *allocator, 3993af6ab5fSopenharmony_ci ir::AstNode *param) 4003af6ab5fSopenharmony_ci{ 4013af6ab5fSopenharmony_ci const auto [name, pattern] = util::Helpers::ParamName(allocator, param, params_.size()); 4023af6ab5fSopenharmony_ci 4033af6ab5fSopenharmony_ci auto *decl = NewDecl<ParameterDecl>(allocator, name); 4043af6ab5fSopenharmony_ci auto *var = AddParam(allocator, FindLocal(name, varbinder::ResolveBindingOptions::BINDINGS), decl, 4053af6ab5fSopenharmony_ci VariableFlags::VAR | VariableFlags::LOCAL); 4063af6ab5fSopenharmony_ci 4073af6ab5fSopenharmony_ci if (var == nullptr) { 4083af6ab5fSopenharmony_ci return {decl, param, nullptr}; 4093af6ab5fSopenharmony_ci } 4103af6ab5fSopenharmony_ci 4113af6ab5fSopenharmony_ci if (!pattern) { 4123af6ab5fSopenharmony_ci decl->BindNode(param); 4133af6ab5fSopenharmony_ci return {decl, nullptr, var}; 4143af6ab5fSopenharmony_ci } 4153af6ab5fSopenharmony_ci 4163af6ab5fSopenharmony_ci std::vector<ir::Identifier *> bindings = util::Helpers::CollectBindingNames(param); 4173af6ab5fSopenharmony_ci 4183af6ab5fSopenharmony_ci for (auto *binding : bindings) { 4193af6ab5fSopenharmony_ci auto *varDecl = NewDecl<VarDecl>(allocator, binding->Name()); 4203af6ab5fSopenharmony_ci varDecl->BindNode(binding); 4213af6ab5fSopenharmony_ci 4223af6ab5fSopenharmony_ci if (FindLocal(varDecl->Name(), varbinder::ResolveBindingOptions::BINDINGS) != nullptr) { 4233af6ab5fSopenharmony_ci return {decl, binding, nullptr}; 4243af6ab5fSopenharmony_ci } 4253af6ab5fSopenharmony_ci 4263af6ab5fSopenharmony_ci auto *paramVar = allocator->New<LocalVariable>(varDecl, VariableFlags::VAR | VariableFlags::LOCAL); 4273af6ab5fSopenharmony_ci TryInsertBinding(varDecl->Name(), paramVar); 4283af6ab5fSopenharmony_ci } 4293af6ab5fSopenharmony_ci 4303af6ab5fSopenharmony_ci return {decl, nullptr, var}; 4313af6ab5fSopenharmony_ci} 4323af6ab5fSopenharmony_ci 4333af6ab5fSopenharmony_civoid FunctionParamScope::BindName(ArenaAllocator *allocator, util::StringView name) 4343af6ab5fSopenharmony_ci{ 4353af6ab5fSopenharmony_ci nameVar_ = AddDecl<ConstDecl, LocalVariable>(allocator, name, VariableFlags::INITIALIZED); 4363af6ab5fSopenharmony_ci if (!functionScope_->InsertBinding(name, nameVar_).second) { 4373af6ab5fSopenharmony_ci nameVar_ = nullptr; 4383af6ab5fSopenharmony_ci } 4393af6ab5fSopenharmony_ci} 4403af6ab5fSopenharmony_ci 4413af6ab5fSopenharmony_ciVariable *FunctionParamScope::AddBinding([[maybe_unused]] ArenaAllocator *allocator, 4423af6ab5fSopenharmony_ci [[maybe_unused]] Variable *currentVariable, [[maybe_unused]] Decl *newDecl, 4433af6ab5fSopenharmony_ci [[maybe_unused]] ScriptExtension extension) 4443af6ab5fSopenharmony_ci{ 4453af6ab5fSopenharmony_ci UNREACHABLE(); 4463af6ab5fSopenharmony_ci} 4473af6ab5fSopenharmony_ci 4483af6ab5fSopenharmony_ciVariable *FunctionScope::AddBinding(ArenaAllocator *allocator, Variable *currentVariable, Decl *newDecl, 4493af6ab5fSopenharmony_ci [[maybe_unused]] ScriptExtension extension) 4503af6ab5fSopenharmony_ci{ 4513af6ab5fSopenharmony_ci ir::Identifier *ident {}; 4523af6ab5fSopenharmony_ci Variable *var {}; 4533af6ab5fSopenharmony_ci switch (newDecl->Type()) { 4543af6ab5fSopenharmony_ci case DeclType::VAR: { 4553af6ab5fSopenharmony_ci return AddVar<LocalVariable>(allocator, currentVariable, newDecl); 4563af6ab5fSopenharmony_ci } 4573af6ab5fSopenharmony_ci case DeclType::FUNC: { 4583af6ab5fSopenharmony_ci return AddFunction<LocalVariable>(allocator, currentVariable, newDecl, extension); 4593af6ab5fSopenharmony_ci } 4603af6ab5fSopenharmony_ci case DeclType::ENUM: { 4613af6ab5fSopenharmony_ci return InsertBinding(newDecl->Name(), allocator->New<EnumVariable>(newDecl, false)).first->second; 4623af6ab5fSopenharmony_ci } 4633af6ab5fSopenharmony_ci case DeclType::ENUM_LITERAL: { 4643af6ab5fSopenharmony_ci return AddTSBinding<LocalVariable>(allocator, currentVariable, newDecl, VariableFlags::ENUM_LITERAL); 4653af6ab5fSopenharmony_ci } 4663af6ab5fSopenharmony_ci // NOTE(psiket):Duplication 4673af6ab5fSopenharmony_ci case DeclType::INTERFACE: { 4683af6ab5fSopenharmony_ci ident = newDecl->Node()->AsTSInterfaceDeclaration()->Id(); 4693af6ab5fSopenharmony_ci auto interfaceVar = allocator->New<LocalVariable>(newDecl, VariableFlags::INTERFACE); 4703af6ab5fSopenharmony_ci var = InsertBinding(newDecl->Name(), interfaceVar).first->second; 4713af6ab5fSopenharmony_ci break; 4723af6ab5fSopenharmony_ci } 4733af6ab5fSopenharmony_ci case DeclType::CLASS: { 4743af6ab5fSopenharmony_ci ident = newDecl->Node()->AsClassDefinition()->Ident(); 4753af6ab5fSopenharmony_ci auto classVar = allocator->New<LocalVariable>(newDecl, VariableFlags::CLASS); 4763af6ab5fSopenharmony_ci var = InsertBinding(newDecl->Name(), classVar).first->second; 4773af6ab5fSopenharmony_ci break; 4783af6ab5fSopenharmony_ci } 4793af6ab5fSopenharmony_ci case DeclType::TYPE_ALIAS: { 4803af6ab5fSopenharmony_ci ident = newDecl->Node()->AsTSTypeAliasDeclaration()->Id(); 4813af6ab5fSopenharmony_ci var = typeAliasScope_->AddBinding(allocator, currentVariable, newDecl, extension); 4823af6ab5fSopenharmony_ci break; 4833af6ab5fSopenharmony_ci } 4843af6ab5fSopenharmony_ci default: { 4853af6ab5fSopenharmony_ci return AddLexical<LocalVariable>(allocator, currentVariable, newDecl); 4863af6ab5fSopenharmony_ci } 4873af6ab5fSopenharmony_ci } 4883af6ab5fSopenharmony_ci if (var != nullptr) { 4893af6ab5fSopenharmony_ci var->SetScope(this); 4903af6ab5fSopenharmony_ci if (ident != nullptr) { 4913af6ab5fSopenharmony_ci ident->SetVariable(var); 4923af6ab5fSopenharmony_ci } 4933af6ab5fSopenharmony_ci } 4943af6ab5fSopenharmony_ci return var; 4953af6ab5fSopenharmony_ci} 4963af6ab5fSopenharmony_ci 4973af6ab5fSopenharmony_ciVariable *GlobalScope::AddBinding(ArenaAllocator *allocator, Variable *currentVariable, Decl *newDecl, 4983af6ab5fSopenharmony_ci [[maybe_unused]] ScriptExtension extension) 4993af6ab5fSopenharmony_ci{ 5003af6ab5fSopenharmony_ci switch (newDecl->Type()) { 5013af6ab5fSopenharmony_ci case DeclType::VAR: { 5023af6ab5fSopenharmony_ci return AddVar<GlobalVariable>(allocator, currentVariable, newDecl); 5033af6ab5fSopenharmony_ci } 5043af6ab5fSopenharmony_ci case DeclType::FUNC: { 5053af6ab5fSopenharmony_ci return AddFunction<GlobalVariable>(allocator, currentVariable, newDecl, extension); 5063af6ab5fSopenharmony_ci } 5073af6ab5fSopenharmony_ci case DeclType::ENUM: { 5083af6ab5fSopenharmony_ci return InsertBinding(newDecl->Name(), allocator->New<EnumVariable>(newDecl, false)).first->second; 5093af6ab5fSopenharmony_ci } 5103af6ab5fSopenharmony_ci case DeclType::ENUM_LITERAL: { 5113af6ab5fSopenharmony_ci return AddTSBinding<LocalVariable>(allocator, currentVariable, newDecl, VariableFlags::ENUM_LITERAL); 5123af6ab5fSopenharmony_ci } 5133af6ab5fSopenharmony_ci case DeclType::INTERFACE: { 5143af6ab5fSopenharmony_ci return AddTSBinding<LocalVariable>(allocator, currentVariable, newDecl, VariableFlags::INTERFACE); 5153af6ab5fSopenharmony_ci } 5163af6ab5fSopenharmony_ci default: { 5173af6ab5fSopenharmony_ci return AddLexical<LocalVariable>(allocator, currentVariable, newDecl); 5183af6ab5fSopenharmony_ci } 5193af6ab5fSopenharmony_ci } 5203af6ab5fSopenharmony_ci} 5213af6ab5fSopenharmony_ci 5223af6ab5fSopenharmony_ciScope::InsertResult GlobalScope::InsertBinding(const util::StringView &name, Variable *const var) 5233af6ab5fSopenharmony_ci{ 5243af6ab5fSopenharmony_ci return GlobalScope::InsertImpl(name, var, false, false); 5253af6ab5fSopenharmony_ci} 5263af6ab5fSopenharmony_ci 5273af6ab5fSopenharmony_ciScope::InsertResult GlobalScope::TryInsertBinding(const util::StringView &name, Variable *const var) 5283af6ab5fSopenharmony_ci{ 5293af6ab5fSopenharmony_ci const auto insRes = Scope::TryInsertBinding(name, var); 5303af6ab5fSopenharmony_ci if (insRes.second) { 5313af6ab5fSopenharmony_ci [[maybe_unused]] const bool insertSuccess = std::get<1>(foreignBindings_.try_emplace(name, var)); 5323af6ab5fSopenharmony_ci ASSERT(insertSuccess); 5333af6ab5fSopenharmony_ci } 5343af6ab5fSopenharmony_ci 5353af6ab5fSopenharmony_ci return insRes; 5363af6ab5fSopenharmony_ci} 5373af6ab5fSopenharmony_ci 5383af6ab5fSopenharmony_civoid GlobalScope::MergeBindings([[maybe_unused]] const VariableMap &bindings) 5393af6ab5fSopenharmony_ci{ 5403af6ab5fSopenharmony_ci UNREACHABLE(); 5413af6ab5fSopenharmony_ci} 5423af6ab5fSopenharmony_ci 5433af6ab5fSopenharmony_ciScope::VariableMap::size_type GlobalScope::EraseBinding(const util::StringView &name) 5443af6ab5fSopenharmony_ci{ 5453af6ab5fSopenharmony_ci const auto erased = Scope::EraseBinding(name); 5463af6ab5fSopenharmony_ci if (erased != 0) { 5473af6ab5fSopenharmony_ci [[maybe_unused]] const auto erasedForeign = foreignBindings_.erase(name); 5483af6ab5fSopenharmony_ci ASSERT(erasedForeign != 0); 5493af6ab5fSopenharmony_ci } 5503af6ab5fSopenharmony_ci 5513af6ab5fSopenharmony_ci return erased; 5523af6ab5fSopenharmony_ci} 5533af6ab5fSopenharmony_ci 5543af6ab5fSopenharmony_ciScope::InsertResult GlobalScope::InsertForeignBinding(const util::StringView &name, Variable *const var) 5553af6ab5fSopenharmony_ci{ 5563af6ab5fSopenharmony_ci return GlobalScope::InsertImpl(name, var, true, false); 5573af6ab5fSopenharmony_ci} 5583af6ab5fSopenharmony_ci 5593af6ab5fSopenharmony_ciScope::InsertResult GlobalScope::InsertImpl(const util::StringView &name, Variable *const var, const bool isForeign, 5603af6ab5fSopenharmony_ci const bool isDynamic) 5613af6ab5fSopenharmony_ci{ 5623af6ab5fSopenharmony_ci if (!isDynamic && isForeign && !var->Declaration()->Name().Is(compiler::Signatures::ETS_GLOBAL)) { 5633af6ab5fSopenharmony_ci const auto *const node = var->Declaration()->Node(); 5643af6ab5fSopenharmony_ci 5653af6ab5fSopenharmony_ci if (!(node->IsExported() || node->IsDefaultExported() || node->IsExportedType())) { 5663af6ab5fSopenharmony_ci return Scope::InsertResult {Bindings().end(), false}; 5673af6ab5fSopenharmony_ci } 5683af6ab5fSopenharmony_ci } 5693af6ab5fSopenharmony_ci 5703af6ab5fSopenharmony_ci const auto insRes = Scope::InsertBinding(name, var); 5713af6ab5fSopenharmony_ci if (insRes.second) { 5723af6ab5fSopenharmony_ci [[maybe_unused]] const bool insertSuccess = std::get<1>(foreignBindings_.emplace(name, isForeign)); 5733af6ab5fSopenharmony_ci ASSERT(insertSuccess); 5743af6ab5fSopenharmony_ci } 5753af6ab5fSopenharmony_ci 5763af6ab5fSopenharmony_ci return insRes; 5773af6ab5fSopenharmony_ci} 5783af6ab5fSopenharmony_ci 5793af6ab5fSopenharmony_cibool GlobalScope::IsForeignBinding(const util::StringView &name) const 5803af6ab5fSopenharmony_ci{ 5813af6ab5fSopenharmony_ci // Asserts make sure that the passed in key comes from this scope 5823af6ab5fSopenharmony_ci ASSERT(Bindings().find(name) != Bindings().end()); 5833af6ab5fSopenharmony_ci ASSERT(foreignBindings_.find(name) != foreignBindings_.end()); 5843af6ab5fSopenharmony_ci 5853af6ab5fSopenharmony_ci return foreignBindings_.at(name); 5863af6ab5fSopenharmony_ci} 5873af6ab5fSopenharmony_ci 5883af6ab5fSopenharmony_ciScope::InsertResult GlobalScope::InsertDynamicBinding(const util::StringView &name, Variable *const var) 5893af6ab5fSopenharmony_ci{ 5903af6ab5fSopenharmony_ci return InsertImpl(name, var, true, true); 5913af6ab5fSopenharmony_ci} 5923af6ab5fSopenharmony_ci 5933af6ab5fSopenharmony_ci// ModuleScope 5943af6ab5fSopenharmony_ci 5953af6ab5fSopenharmony_ciVariable *ModuleScope::AddBinding(ArenaAllocator *allocator, Variable *currentVariable, Decl *newDecl, 5963af6ab5fSopenharmony_ci [[maybe_unused]] ScriptExtension extension) 5973af6ab5fSopenharmony_ci{ 5983af6ab5fSopenharmony_ci switch (newDecl->Type()) { 5993af6ab5fSopenharmony_ci case DeclType::VAR: { 6003af6ab5fSopenharmony_ci return AddVar<LocalVariable>(allocator, currentVariable, newDecl); 6013af6ab5fSopenharmony_ci } 6023af6ab5fSopenharmony_ci case DeclType::FUNC: { 6033af6ab5fSopenharmony_ci return AddFunction<LocalVariable>(allocator, currentVariable, newDecl, extension); 6043af6ab5fSopenharmony_ci } 6053af6ab5fSopenharmony_ci case DeclType::ENUM: { 6063af6ab5fSopenharmony_ci return InsertBinding(newDecl->Name(), allocator->New<EnumVariable>(newDecl, false)).first->second; 6073af6ab5fSopenharmony_ci } 6083af6ab5fSopenharmony_ci case DeclType::ENUM_LITERAL: { 6093af6ab5fSopenharmony_ci return AddTSBinding<LocalVariable>(allocator, currentVariable, newDecl, VariableFlags::ENUM_LITERAL); 6103af6ab5fSopenharmony_ci } 6113af6ab5fSopenharmony_ci case DeclType::INTERFACE: { 6123af6ab5fSopenharmony_ci return AddTSBinding<LocalVariable>(allocator, currentVariable, newDecl, VariableFlags::INTERFACE); 6133af6ab5fSopenharmony_ci } 6143af6ab5fSopenharmony_ci case DeclType::IMPORT: { 6153af6ab5fSopenharmony_ci return AddImport(allocator, currentVariable, newDecl); 6163af6ab5fSopenharmony_ci } 6173af6ab5fSopenharmony_ci case DeclType::EXPORT: { 6183af6ab5fSopenharmony_ci return allocator->New<LocalVariable>(newDecl, VariableFlags::NONE); 6193af6ab5fSopenharmony_ci } 6203af6ab5fSopenharmony_ci default: { 6213af6ab5fSopenharmony_ci return AddLexical<LocalVariable>(allocator, currentVariable, newDecl); 6223af6ab5fSopenharmony_ci } 6233af6ab5fSopenharmony_ci } 6243af6ab5fSopenharmony_ci} 6253af6ab5fSopenharmony_ci 6263af6ab5fSopenharmony_civoid ModuleScope::AddImportDecl(ir::ImportDeclaration *importDecl, ImportDeclList &&decls) 6273af6ab5fSopenharmony_ci{ 6283af6ab5fSopenharmony_ci auto res = imports_.emplace_back(importDecl, decls); 6293af6ab5fSopenharmony_ci 6303af6ab5fSopenharmony_ci for (auto &decl : res.second) { 6313af6ab5fSopenharmony_ci decl->BindNode(importDecl); 6323af6ab5fSopenharmony_ci } 6333af6ab5fSopenharmony_ci} 6343af6ab5fSopenharmony_ci 6353af6ab5fSopenharmony_civoid ModuleScope::AddExportDecl(ir::AstNode *exportDecl, ExportDecl *decl) 6363af6ab5fSopenharmony_ci{ 6373af6ab5fSopenharmony_ci decl->BindNode(exportDecl); 6383af6ab5fSopenharmony_ci 6393af6ab5fSopenharmony_ci ArenaVector<ExportDecl *> decls(allocator_->Adapter()); 6403af6ab5fSopenharmony_ci decls.push_back(decl); 6413af6ab5fSopenharmony_ci 6423af6ab5fSopenharmony_ci AddExportDecl(exportDecl, std::move(decls)); 6433af6ab5fSopenharmony_ci} 6443af6ab5fSopenharmony_ci 6453af6ab5fSopenharmony_civoid ModuleScope::AddExportDecl(ir::AstNode *exportDecl, ExportDeclList &&decls) 6463af6ab5fSopenharmony_ci{ 6473af6ab5fSopenharmony_ci auto res = exports_.emplace_back(exportDecl, decls); 6483af6ab5fSopenharmony_ci 6493af6ab5fSopenharmony_ci for (auto &decl : res.second) { 6503af6ab5fSopenharmony_ci decl->BindNode(exportDecl); 6513af6ab5fSopenharmony_ci } 6523af6ab5fSopenharmony_ci} 6533af6ab5fSopenharmony_ci 6543af6ab5fSopenharmony_ciVariable *ModuleScope::AddImport(ArenaAllocator *allocator, Variable *currentVariable, Decl *newDecl) 6553af6ab5fSopenharmony_ci{ 6563af6ab5fSopenharmony_ci if (currentVariable != nullptr && currentVariable->Declaration()->Type() != DeclType::VAR) { 6573af6ab5fSopenharmony_ci return nullptr; 6583af6ab5fSopenharmony_ci } 6593af6ab5fSopenharmony_ci 6603af6ab5fSopenharmony_ci if (newDecl->Node()->IsImportNamespaceSpecifier()) { 6613af6ab5fSopenharmony_ci return InsertBinding(newDecl->Name(), allocator->New<LocalVariable>(newDecl, VariableFlags::READONLY)) 6623af6ab5fSopenharmony_ci .first->second; 6633af6ab5fSopenharmony_ci } 6643af6ab5fSopenharmony_ci 6653af6ab5fSopenharmony_ci auto *variable = allocator->New<ModuleVariable>(newDecl, VariableFlags::NONE); 6663af6ab5fSopenharmony_ci variable->ExoticName() = newDecl->AsImportDecl()->ImportName(); 6673af6ab5fSopenharmony_ci InsertBinding(newDecl->Name(), variable); 6683af6ab5fSopenharmony_ci return variable; 6693af6ab5fSopenharmony_ci} 6703af6ab5fSopenharmony_ci 6713af6ab5fSopenharmony_cibool ModuleScope::ExportAnalysis() 6723af6ab5fSopenharmony_ci{ 6733af6ab5fSopenharmony_ci std::set<util::StringView> exportedNames; 6743af6ab5fSopenharmony_ci 6753af6ab5fSopenharmony_ci for (const auto &[exportDecl, decls] : exports_) { 6763af6ab5fSopenharmony_ci if (exportDecl->IsExportAllDeclaration()) { 6773af6ab5fSopenharmony_ci const auto *exportAllDecl = exportDecl->AsExportAllDeclaration(); 6783af6ab5fSopenharmony_ci 6793af6ab5fSopenharmony_ci if (exportAllDecl->Exported() == nullptr) { 6803af6ab5fSopenharmony_ci continue; 6813af6ab5fSopenharmony_ci } 6823af6ab5fSopenharmony_ci 6833af6ab5fSopenharmony_ci auto result = exportedNames.insert(exportAllDecl->Exported()->Name()); 6843af6ab5fSopenharmony_ci if (!result.second) { 6853af6ab5fSopenharmony_ci return false; 6863af6ab5fSopenharmony_ci } 6873af6ab5fSopenharmony_ci 6883af6ab5fSopenharmony_ci continue; 6893af6ab5fSopenharmony_ci } 6903af6ab5fSopenharmony_ci 6913af6ab5fSopenharmony_ci if (exportDecl->IsExportNamedDeclaration()) { 6923af6ab5fSopenharmony_ci const auto *exportNamedDecl = exportDecl->AsExportNamedDeclaration(); 6933af6ab5fSopenharmony_ci 6943af6ab5fSopenharmony_ci if (exportNamedDecl->Source() != nullptr) { 6953af6ab5fSopenharmony_ci continue; 6963af6ab5fSopenharmony_ci } 6973af6ab5fSopenharmony_ci } 6983af6ab5fSopenharmony_ci 6993af6ab5fSopenharmony_ci for (const auto *decl : decls) { 7003af6ab5fSopenharmony_ci varbinder::Variable *variable = FindLocal(decl->LocalName(), varbinder::ResolveBindingOptions::BINDINGS); 7013af6ab5fSopenharmony_ci 7023af6ab5fSopenharmony_ci if (variable == nullptr) { 7033af6ab5fSopenharmony_ci continue; 7043af6ab5fSopenharmony_ci } 7053af6ab5fSopenharmony_ci 7063af6ab5fSopenharmony_ci auto result = exportedNames.insert(decl->ExportName()); 7073af6ab5fSopenharmony_ci if (!result.second) { 7083af6ab5fSopenharmony_ci return false; 7093af6ab5fSopenharmony_ci } 7103af6ab5fSopenharmony_ci 7113af6ab5fSopenharmony_ci if (!variable->IsModuleVariable()) { 7123af6ab5fSopenharmony_ci variable->AddFlag(VariableFlags::LOCAL_EXPORT); 7133af6ab5fSopenharmony_ci localExports_.insert({variable, decl->ExportName()}); 7143af6ab5fSopenharmony_ci } 7153af6ab5fSopenharmony_ci } 7163af6ab5fSopenharmony_ci } 7173af6ab5fSopenharmony_ci 7183af6ab5fSopenharmony_ci return true; 7193af6ab5fSopenharmony_ci} 7203af6ab5fSopenharmony_ci 7213af6ab5fSopenharmony_ciVariable *FunctionScope::FindLocal(const util::StringView &name, ResolveBindingOptions options) const 7223af6ab5fSopenharmony_ci{ 7233af6ab5fSopenharmony_ci if ((options & ResolveBindingOptions::TYPE_ALIASES) != 0) { 7243af6ab5fSopenharmony_ci auto found = typeAliasScope_->Bindings().find(name); 7253af6ab5fSopenharmony_ci if (found != typeAliasScope_->Bindings().end()) { 7263af6ab5fSopenharmony_ci return found->second; 7273af6ab5fSopenharmony_ci } 7283af6ab5fSopenharmony_ci } 7293af6ab5fSopenharmony_ci 7303af6ab5fSopenharmony_ci if ((options & ResolveBindingOptions::ALL_NON_TYPE) == 0) { 7313af6ab5fSopenharmony_ci return nullptr; 7323af6ab5fSopenharmony_ci } 7333af6ab5fSopenharmony_ci 7343af6ab5fSopenharmony_ci if ((options & ResolveBindingOptions::INTERFACES) != 0) { 7353af6ab5fSopenharmony_ci std::string tsBindingName = varbinder::TSBinding::ToTSBinding(name); 7363af6ab5fSopenharmony_ci util::StringView interfaceNameView(tsBindingName); 7373af6ab5fSopenharmony_ci 7383af6ab5fSopenharmony_ci auto res = Bindings().find(interfaceNameView); 7393af6ab5fSopenharmony_ci if (res != Bindings().end()) { 7403af6ab5fSopenharmony_ci return res->second; 7413af6ab5fSopenharmony_ci } 7423af6ab5fSopenharmony_ci 7433af6ab5fSopenharmony_ci if ((options & ResolveBindingOptions::BINDINGS) == 0) { 7443af6ab5fSopenharmony_ci return nullptr; 7453af6ab5fSopenharmony_ci } 7463af6ab5fSopenharmony_ci } 7473af6ab5fSopenharmony_ci 7483af6ab5fSopenharmony_ci auto res = Bindings().find(name); 7493af6ab5fSopenharmony_ci if (res == Bindings().end()) { 7503af6ab5fSopenharmony_ci return nullptr; 7513af6ab5fSopenharmony_ci } 7523af6ab5fSopenharmony_ci 7533af6ab5fSopenharmony_ci return res->second; 7543af6ab5fSopenharmony_ci} 7553af6ab5fSopenharmony_ci 7563af6ab5fSopenharmony_ci// LocalScope 7573af6ab5fSopenharmony_ci 7583af6ab5fSopenharmony_ciVariable *LocalScope::AddBinding(ArenaAllocator *allocator, Variable *currentVariable, Decl *newDecl, 7593af6ab5fSopenharmony_ci [[maybe_unused]] ScriptExtension extension) 7603af6ab5fSopenharmony_ci{ 7613af6ab5fSopenharmony_ci return AddLocal(allocator, currentVariable, newDecl, extension); 7623af6ab5fSopenharmony_ci} 7633af6ab5fSopenharmony_ci 7643af6ab5fSopenharmony_ciVariable *LocalScopeWithTypeAlias::AddBinding(ArenaAllocator *allocator, Variable *currentVariable, Decl *newDecl, 7653af6ab5fSopenharmony_ci [[maybe_unused]] ScriptExtension extension) 7663af6ab5fSopenharmony_ci{ 7673af6ab5fSopenharmony_ci if (newDecl->IsTypeAliasDecl()) { 7683af6ab5fSopenharmony_ci auto *ident = newDecl->Node()->AsTSTypeAliasDeclaration()->Id(); 7693af6ab5fSopenharmony_ci auto *var = typeAliasScope_->AddBinding(allocator, currentVariable, newDecl, extension); 7703af6ab5fSopenharmony_ci if (var != nullptr) { 7713af6ab5fSopenharmony_ci var->SetScope(this); 7723af6ab5fSopenharmony_ci if (ident != nullptr) { 7733af6ab5fSopenharmony_ci ident->SetVariable(var); 7743af6ab5fSopenharmony_ci } 7753af6ab5fSopenharmony_ci } 7763af6ab5fSopenharmony_ci return var; 7773af6ab5fSopenharmony_ci } 7783af6ab5fSopenharmony_ci return AddLocal(allocator, currentVariable, newDecl, extension); 7793af6ab5fSopenharmony_ci} 7803af6ab5fSopenharmony_ci 7813af6ab5fSopenharmony_ciVariable *LocalScopeWithTypeAlias::FindLocal(const util::StringView &name, ResolveBindingOptions options) const 7823af6ab5fSopenharmony_ci{ 7833af6ab5fSopenharmony_ci if ((options & ResolveBindingOptions::TYPE_ALIASES) != 0) { 7843af6ab5fSopenharmony_ci auto found = typeAliasScope_->Bindings().find(name); 7853af6ab5fSopenharmony_ci if (found != typeAliasScope_->Bindings().end()) { 7863af6ab5fSopenharmony_ci return found->second; 7873af6ab5fSopenharmony_ci } 7883af6ab5fSopenharmony_ci } 7893af6ab5fSopenharmony_ci 7903af6ab5fSopenharmony_ci if ((options & ResolveBindingOptions::ALL_NON_TYPE) == 0) { 7913af6ab5fSopenharmony_ci return nullptr; 7923af6ab5fSopenharmony_ci } 7933af6ab5fSopenharmony_ci 7943af6ab5fSopenharmony_ci if ((options & ResolveBindingOptions::INTERFACES) != 0) { 7953af6ab5fSopenharmony_ci std::string tsBindingName = varbinder::TSBinding::ToTSBinding(name); 7963af6ab5fSopenharmony_ci util::StringView interfaceNameView(tsBindingName); 7973af6ab5fSopenharmony_ci 7983af6ab5fSopenharmony_ci auto res = Bindings().find(interfaceNameView); 7993af6ab5fSopenharmony_ci if (res != Bindings().end()) { 8003af6ab5fSopenharmony_ci return res->second; 8013af6ab5fSopenharmony_ci } 8023af6ab5fSopenharmony_ci 8033af6ab5fSopenharmony_ci if ((options & ResolveBindingOptions::BINDINGS) == 0) { 8043af6ab5fSopenharmony_ci return nullptr; 8053af6ab5fSopenharmony_ci } 8063af6ab5fSopenharmony_ci } 8073af6ab5fSopenharmony_ci 8083af6ab5fSopenharmony_ci auto res = Bindings().find(name); 8093af6ab5fSopenharmony_ci if (res == Bindings().end()) { 8103af6ab5fSopenharmony_ci return nullptr; 8113af6ab5fSopenharmony_ci } 8123af6ab5fSopenharmony_ci 8133af6ab5fSopenharmony_ci return res->second; 8143af6ab5fSopenharmony_ci} 8153af6ab5fSopenharmony_ci 8163af6ab5fSopenharmony_ciVariable *ClassScope::FindLocal(const util::StringView &name, ResolveBindingOptions options) const 8173af6ab5fSopenharmony_ci{ 8183af6ab5fSopenharmony_ci if ((options & ResolveBindingOptions::TYPE_ALIASES) != 0) { 8193af6ab5fSopenharmony_ci auto found = TypeAliasScope()->Bindings().find(name); 8203af6ab5fSopenharmony_ci if (found != TypeAliasScope()->Bindings().end()) { 8213af6ab5fSopenharmony_ci return found->second; 8223af6ab5fSopenharmony_ci } 8233af6ab5fSopenharmony_ci } 8243af6ab5fSopenharmony_ci 8253af6ab5fSopenharmony_ci if ((options & ResolveBindingOptions::VARIABLES) != 0) { 8263af6ab5fSopenharmony_ci auto found = instanceFieldScope_->Bindings().find(name); 8273af6ab5fSopenharmony_ci if (found != instanceFieldScope_->Bindings().end()) { 8283af6ab5fSopenharmony_ci return found->second; 8293af6ab5fSopenharmony_ci } 8303af6ab5fSopenharmony_ci } 8313af6ab5fSopenharmony_ci 8323af6ab5fSopenharmony_ci if ((options & ResolveBindingOptions::STATIC_VARIABLES) != 0) { 8333af6ab5fSopenharmony_ci auto found = staticFieldScope_->Bindings().find(name); 8343af6ab5fSopenharmony_ci if (found != staticFieldScope_->Bindings().end()) { 8353af6ab5fSopenharmony_ci return found->second; 8363af6ab5fSopenharmony_ci } 8373af6ab5fSopenharmony_ci } 8383af6ab5fSopenharmony_ci 8393af6ab5fSopenharmony_ci if ((options & ResolveBindingOptions::DECLARATION) != 0) { 8403af6ab5fSopenharmony_ci auto found = instanceDeclScope_->Bindings().find(name); 8413af6ab5fSopenharmony_ci if (found != instanceDeclScope_->Bindings().end()) { 8423af6ab5fSopenharmony_ci return found->second; 8433af6ab5fSopenharmony_ci } 8443af6ab5fSopenharmony_ci } 8453af6ab5fSopenharmony_ci 8463af6ab5fSopenharmony_ci if ((options & ResolveBindingOptions::STATIC_DECLARATION) != 0) { 8473af6ab5fSopenharmony_ci auto found = staticDeclScope_->Bindings().find(name); 8483af6ab5fSopenharmony_ci if (found != staticDeclScope_->Bindings().end()) { 8493af6ab5fSopenharmony_ci return found->second; 8503af6ab5fSopenharmony_ci } 8513af6ab5fSopenharmony_ci } 8523af6ab5fSopenharmony_ci 8533af6ab5fSopenharmony_ci if ((options & ResolveBindingOptions::METHODS) != 0) { 8543af6ab5fSopenharmony_ci auto found = instanceMethodScope_->Bindings().find(name); 8553af6ab5fSopenharmony_ci if (found != instanceMethodScope_->Bindings().end()) { 8563af6ab5fSopenharmony_ci return found->second; 8573af6ab5fSopenharmony_ci } 8583af6ab5fSopenharmony_ci } 8593af6ab5fSopenharmony_ci 8603af6ab5fSopenharmony_ci if ((options & ResolveBindingOptions::STATIC_METHODS) != 0) { 8613af6ab5fSopenharmony_ci auto found = staticMethodScope_->Bindings().find(name); 8623af6ab5fSopenharmony_ci if (found != staticMethodScope_->Bindings().end()) { 8633af6ab5fSopenharmony_ci return found->second; 8643af6ab5fSopenharmony_ci } 8653af6ab5fSopenharmony_ci } 8663af6ab5fSopenharmony_ci 8673af6ab5fSopenharmony_ci return nullptr; 8683af6ab5fSopenharmony_ci} 8693af6ab5fSopenharmony_ci 8703af6ab5fSopenharmony_civoid ClassScope::SetBindingProps(Decl *newDecl, BindingProps *props, bool isStatic) 8713af6ab5fSopenharmony_ci{ 8723af6ab5fSopenharmony_ci switch (newDecl->Type()) { 8733af6ab5fSopenharmony_ci case DeclType::CONST: 8743af6ab5fSopenharmony_ci case DeclType::READONLY: 8753af6ab5fSopenharmony_ci case DeclType::LET: { 8763af6ab5fSopenharmony_ci props->SetBindingProps(VariableFlags::PROPERTY, newDecl->Node()->AsClassProperty()->Id(), 8773af6ab5fSopenharmony_ci isStatic ? staticFieldScope_ : instanceFieldScope_); 8783af6ab5fSopenharmony_ci break; 8793af6ab5fSopenharmony_ci } 8803af6ab5fSopenharmony_ci case DeclType::INTERFACE: { 8813af6ab5fSopenharmony_ci props->SetBindingProps(VariableFlags::INTERFACE, newDecl->Node()->AsTSInterfaceDeclaration()->Id(), 8823af6ab5fSopenharmony_ci isStatic ? staticDeclScope_ : instanceDeclScope_); 8833af6ab5fSopenharmony_ci break; 8843af6ab5fSopenharmony_ci } 8853af6ab5fSopenharmony_ci case DeclType::CLASS: { 8863af6ab5fSopenharmony_ci props->SetBindingProps(VariableFlags::CLASS, newDecl->Node()->AsClassDefinition()->Ident(), 8873af6ab5fSopenharmony_ci isStatic ? staticDeclScope_ : instanceDeclScope_); 8883af6ab5fSopenharmony_ci break; 8893af6ab5fSopenharmony_ci } 8903af6ab5fSopenharmony_ci case DeclType::ENUM_LITERAL: { 8913af6ab5fSopenharmony_ci props->SetBindingProps(VariableFlags::ENUM_LITERAL, newDecl->Node()->AsTSEnumDeclaration()->Key(), 8923af6ab5fSopenharmony_ci isStatic ? staticDeclScope_ : instanceDeclScope_); 8933af6ab5fSopenharmony_ci break; 8943af6ab5fSopenharmony_ci } 8953af6ab5fSopenharmony_ci case DeclType::TYPE_ALIAS: { 8963af6ab5fSopenharmony_ci props->SetBindingProps(VariableFlags::TYPE_ALIAS, newDecl->Node()->AsTSTypeAliasDeclaration()->Id(), 8973af6ab5fSopenharmony_ci TypeAliasScope()); 8983af6ab5fSopenharmony_ci break; 8993af6ab5fSopenharmony_ci } 9003af6ab5fSopenharmony_ci default: { 9013af6ab5fSopenharmony_ci UNREACHABLE(); 9023af6ab5fSopenharmony_ci break; 9033af6ab5fSopenharmony_ci } 9043af6ab5fSopenharmony_ci } 9053af6ab5fSopenharmony_ci} 9063af6ab5fSopenharmony_ci 9073af6ab5fSopenharmony_ciVariable *ClassScope::AddBinding(ArenaAllocator *allocator, [[maybe_unused]] Variable *currentVariable, Decl *newDecl, 9083af6ab5fSopenharmony_ci [[maybe_unused]] ScriptExtension extension) 9093af6ab5fSopenharmony_ci{ 9103af6ab5fSopenharmony_ci bool isStatic = newDecl->Node()->IsStatic(); 9113af6ab5fSopenharmony_ci BindingProps props; 9123af6ab5fSopenharmony_ci 9133af6ab5fSopenharmony_ci if (isStatic) { 9143af6ab5fSopenharmony_ci props.SetFlagsType(VariableFlags::STATIC); 9153af6ab5fSopenharmony_ci } 9163af6ab5fSopenharmony_ci 9173af6ab5fSopenharmony_ci SetBindingProps(newDecl, &props, isStatic); 9183af6ab5fSopenharmony_ci 9193af6ab5fSopenharmony_ci auto options = newDecl->Type() != DeclType::TYPE_ALIAS ? ResolveBindingOptions::ALL_NON_TYPE 9203af6ab5fSopenharmony_ci : ResolveBindingOptions::TYPE_ALIASES; 9213af6ab5fSopenharmony_ci 9223af6ab5fSopenharmony_ci const auto *foundVar = FindLocal(newDecl->Name(), options); 9233af6ab5fSopenharmony_ci if (foundVar != nullptr) { 9243af6ab5fSopenharmony_ci if (!newDecl->IsLetOrConstDecl()) { 9253af6ab5fSopenharmony_ci return nullptr; 9263af6ab5fSopenharmony_ci } 9273af6ab5fSopenharmony_ci 9283af6ab5fSopenharmony_ci foundVar = FindLocal(newDecl->Name(), 9293af6ab5fSopenharmony_ci ResolveBindingOptions::ALL ^ (isStatic ? ResolveBindingOptions::VARIABLES 9303af6ab5fSopenharmony_ci : ResolveBindingOptions::STATIC_VARIABLES)); 9313af6ab5fSopenharmony_ci if (foundVar != nullptr) { 9323af6ab5fSopenharmony_ci return nullptr; 9333af6ab5fSopenharmony_ci } 9343af6ab5fSopenharmony_ci } 9353af6ab5fSopenharmony_ci 9363af6ab5fSopenharmony_ci auto *var = props.GetTargetScope()->AddBinding(allocator, nullptr, newDecl, extension); 9373af6ab5fSopenharmony_ci if (var == nullptr) { 9383af6ab5fSopenharmony_ci return nullptr; 9393af6ab5fSopenharmony_ci } 9403af6ab5fSopenharmony_ci 9413af6ab5fSopenharmony_ci if (auto node = newDecl->Node(); 9423af6ab5fSopenharmony_ci node->IsStatement() && 9433af6ab5fSopenharmony_ci (node->AsStatement()->IsMethodDefinition() || node->IsClassProperty() || node->IsClassStaticBlock()) && 9443af6ab5fSopenharmony_ci node->AsStatement()->AsClassElement()->Value() != nullptr) { 9453af6ab5fSopenharmony_ci props.SetFlagsType(VariableFlags::INITIALIZED); 9463af6ab5fSopenharmony_ci } 9473af6ab5fSopenharmony_ci 9483af6ab5fSopenharmony_ci var->SetScope(this); 9493af6ab5fSopenharmony_ci var->AddFlag(props.GetFlags()); 9503af6ab5fSopenharmony_ci 9513af6ab5fSopenharmony_ci if (props.GetIdent() != nullptr) { 9523af6ab5fSopenharmony_ci props.GetIdent()->SetVariable(var); 9533af6ab5fSopenharmony_ci } 9543af6ab5fSopenharmony_ci 9553af6ab5fSopenharmony_ci return var; 9563af6ab5fSopenharmony_ci} 9573af6ab5fSopenharmony_ci 9583af6ab5fSopenharmony_civoid LoopDeclarationScope::ConvertToVariableScope(ArenaAllocator *allocator) 9593af6ab5fSopenharmony_ci{ 9603af6ab5fSopenharmony_ci if (NeedLexEnv()) { 9613af6ab5fSopenharmony_ci return; 9623af6ab5fSopenharmony_ci } 9633af6ab5fSopenharmony_ci 9643af6ab5fSopenharmony_ci const auto &bindings = Bindings(); 9653af6ab5fSopenharmony_ci for (auto &[name, var] : bindings) { 9663af6ab5fSopenharmony_ci if (!var->LexicalBound() || !var->Declaration()->IsLetOrConstDecl()) { 9673af6ab5fSopenharmony_ci continue; 9683af6ab5fSopenharmony_ci } 9693af6ab5fSopenharmony_ci 9703af6ab5fSopenharmony_ci slotIndex_++; 9713af6ab5fSopenharmony_ci loopType_ = ScopeType::LOOP_DECL; 9723af6ab5fSopenharmony_ci auto *copiedVar = var->AsLocalVariable()->Copy(allocator, var->Declaration()); 9733af6ab5fSopenharmony_ci copiedVar->AddFlag(VariableFlags::INITIALIZED | VariableFlags::PER_ITERATION); 9743af6ab5fSopenharmony_ci var->AddFlag(VariableFlags::LOOP_DECL); 9753af6ab5fSopenharmony_ci loopScope_->InsertBinding(name, copiedVar); 9763af6ab5fSopenharmony_ci } 9773af6ab5fSopenharmony_ci 9783af6ab5fSopenharmony_ci if (loopType_ == ScopeType::LOOP_DECL) { 9793af6ab5fSopenharmony_ci auto *parentVarScope = Parent()->EnclosingVariableScope(); 9803af6ab5fSopenharmony_ci slotIndex_ = std::max(slotIndex_, parentVarScope->LexicalSlots()); 9813af6ab5fSopenharmony_ci evalBindings_ = parentVarScope->EvalBindings(); 9823af6ab5fSopenharmony_ci initScope_ = allocator->New<LocalScope>(allocator, Parent()); 9833af6ab5fSopenharmony_ci initScope_->BindNode(Node()); 9843af6ab5fSopenharmony_ci initScope_->MergeBindings(bindings); 9853af6ab5fSopenharmony_ci } 9863af6ab5fSopenharmony_ci} 9873af6ab5fSopenharmony_ci 9883af6ab5fSopenharmony_civoid LoopScope::ConvertToVariableScope(ArenaAllocator *allocator) 9893af6ab5fSopenharmony_ci{ 9903af6ab5fSopenharmony_ci declScope_->ConvertToVariableScope(allocator); 9913af6ab5fSopenharmony_ci 9923af6ab5fSopenharmony_ci if (loopType_ != ScopeType::LOCAL) { 9933af6ab5fSopenharmony_ci return; 9943af6ab5fSopenharmony_ci } 9953af6ab5fSopenharmony_ci 9963af6ab5fSopenharmony_ci for (const auto &[_, var] : Bindings()) { 9973af6ab5fSopenharmony_ci (void)_; 9983af6ab5fSopenharmony_ci if (var->LexicalBound() && var->Declaration()->IsLetDecl()) { 9993af6ab5fSopenharmony_ci ASSERT(declScope_->NeedLexEnv()); 10003af6ab5fSopenharmony_ci loopType_ = ScopeType::LOOP; 10013af6ab5fSopenharmony_ci break; 10023af6ab5fSopenharmony_ci } 10033af6ab5fSopenharmony_ci } 10043af6ab5fSopenharmony_ci 10053af6ab5fSopenharmony_ci if (loopType_ == ScopeType::LOOP) { 10063af6ab5fSopenharmony_ci slotIndex_ = std::max(slotIndex_, declScope_->LexicalSlots()); 10073af6ab5fSopenharmony_ci evalBindings_ = declScope_->EvalBindings(); 10083af6ab5fSopenharmony_ci } 10093af6ab5fSopenharmony_ci} 10103af6ab5fSopenharmony_ci 10113af6ab5fSopenharmony_ciVariable *CatchParamScope::AddBinding(ArenaAllocator *allocator, Variable *currentVariable, Decl *newDecl, 10123af6ab5fSopenharmony_ci [[maybe_unused]] ScriptExtension extension) 10133af6ab5fSopenharmony_ci{ 10143af6ab5fSopenharmony_ci return AddParam(allocator, currentVariable, newDecl, VariableFlags::INITIALIZED); 10153af6ab5fSopenharmony_ci} 10163af6ab5fSopenharmony_ci 10173af6ab5fSopenharmony_ciVariable *CatchScope::AddBinding(ArenaAllocator *allocator, Variable *currentVariable, Decl *newDecl, 10183af6ab5fSopenharmony_ci [[maybe_unused]] ScriptExtension extension) 10193af6ab5fSopenharmony_ci{ 10203af6ab5fSopenharmony_ci if (!newDecl->IsVarDecl() && 10213af6ab5fSopenharmony_ci (paramScope_->FindLocal(newDecl->Name(), varbinder::ResolveBindingOptions::BINDINGS) != nullptr)) { 10223af6ab5fSopenharmony_ci return nullptr; 10233af6ab5fSopenharmony_ci } 10243af6ab5fSopenharmony_ci 10253af6ab5fSopenharmony_ci if (newDecl->IsTypeAliasDecl()) { 10263af6ab5fSopenharmony_ci auto *ident = newDecl->Node()->AsTSTypeAliasDeclaration()->Id(); 10273af6ab5fSopenharmony_ci auto *var = TypeAliasScope()->AddBinding(allocator, currentVariable, newDecl, extension); 10283af6ab5fSopenharmony_ci if (var != nullptr) { 10293af6ab5fSopenharmony_ci var->SetScope(this); 10303af6ab5fSopenharmony_ci if (ident != nullptr) { 10313af6ab5fSopenharmony_ci ident->SetVariable(var); 10323af6ab5fSopenharmony_ci } 10333af6ab5fSopenharmony_ci } 10343af6ab5fSopenharmony_ci return var; 10353af6ab5fSopenharmony_ci } 10363af6ab5fSopenharmony_ci 10373af6ab5fSopenharmony_ci return AddLocal(allocator, currentVariable, newDecl, extension); 10383af6ab5fSopenharmony_ci} 10393af6ab5fSopenharmony_ci} // namespace ark::es2panda::varbinder 1040