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