13af6ab5fSopenharmony_ci/* 23af6ab5fSopenharmony_ci * Copyright (c) 2023-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 "util/errorHandler.h" 173af6ab5fSopenharmony_ci#include "scopesInitPhase.h" 183af6ab5fSopenharmony_ci 193af6ab5fSopenharmony_cinamespace ark::es2panda::compiler { 203af6ab5fSopenharmony_ci 213af6ab5fSopenharmony_citemplate <typename T> 223af6ab5fSopenharmony_civarbinder::LexicalScope<T> LexicalScopeCreateOrEnter(varbinder::VarBinder *varBinder, ir::AstNode *ast) 233af6ab5fSopenharmony_ci{ 243af6ab5fSopenharmony_ci if (ast != nullptr && ast->Scope() != nullptr) { 253af6ab5fSopenharmony_ci return varbinder::LexicalScope<T>::Enter(varBinder, reinterpret_cast<T *>(ast->Scope())); 263af6ab5fSopenharmony_ci } 273af6ab5fSopenharmony_ci return varbinder::LexicalScope<T>(varBinder); 283af6ab5fSopenharmony_ci} 293af6ab5fSopenharmony_ci 303af6ab5fSopenharmony_citemplate <typename T, typename... Args> 313af6ab5fSopenharmony_ciT *AddOrGetDecl(varbinder::VarBinder *varBinder, util::StringView name, ir::AstNode *ast, 323af6ab5fSopenharmony_ci const lexer::SourcePosition &pos, Args &&...args) 333af6ab5fSopenharmony_ci{ 343af6ab5fSopenharmony_ci if (auto *var = varBinder->GetScope()->FindLocal(name, varbinder::ResolveBindingOptions::BINDINGS); 353af6ab5fSopenharmony_ci var != nullptr && var->Declaration() != nullptr && var->Declaration()->Node() == ast) { 363af6ab5fSopenharmony_ci return reinterpret_cast<T *>(var->Declaration()); 373af6ab5fSopenharmony_ci } 383af6ab5fSopenharmony_ci return varBinder->AddDecl<T>(pos, args...); 393af6ab5fSopenharmony_ci} 403af6ab5fSopenharmony_ci 413af6ab5fSopenharmony_cibool ScopesInitPhase::Perform(PhaseContext *ctx, parser::Program *program) 423af6ab5fSopenharmony_ci{ 433af6ab5fSopenharmony_ci Prepare(ctx, program); 443af6ab5fSopenharmony_ci program->VarBinder()->InitTopScope(); 453af6ab5fSopenharmony_ci HandleBlockStmt(program->Ast(), GetScope()); 463af6ab5fSopenharmony_ci Finalize(); 473af6ab5fSopenharmony_ci return true; 483af6ab5fSopenharmony_ci} 493af6ab5fSopenharmony_ci 503af6ab5fSopenharmony_civoid ScopesInitPhase::VisitScriptFunction(ir::ScriptFunction *scriptFunction) 513af6ab5fSopenharmony_ci{ 523af6ab5fSopenharmony_ci if (auto *const id = scriptFunction->Id(); id != nullptr && id->Variable() == nullptr) { 533af6ab5fSopenharmony_ci auto const *const curScope = VarBinder()->GetScope(); 543af6ab5fSopenharmony_ci auto const &functionName = id->Name(); 553af6ab5fSopenharmony_ci auto const res = 563af6ab5fSopenharmony_ci curScope->Find(functionName, scriptFunction->IsStatic() ? varbinder::ResolveBindingOptions::ALL_STATIC 573af6ab5fSopenharmony_ci : varbinder::ResolveBindingOptions::ALL_NON_STATIC); 583af6ab5fSopenharmony_ci if (res.variable != nullptr && res.variable->Declaration()->IsFunctionDecl()) { 593af6ab5fSopenharmony_ci id->SetVariable(res.variable); 603af6ab5fSopenharmony_ci } 613af6ab5fSopenharmony_ci } 623af6ab5fSopenharmony_ci 633af6ab5fSopenharmony_ci HandleFunction(scriptFunction); 643af6ab5fSopenharmony_ci} 653af6ab5fSopenharmony_ci 663af6ab5fSopenharmony_civoid ScopesInitPhase::VisitBlockStatement(ir::BlockStatement *blockStmt) 673af6ab5fSopenharmony_ci{ 683af6ab5fSopenharmony_ci auto localCtx = LexicalScopeCreateOrEnter<varbinder::LocalScopeWithTypeAlias>(VarBinder(), blockStmt); 693af6ab5fSopenharmony_ci HandleBlockStmt(blockStmt, GetScope()); 703af6ab5fSopenharmony_ci} 713af6ab5fSopenharmony_ci 723af6ab5fSopenharmony_civoid ScopesInitPhase::VisitImportDeclaration(ir::ImportDeclaration *importDeclaration) 733af6ab5fSopenharmony_ci{ 743af6ab5fSopenharmony_ci ImportDeclarationContext importCtx(VarBinder()); 753af6ab5fSopenharmony_ci Iterate(importDeclaration); 763af6ab5fSopenharmony_ci importCtx.BindImportDecl(importDeclaration); 773af6ab5fSopenharmony_ci} 783af6ab5fSopenharmony_ci 793af6ab5fSopenharmony_civoid ScopesInitPhase::VisitClassStaticBlock(ir::ClassStaticBlock *staticBlock) 803af6ab5fSopenharmony_ci{ 813af6ab5fSopenharmony_ci Iterate(staticBlock); 823af6ab5fSopenharmony_ci} 833af6ab5fSopenharmony_ci 843af6ab5fSopenharmony_civoid ScopesInitPhase::VisitMethodDefinition(ir::MethodDefinition *methodDefinition) 853af6ab5fSopenharmony_ci{ 863af6ab5fSopenharmony_ci Iterate(methodDefinition); 873af6ab5fSopenharmony_ci} 883af6ab5fSopenharmony_ci 893af6ab5fSopenharmony_civarbinder::FunctionParamScope *ScopesInitPhase::HandleFunctionSig(ir::TSTypeParameterDeclaration *typeParams, 903af6ab5fSopenharmony_ci const ir::FunctionSignature::FunctionParams ¶ms, 913af6ab5fSopenharmony_ci ir::TypeNode *returnType) 923af6ab5fSopenharmony_ci{ 933af6ab5fSopenharmony_ci auto typeParamsCtx = varbinder::LexicalScope<varbinder::LocalScope>(VarBinder()); 943af6ab5fSopenharmony_ci CallNode(typeParams); 953af6ab5fSopenharmony_ci 963af6ab5fSopenharmony_ci auto lexicalScope = varbinder::LexicalScope<varbinder::FunctionParamScope>(VarBinder()); 973af6ab5fSopenharmony_ci CallFuncParams(params); 983af6ab5fSopenharmony_ci CallNode(returnType); 993af6ab5fSopenharmony_ci 1003af6ab5fSopenharmony_ci return lexicalScope.GetScope(); 1013af6ab5fSopenharmony_ci} 1023af6ab5fSopenharmony_ci 1033af6ab5fSopenharmony_civoid ScopesInitPhase::HandleFunction(ir::ScriptFunction *function) 1043af6ab5fSopenharmony_ci{ 1053af6ab5fSopenharmony_ci CallNode(function->Id()); 1063af6ab5fSopenharmony_ci // NOTE(gogabr): this will skip type/value parameters when they are added to an existing function sig 1073af6ab5fSopenharmony_ci auto funcParamScope = (function->Scope() == nullptr) ? HandleFunctionSig(function->TypeParams(), function->Params(), 1083af6ab5fSopenharmony_ci function->ReturnTypeAnnotation()) 1093af6ab5fSopenharmony_ci : function->Scope()->ParamScope(); 1103af6ab5fSopenharmony_ci auto paramCtx = varbinder::LexicalScope<varbinder::FunctionParamScope>::Enter(VarBinder(), funcParamScope, false); 1113af6ab5fSopenharmony_ci 1123af6ab5fSopenharmony_ci auto functionCtx = LexicalScopeCreateOrEnter<varbinder::FunctionScope>(VarBinder(), function); 1133af6ab5fSopenharmony_ci auto *functionScope = functionCtx.GetScope(); 1143af6ab5fSopenharmony_ci BindFunctionScopes(functionScope, funcParamScope); 1153af6ab5fSopenharmony_ci 1163af6ab5fSopenharmony_ci if (function->Body() != nullptr && function->Body()->IsBlockStatement()) { 1173af6ab5fSopenharmony_ci HandleBlockStmt(function->Body()->AsBlockStatement(), functionScope); 1183af6ab5fSopenharmony_ci } else { 1193af6ab5fSopenharmony_ci Iterate(function->Body()); 1203af6ab5fSopenharmony_ci } 1213af6ab5fSopenharmony_ci BindScopeNode(functionScope, function); 1223af6ab5fSopenharmony_ci funcParamScope->BindNode(function); 1233af6ab5fSopenharmony_ci} 1243af6ab5fSopenharmony_ci 1253af6ab5fSopenharmony_civoid ScopesInitPhase::HandleBlockStmt(ir::BlockStatement *block, varbinder::Scope *scope) 1263af6ab5fSopenharmony_ci{ 1273af6ab5fSopenharmony_ci if (block->Scope() == nullptr) { 1283af6ab5fSopenharmony_ci BindScopeNode(scope, block); 1293af6ab5fSopenharmony_ci } 1303af6ab5fSopenharmony_ci Iterate(block); 1313af6ab5fSopenharmony_ci} 1323af6ab5fSopenharmony_ci 1333af6ab5fSopenharmony_civoid ScopesInitPhase::VisitClassDefinition(ir::ClassDefinition *classDef) 1343af6ab5fSopenharmony_ci{ 1353af6ab5fSopenharmony_ci auto classCtx = LexicalScopeCreateOrEnter<varbinder::LocalScope>(VarBinder(), classDef); 1363af6ab5fSopenharmony_ci AddOrGetDecl<varbinder::ConstDecl>(VarBinder(), classDef->PrivateId(), classDef, classDef->Start(), 1373af6ab5fSopenharmony_ci classDef->PrivateId()); 1383af6ab5fSopenharmony_ci BindClassName(classDef); 1393af6ab5fSopenharmony_ci 1403af6ab5fSopenharmony_ci auto *classScope = classCtx.GetScope(); 1413af6ab5fSopenharmony_ci BindScopeNode(classScope, classDef); 1423af6ab5fSopenharmony_ci Iterate(classDef); 1433af6ab5fSopenharmony_ci} 1443af6ab5fSopenharmony_ci 1453af6ab5fSopenharmony_civoid ScopesInitPhase::VisitForUpdateStatement(ir::ForUpdateStatement *forUpdateStmt) 1463af6ab5fSopenharmony_ci{ 1473af6ab5fSopenharmony_ci auto declCtx = (forUpdateStmt->Scope() == nullptr) 1483af6ab5fSopenharmony_ci ? varbinder::LexicalScope<varbinder::LoopDeclarationScope>(VarBinder()) 1493af6ab5fSopenharmony_ci : varbinder::LexicalScope<varbinder::LoopDeclarationScope>::Enter( 1503af6ab5fSopenharmony_ci VarBinder(), forUpdateStmt->Scope()->DeclScope()); 1513af6ab5fSopenharmony_ci CallNode(forUpdateStmt->Init()); 1523af6ab5fSopenharmony_ci 1533af6ab5fSopenharmony_ci auto lexicalScope = LexicalScopeCreateOrEnter<varbinder::LoopScope>(VarBinder(), forUpdateStmt); 1543af6ab5fSopenharmony_ci AttachLabelToScope(forUpdateStmt); 1553af6ab5fSopenharmony_ci CallNode(forUpdateStmt->Test()); 1563af6ab5fSopenharmony_ci CallNode(forUpdateStmt->Update()); 1573af6ab5fSopenharmony_ci CallNode(forUpdateStmt->Body()); 1583af6ab5fSopenharmony_ci lexicalScope.GetScope()->BindDecls(declCtx.GetScope()); 1593af6ab5fSopenharmony_ci HandleFor(declCtx.GetScope(), lexicalScope.GetScope(), forUpdateStmt); 1603af6ab5fSopenharmony_ci} 1613af6ab5fSopenharmony_ci 1623af6ab5fSopenharmony_civoid ScopesInitPhase::VisitForInStatement(ir::ForInStatement *forInStmt) 1633af6ab5fSopenharmony_ci{ 1643af6ab5fSopenharmony_ci auto declCtx = (forInStmt->Scope() == nullptr) 1653af6ab5fSopenharmony_ci ? varbinder::LexicalScope<varbinder::LoopDeclarationScope>(VarBinder()) 1663af6ab5fSopenharmony_ci : varbinder::LexicalScope<varbinder::LoopDeclarationScope>::Enter( 1673af6ab5fSopenharmony_ci VarBinder(), forInStmt->Scope()->DeclScope()); 1683af6ab5fSopenharmony_ci CallNode(forInStmt->Left()); 1693af6ab5fSopenharmony_ci 1703af6ab5fSopenharmony_ci auto lexicalScope = LexicalScopeCreateOrEnter<varbinder::LoopScope>(VarBinder(), forInStmt); 1713af6ab5fSopenharmony_ci CallNode(forInStmt->Right()); 1723af6ab5fSopenharmony_ci CallNode(forInStmt->Body()); 1733af6ab5fSopenharmony_ci HandleFor(declCtx.GetScope(), lexicalScope.GetScope(), forInStmt); 1743af6ab5fSopenharmony_ci} 1753af6ab5fSopenharmony_civoid ScopesInitPhase::VisitForOfStatement(ir::ForOfStatement *forOfStmt) 1763af6ab5fSopenharmony_ci{ 1773af6ab5fSopenharmony_ci auto declCtx = (forOfStmt->Scope() == nullptr) 1783af6ab5fSopenharmony_ci ? varbinder::LexicalScope<varbinder::LoopDeclarationScope>(VarBinder()) 1793af6ab5fSopenharmony_ci : varbinder::LexicalScope<varbinder::LoopDeclarationScope>::Enter( 1803af6ab5fSopenharmony_ci VarBinder(), forOfStmt->Scope()->DeclScope()); 1813af6ab5fSopenharmony_ci CallNode(forOfStmt->Left()); 1823af6ab5fSopenharmony_ci 1833af6ab5fSopenharmony_ci auto lexicalScope = LexicalScopeCreateOrEnter<varbinder::LoopScope>(VarBinder(), forOfStmt); 1843af6ab5fSopenharmony_ci AttachLabelToScope(forOfStmt); 1853af6ab5fSopenharmony_ci CallNode(forOfStmt->Right()); 1863af6ab5fSopenharmony_ci CallNode(forOfStmt->Body()); 1873af6ab5fSopenharmony_ci HandleFor(declCtx.GetScope(), lexicalScope.GetScope(), forOfStmt); 1883af6ab5fSopenharmony_ci} 1893af6ab5fSopenharmony_ci 1903af6ab5fSopenharmony_civoid ScopesInitPhase::VisitCatchClause(ir::CatchClause *catchClause) 1913af6ab5fSopenharmony_ci{ 1923af6ab5fSopenharmony_ci auto catchParamCtx = (catchClause->Scope() == nullptr) 1933af6ab5fSopenharmony_ci ? varbinder::LexicalScope<varbinder::CatchParamScope>(VarBinder()) 1943af6ab5fSopenharmony_ci : varbinder::LexicalScope<varbinder::CatchParamScope>::Enter( 1953af6ab5fSopenharmony_ci VarBinder(), catchClause->Scope()->ParamScope()); 1963af6ab5fSopenharmony_ci auto *catchParamScope = catchParamCtx.GetScope(); 1973af6ab5fSopenharmony_ci auto *param = catchClause->Param(); 1983af6ab5fSopenharmony_ci 1993af6ab5fSopenharmony_ci CallNode(param); 2003af6ab5fSopenharmony_ci 2013af6ab5fSopenharmony_ci if (param != nullptr) { 2023af6ab5fSopenharmony_ci auto [param_decl, var] = VarBinder()->AddParamDecl(param); 2033af6ab5fSopenharmony_ci (void)param_decl; 2043af6ab5fSopenharmony_ci if (param->IsIdentifier()) { 2053af6ab5fSopenharmony_ci var->SetScope(catchParamScope); 2063af6ab5fSopenharmony_ci param->AsIdentifier()->SetVariable(var); 2073af6ab5fSopenharmony_ci } 2083af6ab5fSopenharmony_ci } 2093af6ab5fSopenharmony_ci 2103af6ab5fSopenharmony_ci // Catch Clause is scope bearer 2113af6ab5fSopenharmony_ci catchParamScope->BindNode(catchClause); 2123af6ab5fSopenharmony_ci 2133af6ab5fSopenharmony_ci auto catchCtx = LexicalScopeCreateOrEnter<varbinder::CatchScope>(VarBinder(), catchClause); 2143af6ab5fSopenharmony_ci auto *catchScope = catchCtx.GetScope(); 2153af6ab5fSopenharmony_ci 2163af6ab5fSopenharmony_ci catchScope->AssignParamScope(catchParamScope); 2173af6ab5fSopenharmony_ci auto body = catchClause->Body(); 2183af6ab5fSopenharmony_ci HandleBlockStmt(body, catchScope); 2193af6ab5fSopenharmony_ci 2203af6ab5fSopenharmony_ci BindScopeNode(catchScope, catchClause); 2213af6ab5fSopenharmony_ci} 2223af6ab5fSopenharmony_ci 2233af6ab5fSopenharmony_civoid ScopesInitPhase::VisitVariableDeclarator(ir::VariableDeclarator *varDecl) 2243af6ab5fSopenharmony_ci{ 2253af6ab5fSopenharmony_ci auto init = varDecl->Id(); 2263af6ab5fSopenharmony_ci std::vector<ir::Identifier *> bindings = util::Helpers::CollectBindingNames(init); 2273af6ab5fSopenharmony_ci for (auto *binding : bindings) { 2283af6ab5fSopenharmony_ci auto [decl, var] = AddOrGetVarDecl(varDecl->Flag(), varDecl->Start(), binding); 2293af6ab5fSopenharmony_ci BindVarDecl(binding, init, decl, var); 2303af6ab5fSopenharmony_ci } 2313af6ab5fSopenharmony_ci Iterate(varDecl); 2323af6ab5fSopenharmony_ci} 2333af6ab5fSopenharmony_ci 2343af6ab5fSopenharmony_civoid ScopesInitPhase::VisitSwitchStatement(ir::SwitchStatement *switchStmt) 2353af6ab5fSopenharmony_ci{ 2363af6ab5fSopenharmony_ci CallNode(switchStmt->Discriminant()); 2373af6ab5fSopenharmony_ci auto localCtx = LexicalScopeCreateOrEnter<varbinder::LocalScopeWithTypeAlias>(VarBinder(), switchStmt); 2383af6ab5fSopenharmony_ci AttachLabelToScope(switchStmt); 2393af6ab5fSopenharmony_ci BindScopeNode(localCtx.GetScope(), switchStmt); 2403af6ab5fSopenharmony_ci CallNode(switchStmt->Cases()); 2413af6ab5fSopenharmony_ci} 2423af6ab5fSopenharmony_ci 2433af6ab5fSopenharmony_civoid ScopesInitPhase::VisitWhileStatement(ir::WhileStatement *whileStmt) 2443af6ab5fSopenharmony_ci{ 2453af6ab5fSopenharmony_ci CallNode(whileStmt->Test()); 2463af6ab5fSopenharmony_ci auto lexicalScope = LexicalScopeCreateOrEnter<varbinder::LoopScope>(VarBinder(), whileStmt); 2473af6ab5fSopenharmony_ci AttachLabelToScope(whileStmt); 2483af6ab5fSopenharmony_ci BindScopeNode(lexicalScope.GetScope(), whileStmt); 2493af6ab5fSopenharmony_ci CallNode(whileStmt->Body()); 2503af6ab5fSopenharmony_ci} 2513af6ab5fSopenharmony_ci 2523af6ab5fSopenharmony_civoid ScopesInitPhase::VisitETSStructDeclaration(ir::ETSStructDeclaration *structDecl) 2533af6ab5fSopenharmony_ci{ 2543af6ab5fSopenharmony_ci Iterate(structDecl); 2553af6ab5fSopenharmony_ci BindClassDefinition(structDecl->Definition()); 2563af6ab5fSopenharmony_ci} 2573af6ab5fSopenharmony_ci 2583af6ab5fSopenharmony_civoid ScopesInitPhase::VisitClassDeclaration(ir::ClassDeclaration *classDecl) 2593af6ab5fSopenharmony_ci{ 2603af6ab5fSopenharmony_ci Iterate(classDecl); 2613af6ab5fSopenharmony_ci BindClassDefinition(classDecl->Definition()); 2623af6ab5fSopenharmony_ci} 2633af6ab5fSopenharmony_ci 2643af6ab5fSopenharmony_civoid ScopesInitPhase::VisitDoWhileStatement(ir::DoWhileStatement *doWhileStmt) 2653af6ab5fSopenharmony_ci{ 2663af6ab5fSopenharmony_ci auto lexicalScope = LexicalScopeCreateOrEnter<varbinder::LoopScope>(VarBinder(), doWhileStmt); 2673af6ab5fSopenharmony_ci AttachLabelToScope(doWhileStmt); 2683af6ab5fSopenharmony_ci BindScopeNode(lexicalScope.GetScope(), doWhileStmt); 2693af6ab5fSopenharmony_ci Iterate(doWhileStmt); 2703af6ab5fSopenharmony_ci} 2713af6ab5fSopenharmony_ci 2723af6ab5fSopenharmony_civoid ScopesInitPhase::VisitFunctionDeclaration(ir::FunctionDeclaration *funcDecl) 2733af6ab5fSopenharmony_ci{ 2743af6ab5fSopenharmony_ci const auto func = funcDecl->Function(); 2753af6ab5fSopenharmony_ci if (!funcDecl->IsAnonymous()) { 2763af6ab5fSopenharmony_ci CreateFuncDecl(func); 2773af6ab5fSopenharmony_ci } 2783af6ab5fSopenharmony_ci Iterate(funcDecl); 2793af6ab5fSopenharmony_ci} 2803af6ab5fSopenharmony_ci 2813af6ab5fSopenharmony_civoid ScopesInitPhase::VisitExportAllDeclaration(ir::ExportAllDeclaration *exportAllDecl) 2823af6ab5fSopenharmony_ci{ 2833af6ab5fSopenharmony_ci Iterate(exportAllDecl); 2843af6ab5fSopenharmony_ci const auto name = exportAllDecl->Exported() != nullptr ? exportAllDecl->Exported()->Name() : "*"; 2853af6ab5fSopenharmony_ci auto *decl = 2863af6ab5fSopenharmony_ci AddOrGetDecl<varbinder::ExportDecl>(VarBinder(), name, exportAllDecl, exportAllDecl->Start(), name, "*"); 2873af6ab5fSopenharmony_ci VarBinder()->GetScope()->AsModuleScope()->AddExportDecl(exportAllDecl, decl); 2883af6ab5fSopenharmony_ci} 2893af6ab5fSopenharmony_ci 2903af6ab5fSopenharmony_civoid ScopesInitPhase::VisitImportNamespaceSpecifier(ir::ImportNamespaceSpecifier *importSpec) 2913af6ab5fSopenharmony_ci{ 2923af6ab5fSopenharmony_ci Iterate(importSpec); 2933af6ab5fSopenharmony_ci AddOrGetDecl<varbinder::ImportDecl>(VarBinder(), importSpec->Local()->Name(), importSpec, importSpec->Start(), "*", 2943af6ab5fSopenharmony_ci importSpec->Local()->Name(), importSpec); 2953af6ab5fSopenharmony_ci} 2963af6ab5fSopenharmony_ci 2973af6ab5fSopenharmony_civoid ScopesInitPhase::VisitImportSpecifier(ir::ImportSpecifier *importSpec) 2983af6ab5fSopenharmony_ci{ 2993af6ab5fSopenharmony_ci Iterate(importSpec); 3003af6ab5fSopenharmony_ci const auto *imported = importSpec->Imported(); 3013af6ab5fSopenharmony_ci AddOrGetDecl<varbinder::ImportDecl>(VarBinder(), importSpec->Local()->Name(), importSpec, importSpec->Start(), 3023af6ab5fSopenharmony_ci imported->Name(), importSpec->Local()->Name(), importSpec); 3033af6ab5fSopenharmony_ci} 3043af6ab5fSopenharmony_ci 3053af6ab5fSopenharmony_civoid ScopesInitPhase::VisitImportDefaultSpecifier(ir::ImportDefaultSpecifier *importSpec) 3063af6ab5fSopenharmony_ci{ 3073af6ab5fSopenharmony_ci Iterate(importSpec); 3083af6ab5fSopenharmony_ci const auto *local = importSpec->Local(); 3093af6ab5fSopenharmony_ci AddOrGetDecl<varbinder::ImportDecl>(VarBinder(), local->Name(), importSpec, local->Start(), "default", 3103af6ab5fSopenharmony_ci local->Name(), importSpec); 3113af6ab5fSopenharmony_ci} 3123af6ab5fSopenharmony_ci 3133af6ab5fSopenharmony_civoid ScopesInitPhase::VisitExportDefaultDeclaration(ir::ExportDefaultDeclaration *exportDecl) 3143af6ab5fSopenharmony_ci{ 3153af6ab5fSopenharmony_ci ExportDeclarationContext exportDeclCtx(VarBinder()); 3163af6ab5fSopenharmony_ci Iterate(exportDecl); 3173af6ab5fSopenharmony_ci exportDeclCtx.BindExportDecl(exportDecl); 3183af6ab5fSopenharmony_ci} 3193af6ab5fSopenharmony_ci 3203af6ab5fSopenharmony_civoid ScopesInitPhase::VisitArrowFunctionExpression(ir::ArrowFunctionExpression *arrowExpr) 3213af6ab5fSopenharmony_ci{ 3223af6ab5fSopenharmony_ci Iterate(arrowExpr); 3233af6ab5fSopenharmony_ci} 3243af6ab5fSopenharmony_ci 3253af6ab5fSopenharmony_civoid ScopesInitPhase::VisitDirectEvalExpression(ir::DirectEvalExpression *directCallExpr) 3263af6ab5fSopenharmony_ci{ 3273af6ab5fSopenharmony_ci VarBinder()->PropagateDirectEval(); 3283af6ab5fSopenharmony_ci Iterate(directCallExpr); 3293af6ab5fSopenharmony_ci} 3303af6ab5fSopenharmony_ci 3313af6ab5fSopenharmony_civoid ScopesInitPhase::VisitExportNamedDeclaration(ir::ExportNamedDeclaration *exportDecl) 3323af6ab5fSopenharmony_ci{ 3333af6ab5fSopenharmony_ci if (exportDecl->Decl() != nullptr) { 3343af6ab5fSopenharmony_ci ExportDeclarationContext exportDeclCtx(VarBinder()); 3353af6ab5fSopenharmony_ci Iterate(exportDecl); 3363af6ab5fSopenharmony_ci exportDeclCtx.BindExportDecl(exportDecl); 3373af6ab5fSopenharmony_ci } else { 3383af6ab5fSopenharmony_ci varbinder::ModuleScope::ExportDeclList exportDecls(program_->Allocator()->Adapter()); 3393af6ab5fSopenharmony_ci 3403af6ab5fSopenharmony_ci for (auto *spec : exportDecl->Specifiers()) { 3413af6ab5fSopenharmony_ci auto *decl = 3423af6ab5fSopenharmony_ci AddOrGetDecl<varbinder::ExportDecl>(VarBinder(), spec->Local()->Name(), spec, exportDecl->Start(), 3433af6ab5fSopenharmony_ci spec->Exported()->Name(), spec->Local()->Name(), spec); 3443af6ab5fSopenharmony_ci exportDecls.push_back(decl); 3453af6ab5fSopenharmony_ci } 3463af6ab5fSopenharmony_ci VarBinder()->GetScope()->AsModuleScope()->AddExportDecl(exportDecl, std::move(exportDecls)); 3473af6ab5fSopenharmony_ci } 3483af6ab5fSopenharmony_ci} 3493af6ab5fSopenharmony_ci 3503af6ab5fSopenharmony_civoid ScopesInitPhase::VisitTSFunctionType(ir::TSFunctionType *funcType) 3513af6ab5fSopenharmony_ci{ 3523af6ab5fSopenharmony_ci auto lexicalScope = LexicalScopeCreateOrEnter<varbinder::FunctionParamScope>(VarBinder(), funcType); 3533af6ab5fSopenharmony_ci auto *funcParamScope = lexicalScope.GetScope(); 3543af6ab5fSopenharmony_ci BindScopeNode(funcParamScope, funcType); 3553af6ab5fSopenharmony_ci Iterate(funcType); 3563af6ab5fSopenharmony_ci} 3573af6ab5fSopenharmony_ci 3583af6ab5fSopenharmony_civoid ScopesInitPhase::SetProgram(parser::Program *program) noexcept 3593af6ab5fSopenharmony_ci{ 3603af6ab5fSopenharmony_ci program_ = program; 3613af6ab5fSopenharmony_ci} 3623af6ab5fSopenharmony_ci 3633af6ab5fSopenharmony_civoid ScopesInitPhase::CallFuncParams(const ArenaVector<ir::Expression *> ¶ms) 3643af6ab5fSopenharmony_ci{ 3653af6ab5fSopenharmony_ci // NOTE: extract params to separate class 3663af6ab5fSopenharmony_ci for (auto *param : params) { 3673af6ab5fSopenharmony_ci if (!param->IsETSParameterExpression()) { 3683af6ab5fSopenharmony_ci VarBinder()->AddParamDecl(param); 3693af6ab5fSopenharmony_ci } 3703af6ab5fSopenharmony_ci } 3713af6ab5fSopenharmony_ci CallNode(params); 3723af6ab5fSopenharmony_ci} 3733af6ab5fSopenharmony_ci 3743af6ab5fSopenharmony_civoid ScopesInitPhase::IterateNoTParams(ir::ClassDefinition *classDef) 3753af6ab5fSopenharmony_ci{ 3763af6ab5fSopenharmony_ci CallNode(classDef->Super()); 3773af6ab5fSopenharmony_ci CallNode(classDef->SuperTypeParams()); 3783af6ab5fSopenharmony_ci CallNode(classDef->Implements()); 3793af6ab5fSopenharmony_ci CallNode(classDef->Ctor()); 3803af6ab5fSopenharmony_ci CallNode(classDef->Body()); 3813af6ab5fSopenharmony_ci} 3823af6ab5fSopenharmony_ci 3833af6ab5fSopenharmony_civoid ScopesInitPhase::ThrowSyntaxError(std::string_view errorMessage, const lexer::SourcePosition &pos) const 3843af6ab5fSopenharmony_ci{ 3853af6ab5fSopenharmony_ci util::ErrorHandler::ThrowSyntaxError(Program(), errorMessage, pos); 3863af6ab5fSopenharmony_ci} 3873af6ab5fSopenharmony_ci 3883af6ab5fSopenharmony_civoid ScopesInitPhase::CreateFuncDecl(ir::ScriptFunction *func) 3893af6ab5fSopenharmony_ci{ 3903af6ab5fSopenharmony_ci AddOrGetDecl<varbinder::FunctionDecl>(VarBinder(), func->Id()->Name(), func, func->Id()->Start(), Allocator(), 3913af6ab5fSopenharmony_ci func->Id()->Name(), func); 3923af6ab5fSopenharmony_ci} 3933af6ab5fSopenharmony_ci 3943af6ab5fSopenharmony_ciutil::StringView ScopesInitPhase::FormInterfaceOrEnumDeclarationIdBinding(ir::Identifier *id) 3953af6ab5fSopenharmony_ci{ 3963af6ab5fSopenharmony_ci return id->Name(); 3973af6ab5fSopenharmony_ci} 3983af6ab5fSopenharmony_ci 3993af6ab5fSopenharmony_civarbinder::Decl *ScopesInitPhase::BindClassName(ir::ClassDefinition *classDef) 4003af6ab5fSopenharmony_ci{ 4013af6ab5fSopenharmony_ci const auto identNode = classDef->Ident(); 4023af6ab5fSopenharmony_ci if (identNode == nullptr) { 4033af6ab5fSopenharmony_ci return nullptr; 4043af6ab5fSopenharmony_ci } 4053af6ab5fSopenharmony_ci 4063af6ab5fSopenharmony_ci auto identDecl = AddOrGetDecl<varbinder::ConstDecl>(VarBinder(), identNode->Name(), classDef, identNode->Start(), 4073af6ab5fSopenharmony_ci identNode->Name()); 4083af6ab5fSopenharmony_ci if (identDecl != nullptr) { 4093af6ab5fSopenharmony_ci identDecl->BindNode(classDef); 4103af6ab5fSopenharmony_ci } 4113af6ab5fSopenharmony_ci return identDecl; 4123af6ab5fSopenharmony_ci} 4133af6ab5fSopenharmony_ci 4143af6ab5fSopenharmony_civoid ScopesInitPhase::BindFunctionScopes(varbinder::FunctionScope *scope, varbinder::FunctionParamScope *paramScope) 4153af6ab5fSopenharmony_ci{ 4163af6ab5fSopenharmony_ci scope->BindParamScope(paramScope); 4173af6ab5fSopenharmony_ci paramScope->BindFunctionScope(scope); 4183af6ab5fSopenharmony_ci} 4193af6ab5fSopenharmony_ci 4203af6ab5fSopenharmony_civoid ScopesInitPhase::BindClassDefinition(ir::ClassDefinition *classDef) 4213af6ab5fSopenharmony_ci{ 4223af6ab5fSopenharmony_ci if (classDef->IsGlobal()) { 4233af6ab5fSopenharmony_ci return; // We handle it in ClassDeclaration 4243af6ab5fSopenharmony_ci } 4253af6ab5fSopenharmony_ci const auto locStart = classDef->Ident()->Start(); 4263af6ab5fSopenharmony_ci const auto &className = classDef->Ident()->Name(); 4273af6ab5fSopenharmony_ci if ((classDef->Modifiers() & ir::ClassDefinitionModifiers::CLASS_DECL) != 0U) { 4283af6ab5fSopenharmony_ci AddOrGetDecl<varbinder::ClassDecl>(VarBinder(), className, classDef, locStart, className, classDef); 4293af6ab5fSopenharmony_ci } else { 4303af6ab5fSopenharmony_ci AddOrGetDecl<varbinder::LetDecl>(VarBinder(), className, classDef, locStart, className, classDef); 4313af6ab5fSopenharmony_ci } 4323af6ab5fSopenharmony_ci} 4333af6ab5fSopenharmony_ci 4343af6ab5fSopenharmony_cistd::tuple<varbinder::Decl *, varbinder::Variable *> ScopesInitPhase::AddOrGetVarDecl(ir::VariableDeclaratorFlag flag, 4353af6ab5fSopenharmony_ci lexer::SourcePosition startLoc, 4363af6ab5fSopenharmony_ci const ir::Identifier *id) 4373af6ab5fSopenharmony_ci{ 4383af6ab5fSopenharmony_ci if (auto var = id->Variable(); var != nullptr) { 4393af6ab5fSopenharmony_ci return {var->Declaration(), var}; 4403af6ab5fSopenharmony_ci } 4413af6ab5fSopenharmony_ci auto name = id->Name(); 4423af6ab5fSopenharmony_ci switch (flag) { 4433af6ab5fSopenharmony_ci case ir::VariableDeclaratorFlag::LET: 4443af6ab5fSopenharmony_ci return VarBinder()->NewVarDecl<varbinder::LetDecl>(startLoc, name); 4453af6ab5fSopenharmony_ci case ir::VariableDeclaratorFlag::VAR: 4463af6ab5fSopenharmony_ci return VarBinder()->NewVarDecl<varbinder::VarDecl>(startLoc, name); 4473af6ab5fSopenharmony_ci case ir::VariableDeclaratorFlag::CONST: 4483af6ab5fSopenharmony_ci return VarBinder()->NewVarDecl<varbinder::ConstDecl>(startLoc, name); 4493af6ab5fSopenharmony_ci default: 4503af6ab5fSopenharmony_ci UNREACHABLE(); 4513af6ab5fSopenharmony_ci } 4523af6ab5fSopenharmony_ci} 4533af6ab5fSopenharmony_ci 4543af6ab5fSopenharmony_civoid ScopesInitPhase::BindVarDecl([[maybe_unused]] ir::Identifier *binding, ir::Expression *init, varbinder::Decl *decl, 4553af6ab5fSopenharmony_ci [[maybe_unused]] varbinder::Variable *var) 4563af6ab5fSopenharmony_ci{ 4573af6ab5fSopenharmony_ci decl->BindNode(init); 4583af6ab5fSopenharmony_ci} 4593af6ab5fSopenharmony_ci 4603af6ab5fSopenharmony_civoid ScopesInitPhase::AttachLabelToScope([[maybe_unused]] ir::AstNode *node) {} 4613af6ab5fSopenharmony_ci 4623af6ab5fSopenharmony_civoid ScopesInitPhase::VisitFunctionExpression(ir::FunctionExpression *funcExpr) 4633af6ab5fSopenharmony_ci{ 4643af6ab5fSopenharmony_ci Iterate(funcExpr); 4653af6ab5fSopenharmony_ci if (!funcExpr->IsAnonymous()) { 4663af6ab5fSopenharmony_ci auto func = funcExpr->Function(); 4673af6ab5fSopenharmony_ci auto id = funcExpr->Id(); 4683af6ab5fSopenharmony_ci auto *funcParamScope = func->Scope()->ParamScope(); 4693af6ab5fSopenharmony_ci funcParamScope->BindName(Allocator(), id->Name()); 4703af6ab5fSopenharmony_ci func->SetIdent(id->Clone(Allocator(), nullptr)); 4713af6ab5fSopenharmony_ci } 4723af6ab5fSopenharmony_ci} 4733af6ab5fSopenharmony_ci 4743af6ab5fSopenharmony_civoid ScopesInitPhase::Prepare(ScopesInitPhase::PhaseContext *ctx, parser::Program *program) 4753af6ab5fSopenharmony_ci{ 4763af6ab5fSopenharmony_ci ctx_ = ctx; 4773af6ab5fSopenharmony_ci program_ = program; 4783af6ab5fSopenharmony_ci} 4793af6ab5fSopenharmony_ci 4803af6ab5fSopenharmony_civoid ScopesInitPhase::Finalize() 4813af6ab5fSopenharmony_ci{ 4823af6ab5fSopenharmony_ci AnalyzeExports(); 4833af6ab5fSopenharmony_ci} 4843af6ab5fSopenharmony_ci 4853af6ab5fSopenharmony_civoid ScopesInitPhase::AnalyzeExports() 4863af6ab5fSopenharmony_ci{ 4873af6ab5fSopenharmony_ci if (Program()->Kind() == parser::ScriptKind::MODULE && VarBinder()->TopScope()->IsModuleScope() && 4883af6ab5fSopenharmony_ci !VarBinder()->TopScope()->AsModuleScope()->ExportAnalysis()) { 4893af6ab5fSopenharmony_ci ThrowSyntaxError("Invalid exported binding", Program()->Ast()->End()); 4903af6ab5fSopenharmony_ci } 4913af6ab5fSopenharmony_ci} 4923af6ab5fSopenharmony_ci 4933af6ab5fSopenharmony_civoid ScopeInitTyped::VisitTSModuleDeclaration(ir::TSModuleDeclaration *moduleDecl) 4943af6ab5fSopenharmony_ci{ 4953af6ab5fSopenharmony_ci if (!moduleDecl->IsExternalOrAmbient()) { 4963af6ab5fSopenharmony_ci auto name = moduleDecl->Name()->AsIdentifier()->Name(); 4973af6ab5fSopenharmony_ci auto *decl = AddOrGetDecl<varbinder::VarDecl>(VarBinder(), name, moduleDecl, moduleDecl->Name()->Start(), name); 4983af6ab5fSopenharmony_ci decl->BindNode(moduleDecl); 4993af6ab5fSopenharmony_ci } 5003af6ab5fSopenharmony_ci auto localCtx = LexicalScopeCreateOrEnter<varbinder::LocalScope>(VarBinder(), moduleDecl); 5013af6ab5fSopenharmony_ci BindScopeNode(localCtx.GetScope(), moduleDecl); 5023af6ab5fSopenharmony_ci Iterate(moduleDecl); 5033af6ab5fSopenharmony_ci} 5043af6ab5fSopenharmony_ci 5053af6ab5fSopenharmony_civoid ScopeInitTyped::VisitTSModuleBlock(ir::TSModuleBlock *block) 5063af6ab5fSopenharmony_ci{ 5073af6ab5fSopenharmony_ci auto localCtx = LexicalScopeCreateOrEnter<varbinder::LocalScope>(VarBinder(), block); 5083af6ab5fSopenharmony_ci Iterate(block); 5093af6ab5fSopenharmony_ci BindScopeNode(localCtx.GetScope(), block); 5103af6ab5fSopenharmony_ci} 5113af6ab5fSopenharmony_ci 5123af6ab5fSopenharmony_civoid ScopeInitTyped::VisitTSTypeAliasDeclaration(ir::TSTypeAliasDeclaration *typeAliasDecl) 5133af6ab5fSopenharmony_ci{ 5143af6ab5fSopenharmony_ci const auto id = typeAliasDecl->Id(); 5153af6ab5fSopenharmony_ci varbinder::TSBinding tsBinding(Allocator(), id->Name()); 5163af6ab5fSopenharmony_ci auto *decl = VarBinder()->AddTsDecl<varbinder::TypeAliasDecl>(id->Start(), tsBinding.View()); 5173af6ab5fSopenharmony_ci auto typeParamsCtx = LexicalScopeCreateOrEnter<varbinder::LocalScope>(VarBinder(), typeAliasDecl->TypeParams()); 5183af6ab5fSopenharmony_ci decl->BindNode(typeAliasDecl); 5193af6ab5fSopenharmony_ci Iterate(typeAliasDecl); 5203af6ab5fSopenharmony_ci} 5213af6ab5fSopenharmony_ci 5223af6ab5fSopenharmony_ciutil::StringView ScopeInitTyped::FormInterfaceOrEnumDeclarationIdBinding(ir::Identifier *id) 5233af6ab5fSopenharmony_ci{ 5243af6ab5fSopenharmony_ci varbinder::TSBinding tsBinding(Allocator(), id->Name()); 5253af6ab5fSopenharmony_ci return tsBinding.View(); 5263af6ab5fSopenharmony_ci} 5273af6ab5fSopenharmony_ci 5283af6ab5fSopenharmony_civoid ScopeInitTyped::VisitTSInterfaceDeclaration(ir::TSInterfaceDeclaration *interfDecl) 5293af6ab5fSopenharmony_ci{ 5303af6ab5fSopenharmony_ci const auto &bindings = VarBinder()->GetScope()->Bindings(); 5313af6ab5fSopenharmony_ci const auto ident = interfDecl->Id(); 5323af6ab5fSopenharmony_ci const auto name = FormInterfaceOrEnumDeclarationIdBinding(ident); 5333af6ab5fSopenharmony_ci auto res = bindings.find(name); 5343af6ab5fSopenharmony_ci 5353af6ab5fSopenharmony_ci varbinder::InterfaceDecl *decl {}; 5363af6ab5fSopenharmony_ci 5373af6ab5fSopenharmony_ci bool alreadyExists = false; 5383af6ab5fSopenharmony_ci if (res == bindings.end()) { 5393af6ab5fSopenharmony_ci decl = VarBinder()->AddTsDecl<varbinder::InterfaceDecl>(ident->Start(), Allocator(), name); 5403af6ab5fSopenharmony_ci } else if (!AllowInterfaceRedeclaration()) { 5413af6ab5fSopenharmony_ci ThrowSyntaxError("Interface redeclaration is not allowed", interfDecl->Start()); 5423af6ab5fSopenharmony_ci } else if (!res->second->Declaration()->IsInterfaceDecl()) { 5433af6ab5fSopenharmony_ci VarBinder()->ThrowRedeclaration(ident->Start(), ident->Name()); 5443af6ab5fSopenharmony_ci } else { 5453af6ab5fSopenharmony_ci decl = res->second->Declaration()->AsInterfaceDecl(); 5463af6ab5fSopenharmony_ci alreadyExists = true; 5473af6ab5fSopenharmony_ci } 5483af6ab5fSopenharmony_ci 5493af6ab5fSopenharmony_ci CallNode(ident); 5503af6ab5fSopenharmony_ci auto typeParamsCtx = LexicalScopeCreateOrEnter<varbinder::LocalScope>(VarBinder(), interfDecl->TypeParams()); 5513af6ab5fSopenharmony_ci CallNode(interfDecl->TypeParams()); 5523af6ab5fSopenharmony_ci CallNode(interfDecl->Extends()); 5533af6ab5fSopenharmony_ci 5543af6ab5fSopenharmony_ci auto localScope = LexicalScopeCreateOrEnter<varbinder::LocalScope>(VarBinder(), interfDecl); 5553af6ab5fSopenharmony_ci auto *identDecl = 5563af6ab5fSopenharmony_ci AddOrGetDecl<varbinder::ConstDecl>(VarBinder(), ident->Name(), interfDecl, ident->Start(), ident->Name()); 5573af6ab5fSopenharmony_ci identDecl->BindNode(interfDecl); 5583af6ab5fSopenharmony_ci BindScopeNode(localScope.GetScope(), interfDecl); 5593af6ab5fSopenharmony_ci 5603af6ab5fSopenharmony_ci CallNode(interfDecl->Body()); 5613af6ab5fSopenharmony_ci if (!alreadyExists) { 5623af6ab5fSopenharmony_ci decl->BindNode(interfDecl); 5633af6ab5fSopenharmony_ci } 5643af6ab5fSopenharmony_ci decl->Add(interfDecl); 5653af6ab5fSopenharmony_ci} 5663af6ab5fSopenharmony_ci 5673af6ab5fSopenharmony_civoid ScopeInitTyped::VisitTSEnumMember(ir::TSEnumMember *enumMember) 5683af6ab5fSopenharmony_ci{ 5693af6ab5fSopenharmony_ci const auto key = enumMember->Key(); 5703af6ab5fSopenharmony_ci util::StringView name; 5713af6ab5fSopenharmony_ci if (key->IsIdentifier()) { 5723af6ab5fSopenharmony_ci name = key->AsIdentifier()->Name(); 5733af6ab5fSopenharmony_ci } else if (key->IsStringLiteral()) { 5743af6ab5fSopenharmony_ci name = key->AsStringLiteral()->Str(); 5753af6ab5fSopenharmony_ci } else { 5763af6ab5fSopenharmony_ci UNREACHABLE(); 5773af6ab5fSopenharmony_ci } 5783af6ab5fSopenharmony_ci auto *decl = AddOrGetDecl<varbinder::EnumDecl>(VarBinder(), name, enumMember, key->Start(), name); 5793af6ab5fSopenharmony_ci decl->BindNode(enumMember); 5803af6ab5fSopenharmony_ci} 5813af6ab5fSopenharmony_ci 5823af6ab5fSopenharmony_civoid ScopeInitTyped::VisitTSEnumDeclaration(ir::TSEnumDeclaration *enumDecl) 5833af6ab5fSopenharmony_ci{ 5843af6ab5fSopenharmony_ci util::StringView ident = FormInterfaceOrEnumDeclarationIdBinding(enumDecl->Key()); 5853af6ab5fSopenharmony_ci const auto &bindings = VarBinder()->GetScope()->Bindings(); 5863af6ab5fSopenharmony_ci auto res = bindings.find(ident); 5873af6ab5fSopenharmony_ci 5883af6ab5fSopenharmony_ci varbinder::EnumLiteralDecl *decl {}; 5893af6ab5fSopenharmony_ci if (res == bindings.end()) { 5903af6ab5fSopenharmony_ci decl = VarBinder()->AddTsDecl<varbinder::EnumLiteralDecl>(enumDecl->Start(), ident, enumDecl->IsConst()); 5913af6ab5fSopenharmony_ci varbinder::LexicalScope enumCtx = LexicalScopeCreateOrEnter<varbinder::LocalScope>(VarBinder(), enumDecl); 5923af6ab5fSopenharmony_ci decl->BindScope(enumCtx.GetScope()); 5933af6ab5fSopenharmony_ci BindScopeNode(VarBinder()->GetScope()->AsLocalScope(), enumDecl); 5943af6ab5fSopenharmony_ci } else if (!res->second->Declaration()->IsEnumLiteralDecl() || 5953af6ab5fSopenharmony_ci (enumDecl->IsConst() ^ res->second->Declaration()->AsEnumLiteralDecl()->IsConst()) != 0) { 5963af6ab5fSopenharmony_ci auto loc = enumDecl->Key()->End(); 5973af6ab5fSopenharmony_ci loc.index++; 5983af6ab5fSopenharmony_ci VarBinder()->ThrowRedeclaration(loc, enumDecl->Key()->Name()); 5993af6ab5fSopenharmony_ci } else { 6003af6ab5fSopenharmony_ci decl = res->second->Declaration()->AsEnumLiteralDecl(); 6013af6ab5fSopenharmony_ci 6023af6ab5fSopenharmony_ci auto scopeCtx = varbinder::LexicalScope<varbinder::LocalScope>::Enter(VarBinder(), decl->Scope()); 6033af6ab5fSopenharmony_ci } 6043af6ab5fSopenharmony_ci decl->BindNode(enumDecl); 6053af6ab5fSopenharmony_ci Iterate(enumDecl); 6063af6ab5fSopenharmony_ci} 6073af6ab5fSopenharmony_ci 6083af6ab5fSopenharmony_civoid ScopeInitTyped::VisitTSTypeParameter(ir::TSTypeParameter *typeParam) 6093af6ab5fSopenharmony_ci{ 6103af6ab5fSopenharmony_ci auto name = typeParam->Name()->Name(); 6113af6ab5fSopenharmony_ci auto decl = AddOrGetDecl<varbinder::TypeParameterDecl>(VarBinder(), name, typeParam, typeParam->Start(), name); 6123af6ab5fSopenharmony_ci decl->BindNode(typeParam); 6133af6ab5fSopenharmony_ci Iterate(typeParam); 6143af6ab5fSopenharmony_ci} 6153af6ab5fSopenharmony_ci 6163af6ab5fSopenharmony_civoid ScopeInitTyped::VisitTSTypeParameterDeclaration(ir::TSTypeParameterDeclaration *paramDecl) 6173af6ab5fSopenharmony_ci{ 6183af6ab5fSopenharmony_ci BindScopeNode(VarBinder()->GetScope()->AsLocalScope(), paramDecl); 6193af6ab5fSopenharmony_ci Iterate(paramDecl); 6203af6ab5fSopenharmony_ci} 6213af6ab5fSopenharmony_ci 6223af6ab5fSopenharmony_civoid ScopeInitTyped::VisitClassDefinition(ir::ClassDefinition *classDef) 6233af6ab5fSopenharmony_ci{ 6243af6ab5fSopenharmony_ci auto typeParamsCtx = LexicalScopeCreateOrEnter<varbinder::LocalScope>(VarBinder(), classDef->TypeParams()); 6253af6ab5fSopenharmony_ci CallNode(classDef->TypeParams()); 6263af6ab5fSopenharmony_ci 6273af6ab5fSopenharmony_ci auto classCtx = LexicalScopeCreateOrEnter<varbinder::LocalScope>(VarBinder(), classDef); 6283af6ab5fSopenharmony_ci BindClassName(classDef); 6293af6ab5fSopenharmony_ci AddOrGetDecl<varbinder::ConstDecl>(VarBinder(), classDef->PrivateId(), classDef, classDef->Start(), 6303af6ab5fSopenharmony_ci classDef->PrivateId()); 6313af6ab5fSopenharmony_ci BindScopeNode(classCtx.GetScope(), classDef); 6323af6ab5fSopenharmony_ci IterateNoTParams(classDef); 6333af6ab5fSopenharmony_ci} 6343af6ab5fSopenharmony_ci 6353af6ab5fSopenharmony_civoid InitScopesPhaseTs::VisitExportDefaultDeclaration(ir::ExportDefaultDeclaration *exportDecl) 6363af6ab5fSopenharmony_ci{ 6373af6ab5fSopenharmony_ci ExportDeclarationContext exportDeclCtx(VarBinder()); 6383af6ab5fSopenharmony_ci Iterate(exportDecl); 6393af6ab5fSopenharmony_ci} 6403af6ab5fSopenharmony_ci 6413af6ab5fSopenharmony_civoid InitScopesPhaseTs::VisitExportNamedDeclaration(ir::ExportNamedDeclaration *exportDecl) 6423af6ab5fSopenharmony_ci{ 6433af6ab5fSopenharmony_ci ExportDeclarationContext exportDeclCtx(VarBinder()); 6443af6ab5fSopenharmony_ci Iterate(exportDecl); 6453af6ab5fSopenharmony_ci} 6463af6ab5fSopenharmony_ci 6473af6ab5fSopenharmony_civoid InitScopesPhaseTs::VisitImportDeclaration(ir::ImportDeclaration *importDeclaration) 6483af6ab5fSopenharmony_ci{ 6493af6ab5fSopenharmony_ci ImportDeclarationContext importCtx(VarBinder()); 6503af6ab5fSopenharmony_ci Iterate(importDeclaration); 6513af6ab5fSopenharmony_ci} 6523af6ab5fSopenharmony_ci 6533af6ab5fSopenharmony_civoid InitScopesPhaseTs::VisitTSFunctionType(ir::TSFunctionType *constrType) 6543af6ab5fSopenharmony_ci{ 6553af6ab5fSopenharmony_ci auto lexicalScope = 6563af6ab5fSopenharmony_ci (constrType->Scope() == nullptr) 6573af6ab5fSopenharmony_ci ? HandleFunctionSig(constrType->TypeParams(), constrType->Params(), constrType->ReturnType()) 6583af6ab5fSopenharmony_ci : constrType->Scope(); 6593af6ab5fSopenharmony_ci BindScopeNode(lexicalScope, constrType); 6603af6ab5fSopenharmony_ci} 6613af6ab5fSopenharmony_ci 6623af6ab5fSopenharmony_civoid InitScopesPhaseTs::CreateFuncDecl(ir::ScriptFunction *func) 6633af6ab5fSopenharmony_ci{ 6643af6ab5fSopenharmony_ci const auto identNode = func->Id(); 6653af6ab5fSopenharmony_ci const auto startLoc = identNode->Start(); 6663af6ab5fSopenharmony_ci const auto &bindings = VarBinder()->GetScope()->Bindings(); 6673af6ab5fSopenharmony_ci auto res = bindings.find(identNode->Name()); 6683af6ab5fSopenharmony_ci varbinder::FunctionDecl *decl {}; 6693af6ab5fSopenharmony_ci 6703af6ab5fSopenharmony_ci if (res == bindings.end()) { 6713af6ab5fSopenharmony_ci decl = VarBinder()->AddDecl<varbinder::FunctionDecl>(startLoc, Allocator(), identNode->Name(), func); 6723af6ab5fSopenharmony_ci } else { 6733af6ab5fSopenharmony_ci varbinder::Decl *currentDecl = res->second->Declaration(); 6743af6ab5fSopenharmony_ci 6753af6ab5fSopenharmony_ci auto &existing = currentDecl->AsFunctionDecl()->Decls(); 6763af6ab5fSopenharmony_ci if (std::find(existing.begin(), existing.end(), func) != existing.end()) { 6773af6ab5fSopenharmony_ci return; 6783af6ab5fSopenharmony_ci } 6793af6ab5fSopenharmony_ci 6803af6ab5fSopenharmony_ci if (!currentDecl->IsFunctionDecl() || 6813af6ab5fSopenharmony_ci !currentDecl->AsFunctionDecl()->Node()->AsScriptFunction()->IsOverload()) { 6823af6ab5fSopenharmony_ci VarBinder()->ThrowRedeclaration(startLoc, currentDecl->Name()); 6833af6ab5fSopenharmony_ci } 6843af6ab5fSopenharmony_ci decl = currentDecl->AsFunctionDecl(); 6853af6ab5fSopenharmony_ci } 6863af6ab5fSopenharmony_ci 6873af6ab5fSopenharmony_ci decl->Add(func); 6883af6ab5fSopenharmony_ci} 6893af6ab5fSopenharmony_ci 6903af6ab5fSopenharmony_civoid InitScopesPhaseTs::VisitTSConstructorType(ir::TSConstructorType *constrT) 6913af6ab5fSopenharmony_ci{ 6923af6ab5fSopenharmony_ci auto funcParamScope = (constrT->Scope() == nullptr) 6933af6ab5fSopenharmony_ci ? HandleFunctionSig(constrT->TypeParams(), constrT->Params(), constrT->ReturnType()) 6943af6ab5fSopenharmony_ci : constrT->Scope(); 6953af6ab5fSopenharmony_ci BindScopeNode(funcParamScope, constrT); 6963af6ab5fSopenharmony_ci} 6973af6ab5fSopenharmony_ci 6983af6ab5fSopenharmony_civoid InitScopesPhaseTs::VisitArrowFunctionExpression(ir::ArrowFunctionExpression *arrowFExpr) 6993af6ab5fSopenharmony_ci{ 7003af6ab5fSopenharmony_ci auto typeParamsCtx = 7013af6ab5fSopenharmony_ci LexicalScopeCreateOrEnter<varbinder::LocalScope>(VarBinder(), arrowFExpr->Function()->TypeParams()); 7023af6ab5fSopenharmony_ci Iterate(arrowFExpr); 7033af6ab5fSopenharmony_ci} 7043af6ab5fSopenharmony_ci 7053af6ab5fSopenharmony_civoid InitScopesPhaseTs::VisitTSSignatureDeclaration(ir::TSSignatureDeclaration *signDecl) 7063af6ab5fSopenharmony_ci{ 7073af6ab5fSopenharmony_ci auto funcParamScope = (signDecl->Scope() == nullptr) ? HandleFunctionSig(signDecl->TypeParams(), signDecl->Params(), 7083af6ab5fSopenharmony_ci signDecl->ReturnTypeAnnotation()) 7093af6ab5fSopenharmony_ci : signDecl->Scope(); 7103af6ab5fSopenharmony_ci BindScopeNode(funcParamScope, signDecl); 7113af6ab5fSopenharmony_ci} 7123af6ab5fSopenharmony_ci 7133af6ab5fSopenharmony_civoid InitScopesPhaseTs::VisitTSMethodSignature(ir::TSMethodSignature *methodSign) 7143af6ab5fSopenharmony_ci{ 7153af6ab5fSopenharmony_ci auto funcParamScope = 7163af6ab5fSopenharmony_ci (methodSign->Scope() == nullptr) 7173af6ab5fSopenharmony_ci ? HandleFunctionSig(methodSign->TypeParams(), methodSign->Params(), methodSign->ReturnTypeAnnotation()) 7183af6ab5fSopenharmony_ci : methodSign->Scope(); 7193af6ab5fSopenharmony_ci BindScopeNode(funcParamScope, methodSign); 7203af6ab5fSopenharmony_ci} 7213af6ab5fSopenharmony_ci 7223af6ab5fSopenharmony_civoid InitScopesPhaseETS::RunExternalNode(ir::AstNode *node, varbinder::VarBinder *varbinder) 7233af6ab5fSopenharmony_ci{ 7243af6ab5fSopenharmony_ci auto program = parser::Program(varbinder->Allocator(), varbinder); 7253af6ab5fSopenharmony_ci RunExternalNode(node, &program); 7263af6ab5fSopenharmony_ci} 7273af6ab5fSopenharmony_ci 7283af6ab5fSopenharmony_civoid InitScopesPhaseETS::RunExternalNode(ir::AstNode *node, parser::Program *ctx) 7293af6ab5fSopenharmony_ci{ 7303af6ab5fSopenharmony_ci auto scopesPhase = InitScopesPhaseETS(); 7313af6ab5fSopenharmony_ci scopesPhase.SetProgram(ctx); 7323af6ab5fSopenharmony_ci scopesPhase.CallNode(node); 7333af6ab5fSopenharmony_ci} 7343af6ab5fSopenharmony_ci 7353af6ab5fSopenharmony_cibool InitScopesPhaseETS::Perform(PhaseContext *ctx, parser::Program *program) 7363af6ab5fSopenharmony_ci{ 7373af6ab5fSopenharmony_ci Prepare(ctx, program); 7383af6ab5fSopenharmony_ci 7393af6ab5fSopenharmony_ci if (program->VarBinder()->TopScope() == nullptr) { 7403af6ab5fSopenharmony_ci program->VarBinder()->InitTopScope(); 7413af6ab5fSopenharmony_ci BindScopeNode(GetScope(), program->Ast()); 7423af6ab5fSopenharmony_ci AddGlobalToBinder(program); 7433af6ab5fSopenharmony_ci } 7443af6ab5fSopenharmony_ci HandleProgram(program); 7453af6ab5fSopenharmony_ci Finalize(); 7463af6ab5fSopenharmony_ci return true; 7473af6ab5fSopenharmony_ci} 7483af6ab5fSopenharmony_ci 7493af6ab5fSopenharmony_civoid InitScopesPhaseETS::HandleProgram(parser::Program *program) 7503af6ab5fSopenharmony_ci{ 7513af6ab5fSopenharmony_ci for (auto &[_, prog_list] : program->ExternalSources()) { 7523af6ab5fSopenharmony_ci (void)_; 7533af6ab5fSopenharmony_ci auto savedTopScope(program->VarBinder()->TopScope()); 7543af6ab5fSopenharmony_ci auto mainProg = prog_list.front(); 7553af6ab5fSopenharmony_ci mainProg->VarBinder()->InitTopScope(); 7563af6ab5fSopenharmony_ci AddGlobalToBinder(mainProg); 7573af6ab5fSopenharmony_ci BindScopeNode(mainProg->VarBinder()->GetScope(), mainProg->Ast()); 7583af6ab5fSopenharmony_ci auto globalClass = mainProg->GlobalClass(); 7593af6ab5fSopenharmony_ci auto globalScope = mainProg->GlobalScope(); 7603af6ab5fSopenharmony_ci for (auto &prog : prog_list) { 7613af6ab5fSopenharmony_ci prog->SetGlobalClass(globalClass); 7623af6ab5fSopenharmony_ci BindScopeNode(prog->VarBinder()->GetScope(), prog->Ast()); 7633af6ab5fSopenharmony_ci prog->VarBinder()->ResetTopScope(globalScope); 7643af6ab5fSopenharmony_ci if (mainProg->Ast() != nullptr) { 7653af6ab5fSopenharmony_ci InitScopesPhaseETS().Perform(Context(), prog); 7663af6ab5fSopenharmony_ci } 7673af6ab5fSopenharmony_ci } 7683af6ab5fSopenharmony_ci program->VarBinder()->ResetTopScope(savedTopScope); 7693af6ab5fSopenharmony_ci } 7703af6ab5fSopenharmony_ci ASSERT(program->Ast() != nullptr); 7713af6ab5fSopenharmony_ci 7723af6ab5fSopenharmony_ci HandleETSScript(program->Ast()); 7733af6ab5fSopenharmony_ci} 7743af6ab5fSopenharmony_ci 7753af6ab5fSopenharmony_civoid InitScopesPhaseETS::BindVarDecl(ir::Identifier *binding, ir::Expression *init, varbinder::Decl *decl, 7763af6ab5fSopenharmony_ci varbinder::Variable *var) 7773af6ab5fSopenharmony_ci{ 7783af6ab5fSopenharmony_ci binding->SetVariable(var); 7793af6ab5fSopenharmony_ci var->SetScope(VarBinder()->GetScope()); 7803af6ab5fSopenharmony_ci var->AddFlag(varbinder::VariableFlags::LOCAL); 7813af6ab5fSopenharmony_ci decl->BindNode(init); 7823af6ab5fSopenharmony_ci} 7833af6ab5fSopenharmony_ci 7843af6ab5fSopenharmony_civoid InitScopesPhaseETS::VisitBlockExpression(ir::BlockExpression *blockExpr) 7853af6ab5fSopenharmony_ci{ 7863af6ab5fSopenharmony_ci auto localCtx = LexicalScopeCreateOrEnter<varbinder::LocalScope>(VarBinder(), blockExpr); 7873af6ab5fSopenharmony_ci if (blockExpr->Scope() == nullptr) { 7883af6ab5fSopenharmony_ci BindScopeNode(GetScope(), blockExpr); 7893af6ab5fSopenharmony_ci } 7903af6ab5fSopenharmony_ci Iterate(blockExpr); 7913af6ab5fSopenharmony_ci} 7923af6ab5fSopenharmony_ci 7933af6ab5fSopenharmony_civoid InitScopesPhaseETS::VisitClassStaticBlock(ir::ClassStaticBlock *staticBlock) 7943af6ab5fSopenharmony_ci{ 7953af6ab5fSopenharmony_ci const auto func = staticBlock->Function(); 7963af6ab5fSopenharmony_ci 7973af6ab5fSopenharmony_ci { 7983af6ab5fSopenharmony_ci auto funcParamCtx = (func->Scope() == nullptr) 7993af6ab5fSopenharmony_ci ? varbinder::LexicalScope<varbinder::FunctionParamScope>(VarBinder()) 8003af6ab5fSopenharmony_ci : varbinder::LexicalScope<varbinder::FunctionParamScope>::Enter( 8013af6ab5fSopenharmony_ci VarBinder(), func->Scope()->ParamScope()); 8023af6ab5fSopenharmony_ci auto *funcParamScope = funcParamCtx.GetScope(); 8033af6ab5fSopenharmony_ci auto funcCtx = LexicalScopeCreateOrEnter<varbinder::FunctionScope>(VarBinder(), func); 8043af6ab5fSopenharmony_ci auto *funcScope = funcCtx.GetScope(); 8053af6ab5fSopenharmony_ci 8063af6ab5fSopenharmony_ci func->Body()->AsBlockStatement()->SetScope(funcScope); 8073af6ab5fSopenharmony_ci BindScopeNode(funcScope, func); 8083af6ab5fSopenharmony_ci funcParamScope->BindNode(func); 8093af6ab5fSopenharmony_ci BindFunctionScopes(funcScope, funcParamScope); 8103af6ab5fSopenharmony_ci Iterate(func->Body()->AsBlockStatement()); 8113af6ab5fSopenharmony_ci } 8123af6ab5fSopenharmony_ci 8133af6ab5fSopenharmony_ci auto classCtx = varbinder::LexicalScope<varbinder::LocalScope>::Enter( 8143af6ab5fSopenharmony_ci VarBinder(), VarBinder()->GetScope()->AsClassScope()->StaticMethodScope()); 8153af6ab5fSopenharmony_ci 8163af6ab5fSopenharmony_ci if (func->Id()->Variable() != nullptr) { 8173af6ab5fSopenharmony_ci return; 8183af6ab5fSopenharmony_ci } 8193af6ab5fSopenharmony_ci 8203af6ab5fSopenharmony_ci auto [_, var] = VarBinder()->NewVarDecl<varbinder::FunctionDecl>(staticBlock->Start(), Allocator(), 8213af6ab5fSopenharmony_ci func->Id()->Name(), staticBlock); 8223af6ab5fSopenharmony_ci (void)_; 8233af6ab5fSopenharmony_ci var->AddFlag(varbinder::VariableFlags::METHOD); 8243af6ab5fSopenharmony_ci func->Id()->SetVariable(var); 8253af6ab5fSopenharmony_ci} 8263af6ab5fSopenharmony_ci 8273af6ab5fSopenharmony_civoid InitScopesPhaseETS::VisitImportNamespaceSpecifier(ir::ImportNamespaceSpecifier *importSpec) 8283af6ab5fSopenharmony_ci{ 8293af6ab5fSopenharmony_ci if (importSpec->Local()->Name().Empty()) { 8303af6ab5fSopenharmony_ci return; 8313af6ab5fSopenharmony_ci } 8323af6ab5fSopenharmony_ci AddOrGetDecl<varbinder::ImportDecl>(VarBinder(), importSpec->Local()->Name(), importSpec, importSpec->Start(), 8333af6ab5fSopenharmony_ci importSpec->Local()->Name(), importSpec->Local()->Name(), importSpec); 8343af6ab5fSopenharmony_ci auto var = 8353af6ab5fSopenharmony_ci VarBinder()->GetScope()->FindLocal(importSpec->Local()->Name(), varbinder::ResolveBindingOptions::BINDINGS); 8363af6ab5fSopenharmony_ci importSpec->Local()->SetVariable(var); 8373af6ab5fSopenharmony_ci Iterate(importSpec); 8383af6ab5fSopenharmony_ci} 8393af6ab5fSopenharmony_ci 8403af6ab5fSopenharmony_civoid InitScopesPhaseETS::VisitImportSpecifier(ir::ImportSpecifier *importSpec) 8413af6ab5fSopenharmony_ci{ 8423af6ab5fSopenharmony_ci if (importSpec->Parent()->AsETSImportDeclaration()->IsPureDynamic()) { 8433af6ab5fSopenharmony_ci auto [decl, var] = 8443af6ab5fSopenharmony_ci VarBinder()->NewVarDecl<varbinder::LetDecl>(importSpec->Start(), importSpec->Local()->Name(), importSpec); 8453af6ab5fSopenharmony_ci var->AddFlag(varbinder::VariableFlags::INITIALIZED); 8463af6ab5fSopenharmony_ci } 8473af6ab5fSopenharmony_ci Iterate(importSpec); 8483af6ab5fSopenharmony_ci} 8493af6ab5fSopenharmony_ci 8503af6ab5fSopenharmony_ci// Auxiliary method to avoid extra nested levels and too large function size 8513af6ab5fSopenharmony_civoid AddOverload(ir::MethodDefinition *overload, varbinder::Variable *variable) noexcept 8523af6ab5fSopenharmony_ci{ 8533af6ab5fSopenharmony_ci auto *currentNode = variable->Declaration()->Node(); 8543af6ab5fSopenharmony_ci currentNode->AsMethodDefinition()->AddOverload(overload); 8553af6ab5fSopenharmony_ci overload->Id()->SetVariable(variable); 8563af6ab5fSopenharmony_ci overload->SetParent(currentNode); 8573af6ab5fSopenharmony_ci} 8583af6ab5fSopenharmony_ci 8593af6ab5fSopenharmony_civoid InitScopesPhaseETS::DeclareClassMethod(ir::MethodDefinition *method) 8603af6ab5fSopenharmony_ci{ 8613af6ab5fSopenharmony_ci ASSERT(VarBinder()->GetScope()->IsClassScope()); 8623af6ab5fSopenharmony_ci 8633af6ab5fSopenharmony_ci if ((method->AsMethodDefinition()->Function()->Flags() & ir::ScriptFunctionFlags::OVERLOAD) != 0) { 8643af6ab5fSopenharmony_ci return; 8653af6ab5fSopenharmony_ci } 8663af6ab5fSopenharmony_ci 8673af6ab5fSopenharmony_ci const auto methodName = method->Id(); 8683af6ab5fSopenharmony_ci auto *const clsScope = VarBinder()->GetScope()->AsClassScope(); 8693af6ab5fSopenharmony_ci auto options = 8703af6ab5fSopenharmony_ci method->IsStatic() 8713af6ab5fSopenharmony_ci ? varbinder::ResolveBindingOptions::STATIC_VARIABLES | varbinder::ResolveBindingOptions::STATIC_DECLARATION 8723af6ab5fSopenharmony_ci : varbinder::ResolveBindingOptions::VARIABLES | varbinder::ResolveBindingOptions::DECLARATION; 8733af6ab5fSopenharmony_ci if (clsScope->FindLocal(methodName->Name(), options) != nullptr) { 8743af6ab5fSopenharmony_ci VarBinder()->ThrowRedeclaration(methodName->Start(), methodName->Name()); 8753af6ab5fSopenharmony_ci } 8763af6ab5fSopenharmony_ci 8773af6ab5fSopenharmony_ci varbinder::LocalScope *targetScope {}; 8783af6ab5fSopenharmony_ci if (method->IsStatic() || method->IsConstructor()) { 8793af6ab5fSopenharmony_ci targetScope = clsScope->StaticMethodScope(); 8803af6ab5fSopenharmony_ci } else { 8813af6ab5fSopenharmony_ci targetScope = clsScope->InstanceMethodScope(); 8823af6ab5fSopenharmony_ci } 8833af6ab5fSopenharmony_ci auto *found = targetScope->FindLocal(methodName->Name(), varbinder::ResolveBindingOptions::BINDINGS); 8843af6ab5fSopenharmony_ci 8853af6ab5fSopenharmony_ci MaybeAddOverload(method, methodName, found, clsScope, targetScope); 8863af6ab5fSopenharmony_ci} 8873af6ab5fSopenharmony_ci 8883af6ab5fSopenharmony_civoid InitScopesPhaseETS::MaybeAddOverload(ir::MethodDefinition *method, ir::Identifier *methodName, 8893af6ab5fSopenharmony_ci varbinder::Variable *found, varbinder::ClassScope *clsScope, 8903af6ab5fSopenharmony_ci varbinder::LocalScope *targetScope) 8913af6ab5fSopenharmony_ci{ 8923af6ab5fSopenharmony_ci if (found == nullptr) { 8933af6ab5fSopenharmony_ci auto classCtx = varbinder::LexicalScope<varbinder::LocalScope>::Enter(VarBinder(), targetScope); 8943af6ab5fSopenharmony_ci 8953af6ab5fSopenharmony_ci auto *var = methodName->Variable(); 8963af6ab5fSopenharmony_ci if (var == nullptr) { 8973af6ab5fSopenharmony_ci var = std::get<1>(VarBinder()->NewVarDecl<varbinder::FunctionDecl>(methodName->Start(), Allocator(), 8983af6ab5fSopenharmony_ci methodName->Name(), method)); 8993af6ab5fSopenharmony_ci var->SetScope(clsScope); 9003af6ab5fSopenharmony_ci var->AddFlag(varbinder::VariableFlags::METHOD); 9013af6ab5fSopenharmony_ci methodName->SetVariable(var); 9023af6ab5fSopenharmony_ci } 9033af6ab5fSopenharmony_ci for (auto *overload : method->Overloads()) { 9043af6ab5fSopenharmony_ci ASSERT((overload->Function()->Flags() & ir::ScriptFunctionFlags::OVERLOAD)); 9053af6ab5fSopenharmony_ci overload->Id()->SetVariable(var); 9063af6ab5fSopenharmony_ci overload->SetParent(var->Declaration()->Node()); 9073af6ab5fSopenharmony_ci } 9083af6ab5fSopenharmony_ci } else { 9093af6ab5fSopenharmony_ci if (methodName->Name().Is(compiler::Signatures::MAIN) && clsScope->Parent()->IsGlobalScope()) { 9103af6ab5fSopenharmony_ci ThrowSyntaxError("Main overload is not enabled", methodName->Start()); 9113af6ab5fSopenharmony_ci } 9123af6ab5fSopenharmony_ci AddOverload(method, found); 9133af6ab5fSopenharmony_ci method->Function()->AddFlag(ir::ScriptFunctionFlags::OVERLOAD); 9143af6ab5fSopenharmony_ci 9153af6ab5fSopenharmony_ci // default params overloads 9163af6ab5fSopenharmony_ci for (auto *overload : method->Overloads()) { 9173af6ab5fSopenharmony_ci ASSERT((overload->Function()->Flags() & ir::ScriptFunctionFlags::OVERLOAD)); 9183af6ab5fSopenharmony_ci AddOverload(overload, found); 9193af6ab5fSopenharmony_ci } 9203af6ab5fSopenharmony_ci method->ClearOverloads(); 9213af6ab5fSopenharmony_ci } 9223af6ab5fSopenharmony_ci} 9233af6ab5fSopenharmony_ci 9243af6ab5fSopenharmony_civoid InitScopesPhaseETS::VisitETSReExportDeclaration(ir::ETSReExportDeclaration *reExport) 9253af6ab5fSopenharmony_ci{ 9263af6ab5fSopenharmony_ci if (reExport->GetETSImportDeclarations()->Language().IsDynamic()) { 9273af6ab5fSopenharmony_ci VarBinder()->AsETSBinder()->AddDynamicImport(reExport->GetETSImportDeclarations()); 9283af6ab5fSopenharmony_ci } 9293af6ab5fSopenharmony_ci VarBinder()->AsETSBinder()->AddReExportImport(reExport); 9303af6ab5fSopenharmony_ci} 9313af6ab5fSopenharmony_ci 9323af6ab5fSopenharmony_civoid InitScopesPhaseETS::VisitETSParameterExpression(ir::ETSParameterExpression *paramExpr) 9333af6ab5fSopenharmony_ci{ 9343af6ab5fSopenharmony_ci auto *const var = std::get<1>(VarBinder()->AddParamDecl(paramExpr)); 9353af6ab5fSopenharmony_ci paramExpr->Ident()->SetVariable(var); 9363af6ab5fSopenharmony_ci var->SetScope(VarBinder()->GetScope()); 9373af6ab5fSopenharmony_ci Iterate(paramExpr); 9383af6ab5fSopenharmony_ci} 9393af6ab5fSopenharmony_ci 9403af6ab5fSopenharmony_civoid InitScopesPhaseETS::VisitETSImportDeclaration(ir::ETSImportDeclaration *importDecl) 9413af6ab5fSopenharmony_ci{ 9423af6ab5fSopenharmony_ci ImportDeclarationContext importCtx(VarBinder()); 9433af6ab5fSopenharmony_ci if (importDecl->Language().IsDynamic()) { 9443af6ab5fSopenharmony_ci VarBinder()->AsETSBinder()->AddDynamicImport(importDecl); 9453af6ab5fSopenharmony_ci } 9463af6ab5fSopenharmony_ci Iterate(importDecl); 9473af6ab5fSopenharmony_ci} 9483af6ab5fSopenharmony_ci 9493af6ab5fSopenharmony_civoid InitScopesPhaseETS::VisitTSEnumMember(ir::TSEnumMember *enumMember) 9503af6ab5fSopenharmony_ci{ 9513af6ab5fSopenharmony_ci auto ident = enumMember->Key()->AsIdentifier(); 9523af6ab5fSopenharmony_ci if (ident->Variable() != nullptr) { 9533af6ab5fSopenharmony_ci return; 9543af6ab5fSopenharmony_ci } 9553af6ab5fSopenharmony_ci auto [decl, var] = VarBinder()->NewVarDecl<varbinder::LetDecl>(ident->Start(), ident->Name()); 9563af6ab5fSopenharmony_ci var->SetScope(VarBinder()->GetScope()); 9573af6ab5fSopenharmony_ci var->AddFlag(varbinder::VariableFlags::STATIC); 9583af6ab5fSopenharmony_ci ident->SetVariable(var); 9593af6ab5fSopenharmony_ci decl->BindNode(enumMember); 9603af6ab5fSopenharmony_ci Iterate(enumMember); 9613af6ab5fSopenharmony_ci} 9623af6ab5fSopenharmony_ci 9633af6ab5fSopenharmony_civoid InitScopesPhaseETS::VisitMethodDefinition(ir::MethodDefinition *method) 9643af6ab5fSopenharmony_ci{ 9653af6ab5fSopenharmony_ci auto *curScope = VarBinder()->GetScope(); 9663af6ab5fSopenharmony_ci const auto methodName = method->Id(); 9673af6ab5fSopenharmony_ci auto res = 9683af6ab5fSopenharmony_ci curScope->Find(methodName->Name(), method->IsStatic() ? varbinder::ResolveBindingOptions::ALL_STATIC 9693af6ab5fSopenharmony_ci : varbinder::ResolveBindingOptions::ALL_NON_STATIC); 9703af6ab5fSopenharmony_ci if (res.variable != nullptr && !res.variable->Declaration()->IsFunctionDecl() && res.scope == curScope) { 9713af6ab5fSopenharmony_ci VarBinder()->ThrowRedeclaration(methodName->Start(), res.name); 9723af6ab5fSopenharmony_ci } 9733af6ab5fSopenharmony_ci Iterate(method); 9743af6ab5fSopenharmony_ci DeclareClassMethod(method); 9753af6ab5fSopenharmony_ci} 9763af6ab5fSopenharmony_ci 9773af6ab5fSopenharmony_civoid InitScopesPhaseETS::VisitETSFunctionType(ir::ETSFunctionType *funcType) 9783af6ab5fSopenharmony_ci{ 9793af6ab5fSopenharmony_ci auto typeParamsCtx = LexicalScopeCreateOrEnter<varbinder::LocalScope>(VarBinder(), funcType->TypeParams()); 9803af6ab5fSopenharmony_ci 9813af6ab5fSopenharmony_ci // Check for existing scope 9823af6ab5fSopenharmony_ci // In some cases we can visit function again with scope that already exists 9833af6ab5fSopenharmony_ci // Example: async lambda, we "move" original function to another place and visit it again 9843af6ab5fSopenharmony_ci if (funcType->Scope() == nullptr) { 9853af6ab5fSopenharmony_ci varbinder::LexicalScope<varbinder::FunctionParamScope> lexicalScope(VarBinder()); 9863af6ab5fSopenharmony_ci auto *funcParamScope = lexicalScope.GetScope(); 9873af6ab5fSopenharmony_ci BindScopeNode(funcParamScope, funcType); 9883af6ab5fSopenharmony_ci Iterate(funcType); 9893af6ab5fSopenharmony_ci } 9903af6ab5fSopenharmony_ci} 9913af6ab5fSopenharmony_ci 9923af6ab5fSopenharmony_civoid InitScopesPhaseETS::VisitETSNewClassInstanceExpression(ir::ETSNewClassInstanceExpression *newClassExpr) 9933af6ab5fSopenharmony_ci{ 9943af6ab5fSopenharmony_ci CallNode(newClassExpr->GetArguments()); 9953af6ab5fSopenharmony_ci CallNode(newClassExpr->GetTypeRef()); 9963af6ab5fSopenharmony_ci if (newClassExpr->ClassDefinition() != nullptr) { 9973af6ab5fSopenharmony_ci const auto classDef = newClassExpr->ClassDefinition(); 9983af6ab5fSopenharmony_ci auto *parentClassScope = VarBinder()->GetScope(); 9993af6ab5fSopenharmony_ci while (!parentClassScope->IsClassScope()) { 10003af6ab5fSopenharmony_ci ASSERT(parentClassScope->Parent()); 10013af6ab5fSopenharmony_ci parentClassScope = parentClassScope->Parent(); 10023af6ab5fSopenharmony_ci } 10033af6ab5fSopenharmony_ci auto classCtx = LexicalScopeCreateOrEnter<varbinder::ClassScope>(VarBinder(), newClassExpr->ClassDefinition()); 10043af6ab5fSopenharmony_ci util::UString anonymousName(util::StringView("#"), Allocator()); 10053af6ab5fSopenharmony_ci anonymousName.Append(std::to_string(parentClassScope->AsClassScope()->GetAndIncrementAnonymousClassIdx())); 10063af6ab5fSopenharmony_ci classDef->SetInternalName(anonymousName.View()); 10073af6ab5fSopenharmony_ci classDef->Ident()->SetName(anonymousName.View()); 10083af6ab5fSopenharmony_ci CallNode(classDef); 10093af6ab5fSopenharmony_ci } 10103af6ab5fSopenharmony_ci} 10113af6ab5fSopenharmony_ci 10123af6ab5fSopenharmony_civoid InitScopesPhaseETS::VisitTSTypeParameter(ir::TSTypeParameter *typeParam) 10133af6ab5fSopenharmony_ci{ 10143af6ab5fSopenharmony_ci if (typeParam->Name()->Variable() != nullptr) { 10153af6ab5fSopenharmony_ci return; 10163af6ab5fSopenharmony_ci } 10173af6ab5fSopenharmony_ci auto [decl, var] = 10183af6ab5fSopenharmony_ci VarBinder()->NewVarDecl<varbinder::TypeParameterDecl>(typeParam->Name()->Start(), typeParam->Name()->Name()); 10193af6ab5fSopenharmony_ci typeParam->Name()->SetVariable(var); 10203af6ab5fSopenharmony_ci var->SetScope(VarBinder()->GetScope()); 10213af6ab5fSopenharmony_ci var->AddFlag(varbinder::VariableFlags::TYPE_PARAMETER); 10223af6ab5fSopenharmony_ci decl->BindNode(typeParam); 10233af6ab5fSopenharmony_ci} 10243af6ab5fSopenharmony_ci 10253af6ab5fSopenharmony_civoid InitScopesPhaseETS::VisitTSInterfaceDeclaration(ir::TSInterfaceDeclaration *interfaceDecl) 10263af6ab5fSopenharmony_ci{ 10273af6ab5fSopenharmony_ci { 10283af6ab5fSopenharmony_ci auto typeParamsCtx = LexicalScopeCreateOrEnter<varbinder::LocalScope>(VarBinder(), interfaceDecl->TypeParams()); 10293af6ab5fSopenharmony_ci CallNode(interfaceDecl->TypeParams()); 10303af6ab5fSopenharmony_ci CallNode(interfaceDecl->Extends()); 10313af6ab5fSopenharmony_ci auto localScope = LexicalScopeCreateOrEnter<varbinder::ClassScope>(VarBinder(), interfaceDecl); 10323af6ab5fSopenharmony_ci CallNode(interfaceDecl->Body()); 10333af6ab5fSopenharmony_ci BindScopeNode(localScope.GetScope(), interfaceDecl); 10343af6ab5fSopenharmony_ci } 10353af6ab5fSopenharmony_ci auto name = FormInterfaceOrEnumDeclarationIdBinding(interfaceDecl->Id()); 10363af6ab5fSopenharmony_ci auto *decl = AddOrGetDecl<varbinder::InterfaceDecl>(VarBinder(), name, interfaceDecl, interfaceDecl->Start(), 10373af6ab5fSopenharmony_ci Allocator(), name, interfaceDecl); 10383af6ab5fSopenharmony_ci decl->AsInterfaceDecl()->Add(interfaceDecl); 10393af6ab5fSopenharmony_ci} 10403af6ab5fSopenharmony_ci 10413af6ab5fSopenharmony_civoid InitScopesPhaseETS::VisitTSEnumDeclaration(ir::TSEnumDeclaration *enumDecl) 10423af6ab5fSopenharmony_ci{ 10433af6ab5fSopenharmony_ci { 10443af6ab5fSopenharmony_ci const auto enumCtx = LexicalScopeCreateOrEnter<varbinder::LocalScope>(VarBinder(), enumDecl); 10453af6ab5fSopenharmony_ci BindScopeNode(enumCtx.GetScope(), enumDecl); 10463af6ab5fSopenharmony_ci Iterate(enumDecl); 10473af6ab5fSopenharmony_ci } 10483af6ab5fSopenharmony_ci auto name = FormInterfaceOrEnumDeclarationIdBinding(enumDecl->Key()); 10493af6ab5fSopenharmony_ci auto *decl = AddOrGetDecl<varbinder::EnumLiteralDecl>(VarBinder(), name, enumDecl, enumDecl->Start(), name, 10503af6ab5fSopenharmony_ci enumDecl, enumDecl->IsConst()); 10513af6ab5fSopenharmony_ci decl->BindScope(enumDecl->Scope()); 10523af6ab5fSopenharmony_ci} 10533af6ab5fSopenharmony_ci 10543af6ab5fSopenharmony_civoid InitScopesPhaseETS::VisitTSTypeAliasDeclaration(ir::TSTypeAliasDeclaration *typeAlias) 10553af6ab5fSopenharmony_ci{ 10563af6ab5fSopenharmony_ci AddOrGetDecl<varbinder::TypeAliasDecl>(VarBinder(), typeAlias->Id()->Name(), typeAlias, typeAlias->Id()->Start(), 10573af6ab5fSopenharmony_ci typeAlias->Id()->Name(), typeAlias); 10583af6ab5fSopenharmony_ci auto typeParamsCtx = LexicalScopeCreateOrEnter<varbinder::LocalScope>(VarBinder(), typeAlias->TypeParams()); 10593af6ab5fSopenharmony_ci Iterate(typeAlias); 10603af6ab5fSopenharmony_ci} 10613af6ab5fSopenharmony_ci 10623af6ab5fSopenharmony_civoid InitScopesPhaseETS::AddGlobalToBinder(parser::Program *program) 10633af6ab5fSopenharmony_ci{ 10643af6ab5fSopenharmony_ci auto globalId = program->GlobalClass()->Ident(); 10653af6ab5fSopenharmony_ci if (globalId->Variable() != nullptr) { 10663af6ab5fSopenharmony_ci return; 10673af6ab5fSopenharmony_ci } 10683af6ab5fSopenharmony_ci 10693af6ab5fSopenharmony_ci auto [decl2, var] = program->VarBinder()->NewVarDecl<varbinder::ClassDecl>(globalId->Start(), globalId->Name()); 10703af6ab5fSopenharmony_ci 10713af6ab5fSopenharmony_ci auto classCtx = LexicalScopeCreateOrEnter<varbinder::ClassScope>(program->VarBinder(), program->GlobalClass()); 10723af6ab5fSopenharmony_ci classCtx.GetScope()->BindNode(program->GlobalClass()); 10733af6ab5fSopenharmony_ci program->GlobalClass()->SetScope(classCtx.GetScope()); 10743af6ab5fSopenharmony_ci 10753af6ab5fSopenharmony_ci auto *classDecl = program->GlobalClass()->Parent(); 10763af6ab5fSopenharmony_ci decl2->BindNode(classDecl); 10773af6ab5fSopenharmony_ci globalId->SetVariable(var); 10783af6ab5fSopenharmony_ci} 10793af6ab5fSopenharmony_ci 10803af6ab5fSopenharmony_civoid InitScopesPhaseETS::HandleETSScript(ir::BlockStatement *script) 10813af6ab5fSopenharmony_ci{ 10823af6ab5fSopenharmony_ci for (auto decl : script->Statements()) { 10833af6ab5fSopenharmony_ci if (decl->IsETSImportDeclaration()) { 10843af6ab5fSopenharmony_ci CallNode(decl); 10853af6ab5fSopenharmony_ci } else { 10863af6ab5fSopenharmony_ci auto classCtx = 10873af6ab5fSopenharmony_ci varbinder::LexicalScope<varbinder::ClassScope>::Enter(VarBinder(), Program()->GlobalClassScope()); 10883af6ab5fSopenharmony_ci CallNode(decl); 10893af6ab5fSopenharmony_ci } 10903af6ab5fSopenharmony_ci } 10913af6ab5fSopenharmony_ci auto classCtx = varbinder::LexicalScope<varbinder::ClassScope>::Enter(VarBinder(), Program()->GlobalClassScope()); 10923af6ab5fSopenharmony_ci 10933af6ab5fSopenharmony_ci for (auto decl : script->Statements()) { 10943af6ab5fSopenharmony_ci AddGlobalDeclaration(decl); 10953af6ab5fSopenharmony_ci } 10963af6ab5fSopenharmony_ci} 10973af6ab5fSopenharmony_ci 10983af6ab5fSopenharmony_civoid InitScopesPhaseETS::VisitClassDefinition(ir::ClassDefinition *classDef) 10993af6ab5fSopenharmony_ci{ 11003af6ab5fSopenharmony_ci if (classDef->IsGlobal()) { 11013af6ab5fSopenharmony_ci ParseGlobalClass(classDef); 11023af6ab5fSopenharmony_ci return; 11033af6ab5fSopenharmony_ci } 11043af6ab5fSopenharmony_ci auto typeParamsCtx = LexicalScopeCreateOrEnter<varbinder::LocalScope>(VarBinder(), classDef->TypeParams()); 11053af6ab5fSopenharmony_ci CallNode(classDef->TypeParams()); 11063af6ab5fSopenharmony_ci auto classCtx = LexicalScopeCreateOrEnter<varbinder::ClassScope>(VarBinder(), classDef); 11073af6ab5fSopenharmony_ci 11083af6ab5fSopenharmony_ci IterateNoTParams(classDef); 11093af6ab5fSopenharmony_ci FilterOverloads(classDef->Body()); 11103af6ab5fSopenharmony_ci auto *classScope = classCtx.GetScope(); 11113af6ab5fSopenharmony_ci BindScopeNode(classScope, classDef); 11123af6ab5fSopenharmony_ci} 11133af6ab5fSopenharmony_ci 11143af6ab5fSopenharmony_civoid InitScopesPhaseETS::VisitTSInterfaceBody(ir::TSInterfaceBody *interfBody) 11153af6ab5fSopenharmony_ci{ 11163af6ab5fSopenharmony_ci Iterate(interfBody); 11173af6ab5fSopenharmony_ci FilterInterfaceOverloads(interfBody->Body()); 11183af6ab5fSopenharmony_ci} 11193af6ab5fSopenharmony_ci 11203af6ab5fSopenharmony_civoid InitScopesPhaseETS::FilterInterfaceOverloads(ArenaVector<ir::AstNode *, false> &props) 11213af6ab5fSopenharmony_ci{ 11223af6ab5fSopenharmony_ci auto condition = [](ir::AstNode *prop) { 11233af6ab5fSopenharmony_ci if (prop->IsMethodDefinition()) { 11243af6ab5fSopenharmony_ci const auto func = prop->AsMethodDefinition()->Function(); 11253af6ab5fSopenharmony_ci return func->IsOverload() && func->Body() != nullptr; 11263af6ab5fSopenharmony_ci } 11273af6ab5fSopenharmony_ci return false; 11283af6ab5fSopenharmony_ci }; 11293af6ab5fSopenharmony_ci props.erase(std::remove_if(props.begin(), props.end(), condition), props.end()); 11303af6ab5fSopenharmony_ci} 11313af6ab5fSopenharmony_ci 11323af6ab5fSopenharmony_civoid InitScopesPhaseETS::FilterOverloads(ArenaVector<ir::AstNode *, false> &props) 11333af6ab5fSopenharmony_ci{ 11343af6ab5fSopenharmony_ci auto condition = [](ir::AstNode *prop) { 11353af6ab5fSopenharmony_ci if (prop->IsMethodDefinition()) { 11363af6ab5fSopenharmony_ci const auto func = prop->AsMethodDefinition()->Function(); 11373af6ab5fSopenharmony_ci return func->IsOverload(); 11383af6ab5fSopenharmony_ci } 11393af6ab5fSopenharmony_ci return false; 11403af6ab5fSopenharmony_ci }; 11413af6ab5fSopenharmony_ci props.erase(std::remove_if(props.begin(), props.end(), condition), props.end()); 11423af6ab5fSopenharmony_ci} 11433af6ab5fSopenharmony_ci 11443af6ab5fSopenharmony_civoid InitScopesPhaseETS::VisitClassProperty(ir::ClassProperty *classProp) 11453af6ab5fSopenharmony_ci{ 11463af6ab5fSopenharmony_ci auto curScope = VarBinder()->GetScope(); 11473af6ab5fSopenharmony_ci const auto name = classProp->Key()->AsIdentifier()->Name(); 11483af6ab5fSopenharmony_ci if (classProp->IsClassStaticBlock()) { 11493af6ab5fSopenharmony_ci ASSERT(curScope->IsClassScope()); 11503af6ab5fSopenharmony_ci auto classCtx = varbinder::LexicalScope<varbinder::LocalScope>::Enter( 11513af6ab5fSopenharmony_ci VarBinder(), curScope->AsClassScope()->StaticMethodScope()); 11523af6ab5fSopenharmony_ci auto *var = classProp->Id()->Variable(); 11533af6ab5fSopenharmony_ci if (var == nullptr) { 11543af6ab5fSopenharmony_ci var = std::get<1>(VarBinder()->NewVarDecl<varbinder::FunctionDecl>(classProp->Start(), Allocator(), 11553af6ab5fSopenharmony_ci classProp->Id()->Name(), classProp)); 11563af6ab5fSopenharmony_ci } 11573af6ab5fSopenharmony_ci var->AddFlag(varbinder::VariableFlags::METHOD); 11583af6ab5fSopenharmony_ci classProp->AsClassStaticBlock()->Function()->Id()->SetVariable(var); 11593af6ab5fSopenharmony_ci } else if (classProp->IsConst()) { 11603af6ab5fSopenharmony_ci ASSERT(curScope->Parent() != nullptr); 11613af6ab5fSopenharmony_ci const auto initializer = classProp->Value(); 11623af6ab5fSopenharmony_ci if (initializer == nullptr && curScope->Parent()->IsGlobalScope() && !classProp->IsDeclare()) { 11633af6ab5fSopenharmony_ci auto pos = classProp->End(); 11643af6ab5fSopenharmony_ci // NOTE: Just use property Name? 11653af6ab5fSopenharmony_ci if (!classProp->TypeAnnotation()->IsETSPrimitiveType()) { 11663af6ab5fSopenharmony_ci pos.index--; 11673af6ab5fSopenharmony_ci } 11683af6ab5fSopenharmony_ci ThrowSyntaxError("Missing initializer in const declaration", pos); 11693af6ab5fSopenharmony_ci } 11703af6ab5fSopenharmony_ci AddOrGetDecl<varbinder::ConstDecl>(VarBinder(), name, classProp, classProp->Key()->Start(), name, classProp); 11713af6ab5fSopenharmony_ci } else if (classProp->IsReadonly()) { 11723af6ab5fSopenharmony_ci ASSERT(curScope->Parent() != nullptr); 11733af6ab5fSopenharmony_ci if (curScope->Parent()->IsGlobalScope() && !classProp->IsDeclare()) { 11743af6ab5fSopenharmony_ci auto pos = classProp->End(); 11753af6ab5fSopenharmony_ci ThrowSyntaxError("Readonly field cannot be in Global scope", pos); 11763af6ab5fSopenharmony_ci } 11773af6ab5fSopenharmony_ci AddOrGetDecl<varbinder::ReadonlyDecl>(VarBinder(), name, classProp, classProp->Key()->Start(), name, classProp); 11783af6ab5fSopenharmony_ci } else { 11793af6ab5fSopenharmony_ci AddOrGetDecl<varbinder::LetDecl>(VarBinder(), name, classProp, classProp->Key()->Start(), name, classProp); 11803af6ab5fSopenharmony_ci } 11813af6ab5fSopenharmony_ci Iterate(classProp); 11823af6ab5fSopenharmony_ci} 11833af6ab5fSopenharmony_ci 11843af6ab5fSopenharmony_civoid InitScopesPhaseETS::VisitBreakStatement(ir::BreakStatement *stmt) 11853af6ab5fSopenharmony_ci{ 11863af6ab5fSopenharmony_ci auto label = stmt->Ident(); 11873af6ab5fSopenharmony_ci if (label != nullptr) { 11883af6ab5fSopenharmony_ci auto scope = VarBinder()->GetScope(); 11893af6ab5fSopenharmony_ci auto var = scope->FindInFunctionScope(label->Name(), varbinder::ResolveBindingOptions::ALL).variable; 11903af6ab5fSopenharmony_ci label->SetVariable(var); 11913af6ab5fSopenharmony_ci } 11923af6ab5fSopenharmony_ci} 11933af6ab5fSopenharmony_ci 11943af6ab5fSopenharmony_civoid InitScopesPhaseETS::VisitContinueStatement(ir::ContinueStatement *stmt) 11953af6ab5fSopenharmony_ci{ 11963af6ab5fSopenharmony_ci auto label = stmt->Ident(); 11973af6ab5fSopenharmony_ci if (label != nullptr) { 11983af6ab5fSopenharmony_ci auto scope = VarBinder()->GetScope(); 11993af6ab5fSopenharmony_ci auto var = scope->FindInFunctionScope(label->Name(), varbinder::ResolveBindingOptions::ALL).variable; 12003af6ab5fSopenharmony_ci label->SetVariable(var); 12013af6ab5fSopenharmony_ci } 12023af6ab5fSopenharmony_ci} 12033af6ab5fSopenharmony_ci 12043af6ab5fSopenharmony_civoid InitScopesPhaseETS::AttachLabelToScope(ir::AstNode *node) 12053af6ab5fSopenharmony_ci{ 12063af6ab5fSopenharmony_ci if (node->Parent() == nullptr) { 12073af6ab5fSopenharmony_ci return; 12083af6ab5fSopenharmony_ci } 12093af6ab5fSopenharmony_ci 12103af6ab5fSopenharmony_ci if (!node->Parent()->IsLabelledStatement()) { 12113af6ab5fSopenharmony_ci return; 12123af6ab5fSopenharmony_ci } 12133af6ab5fSopenharmony_ci 12143af6ab5fSopenharmony_ci auto stmt = node->Parent()->AsLabelledStatement(); 12153af6ab5fSopenharmony_ci auto label = stmt->Ident(); 12163af6ab5fSopenharmony_ci if (label == nullptr) { 12173af6ab5fSopenharmony_ci return; 12183af6ab5fSopenharmony_ci } 12193af6ab5fSopenharmony_ci 12203af6ab5fSopenharmony_ci auto decl = AddOrGetDecl<varbinder::LabelDecl>(VarBinder(), label->Name(), stmt, label->Start(), label->Name()); 12213af6ab5fSopenharmony_ci decl->BindNode(stmt); 12223af6ab5fSopenharmony_ci 12233af6ab5fSopenharmony_ci auto var = VarBinder()->GetScope()->FindLocal(label->Name(), varbinder::ResolveBindingOptions::BINDINGS); 12243af6ab5fSopenharmony_ci if (var != nullptr) { 12253af6ab5fSopenharmony_ci label->SetVariable(var); 12263af6ab5fSopenharmony_ci var->SetScope(VarBinder()->GetScope()); 12273af6ab5fSopenharmony_ci var->AddFlag(varbinder::VariableFlags::LOCAL); 12283af6ab5fSopenharmony_ci } 12293af6ab5fSopenharmony_ci} 12303af6ab5fSopenharmony_ci 12313af6ab5fSopenharmony_civoid InitScopesPhaseETS::ParseGlobalClass(ir::ClassDefinition *global) 12323af6ab5fSopenharmony_ci{ 12333af6ab5fSopenharmony_ci for (auto decl : global->Body()) { 12343af6ab5fSopenharmony_ci if (decl->IsDefaultExported()) { 12353af6ab5fSopenharmony_ci if (VarBinder()->AsETSBinder()->DefaultExport() != nullptr) { 12363af6ab5fSopenharmony_ci ThrowSyntaxError("Only one default export is allowed in a module", decl->Start()); 12373af6ab5fSopenharmony_ci } 12383af6ab5fSopenharmony_ci VarBinder()->AsETSBinder()->SetDefaultExport(decl); 12393af6ab5fSopenharmony_ci } 12403af6ab5fSopenharmony_ci CallNode(decl); 12413af6ab5fSopenharmony_ci } 12423af6ab5fSopenharmony_ci FilterOverloads(global->Body()); 12433af6ab5fSopenharmony_ci} 12443af6ab5fSopenharmony_ci 12453af6ab5fSopenharmony_civoid InitScopesPhaseETS::AddGlobalDeclaration(ir::AstNode *node) 12463af6ab5fSopenharmony_ci{ 12473af6ab5fSopenharmony_ci ir::Identifier *ident = nullptr; 12483af6ab5fSopenharmony_ci bool isBuiltin = false; 12493af6ab5fSopenharmony_ci switch (node->Type()) { 12503af6ab5fSopenharmony_ci case ir::AstNodeType::CLASS_DECLARATION: { 12513af6ab5fSopenharmony_ci auto def = node->AsClassDeclaration()->Definition(); 12523af6ab5fSopenharmony_ci if (def->IsGlobal()) { 12533af6ab5fSopenharmony_ci return; 12543af6ab5fSopenharmony_ci } 12553af6ab5fSopenharmony_ci ident = def->Ident(); 12563af6ab5fSopenharmony_ci isBuiltin = def->IsFromExternal(); 12573af6ab5fSopenharmony_ci break; 12583af6ab5fSopenharmony_ci } 12593af6ab5fSopenharmony_ci case ir::AstNodeType::STRUCT_DECLARATION: { 12603af6ab5fSopenharmony_ci ident = node->AsETSStructDeclaration()->Definition()->Ident(); 12613af6ab5fSopenharmony_ci isBuiltin = node->AsETSStructDeclaration()->Definition()->IsFromExternal(); 12623af6ab5fSopenharmony_ci break; 12633af6ab5fSopenharmony_ci } 12643af6ab5fSopenharmony_ci case ir::AstNodeType::TS_INTERFACE_DECLARATION: { 12653af6ab5fSopenharmony_ci ident = node->AsTSInterfaceDeclaration()->Id(); 12663af6ab5fSopenharmony_ci isBuiltin = node->AsTSInterfaceDeclaration()->IsFromExternal(); 12673af6ab5fSopenharmony_ci break; 12683af6ab5fSopenharmony_ci } 12693af6ab5fSopenharmony_ci case ir::AstNodeType::TS_ENUM_DECLARATION: { 12703af6ab5fSopenharmony_ci ident = node->AsTSEnumDeclaration()->Key(); 12713af6ab5fSopenharmony_ci break; 12723af6ab5fSopenharmony_ci } 12733af6ab5fSopenharmony_ci case ir::AstNodeType::TS_TYPE_ALIAS_DECLARATION: { 12743af6ab5fSopenharmony_ci ident = node->AsTSTypeAliasDeclaration()->Id(); 12753af6ab5fSopenharmony_ci break; 12763af6ab5fSopenharmony_ci } 12773af6ab5fSopenharmony_ci default: { 12783af6ab5fSopenharmony_ci break; 12793af6ab5fSopenharmony_ci } 12803af6ab5fSopenharmony_ci } 12813af6ab5fSopenharmony_ci if (ident != nullptr) { 12823af6ab5fSopenharmony_ci VarBinder()->TopScope()->InsertBinding(ident->Name(), ident->Variable()); 12833af6ab5fSopenharmony_ci if (isBuiltin) { 12843af6ab5fSopenharmony_ci ident->Variable()->AddFlag(varbinder::VariableFlags::BUILTIN_TYPE); 12853af6ab5fSopenharmony_ci } 12863af6ab5fSopenharmony_ci } 12873af6ab5fSopenharmony_ci} 12883af6ab5fSopenharmony_ci 12893af6ab5fSopenharmony_civoid InitScopesPhaseAS::VisitArrowFunctionExpression(ir::ArrowFunctionExpression *arrowExpr) 12903af6ab5fSopenharmony_ci{ 12913af6ab5fSopenharmony_ci Iterate(arrowExpr); 12923af6ab5fSopenharmony_ci} 12933af6ab5fSopenharmony_ci 12943af6ab5fSopenharmony_civoid InitScopesPhaseAS::VisitExportNamedDeclaration(ir::ExportNamedDeclaration *exportDecl) 12953af6ab5fSopenharmony_ci{ 12963af6ab5fSopenharmony_ci ExportDeclarationContext exportDeclCtx(VarBinder()); 12973af6ab5fSopenharmony_ci Iterate(exportDecl); 12983af6ab5fSopenharmony_ci} 12993af6ab5fSopenharmony_ci 13003af6ab5fSopenharmony_ci} // namespace ark::es2panda::compiler 1301