13af6ab5fSopenharmony_ci/** 23af6ab5fSopenharmony_ci * Copyright (c) 2021 Huawei Device Co., Ltd. 33af6ab5fSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 43af6ab5fSopenharmony_ci * you may not use this file except in compliance with the License. 53af6ab5fSopenharmony_ci * You may obtain a copy of the License at 63af6ab5fSopenharmony_ci * 73af6ab5fSopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 83af6ab5fSopenharmony_ci * 93af6ab5fSopenharmony_ci * Unless required by applicable law or agreed to in writing, software 103af6ab5fSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 113af6ab5fSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 123af6ab5fSopenharmony_ci * See the License for the specific language governing permissions and 133af6ab5fSopenharmony_ci * limitations under the License. 143af6ab5fSopenharmony_ci */ 153af6ab5fSopenharmony_ci 163af6ab5fSopenharmony_ci#include "binder.h" 173af6ab5fSopenharmony_ci 183af6ab5fSopenharmony_ci#include "binder/scope.h" 193af6ab5fSopenharmony_ci#include "binder/tsBinding.h" 203af6ab5fSopenharmony_ci#include "es2panda.h" 213af6ab5fSopenharmony_ci#include "ir/astNode.h" 223af6ab5fSopenharmony_ci#include "ir/base/annotation.h" 233af6ab5fSopenharmony_ci#include "ir/base/catchClause.h" 243af6ab5fSopenharmony_ci#include "ir/base/classDefinition.h" 253af6ab5fSopenharmony_ci#include "ir/base/classProperty.h" 263af6ab5fSopenharmony_ci#include "ir/base/methodDefinition.h" 273af6ab5fSopenharmony_ci#include "ir/base/property.h" 283af6ab5fSopenharmony_ci#include "ir/base/scriptFunction.h" 293af6ab5fSopenharmony_ci#include "ir/base/spreadElement.h" 303af6ab5fSopenharmony_ci#include "ir/expressions/arrayExpression.h" 313af6ab5fSopenharmony_ci#include "ir/expressions/assignmentExpression.h" 323af6ab5fSopenharmony_ci#include "ir/expressions/callExpression.h" 333af6ab5fSopenharmony_ci#include "ir/expressions/identifier.h" 343af6ab5fSopenharmony_ci#include "ir/expressions/objectExpression.h" 353af6ab5fSopenharmony_ci#include "ir/expressions/privateIdentifier.h" 363af6ab5fSopenharmony_ci#include "ir/expressions/literals/numberLiteral.h" 373af6ab5fSopenharmony_ci#include "ir/module/exportNamedDeclaration.h" 383af6ab5fSopenharmony_ci#include "ir/module/exportSpecifier.h" 393af6ab5fSopenharmony_ci#include "ir/statements/blockStatement.h" 403af6ab5fSopenharmony_ci#include "ir/statements/classDeclaration.h" 413af6ab5fSopenharmony_ci#include "ir/statements/doWhileStatement.h" 423af6ab5fSopenharmony_ci#include "ir/statements/forInStatement.h" 433af6ab5fSopenharmony_ci#include "ir/statements/forOfStatement.h" 443af6ab5fSopenharmony_ci#include "ir/statements/forUpdateStatement.h" 453af6ab5fSopenharmony_ci#include "ir/statements/ifStatement.h" 463af6ab5fSopenharmony_ci#include "ir/statements/switchCaseStatement.h" 473af6ab5fSopenharmony_ci#include "ir/statements/switchStatement.h" 483af6ab5fSopenharmony_ci#include "ir/statements/variableDeclaration.h" 493af6ab5fSopenharmony_ci#include "ir/statements/variableDeclarator.h" 503af6ab5fSopenharmony_ci#include "ir/statements/whileStatement.h" 513af6ab5fSopenharmony_ci#include "ir/ts/tsClassImplements.h" 523af6ab5fSopenharmony_ci#include "ir/ts/tsConstructorType.h" 533af6ab5fSopenharmony_ci#include "ir/ts/tsEnumDeclaration.h" 543af6ab5fSopenharmony_ci#include "ir/ts/tsFunctionType.h" 553af6ab5fSopenharmony_ci#include "ir/ts/tsIndexSignature.h" 563af6ab5fSopenharmony_ci#include "ir/ts/tsMethodSignature.h" 573af6ab5fSopenharmony_ci#include "ir/ts/tsModuleBlock.h" 583af6ab5fSopenharmony_ci#include "ir/ts/tsModuleDeclaration.h" 593af6ab5fSopenharmony_ci#include "ir/ts/tsSignatureDeclaration.h" 603af6ab5fSopenharmony_ci#include "ir/ts/tsTypeParameterDeclaration.h" 613af6ab5fSopenharmony_ci#include "ir/ts/tsTypeParameterInstantiation.h" 623af6ab5fSopenharmony_ci#include "util/concurrent.h" 633af6ab5fSopenharmony_ci#include "util/patchFix.h" 643af6ab5fSopenharmony_ci 653af6ab5fSopenharmony_cinamespace panda::es2panda::binder { 663af6ab5fSopenharmony_civoid Binder::InitTopScope() 673af6ab5fSopenharmony_ci{ 683af6ab5fSopenharmony_ci if (program_->Kind() == parser::ScriptKind::MODULE) { 693af6ab5fSopenharmony_ci topScope_ = Allocator()->New<ModuleScope>(Allocator(), program_); 703af6ab5fSopenharmony_ci } else { 713af6ab5fSopenharmony_ci topScope_ = Allocator()->New<GlobalScope>(Allocator()); 723af6ab5fSopenharmony_ci } 733af6ab5fSopenharmony_ci 743af6ab5fSopenharmony_ci scope_ = topScope_; 753af6ab5fSopenharmony_ci} 763af6ab5fSopenharmony_ci 773af6ab5fSopenharmony_ciParameterDecl *Binder::AddParamDecl(const ir::AstNode *param) 783af6ab5fSopenharmony_ci{ 793af6ab5fSopenharmony_ci ASSERT(scope_->IsFunctionParamScope() || scope_->IsCatchParamScope()); 803af6ab5fSopenharmony_ci auto [decl, node] = static_cast<ParamScope *>(scope_)->AddParamDecl(Allocator(), param); 813af6ab5fSopenharmony_ci 823af6ab5fSopenharmony_ci if (!node) { 833af6ab5fSopenharmony_ci return decl; 843af6ab5fSopenharmony_ci } 853af6ab5fSopenharmony_ci 863af6ab5fSopenharmony_ci ThrowRedeclaration(node->Start(), decl->Name()); 873af6ab5fSopenharmony_ci} 883af6ab5fSopenharmony_ci 893af6ab5fSopenharmony_civoid Binder::ThrowRedeclaration(const lexer::SourcePosition &pos, const util::StringView &name) 903af6ab5fSopenharmony_ci{ 913af6ab5fSopenharmony_ci lexer::LineIndex index(program_->SourceCode()); 923af6ab5fSopenharmony_ci lexer::SourceLocation loc = index.GetLocation(pos); 933af6ab5fSopenharmony_ci 943af6ab5fSopenharmony_ci std::stringstream ss; 953af6ab5fSopenharmony_ci ss << "Variable '" << name << "' has already been declared."; 963af6ab5fSopenharmony_ci throw Error(ErrorType::SYNTAX, ss.str(), loc.line, loc.col); 973af6ab5fSopenharmony_ci} 983af6ab5fSopenharmony_ci 993af6ab5fSopenharmony_civoid Binder::ThrowUndeclaredExport(const lexer::SourcePosition &pos, const util::StringView &name) 1003af6ab5fSopenharmony_ci{ 1013af6ab5fSopenharmony_ci lexer::LineIndex index(program_->SourceCode()); 1023af6ab5fSopenharmony_ci lexer::SourceLocation loc = index.GetLocation(pos); 1033af6ab5fSopenharmony_ci 1043af6ab5fSopenharmony_ci std::stringstream ss; 1053af6ab5fSopenharmony_ci ss << "Export name '" << name << "' is not defined."; 1063af6ab5fSopenharmony_ci throw Error(ErrorType::SYNTAX, ss.str(), loc.line, loc.col); 1073af6ab5fSopenharmony_ci} 1083af6ab5fSopenharmony_ci 1093af6ab5fSopenharmony_civoid Binder::ThrowInvalidDstrTarget(const lexer::SourcePosition &pos, const util::StringView &name) 1103af6ab5fSopenharmony_ci{ 1113af6ab5fSopenharmony_ci lexer::LineIndex index(program_->SourceCode()); 1123af6ab5fSopenharmony_ci lexer::SourceLocation loc = index.GetLocation(pos); 1133af6ab5fSopenharmony_ci 1143af6ab5fSopenharmony_ci std::stringstream ss; 1153af6ab5fSopenharmony_ci ss << "Invalid destructuring assignment target: " << name; 1163af6ab5fSopenharmony_ci throw Error(ErrorType::SYNTAX, ss.str(), loc.line, loc.col); 1173af6ab5fSopenharmony_ci} 1183af6ab5fSopenharmony_ci 1193af6ab5fSopenharmony_civoid Binder::ThrowInvalidAnnotationDeclaration(const lexer::SourcePosition &pos, const util::StringView &name) 1203af6ab5fSopenharmony_ci{ 1213af6ab5fSopenharmony_ci lexer::LineIndex index(program_->SourceCode()); 1223af6ab5fSopenharmony_ci lexer::SourceLocation loc = index.GetLocation(pos); 1233af6ab5fSopenharmony_ci 1243af6ab5fSopenharmony_ci std::stringstream ss; 1253af6ab5fSopenharmony_ci ss << "Invalid annotation declaration: " << name; 1263af6ab5fSopenharmony_ci throw Error(ErrorType::SYNTAX, ss.str(), loc.line, loc.col); 1273af6ab5fSopenharmony_ci} 1283af6ab5fSopenharmony_ci 1293af6ab5fSopenharmony_civoid Binder::CheckMandatoryArguments(const ir::Identifier *ident) 1303af6ab5fSopenharmony_ci{ 1313af6ab5fSopenharmony_ci const auto *iter = static_cast<const ir::AstNode *>(ident); 1323af6ab5fSopenharmony_ci bool isPatternMember = false; 1333af6ab5fSopenharmony_ci while (iter) { 1343af6ab5fSopenharmony_ci if (iter->IsArrayExpression() || iter->IsArrayPattern()) { 1353af6ab5fSopenharmony_ci isPatternMember = true; 1363af6ab5fSopenharmony_ci break; 1373af6ab5fSopenharmony_ci } 1383af6ab5fSopenharmony_ci 1393af6ab5fSopenharmony_ci if (iter->IsObjectExpression() || iter->IsObjectPattern()) { 1403af6ab5fSopenharmony_ci auto &properties = iter->IsObjectExpression() ? iter->AsObjectExpression()->Properties() : 1413af6ab5fSopenharmony_ci iter->AsObjectPattern()->Properties(); 1423af6ab5fSopenharmony_ci isPatternMember = util::Helpers::IsObjectPropertyValue(properties, ident); 1433af6ab5fSopenharmony_ci break; 1443af6ab5fSopenharmony_ci } 1453af6ab5fSopenharmony_ci iter = iter->Parent(); 1463af6ab5fSopenharmony_ci } 1473af6ab5fSopenharmony_ci 1483af6ab5fSopenharmony_ci if (!isPatternMember) { 1493af6ab5fSopenharmony_ci return; 1503af6ab5fSopenharmony_ci } 1513af6ab5fSopenharmony_ci 1523af6ab5fSopenharmony_ci auto *patternNode = iter; 1533af6ab5fSopenharmony_ci 1543af6ab5fSopenharmony_ci while (iter) { 1553af6ab5fSopenharmony_ci if (iter->IsAssignmentExpression() || iter->IsVariableDeclarator() || iter->IsForInStatement() || 1563af6ab5fSopenharmony_ci iter->IsForOfStatement()) { 1573af6ab5fSopenharmony_ci break; 1583af6ab5fSopenharmony_ci } 1593af6ab5fSopenharmony_ci 1603af6ab5fSopenharmony_ci iter = iter->Parent(); 1613af6ab5fSopenharmony_ci } 1623af6ab5fSopenharmony_ci 1633af6ab5fSopenharmony_ci if (!iter) { 1643af6ab5fSopenharmony_ci return; 1653af6ab5fSopenharmony_ci } 1663af6ab5fSopenharmony_ci 1673af6ab5fSopenharmony_ci const ir::AstNode *potentialParent = iter; 1683af6ab5fSopenharmony_ci 1693af6ab5fSopenharmony_ci if (iter->IsAssignmentExpression()) { 1703af6ab5fSopenharmony_ci potentialParent = iter->AsAssignmentExpression()->Left(); 1713af6ab5fSopenharmony_ci } else if (iter->IsVariableDeclarator()) { 1723af6ab5fSopenharmony_ci potentialParent = iter->AsVariableDeclarator()->Id(); 1733af6ab5fSopenharmony_ci } else { 1743af6ab5fSopenharmony_ci potentialParent = iter->IsForInStatement() ? iter->AsForInStatement()->Left() : 1753af6ab5fSopenharmony_ci iter->AsForOfStatement()->Left(); 1763af6ab5fSopenharmony_ci } 1773af6ab5fSopenharmony_ci 1783af6ab5fSopenharmony_ci if (!util::Helpers::IsChild(potentialParent, patternNode)) { 1793af6ab5fSopenharmony_ci return; 1803af6ab5fSopenharmony_ci } 1813af6ab5fSopenharmony_ci 1823af6ab5fSopenharmony_ci ThrowInvalidDstrTarget(ident->Start(), ident->Name()); 1833af6ab5fSopenharmony_ci} 1843af6ab5fSopenharmony_ci 1853af6ab5fSopenharmony_civoid Binder::AssignIndexToModuleVariable() 1863af6ab5fSopenharmony_ci{ 1873af6ab5fSopenharmony_ci ASSERT(program_->ModuleRecord()); 1883af6ab5fSopenharmony_ci program_->ModuleRecord()->AssignIndexToModuleVariable(topScope_->AsModuleScope()); 1893af6ab5fSopenharmony_ci} 1903af6ab5fSopenharmony_ci 1913af6ab5fSopenharmony_civoid Binder::IdentifierAnalysis(ResolveBindingFlags flags) 1923af6ab5fSopenharmony_ci{ 1933af6ab5fSopenharmony_ci ASSERT(program_->Ast()); 1943af6ab5fSopenharmony_ci ASSERT(scope_ == topScope_); 1953af6ab5fSopenharmony_ci 1963af6ab5fSopenharmony_ci bindingFlags_ = flags; 1973af6ab5fSopenharmony_ci // Bind function main0 first to determine whether a lexical variable is in it or not under hot-reload mode 1983af6ab5fSopenharmony_ci if (bindingFlags_ & ResolveBindingFlags::TS_BEFORE_TRANSFORM) { 1993af6ab5fSopenharmony_ci BuildFunction(topScope_, MAIN_FUNC_NAME); 2003af6ab5fSopenharmony_ci ResolveReferences(program_->Ast()); 2013af6ab5fSopenharmony_ci } else if (bindingFlags_ & ResolveBindingFlags::TS_AFTER_TRANSFORM) { 2023af6ab5fSopenharmony_ci // Basically same as js, except of function main0 will not be bound after transform 2033af6ab5fSopenharmony_ci ResolveReferences(program_->Ast()); 2043af6ab5fSopenharmony_ci AddMandatoryParams(); 2053af6ab5fSopenharmony_ci if (topScope_->IsModuleScope()) { 2063af6ab5fSopenharmony_ci AssignIndexToModuleVariable(); 2073af6ab5fSopenharmony_ci } 2083af6ab5fSopenharmony_ci } else if (bindingFlags_ & ResolveBindingFlags::ALL) { 2093af6ab5fSopenharmony_ci BuildFunction(topScope_, MAIN_FUNC_NAME); 2103af6ab5fSopenharmony_ci ResolveReferences(program_->Ast()); 2113af6ab5fSopenharmony_ci AddMandatoryParams(); 2123af6ab5fSopenharmony_ci if (topScope_->IsModuleScope()) { 2133af6ab5fSopenharmony_ci AssignIndexToModuleVariable(); 2143af6ab5fSopenharmony_ci } 2153af6ab5fSopenharmony_ci } 2163af6ab5fSopenharmony_ci} 2173af6ab5fSopenharmony_ci 2183af6ab5fSopenharmony_civoid Binder::ValidateExportDecl(const ir::ExportNamedDeclaration *exportDecl) 2193af6ab5fSopenharmony_ci{ 2203af6ab5fSopenharmony_ci if (exportDecl->Source() != nullptr || exportDecl->Decl() != nullptr || exportDecl->IsType()) { 2213af6ab5fSopenharmony_ci return; 2223af6ab5fSopenharmony_ci } 2233af6ab5fSopenharmony_ci 2243af6ab5fSopenharmony_ci ASSERT(topScope_->IsModuleScope()); 2253af6ab5fSopenharmony_ci for (auto *it : exportDecl->Specifiers()) { 2263af6ab5fSopenharmony_ci if (it->AsExportSpecifier()->IsType()) { 2273af6ab5fSopenharmony_ci continue; 2283af6ab5fSopenharmony_ci } 2293af6ab5fSopenharmony_ci 2303af6ab5fSopenharmony_ci auto localName = it->AsExportSpecifier()->Local()->Name(); 2313af6ab5fSopenharmony_ci if (scope_->IsTSModuleScope()) { 2323af6ab5fSopenharmony_ci auto currentScope = scope_; 2333af6ab5fSopenharmony_ci while (currentScope != nullptr) { 2343af6ab5fSopenharmony_ci if (currentScope->FindLocal(localName, ResolveBindingOptions::ALL) != nullptr || 2353af6ab5fSopenharmony_ci (currentScope->IsTSModuleScope() && (currentScope->InLocalTSBindings(localName) || 2363af6ab5fSopenharmony_ci currentScope->AsTSModuleScope()->InExportBindings(localName)))) { 2373af6ab5fSopenharmony_ci break; 2383af6ab5fSopenharmony_ci } 2393af6ab5fSopenharmony_ci currentScope = currentScope->Parent(); 2403af6ab5fSopenharmony_ci } 2413af6ab5fSopenharmony_ci if (currentScope != nullptr) { 2423af6ab5fSopenharmony_ci continue; 2433af6ab5fSopenharmony_ci } 2443af6ab5fSopenharmony_ci ThrowUndeclaredExport(it->AsExportSpecifier()->Local()->Start(), localName); 2453af6ab5fSopenharmony_ci } 2463af6ab5fSopenharmony_ci ASSERT(topScope_ == scope_); 2473af6ab5fSopenharmony_ci if (scope_->FindLocal(localName) == nullptr) { 2483af6ab5fSopenharmony_ci // The declaration of ts cannot correspond to the variables of ts before transform, 2493af6ab5fSopenharmony_ci // After the transform, they are all js variables. So it can return directly here. 2503af6ab5fSopenharmony_ci if (scope_->InLocalTSBindings(localName) || 2513af6ab5fSopenharmony_ci scope_->FindLocal(localName, ResolveBindingOptions::INTERFACES)) { 2523af6ab5fSopenharmony_ci continue; 2533af6ab5fSopenharmony_ci } 2543af6ab5fSopenharmony_ci ThrowUndeclaredExport(it->AsExportSpecifier()->Local()->Start(), localName); 2553af6ab5fSopenharmony_ci } 2563af6ab5fSopenharmony_ci scope_->AsModuleScope()->ConvertLocalVariableToModuleVariable(Allocator(), localName); 2573af6ab5fSopenharmony_ci } 2583af6ab5fSopenharmony_ci} 2593af6ab5fSopenharmony_ci 2603af6ab5fSopenharmony_civoid Binder::LookupReference(const util::StringView &name) 2613af6ab5fSopenharmony_ci{ 2623af6ab5fSopenharmony_ci ScopeFindResult res = scope_->Find(name); 2633af6ab5fSopenharmony_ci if (res.level == 0) { 2643af6ab5fSopenharmony_ci return; 2653af6ab5fSopenharmony_ci } 2663af6ab5fSopenharmony_ci 2673af6ab5fSopenharmony_ci ASSERT(res.variable); 2683af6ab5fSopenharmony_ci res.variable->SetLexical(res.scope, program_->PatchFixHelper()); 2693af6ab5fSopenharmony_ci} 2703af6ab5fSopenharmony_ci 2713af6ab5fSopenharmony_civoid Binder::InstantiateArguments() 2723af6ab5fSopenharmony_ci{ 2733af6ab5fSopenharmony_ci auto *iter = scope_; 2743af6ab5fSopenharmony_ci while (true) { 2753af6ab5fSopenharmony_ci Scope *scope = iter->IsFunctionParamScope() ? iter : iter->EnclosingVariableScope(); 2763af6ab5fSopenharmony_ci CHECK_NOT_NULL(scope); 2773af6ab5fSopenharmony_ci 2783af6ab5fSopenharmony_ci const auto *node = scope->Node(); 2793af6ab5fSopenharmony_ci 2803af6ab5fSopenharmony_ci if (scope->IsLoopScope()) { 2813af6ab5fSopenharmony_ci iter = scope->Parent(); 2823af6ab5fSopenharmony_ci continue; 2833af6ab5fSopenharmony_ci } 2843af6ab5fSopenharmony_ci 2853af6ab5fSopenharmony_ci if (!node->IsScriptFunction()) { 2863af6ab5fSopenharmony_ci break; 2873af6ab5fSopenharmony_ci } 2883af6ab5fSopenharmony_ci 2893af6ab5fSopenharmony_ci if (!node->AsScriptFunction()->IsArrow()) { 2903af6ab5fSopenharmony_ci auto *argumentsVariable = 2913af6ab5fSopenharmony_ci scope->AddDecl<ConstDecl, LocalVariable>(Allocator(), FUNCTION_ARGUMENTS, VariableFlags::INITIALIZED); 2923af6ab5fSopenharmony_ci 2933af6ab5fSopenharmony_ci if (iter->IsFunctionParamScope()) { 2943af6ab5fSopenharmony_ci if (!argumentsVariable) { 2953af6ab5fSopenharmony_ci break; 2963af6ab5fSopenharmony_ci } 2973af6ab5fSopenharmony_ci 2983af6ab5fSopenharmony_ci scope = iter->AsFunctionParamScope()->GetFunctionScope(); 2993af6ab5fSopenharmony_ci scope->Bindings().insert({argumentsVariable->Name(), argumentsVariable}); 3003af6ab5fSopenharmony_ci } 3013af6ab5fSopenharmony_ci 3023af6ab5fSopenharmony_ci scope->AsVariableScope()->AddFlag(VariableScopeFlags::USE_ARGS); 3033af6ab5fSopenharmony_ci 3043af6ab5fSopenharmony_ci break; 3053af6ab5fSopenharmony_ci } 3063af6ab5fSopenharmony_ci 3073af6ab5fSopenharmony_ci iter = scope->Parent(); 3083af6ab5fSopenharmony_ci } 3093af6ab5fSopenharmony_ci} 3103af6ab5fSopenharmony_ci 3113af6ab5fSopenharmony_civoid Binder::LookupIdentReference(ir::Identifier *ident) 3123af6ab5fSopenharmony_ci{ 3133af6ab5fSopenharmony_ci if (ident->Name().Is(FUNCTION_ARGUMENTS)) { 3143af6ab5fSopenharmony_ci InstantiateArguments(); 3153af6ab5fSopenharmony_ci } 3163af6ab5fSopenharmony_ci 3173af6ab5fSopenharmony_ci ScopeFindResult res; 3183af6ab5fSopenharmony_ci if (bindingFlags_ & ResolveBindingFlags::TS_BEFORE_TRANSFORM) { 3193af6ab5fSopenharmony_ci ident->SetTSVariables(FindIdentifierTSVariables(ident, scope_, res)); 3203af6ab5fSopenharmony_ci } else { 3213af6ab5fSopenharmony_ci if (ident->Parent()->IsTSTypeReference()) { 3223af6ab5fSopenharmony_ci res = scope_->Find(ident->Name(), ResolveBindingOptions::ALL); 3233af6ab5fSopenharmony_ci } else { 3243af6ab5fSopenharmony_ci res = scope_->Find(ident->Name(), ResolveBindingOptions::BINDINGS); 3253af6ab5fSopenharmony_ci } 3263af6ab5fSopenharmony_ci } 3273af6ab5fSopenharmony_ci 3283af6ab5fSopenharmony_ci if (res.variable == nullptr) { 3293af6ab5fSopenharmony_ci return; 3303af6ab5fSopenharmony_ci } 3313af6ab5fSopenharmony_ci 3323af6ab5fSopenharmony_ci if (res.level != 0) { 3333af6ab5fSopenharmony_ci if (!res.variable->Declaration()->IsDeclare() && !ident->Parent()->IsTSTypeReference() && 3343af6ab5fSopenharmony_ci !ident->Parent()->IsTSTypeQuery() && !(bindingFlags_ & ResolveBindingFlags::TS_BEFORE_TRANSFORM)) { 3353af6ab5fSopenharmony_ci util::Concurrent::ProcessConcurrent(Program()->GetLineIndex(), ident, res, program_); 3363af6ab5fSopenharmony_ci res.variable->SetLexical(res.scope, program_->PatchFixHelper()); 3373af6ab5fSopenharmony_ci } 3383af6ab5fSopenharmony_ci } 3393af6ab5fSopenharmony_ci 3403af6ab5fSopenharmony_ci auto decl = res.variable->Declaration(); 3413af6ab5fSopenharmony_ci if (decl->IsLetOrConstOrClassDecl() && !decl->HasFlag(DeclarationFlags::NAMESPACE_IMPORT) && 3423af6ab5fSopenharmony_ci !res.variable->HasFlag(VariableFlags::INITIALIZED)) { 3433af6ab5fSopenharmony_ci ident->SetTdz(); 3443af6ab5fSopenharmony_ci } 3453af6ab5fSopenharmony_ci // in release mode, replace const reference with its initialization 3463af6ab5fSopenharmony_ci if (!this->Program()->IsDebug() && decl->IsConstDecl()) { 3473af6ab5fSopenharmony_ci ReplaceConstReferenceWithInitialization(ident, decl); 3483af6ab5fSopenharmony_ci } 3493af6ab5fSopenharmony_ci 3503af6ab5fSopenharmony_ci ident->SetVariable(res.variable); 3513af6ab5fSopenharmony_ci} 3523af6ab5fSopenharmony_ci 3533af6ab5fSopenharmony_civoid Binder::StoreAndCheckSpecialFunctionName(std::string &internalNameStr, std::string recordName) 3543af6ab5fSopenharmony_ci{ 3553af6ab5fSopenharmony_ci if (program_->PatchFixHelper()) { 3563af6ab5fSopenharmony_ci if (program_->PatchFixHelper()->IsDumpSymbolTable()) { 3573af6ab5fSopenharmony_ci // anonymous, special-name and duplicate function index started from 1 3583af6ab5fSopenharmony_ci specialFuncNameIndexMap_.insert({internalNameStr, std::to_string(++globalIndexForSpecialFunc_)}); 3593af6ab5fSopenharmony_ci return; 3603af6ab5fSopenharmony_ci } 3613af6ab5fSopenharmony_ci if (program_->PatchFixHelper()->IsHotFix()) { 3623af6ab5fSopenharmony_ci // Adding/removing anonymous, special or duplicate functions is supported for hotReload and coldFix mode, 3633af6ab5fSopenharmony_ci // but forbidden in hotFix mode 3643af6ab5fSopenharmony_ci program_->PatchFixHelper()->CheckAndRestoreSpecialFunctionName(++globalIndexForSpecialFunc_, 3653af6ab5fSopenharmony_ci internalNameStr, recordName); 3663af6ab5fSopenharmony_ci return; 3673af6ab5fSopenharmony_ci } 3683af6ab5fSopenharmony_ci // else: must be coldfix or hotreload mode or coldreload mode 3693af6ab5fSopenharmony_ci ASSERT(program_->PatchFixHelper()->IsColdFix() || program_->PatchFixHelper()->IsHotReload() || 3703af6ab5fSopenharmony_ci program_->PatchFixHelper()->IsColdReload()); 3713af6ab5fSopenharmony_ci } 3723af6ab5fSopenharmony_ci} 3733af6ab5fSopenharmony_ci 3743af6ab5fSopenharmony_civoid Binder::BuildFunction(FunctionScope *funcScope, util::StringView name, const ir::ScriptFunction *func) 3753af6ab5fSopenharmony_ci{ 3763af6ab5fSopenharmony_ci if (funcScope->InFunctionScopes()) { 3773af6ab5fSopenharmony_ci return; 3783af6ab5fSopenharmony_ci } 3793af6ab5fSopenharmony_ci functionScopes_.push_back(funcScope); 3803af6ab5fSopenharmony_ci funcScope->SetInFunctionScopes(); 3813af6ab5fSopenharmony_ci if (!util::Helpers::IsDefaultApiVersion(Program()->TargetApiVersion(), Program()->GetTargetApiSubVersion())) { 3823af6ab5fSopenharmony_ci funcScope->SetSelfScopeName(name); 3833af6ab5fSopenharmony_ci auto recordName = program_->FormatedRecordName().Mutf8(); 3843af6ab5fSopenharmony_ci funcScope->BindNameWithScopeInfo(name, util::UString(recordName, Allocator()).View()); 3853af6ab5fSopenharmony_ci if (func && (name == ANONYMOUS_FUNC_NAME)) { 3863af6ab5fSopenharmony_ci anonymousFunctionNames_[func] = util::UString(funcScope->InternalName().Mutf8(), Allocator()).View(); 3873af6ab5fSopenharmony_ci } 3883af6ab5fSopenharmony_ci } else { 3893af6ab5fSopenharmony_ci LegacyBuildFunction(funcScope, name, func); 3903af6ab5fSopenharmony_ci } 3913af6ab5fSopenharmony_ci} 3923af6ab5fSopenharmony_ci 3933af6ab5fSopenharmony_civoid Binder::LegacyBuildFunction(FunctionScope *funcScope, util::StringView name, const ir::ScriptFunction *func) 3943af6ab5fSopenharmony_ci{ 3953af6ab5fSopenharmony_ci bool funcNameWithoutDot = (name.Find(".") == std::string::npos); 3963af6ab5fSopenharmony_ci bool funcNameWithoutBackslash = (name.Find("\\") == std::string::npos); 3973af6ab5fSopenharmony_ci if (name != ANONYMOUS_FUNC_NAME && funcNameWithoutDot && 3983af6ab5fSopenharmony_ci funcNameWithoutBackslash && !functionNames_.count(name)) { 3993af6ab5fSopenharmony_ci // function with normal name, and hasn't been recorded 4003af6ab5fSopenharmony_ci auto internalName = std::string(program_->FormatedRecordName()) + std::string(name); 4013af6ab5fSopenharmony_ci functionNames_.insert(name); 4023af6ab5fSopenharmony_ci funcScope->BindName(name, util::UString(internalName, Allocator()).View()); 4033af6ab5fSopenharmony_ci return; 4043af6ab5fSopenharmony_ci } 4053af6ab5fSopenharmony_ci 4063af6ab5fSopenharmony_ci std::stringstream ss; 4073af6ab5fSopenharmony_ci ss << std::string(program_->FormatedRecordName()); 4083af6ab5fSopenharmony_ci 4093af6ab5fSopenharmony_ci ASSERT(func != nullptr); 4103af6ab5fSopenharmony_ci 4113af6ab5fSopenharmony_ci // For anonymous, special-name and duplicate function, get its source and name, make hash code, 4123af6ab5fSopenharmony_ci // and make #hash_duplicateHashTime#name as its name; 4133af6ab5fSopenharmony_ci auto funcContentNameStr = func->SourceCode(this).Mutf8() + name.Mutf8(); 4143af6ab5fSopenharmony_ci ss << ANONYMOUS_SPECIAL_DUPLICATE_FUNCTION_SPECIFIER << util::Helpers::GetHashString(funcContentNameStr); 4153af6ab5fSopenharmony_ci 4163af6ab5fSopenharmony_ci auto res = functionHashNames_.find(funcContentNameStr); 4173af6ab5fSopenharmony_ci if (res != functionHashNames_.end()) { 4183af6ab5fSopenharmony_ci ss << "_" << res->second++; 4193af6ab5fSopenharmony_ci } else { 4203af6ab5fSopenharmony_ci functionHashNames_.insert({funcContentNameStr, 1}); 4213af6ab5fSopenharmony_ci } 4223af6ab5fSopenharmony_ci ss << ANONYMOUS_SPECIAL_DUPLICATE_FUNCTION_SPECIFIER; 4233af6ab5fSopenharmony_ci 4243af6ab5fSopenharmony_ci if (name == ANONYMOUS_FUNC_NAME) { 4253af6ab5fSopenharmony_ci anonymousFunctionNames_[func] = util::UString(ss.str(), Allocator()).View(); 4263af6ab5fSopenharmony_ci } 4273af6ab5fSopenharmony_ci if (funcNameWithoutDot && funcNameWithoutBackslash) { 4283af6ab5fSopenharmony_ci ss << name; 4293af6ab5fSopenharmony_ci } 4303af6ab5fSopenharmony_ci std::string internalNameStr = ss.str(); 4313af6ab5fSopenharmony_ci StoreAndCheckSpecialFunctionName(internalNameStr, program_->RecordName().Mutf8()); 4323af6ab5fSopenharmony_ci funcScope->BindName(name, util::UString(internalNameStr, Allocator()).View()); 4333af6ab5fSopenharmony_ci} 4343af6ab5fSopenharmony_ci 4353af6ab5fSopenharmony_civoid Binder::BuildScriptFunction(Scope *outerScope, const ir::ScriptFunction *scriptFunc) 4363af6ab5fSopenharmony_ci{ 4373af6ab5fSopenharmony_ci if (bindingFlags_ & ResolveBindingFlags::TS_BEFORE_TRANSFORM) { 4383af6ab5fSopenharmony_ci return; 4393af6ab5fSopenharmony_ci } 4403af6ab5fSopenharmony_ci 4413af6ab5fSopenharmony_ci auto *funcScope = scriptFunc->Scope(); 4423af6ab5fSopenharmony_ci funcScope->ParamScope()->SetParent(outerScope); 4433af6ab5fSopenharmony_ci 4443af6ab5fSopenharmony_ci if (scriptFunc->IsArrow()) { 4453af6ab5fSopenharmony_ci const ir::ScriptFunction *ctor = util::Helpers::GetContainingConstructor(scriptFunc); 4463af6ab5fSopenharmony_ci if (ctor) { 4473af6ab5fSopenharmony_ci ctor->Scope()->AddFlag(VariableScopeFlags::INNER_ARROW); 4483af6ab5fSopenharmony_ci } 4493af6ab5fSopenharmony_ci } 4503af6ab5fSopenharmony_ci 4513af6ab5fSopenharmony_ci ASSERT(scope_->IsFunctionScope() || scope_->IsTSModuleScope() || scope_->IsTSEnumScope()); 4523af6ab5fSopenharmony_ci BuildFunction(scope_->AsFunctionVariableScope(), util::Helpers::FunctionName(Allocator(), scriptFunc), scriptFunc); 4533af6ab5fSopenharmony_ci} 4543af6ab5fSopenharmony_ci 4553af6ab5fSopenharmony_civoid Binder::BuildVarDeclaratorId(const ir::AstNode *parent, ir::AstNode *childNode) 4563af6ab5fSopenharmony_ci{ 4573af6ab5fSopenharmony_ci childNode->SetParent(parent); 4583af6ab5fSopenharmony_ci 4593af6ab5fSopenharmony_ci switch (childNode->Type()) { 4603af6ab5fSopenharmony_ci case ir::AstNodeType::IDENTIFIER: { 4613af6ab5fSopenharmony_ci auto *ident = childNode->AsIdentifier(); 4623af6ab5fSopenharmony_ci const auto &name = ident->Name(); 4633af6ab5fSopenharmony_ci if (name.Is(FUNCTION_ARGUMENTS)) { 4643af6ab5fSopenharmony_ci CheckMandatoryArguments(ident); 4653af6ab5fSopenharmony_ci } 4663af6ab5fSopenharmony_ci 4673af6ab5fSopenharmony_ci if (util::Helpers::IsGlobalIdentifier(name)) { 4683af6ab5fSopenharmony_ci break; 4693af6ab5fSopenharmony_ci } 4703af6ab5fSopenharmony_ci 4713af6ab5fSopenharmony_ci auto *variable = scope_->FindLocal(name, ResolveBindingOptions::BINDINGS); 4723af6ab5fSopenharmony_ci 4733af6ab5fSopenharmony_ci if (Program()->Extension() == ScriptExtension::TS) { 4743af6ab5fSopenharmony_ci ident->SetVariable(variable); 4753af6ab5fSopenharmony_ci BuildTSSignatureDeclarationBaseParamsWithParent(ident, ident->TypeAnnotation()); 4763af6ab5fSopenharmony_ci } 4773af6ab5fSopenharmony_ci 4783af6ab5fSopenharmony_ci variable->AddFlag(VariableFlags::INITIALIZED); 4793af6ab5fSopenharmony_ci break; 4803af6ab5fSopenharmony_ci } 4813af6ab5fSopenharmony_ci case ir::AstNodeType::OBJECT_PATTERN: { 4823af6ab5fSopenharmony_ci auto *objPattern = childNode->AsObjectPattern(); 4833af6ab5fSopenharmony_ci 4843af6ab5fSopenharmony_ci for (auto *prop : objPattern->Properties()) { 4853af6ab5fSopenharmony_ci BuildVarDeclaratorId(childNode, prop); 4863af6ab5fSopenharmony_ci } 4873af6ab5fSopenharmony_ci 4883af6ab5fSopenharmony_ci BuildTSSignatureDeclarationBaseParamsWithParent(objPattern, objPattern->TypeAnnotation()); 4893af6ab5fSopenharmony_ci break; 4903af6ab5fSopenharmony_ci } 4913af6ab5fSopenharmony_ci case ir::AstNodeType::ARRAY_PATTERN: { 4923af6ab5fSopenharmony_ci auto *arrayPattern = childNode->AsArrayPattern(); 4933af6ab5fSopenharmony_ci 4943af6ab5fSopenharmony_ci for (auto *element : childNode->AsArrayPattern()->Elements()) { 4953af6ab5fSopenharmony_ci BuildVarDeclaratorId(childNode, element); 4963af6ab5fSopenharmony_ci } 4973af6ab5fSopenharmony_ci 4983af6ab5fSopenharmony_ci BuildTSSignatureDeclarationBaseParamsWithParent(arrayPattern, arrayPattern->TypeAnnotation()); 4993af6ab5fSopenharmony_ci break; 5003af6ab5fSopenharmony_ci } 5013af6ab5fSopenharmony_ci case ir::AstNodeType::ASSIGNMENT_PATTERN: { 5023af6ab5fSopenharmony_ci ResolveReference(childNode, childNode->AsAssignmentPattern()->Right()); 5033af6ab5fSopenharmony_ci BuildVarDeclaratorId(childNode, childNode->AsAssignmentPattern()->Left()); 5043af6ab5fSopenharmony_ci break; 5053af6ab5fSopenharmony_ci } 5063af6ab5fSopenharmony_ci case ir::AstNodeType::PROPERTY: { 5073af6ab5fSopenharmony_ci ResolveReference(childNode, childNode->AsProperty()->Key()); 5083af6ab5fSopenharmony_ci BuildVarDeclaratorId(childNode, childNode->AsProperty()->Value()); 5093af6ab5fSopenharmony_ci break; 5103af6ab5fSopenharmony_ci } 5113af6ab5fSopenharmony_ci case ir::AstNodeType::REST_ELEMENT: { 5123af6ab5fSopenharmony_ci BuildVarDeclaratorId(childNode, childNode->AsRestElement()->Argument()); 5133af6ab5fSopenharmony_ci break; 5143af6ab5fSopenharmony_ci } 5153af6ab5fSopenharmony_ci default: 5163af6ab5fSopenharmony_ci break; 5173af6ab5fSopenharmony_ci } 5183af6ab5fSopenharmony_ci} 5193af6ab5fSopenharmony_ci 5203af6ab5fSopenharmony_civoid Binder::BuildTSSignatureDeclarationBaseParamsWithParent(const ir::AstNode *parent, ir::AstNode *typeNode) 5213af6ab5fSopenharmony_ci{ 5223af6ab5fSopenharmony_ci if (!typeNode) { 5233af6ab5fSopenharmony_ci return; 5243af6ab5fSopenharmony_ci } 5253af6ab5fSopenharmony_ci typeNode->SetParent(parent); 5263af6ab5fSopenharmony_ci BuildTSSignatureDeclarationBaseParams(typeNode); 5273af6ab5fSopenharmony_ci} 5283af6ab5fSopenharmony_ci 5293af6ab5fSopenharmony_civoid Binder::BuildTSSignatureDeclarationBaseParams(const ir::AstNode *typeNode) 5303af6ab5fSopenharmony_ci{ 5313af6ab5fSopenharmony_ci ASSERT(typeNode != nullptr); 5323af6ab5fSopenharmony_ci 5333af6ab5fSopenharmony_ci Scope *scope = nullptr; 5343af6ab5fSopenharmony_ci 5353af6ab5fSopenharmony_ci switch (typeNode->Type()) { 5363af6ab5fSopenharmony_ci case ir::AstNodeType::TS_FUNCTION_TYPE: { 5373af6ab5fSopenharmony_ci scope = typeNode->AsTSFunctionType()->Scope(); 5383af6ab5fSopenharmony_ci break; 5393af6ab5fSopenharmony_ci } 5403af6ab5fSopenharmony_ci case ir::AstNodeType::TS_CONSTRUCTOR_TYPE: { 5413af6ab5fSopenharmony_ci scope = typeNode->AsTSConstructorType()->Scope(); 5423af6ab5fSopenharmony_ci break; 5433af6ab5fSopenharmony_ci } 5443af6ab5fSopenharmony_ci case ir::AstNodeType::TS_SIGNATURE_DECLARATION: { 5453af6ab5fSopenharmony_ci scope = typeNode->AsTSSignatureDeclaration()->Scope(); 5463af6ab5fSopenharmony_ci break; 5473af6ab5fSopenharmony_ci } 5483af6ab5fSopenharmony_ci case ir::AstNodeType::TS_METHOD_SIGNATURE: { 5493af6ab5fSopenharmony_ci scope = typeNode->AsTSMethodSignature()->Scope(); 5503af6ab5fSopenharmony_ci break; 5513af6ab5fSopenharmony_ci } 5523af6ab5fSopenharmony_ci default: { 5533af6ab5fSopenharmony_ci ResolveReferences(typeNode); 5543af6ab5fSopenharmony_ci return; 5553af6ab5fSopenharmony_ci } 5563af6ab5fSopenharmony_ci } 5573af6ab5fSopenharmony_ci 5583af6ab5fSopenharmony_ci ASSERT(scope && scope->IsFunctionParamScope()); 5593af6ab5fSopenharmony_ci 5603af6ab5fSopenharmony_ci auto scopeCtx = LexicalScope<FunctionParamScope>::Enter(this, scope->AsFunctionParamScope()); 5613af6ab5fSopenharmony_ci ResolveReferences(typeNode); 5623af6ab5fSopenharmony_ci} 5633af6ab5fSopenharmony_ci 5643af6ab5fSopenharmony_civoid Binder::BuildVarDeclarator(ir::VariableDeclarator *varDecl) 5653af6ab5fSopenharmony_ci{ 5663af6ab5fSopenharmony_ci if (varDecl->Parent()->AsVariableDeclaration()->Kind() == ir::VariableDeclaration::VariableDeclarationKind::VAR) { 5673af6ab5fSopenharmony_ci ResolveReferences(varDecl); 5683af6ab5fSopenharmony_ci return; 5693af6ab5fSopenharmony_ci } 5703af6ab5fSopenharmony_ci 5713af6ab5fSopenharmony_ci if (varDecl->Init()) { 5723af6ab5fSopenharmony_ci ResolveReference(varDecl, varDecl->Init()); 5733af6ab5fSopenharmony_ci } 5743af6ab5fSopenharmony_ci 5753af6ab5fSopenharmony_ci BuildVarDeclaratorId(varDecl, varDecl->Id()); 5763af6ab5fSopenharmony_ci} 5773af6ab5fSopenharmony_ci 5783af6ab5fSopenharmony_civoid Binder::BuildClassDefinition(ir::ClassDefinition *classDef) 5793af6ab5fSopenharmony_ci{ 5803af6ab5fSopenharmony_ci if (classDef->Parent()->IsClassDeclaration()) { 5813af6ab5fSopenharmony_ci util::StringView className = classDef->GetName(); 5823af6ab5fSopenharmony_ci ASSERT(!className.Empty()); 5833af6ab5fSopenharmony_ci ScopeFindResult res = scope_->Find(className); 5843af6ab5fSopenharmony_ci 5853af6ab5fSopenharmony_ci ASSERT(res.variable && (res.variable->Declaration()->IsClassDecl() || 5863af6ab5fSopenharmony_ci (res.variable->Declaration()->IsFunctionDecl() && 5873af6ab5fSopenharmony_ci res.variable->Declaration()->AsFunctionDecl()->GetDeclClass() != nullptr))); 5883af6ab5fSopenharmony_ci res.variable->AddFlag(VariableFlags::INITIALIZED); 5893af6ab5fSopenharmony_ci } 5903af6ab5fSopenharmony_ci 5913af6ab5fSopenharmony_ci auto scopeCtx = LexicalScope<ClassScope>::Enter(this, classDef->Scope()); 5923af6ab5fSopenharmony_ci 5933af6ab5fSopenharmony_ci if (classDef->TypeParams()) { 5943af6ab5fSopenharmony_ci ResolveReference(classDef, classDef->TypeParams()); 5953af6ab5fSopenharmony_ci } 5963af6ab5fSopenharmony_ci 5973af6ab5fSopenharmony_ci if (classDef->Super()) { 5983af6ab5fSopenharmony_ci ResolveReference(classDef, classDef->Super()); 5993af6ab5fSopenharmony_ci } 6003af6ab5fSopenharmony_ci 6013af6ab5fSopenharmony_ci if (classDef->SuperTypeParams()) { 6023af6ab5fSopenharmony_ci ResolveReference(classDef, classDef->SuperTypeParams()); 6033af6ab5fSopenharmony_ci } 6043af6ab5fSopenharmony_ci 6053af6ab5fSopenharmony_ci for (auto *iter : classDef->Implements()) { 6063af6ab5fSopenharmony_ci ResolveReference(classDef, iter); 6073af6ab5fSopenharmony_ci } 6083af6ab5fSopenharmony_ci 6093af6ab5fSopenharmony_ci // new class features in ecma2022 are only supported for api11 and above 6103af6ab5fSopenharmony_ci if (Program()->TargetApiVersion() > 10 && !(bindingFlags_ & ResolveBindingFlags::TS_BEFORE_TRANSFORM)) { 6113af6ab5fSopenharmony_ci classDef->BuildClassEnvironment(program_->UseDefineSemantic()); 6123af6ab5fSopenharmony_ci } 6133af6ab5fSopenharmony_ci 6143af6ab5fSopenharmony_ci if (classDef->Ident()) { 6153af6ab5fSopenharmony_ci ScopeFindResult res = scope_->Find(classDef->Ident()->Name()); 6163af6ab5fSopenharmony_ci 6173af6ab5fSopenharmony_ci ASSERT(res.variable && res.variable->Declaration()->IsConstDecl()); 6183af6ab5fSopenharmony_ci res.variable->AddFlag(VariableFlags::INITIALIZED); 6193af6ab5fSopenharmony_ci 6203af6ab5fSopenharmony_ci classDef->Ident()->SetParent(classDef); 6213af6ab5fSopenharmony_ci } 6223af6ab5fSopenharmony_ci bool previousInSendableClass = inSendableClass_; 6233af6ab5fSopenharmony_ci 6243af6ab5fSopenharmony_ci if (!(classDef->Parent()->IsClassDeclaration() && classDef->Parent()->AsClassDeclaration()->IsAnnotationDecl())) { 6253af6ab5fSopenharmony_ci ResolveReference(classDef, classDef->Ctor()); 6263af6ab5fSopenharmony_ci } 6273af6ab5fSopenharmony_ci 6283af6ab5fSopenharmony_ci if (classDef->NeedStaticInitializer()) { 6293af6ab5fSopenharmony_ci ResolveReference(classDef, classDef->StaticInitializer()); 6303af6ab5fSopenharmony_ci } 6313af6ab5fSopenharmony_ci 6323af6ab5fSopenharmony_ci if (classDef->NeedInstanceInitializer()) { 6333af6ab5fSopenharmony_ci ResolveReference(classDef, classDef->InstanceInitializer()); 6343af6ab5fSopenharmony_ci } 6353af6ab5fSopenharmony_ci 6363af6ab5fSopenharmony_ci for (auto *stmt : classDef->Body()) { 6373af6ab5fSopenharmony_ci ResolveReference(classDef, stmt); 6383af6ab5fSopenharmony_ci } 6393af6ab5fSopenharmony_ci 6403af6ab5fSopenharmony_ci for (auto *iter : classDef->IndexSignatures()) { 6413af6ab5fSopenharmony_ci ResolveReference(classDef, iter); 6423af6ab5fSopenharmony_ci } 6433af6ab5fSopenharmony_ci inSendableClass_ = previousInSendableClass; 6443af6ab5fSopenharmony_ci} 6453af6ab5fSopenharmony_ci 6463af6ab5fSopenharmony_civoid Binder::BuildForUpdateLoop(ir::ForUpdateStatement *forUpdateStmt) 6473af6ab5fSopenharmony_ci{ 6483af6ab5fSopenharmony_ci auto *loopScope = forUpdateStmt->Scope(); 6493af6ab5fSopenharmony_ci 6503af6ab5fSopenharmony_ci auto loopCtx = LexicalScope<LoopScope>::Enter(this, loopScope); 6513af6ab5fSopenharmony_ci 6523af6ab5fSopenharmony_ci if (forUpdateStmt->Init()) { 6533af6ab5fSopenharmony_ci ResolveReference(forUpdateStmt, forUpdateStmt->Init()); 6543af6ab5fSopenharmony_ci } 6553af6ab5fSopenharmony_ci 6563af6ab5fSopenharmony_ci if (forUpdateStmt->Update()) { 6573af6ab5fSopenharmony_ci ResolveReference(forUpdateStmt, forUpdateStmt->Update()); 6583af6ab5fSopenharmony_ci } 6593af6ab5fSopenharmony_ci 6603af6ab5fSopenharmony_ci if (forUpdateStmt->Test()) { 6613af6ab5fSopenharmony_ci ResolveReference(forUpdateStmt, forUpdateStmt->Test()); 6623af6ab5fSopenharmony_ci } 6633af6ab5fSopenharmony_ci 6643af6ab5fSopenharmony_ci ResolveReference(forUpdateStmt, forUpdateStmt->Body()); 6653af6ab5fSopenharmony_ci 6663af6ab5fSopenharmony_ci loopCtx.GetScope()->InitVariable(); 6673af6ab5fSopenharmony_ci} 6683af6ab5fSopenharmony_ci 6693af6ab5fSopenharmony_civoid Binder::BuildForInOfLoop(const ir::Statement *parent, binder::LoopScope *loopScope, ir::AstNode *left, 6703af6ab5fSopenharmony_ci ir::Expression *right, ir::Statement *body) 6713af6ab5fSopenharmony_ci{ 6723af6ab5fSopenharmony_ci auto loopCtx = LexicalScope<LoopScope>::Enter(this, loopScope); 6733af6ab5fSopenharmony_ci 6743af6ab5fSopenharmony_ci ResolveReference(parent, right); 6753af6ab5fSopenharmony_ci ResolveReference(parent, left); 6763af6ab5fSopenharmony_ci 6773af6ab5fSopenharmony_ci ResolveReference(parent, body); 6783af6ab5fSopenharmony_ci loopCtx.GetScope()->InitVariable(); 6793af6ab5fSopenharmony_ci} 6803af6ab5fSopenharmony_ci 6813af6ab5fSopenharmony_civoid Binder::BuildCatchClause(ir::CatchClause *catchClauseStmt) 6823af6ab5fSopenharmony_ci{ 6833af6ab5fSopenharmony_ci if (catchClauseStmt->Param()) { 6843af6ab5fSopenharmony_ci auto paramScopeCtx = LexicalScope<CatchParamScope>::Enter(this, catchClauseStmt->Scope()->ParamScope()); 6853af6ab5fSopenharmony_ci ResolveReference(catchClauseStmt, catchClauseStmt->Param()); 6863af6ab5fSopenharmony_ci } 6873af6ab5fSopenharmony_ci 6883af6ab5fSopenharmony_ci auto scopeCtx = LexicalScope<CatchScope>::Enter(this, catchClauseStmt->Scope()); 6893af6ab5fSopenharmony_ci ResolveReference(catchClauseStmt, catchClauseStmt->Body()); 6903af6ab5fSopenharmony_ci} 6913af6ab5fSopenharmony_ci 6923af6ab5fSopenharmony_civoid Binder::ResolveReference(const ir::AstNode *parent, ir::AstNode *childNode) 6933af6ab5fSopenharmony_ci{ 6943af6ab5fSopenharmony_ci childNode->SetParent(parent); 6953af6ab5fSopenharmony_ci 6963af6ab5fSopenharmony_ci ClassTdz classTdz(parent, childNode, scope_); 6973af6ab5fSopenharmony_ci 6983af6ab5fSopenharmony_ci switch (childNode->Type()) { 6993af6ab5fSopenharmony_ci case ir::AstNodeType::IDENTIFIER: { 7003af6ab5fSopenharmony_ci auto *ident = childNode->AsIdentifier(); 7013af6ab5fSopenharmony_ci 7023af6ab5fSopenharmony_ci if (ident->Name().Is(FUNCTION_ARGUMENTS)) { 7033af6ab5fSopenharmony_ci CheckMandatoryArguments(ident); 7043af6ab5fSopenharmony_ci } 7053af6ab5fSopenharmony_ci 7063af6ab5fSopenharmony_ci if (ident->IsReference()) { 7073af6ab5fSopenharmony_ci LookupIdentReference(ident); 7083af6ab5fSopenharmony_ci } 7093af6ab5fSopenharmony_ci 7103af6ab5fSopenharmony_ci /* During ts to js transformation, a non-empty namespace in ts file will be transformed 7113af6ab5fSopenharmony_ci into a anonymous function while empty namespace will be removed. So the name for the 7123af6ab5fSopenharmony_ci namespace need to be stored before the transformation.*/ 7133af6ab5fSopenharmony_ci if (scope_->Type() == ScopeType::TSMODULE) { 7143af6ab5fSopenharmony_ci scope_->SetSelfScopeName(ident->Name()); 7153af6ab5fSopenharmony_ci } 7163af6ab5fSopenharmony_ci 7173af6ab5fSopenharmony_ci ResolveReferences(childNode); 7183af6ab5fSopenharmony_ci break; 7193af6ab5fSopenharmony_ci } 7203af6ab5fSopenharmony_ci case ir::AstNodeType::ANNOTATION: { 7213af6ab5fSopenharmony_ci auto *annotation = childNode->AsAnnotation(); 7223af6ab5fSopenharmony_ci std::string annoName{annotation->Name()}; 7233af6ab5fSopenharmony_ci ScopeFindResult res = scope_->Find(annotation->Name(), bindingOptions_); 7243af6ab5fSopenharmony_ci if (res.variable != nullptr) { 7253af6ab5fSopenharmony_ci if (res.variable->Declaration()->Node()->IsImportSpecifier()) { 7263af6ab5fSopenharmony_ci annotation->SetIsImported(); 7273af6ab5fSopenharmony_ci } else if (!res.variable->Declaration()->Node()->IsClassDefinition()) { 7283af6ab5fSopenharmony_ci ThrowInvalidAnnotationDeclaration(annotation->Start(), annotation->Name()); 7293af6ab5fSopenharmony_ci } 7303af6ab5fSopenharmony_ci } else if (annoName.find_first_of(".") != std::string::npos) { 7313af6ab5fSopenharmony_ci auto importName = annoName.substr(0, annoName.find_first_of(".")); 7323af6ab5fSopenharmony_ci ScopeFindResult res = scope_->Find(util::StringView(importName), bindingOptions_); 7333af6ab5fSopenharmony_ci if (res.variable != nullptr && res.variable->Declaration()->Node()->IsImportNamespaceSpecifier()) { 7343af6ab5fSopenharmony_ci annotation->SetIsImported(); 7353af6ab5fSopenharmony_ci } else { 7363af6ab5fSopenharmony_ci ThrowInvalidAnnotationDeclaration(annotation->Start(), annotation->Name()); 7373af6ab5fSopenharmony_ci } 7383af6ab5fSopenharmony_ci } else { 7393af6ab5fSopenharmony_ci ThrowInvalidAnnotationDeclaration(annotation->Start(), annotation->Name()); 7403af6ab5fSopenharmony_ci } 7413af6ab5fSopenharmony_ci ResolveReferences(childNode); 7423af6ab5fSopenharmony_ci break; 7433af6ab5fSopenharmony_ci } 7443af6ab5fSopenharmony_ci case ir::AstNodeType::PRIVATE_IDENTIFIER: { 7453af6ab5fSopenharmony_ci if (Program()->Extension() == ScriptExtension::JS) { 7463af6ab5fSopenharmony_ci CheckPrivateDeclaration(childNode->AsPrivateIdentifier()); 7473af6ab5fSopenharmony_ci } else if (Program()->Extension() == ScriptExtension::TS && 7483af6ab5fSopenharmony_ci bindingFlags_ == ResolveBindingFlags::TS_AFTER_TRANSFORM) { 7493af6ab5fSopenharmony_ci CheckPrivateDeclaration(childNode->AsPrivateIdentifier()); 7503af6ab5fSopenharmony_ci } 7513af6ab5fSopenharmony_ci break; 7523af6ab5fSopenharmony_ci } 7533af6ab5fSopenharmony_ci case ir::AstNodeType::SUPER_EXPRESSION: { 7543af6ab5fSopenharmony_ci VariableScope *varScope = scope_->EnclosingVariableScope(); 7553af6ab5fSopenharmony_ci varScope->AddFlag(VariableScopeFlags::USE_SUPER); 7563af6ab5fSopenharmony_ci 7573af6ab5fSopenharmony_ci ResolveReferences(childNode); 7583af6ab5fSopenharmony_ci break; 7593af6ab5fSopenharmony_ci } 7603af6ab5fSopenharmony_ci case ir::AstNodeType::SCRIPT_FUNCTION: { 7613af6ab5fSopenharmony_ci bool previousInSendableFunction = inSendableFunction_; 7623af6ab5fSopenharmony_ci auto *scriptFunc = childNode->AsScriptFunction(); 7633af6ab5fSopenharmony_ci // Static initializer only be executed once. Treat it as unshared method. 7643af6ab5fSopenharmony_ci if ((inSendableClass_ && !scriptFunc->IsStaticInitializer()) || inSendableFunction_) { 7653af6ab5fSopenharmony_ci scriptFunc->SetInSendable(); 7663af6ab5fSopenharmony_ci } 7673af6ab5fSopenharmony_ci bool enableSendableClass = program_->TargetApiVersion() >= 7683af6ab5fSopenharmony_ci util::Helpers::SENDABLE_CLASS_MIN_SUPPORTED_API_VERSION; 7693af6ab5fSopenharmony_ci util::Helpers::ScanDirectives(const_cast<ir::ScriptFunction *>(scriptFunc), Program()->GetLineIndex(), 7703af6ab5fSopenharmony_ci enableSendableClass, 7713af6ab5fSopenharmony_ci !util::Helpers::IsDefaultApiVersion(program_->TargetApiVersion(), program_->GetTargetApiSubVersion())); 7723af6ab5fSopenharmony_ci 7733af6ab5fSopenharmony_ci if (scriptFunc->IsConstructor() && util::Helpers::GetClassDefiniton(scriptFunc)->IsSendable()) { 7743af6ab5fSopenharmony_ci scriptFunc->SetInSendable(); 7753af6ab5fSopenharmony_ci inSendableClass_ = true; 7763af6ab5fSopenharmony_ci } else if (scriptFunc->IsSendable()) { 7773af6ab5fSopenharmony_ci scriptFunc->SetInSendable(); 7783af6ab5fSopenharmony_ci inSendableFunction_ = true; 7793af6ab5fSopenharmony_ci } 7803af6ab5fSopenharmony_ci 7813af6ab5fSopenharmony_ci auto *funcScope = scriptFunc->Scope(); 7823af6ab5fSopenharmony_ci 7833af6ab5fSopenharmony_ci auto *outerScope = scope_; 7843af6ab5fSopenharmony_ci 7853af6ab5fSopenharmony_ci if (scriptFunc->Id() != nullptr) { 7863af6ab5fSopenharmony_ci scriptFunc->Id()->SetParent(scriptFunc); 7873af6ab5fSopenharmony_ci } 7883af6ab5fSopenharmony_ci 7893af6ab5fSopenharmony_ci { 7903af6ab5fSopenharmony_ci auto paramScopeCtx = LexicalScope<FunctionParamScope>::Enter(this, funcScope->ParamScope()); 7913af6ab5fSopenharmony_ci 7923af6ab5fSopenharmony_ci if (Program()->Extension() == ScriptExtension::TS) { 7933af6ab5fSopenharmony_ci if (scriptFunc->TypeParams() != nullptr) { 7943af6ab5fSopenharmony_ci ResolveReference(scriptFunc, scriptFunc->TypeParams()); 7953af6ab5fSopenharmony_ci } 7963af6ab5fSopenharmony_ci if (scriptFunc->ThisParams() != nullptr) { 7973af6ab5fSopenharmony_ci ResolveReference(scriptFunc, scriptFunc->ThisParams()); 7983af6ab5fSopenharmony_ci } 7993af6ab5fSopenharmony_ci } 8003af6ab5fSopenharmony_ci 8013af6ab5fSopenharmony_ci for (auto *param : scriptFunc->Params()) { 8023af6ab5fSopenharmony_ci ResolveReference(scriptFunc, param); 8033af6ab5fSopenharmony_ci } 8043af6ab5fSopenharmony_ci } 8053af6ab5fSopenharmony_ci 8063af6ab5fSopenharmony_ci if (Program()->Extension() == ScriptExtension::TS) { 8073af6ab5fSopenharmony_ci if (scriptFunc->ReturnTypeAnnotation()) { 8083af6ab5fSopenharmony_ci ResolveReference(scriptFunc, scriptFunc->ReturnTypeAnnotation()); 8093af6ab5fSopenharmony_ci } 8103af6ab5fSopenharmony_ci 8113af6ab5fSopenharmony_ci if (scriptFunc->IsOverload() || scriptFunc->Declare()) { 8123af6ab5fSopenharmony_ci break; 8133af6ab5fSopenharmony_ci } 8143af6ab5fSopenharmony_ci } 8153af6ab5fSopenharmony_ci 8163af6ab5fSopenharmony_ci auto scopeCtx = LexicalScope<FunctionScope>::Enter(this, funcScope); 8173af6ab5fSopenharmony_ci 8183af6ab5fSopenharmony_ci BuildScriptFunction(outerScope, scriptFunc); 8193af6ab5fSopenharmony_ci 8203af6ab5fSopenharmony_ci ResolveReference(scriptFunc, scriptFunc->Body()); 8213af6ab5fSopenharmony_ci inSendableFunction_ = previousInSendableFunction; 8223af6ab5fSopenharmony_ci break; 8233af6ab5fSopenharmony_ci } 8243af6ab5fSopenharmony_ci case ir::AstNodeType::VARIABLE_DECLARATOR: { 8253af6ab5fSopenharmony_ci BuildVarDeclarator(childNode->AsVariableDeclarator()); 8263af6ab5fSopenharmony_ci 8273af6ab5fSopenharmony_ci break; 8283af6ab5fSopenharmony_ci } 8293af6ab5fSopenharmony_ci case ir::AstNodeType::CLASS_DEFINITION: { 8303af6ab5fSopenharmony_ci auto *classScope = childNode->AsClassDefinition()->Scope(); 8313af6ab5fSopenharmony_ci classScope->SetParent(scope_); 8323af6ab5fSopenharmony_ci BuildClassDefinition(childNode->AsClassDefinition()); 8333af6ab5fSopenharmony_ci 8343af6ab5fSopenharmony_ci break; 8353af6ab5fSopenharmony_ci } 8363af6ab5fSopenharmony_ci case ir::AstNodeType::CLASS_PROPERTY: { 8373af6ab5fSopenharmony_ci /* for ts tranformer cases, all class properties are implemented by transformer in api10 and 8383af6ab5fSopenharmony_ci * only public instance class properties are implemented by transformer in api11*/ 8393af6ab5fSopenharmony_ci auto *prop = childNode->AsClassProperty(); 8403af6ab5fSopenharmony_ci if (Program()->Extension() == ScriptExtension::TS && (Program()->TargetApiVersion() < 11 || 8413af6ab5fSopenharmony_ci (!prop->IsStatic() && !prop->IsPrivate()))) { 8423af6ab5fSopenharmony_ci const ir::ScriptFunction *ctor = util::Helpers::GetContainingConstructor(prop); 8433af6ab5fSopenharmony_ci auto scopeCtx = LexicalScope<FunctionScope>::Enter(this, ctor->Scope()); 8443af6ab5fSopenharmony_ci ResolveReferences(childNode); 8453af6ab5fSopenharmony_ci break; 8463af6ab5fSopenharmony_ci } 8473af6ab5fSopenharmony_ci 8483af6ab5fSopenharmony_ci ResolveReference(prop, prop->Key()); 8493af6ab5fSopenharmony_ci if (prop->Value() != nullptr) { 8503af6ab5fSopenharmony_ci ASSERT(parent->IsClassDefinition()); 8513af6ab5fSopenharmony_ci const auto *classDef = parent->AsClassDefinition(); 8523af6ab5fSopenharmony_ci const ir::MethodDefinition *method = prop->IsStatic() ? classDef->StaticInitializer() : 8533af6ab5fSopenharmony_ci classDef->InstanceInitializer(); 8543af6ab5fSopenharmony_ci auto scopeCtx = LexicalScope<FunctionScope>::Enter(this, method->Function()->Scope()); 8553af6ab5fSopenharmony_ci ResolveReference(prop, prop->Value()); 8563af6ab5fSopenharmony_ci } 8573af6ab5fSopenharmony_ci break; 8583af6ab5fSopenharmony_ci } 8593af6ab5fSopenharmony_ci case ir::AstNodeType::BLOCK_STATEMENT: { 8603af6ab5fSopenharmony_ci auto scope = childNode->AsBlockStatement()->Scope(); 8613af6ab5fSopenharmony_ci auto scopeCtx = scope != nullptr ? 8623af6ab5fSopenharmony_ci LexicalScope<Scope>::Enter(this, scope) : 8633af6ab5fSopenharmony_ci LexicalScope<Scope>::Enter(this, GetScope()); 8643af6ab5fSopenharmony_ci 8653af6ab5fSopenharmony_ci ResolveReferences(childNode); 8663af6ab5fSopenharmony_ci break; 8673af6ab5fSopenharmony_ci } 8683af6ab5fSopenharmony_ci case ir::AstNodeType::SWITCH_STATEMENT: { 8693af6ab5fSopenharmony_ci auto *switchStatement = childNode->AsSwitchStatement(); 8703af6ab5fSopenharmony_ci ResolveReference(switchStatement, switchStatement->Discriminant()); 8713af6ab5fSopenharmony_ci 8723af6ab5fSopenharmony_ci auto scopeCtx = LexicalScope<LocalScope>::Enter(this, childNode->AsSwitchStatement()->Scope()); 8733af6ab5fSopenharmony_ci for (auto *it : switchStatement->Cases()) { 8743af6ab5fSopenharmony_ci ResolveReference(switchStatement, it); 8753af6ab5fSopenharmony_ci } 8763af6ab5fSopenharmony_ci break; 8773af6ab5fSopenharmony_ci } 8783af6ab5fSopenharmony_ci case ir::AstNodeType::DO_WHILE_STATEMENT: { 8793af6ab5fSopenharmony_ci auto *doWhileStatement = childNode->AsDoWhileStatement(); 8803af6ab5fSopenharmony_ci 8813af6ab5fSopenharmony_ci { 8823af6ab5fSopenharmony_ci auto loopScopeCtx = LexicalScope<LoopScope>::Enter(this, doWhileStatement->Scope()); 8833af6ab5fSopenharmony_ci ResolveReference(doWhileStatement, doWhileStatement->Body()); 8843af6ab5fSopenharmony_ci loopScopeCtx.GetScope()->InitVariable(); 8853af6ab5fSopenharmony_ci } 8863af6ab5fSopenharmony_ci 8873af6ab5fSopenharmony_ci ResolveReference(doWhileStatement, doWhileStatement->Test()); 8883af6ab5fSopenharmony_ci break; 8893af6ab5fSopenharmony_ci } 8903af6ab5fSopenharmony_ci case ir::AstNodeType::WHILE_STATEMENT: { 8913af6ab5fSopenharmony_ci auto *whileStatement = childNode->AsWhileStatement(); 8923af6ab5fSopenharmony_ci ResolveReference(whileStatement, whileStatement->Test()); 8933af6ab5fSopenharmony_ci 8943af6ab5fSopenharmony_ci auto loopScopeCtx = LexicalScope<LoopScope>::Enter(this, whileStatement->Scope()); 8953af6ab5fSopenharmony_ci ResolveReference(whileStatement, whileStatement->Body()); 8963af6ab5fSopenharmony_ci loopScopeCtx.GetScope()->InitVariable(); 8973af6ab5fSopenharmony_ci break; 8983af6ab5fSopenharmony_ci } 8993af6ab5fSopenharmony_ci case ir::AstNodeType::FOR_UPDATE_STATEMENT: { 9003af6ab5fSopenharmony_ci BuildForUpdateLoop(childNode->AsForUpdateStatement()); 9013af6ab5fSopenharmony_ci break; 9023af6ab5fSopenharmony_ci } 9033af6ab5fSopenharmony_ci case ir::AstNodeType::FOR_IN_STATEMENT: { 9043af6ab5fSopenharmony_ci auto *forInStmt = childNode->AsForInStatement(); 9053af6ab5fSopenharmony_ci BuildForInOfLoop(forInStmt, forInStmt->Scope(), forInStmt->Left(), forInStmt->Right(), forInStmt->Body()); 9063af6ab5fSopenharmony_ci 9073af6ab5fSopenharmony_ci break; 9083af6ab5fSopenharmony_ci } 9093af6ab5fSopenharmony_ci case ir::AstNodeType::FOR_OF_STATEMENT: { 9103af6ab5fSopenharmony_ci auto *forOfStmt = childNode->AsForOfStatement(); 9113af6ab5fSopenharmony_ci BuildForInOfLoop(forOfStmt, forOfStmt->Scope(), forOfStmt->Left(), forOfStmt->Right(), forOfStmt->Body()); 9123af6ab5fSopenharmony_ci break; 9133af6ab5fSopenharmony_ci } 9143af6ab5fSopenharmony_ci case ir::AstNodeType::CATCH_CLAUSE: { 9153af6ab5fSopenharmony_ci BuildCatchClause(childNode->AsCatchClause()); 9163af6ab5fSopenharmony_ci break; 9173af6ab5fSopenharmony_ci } 9183af6ab5fSopenharmony_ci case ir::AstNodeType::EXPORT_NAMED_DECLARATION: { 9193af6ab5fSopenharmony_ci ValidateExportDecl(childNode->AsExportNamedDeclaration()); 9203af6ab5fSopenharmony_ci 9213af6ab5fSopenharmony_ci ResolveReferences(childNode); 9223af6ab5fSopenharmony_ci break; 9233af6ab5fSopenharmony_ci } 9243af6ab5fSopenharmony_ci // TypeScript specific part 9253af6ab5fSopenharmony_ci case ir::AstNodeType::TS_FUNCTION_TYPE: 9263af6ab5fSopenharmony_ci case ir::AstNodeType::TS_CONSTRUCTOR_TYPE: 9273af6ab5fSopenharmony_ci case ir::AstNodeType::TS_METHOD_SIGNATURE: 9283af6ab5fSopenharmony_ci case ir::AstNodeType::TS_SIGNATURE_DECLARATION: { 9293af6ab5fSopenharmony_ci BuildTSSignatureDeclarationBaseParams(childNode); 9303af6ab5fSopenharmony_ci break; 9313af6ab5fSopenharmony_ci } 9323af6ab5fSopenharmony_ci case ir::AstNodeType::TS_MODULE_DECLARATION: { 9333af6ab5fSopenharmony_ci auto scopeCtx = LexicalScope<Scope>::Enter(this, childNode->AsTSModuleDeclaration()->Scope()); 9343af6ab5fSopenharmony_ci ResolveReferences(childNode); 9353af6ab5fSopenharmony_ci break; 9363af6ab5fSopenharmony_ci } 9373af6ab5fSopenharmony_ci case ir::AstNodeType::TS_ENUM_DECLARATION: { 9383af6ab5fSopenharmony_ci auto scopeCtx = LexicalScope<Scope>::Enter(this, childNode->AsTSEnumDeclaration()->Scope()); 9393af6ab5fSopenharmony_ci ResolveReferences(childNode); 9403af6ab5fSopenharmony_ci break; 9413af6ab5fSopenharmony_ci } 9423af6ab5fSopenharmony_ci default: { 9433af6ab5fSopenharmony_ci ResolveReferences(childNode); 9443af6ab5fSopenharmony_ci break; 9453af6ab5fSopenharmony_ci } 9463af6ab5fSopenharmony_ci } 9473af6ab5fSopenharmony_ci} 9483af6ab5fSopenharmony_civoid Binder::ResolveReferences(const ir::AstNode *parent) 9493af6ab5fSopenharmony_ci{ 9503af6ab5fSopenharmony_ci parent->Iterate([this, parent](auto *childNode) { ResolveReference(parent, childNode); }); 9513af6ab5fSopenharmony_ci} 9523af6ab5fSopenharmony_ci 9533af6ab5fSopenharmony_civoid Binder::AddMandatoryParam(const std::string_view &name) 9543af6ab5fSopenharmony_ci{ 9553af6ab5fSopenharmony_ci ASSERT(scope_->IsFunctionVariableScope()); 9563af6ab5fSopenharmony_ci 9573af6ab5fSopenharmony_ci auto *decl = Allocator()->New<ParameterDecl>(name); 9583af6ab5fSopenharmony_ci auto *param = Allocator()->New<LocalVariable>(decl, VariableFlags::VAR); 9593af6ab5fSopenharmony_ci 9603af6ab5fSopenharmony_ci auto &funcParams = scope_->AsFunctionVariableScope()->ParamScope()->Params(); 9613af6ab5fSopenharmony_ci funcParams.insert(funcParams.begin(), param); 9623af6ab5fSopenharmony_ci scope_->AsFunctionVariableScope()->ParamScope()->Bindings().insert({decl->Name(), param}); 9633af6ab5fSopenharmony_ci scope_->AsFunctionVariableScope()->Bindings().insert({decl->Name(), param}); 9643af6ab5fSopenharmony_ci} 9653af6ab5fSopenharmony_ci 9663af6ab5fSopenharmony_civoid Binder::AddMandatoryParams() 9673af6ab5fSopenharmony_ci{ 9683af6ab5fSopenharmony_ci ASSERT(scope_ == topScope_); 9693af6ab5fSopenharmony_ci ASSERT(!functionScopes_.empty()); 9703af6ab5fSopenharmony_ci auto iter = functionScopes_.begin(); 9713af6ab5fSopenharmony_ci [[maybe_unused]] auto *funcScope = *iter++; 9723af6ab5fSopenharmony_ci 9733af6ab5fSopenharmony_ci ASSERT(funcScope->IsGlobalScope() || funcScope->IsModuleScope()); 9743af6ab5fSopenharmony_ci 9753af6ab5fSopenharmony_ci if (program_->Kind() == parser::ScriptKind::COMMONJS) { 9763af6ab5fSopenharmony_ci AddMandatoryParams(CJS_MAINFUNC_MANDATORY_PARAMS); 9773af6ab5fSopenharmony_ci } else { 9783af6ab5fSopenharmony_ci AddMandatoryParams(FUNCTION_MANDATORY_PARAMS); 9793af6ab5fSopenharmony_ci } 9803af6ab5fSopenharmony_ci 9813af6ab5fSopenharmony_ci for (; iter != functionScopes_.end(); iter++) { 9823af6ab5fSopenharmony_ci funcScope = *iter; 9833af6ab5fSopenharmony_ci const auto *scriptFunc = funcScope->Node()->AsScriptFunction(); 9843af6ab5fSopenharmony_ci 9853af6ab5fSopenharmony_ci auto scopeCtx = LexicalScope<FunctionScope>::Enter(this, funcScope); 9863af6ab5fSopenharmony_ci 9873af6ab5fSopenharmony_ci if (!scriptFunc->IsArrow()) { 9883af6ab5fSopenharmony_ci AddMandatoryParams(FUNCTION_MANDATORY_PARAMS); 9893af6ab5fSopenharmony_ci continue; 9903af6ab5fSopenharmony_ci } 9913af6ab5fSopenharmony_ci 9923af6ab5fSopenharmony_ci const ir::ScriptFunction *ctor = util::Helpers::GetContainingConstructor(scriptFunc); 9933af6ab5fSopenharmony_ci bool lexicalFunctionObject {}; 9943af6ab5fSopenharmony_ci 9953af6ab5fSopenharmony_ci if (ctor && util::Helpers::GetClassDefiniton(ctor)->Super() && 9963af6ab5fSopenharmony_ci funcScope->HasFlag(VariableScopeFlags::USE_SUPER)) { 9973af6ab5fSopenharmony_ci ASSERT(ctor->Scope()->HasFlag(VariableScopeFlags::INNER_ARROW)); 9983af6ab5fSopenharmony_ci ctor->Scope()->AddFlag(VariableScopeFlags::SET_LEXICAL_FUNCTION); 9993af6ab5fSopenharmony_ci lexicalFunctionObject = true; 10003af6ab5fSopenharmony_ci AddMandatoryParams(CTOR_ARROW_MANDATORY_PARAMS); 10013af6ab5fSopenharmony_ci } else { 10023af6ab5fSopenharmony_ci AddMandatoryParams(ARROW_MANDATORY_PARAMS); 10033af6ab5fSopenharmony_ci } 10043af6ab5fSopenharmony_ci 10053af6ab5fSopenharmony_ci LookupReference(MANDATORY_PARAM_NEW_TARGET); 10063af6ab5fSopenharmony_ci LookupReference(MANDATORY_PARAM_THIS); 10073af6ab5fSopenharmony_ci 10083af6ab5fSopenharmony_ci if (funcScope->HasFlag(VariableScopeFlags::USE_ARGS)) { 10093af6ab5fSopenharmony_ci LookupReference(FUNCTION_ARGUMENTS); 10103af6ab5fSopenharmony_ci } 10113af6ab5fSopenharmony_ci 10123af6ab5fSopenharmony_ci if (lexicalFunctionObject) { 10133af6ab5fSopenharmony_ci LookupReference(MANDATORY_PARAM_FUNC); 10143af6ab5fSopenharmony_ci } 10153af6ab5fSopenharmony_ci } 10163af6ab5fSopenharmony_ci} 10173af6ab5fSopenharmony_ci 10183af6ab5fSopenharmony_civoid Binder::AddDeclarationName(const util::StringView &name, DeclType type) 10193af6ab5fSopenharmony_ci{ 10203af6ab5fSopenharmony_ci if (extension_ != ScriptExtension::TS) { 10213af6ab5fSopenharmony_ci return; 10223af6ab5fSopenharmony_ci } 10233af6ab5fSopenharmony_ci variableNames_.insert(name); 10243af6ab5fSopenharmony_ci 10253af6ab5fSopenharmony_ci if (type == DeclType::ENUM) { 10263af6ab5fSopenharmony_ci return; 10273af6ab5fSopenharmony_ci } 10283af6ab5fSopenharmony_ci auto *scope = GetScope(); 10293af6ab5fSopenharmony_ci while (scope != nullptr) { 10303af6ab5fSopenharmony_ci if (scope->IsTSModuleScope()) { 10313af6ab5fSopenharmony_ci scope->AsTSModuleScope()->AddDeclarationName(name); 10323af6ab5fSopenharmony_ci } 10333af6ab5fSopenharmony_ci if (scope->IsTSEnumScope()) { 10343af6ab5fSopenharmony_ci scope->AsTSEnumScope()->AddDeclarationName(name); 10353af6ab5fSopenharmony_ci } 10363af6ab5fSopenharmony_ci scope = scope->Parent(); 10373af6ab5fSopenharmony_ci } 10383af6ab5fSopenharmony_ci} 10393af6ab5fSopenharmony_ci 10403af6ab5fSopenharmony_cibool Binder::HasVariableName(const util::StringView &name) const 10413af6ab5fSopenharmony_ci{ 10423af6ab5fSopenharmony_ci return variableNames_.find(name) != variableNames_.end(); 10433af6ab5fSopenharmony_ci} 10443af6ab5fSopenharmony_ci 10453af6ab5fSopenharmony_cistd::vector<Variable *> Binder::FindIdentifierTSVariables(const ir::Identifier *identifier, Scope *scope, 10463af6ab5fSopenharmony_ci ScopeFindResult &res) 10473af6ab5fSopenharmony_ci{ 10483af6ab5fSopenharmony_ci const auto &name = identifier->Name(); 10493af6ab5fSopenharmony_ci std::vector<binder::Variable *> findRes; 10503af6ab5fSopenharmony_ci 10513af6ab5fSopenharmony_ci auto currentScope = scope; 10523af6ab5fSopenharmony_ci while (currentScope != nullptr) { 10533af6ab5fSopenharmony_ci // Find ts variables 10543af6ab5fSopenharmony_ci auto fn = [&findRes](Variable *variable) { 10553af6ab5fSopenharmony_ci if (variable != nullptr) { 10563af6ab5fSopenharmony_ci findRes.emplace_back(variable); 10573af6ab5fSopenharmony_ci } 10583af6ab5fSopenharmony_ci }; 10593af6ab5fSopenharmony_ci 10603af6ab5fSopenharmony_ci fn(currentScope->FindLocalTSVariable<binder::TSBindingType::NAMESPACE>(name)); 10613af6ab5fSopenharmony_ci fn(currentScope->FindLocalTSVariable<binder::TSBindingType::ENUMLITERAL>(name)); 10623af6ab5fSopenharmony_ci fn(currentScope->FindLocalTSVariable<binder::TSBindingType::IMPORT_EQUALS>(name)); 10633af6ab5fSopenharmony_ci if (currentScope->IsTSModuleScope()) { 10643af6ab5fSopenharmony_ci fn(currentScope->AsTSModuleScope()->FindExportTSVariable<binder::TSBindingType::NAMESPACE>(name)); 10653af6ab5fSopenharmony_ci fn(currentScope->AsTSModuleScope()->FindExportTSVariable<binder::TSBindingType::ENUMLITERAL>(name)); 10663af6ab5fSopenharmony_ci fn(currentScope->AsTSModuleScope()->FindExportTSVariable<binder::TSBindingType::IMPORT_EQUALS>(name)); 10673af6ab5fSopenharmony_ci } 10683af6ab5fSopenharmony_ci 10693af6ab5fSopenharmony_ci // Find js variable 10703af6ab5fSopenharmony_ci if (currentScope->FindLocal(name, bindingOptions_) != nullptr) { 10713af6ab5fSopenharmony_ci res = scope->Find(name, bindingOptions_); 10723af6ab5fSopenharmony_ci break; 10733af6ab5fSopenharmony_ci } 10743af6ab5fSopenharmony_ci 10753af6ab5fSopenharmony_ci if (!findRes.empty()) { 10763af6ab5fSopenharmony_ci break; 10773af6ab5fSopenharmony_ci } 10783af6ab5fSopenharmony_ci 10793af6ab5fSopenharmony_ci currentScope = currentScope->Parent(); 10803af6ab5fSopenharmony_ci } 10813af6ab5fSopenharmony_ci 10823af6ab5fSopenharmony_ci return findRes; 10833af6ab5fSopenharmony_ci} 10843af6ab5fSopenharmony_ci 10853af6ab5fSopenharmony_civoid Binder::ReplaceConstReferenceWithInitialization(const ir::Identifier *ident, const Decl *decl) 10863af6ab5fSopenharmony_ci{ 10873af6ab5fSopenharmony_ci bool isValidAssignmentExpr = ident->Parent()->IsAssignmentExpression() && 10883af6ab5fSopenharmony_ci ident->Parent()->AsAssignmentExpression()->Right() == ident; 10893af6ab5fSopenharmony_ci bool isBinaryExpr = ident->Parent()->IsBinaryExpression(); 10903af6ab5fSopenharmony_ci bool isVariableDecl = ident->Parent()->IsVariableDeclarator() && 10913af6ab5fSopenharmony_ci ident->Parent()->AsVariableDeclarator()->Init() == ident; 10923af6ab5fSopenharmony_ci if (!isValidAssignmentExpr && !isBinaryExpr && !isVariableDecl) { 10933af6ab5fSopenharmony_ci return; 10943af6ab5fSopenharmony_ci } 10953af6ab5fSopenharmony_ci 10963af6ab5fSopenharmony_ci if (decl->Node() == nullptr || decl->Node()->Parent() == nullptr || 10973af6ab5fSopenharmony_ci !decl->Node()->Parent()->IsVariableDeclarator()) { 10983af6ab5fSopenharmony_ci return; 10993af6ab5fSopenharmony_ci } 11003af6ab5fSopenharmony_ci 11013af6ab5fSopenharmony_ci const ir::AstNode *initialization = static_cast<const ir::AstNode *>( 11023af6ab5fSopenharmony_ci decl->Node()->Parent()->AsVariableDeclarator()->Init()); 11033af6ab5fSopenharmony_ci if (initialization == nullptr || !initialization->IsNumberLiteral()) { 11043af6ab5fSopenharmony_ci return; 11053af6ab5fSopenharmony_ci } 11063af6ab5fSopenharmony_ci 11073af6ab5fSopenharmony_ci auto newNode = Allocator()->New<ir::NumberLiteral>(initialization->AsNumberLiteral()->Number()); 11083af6ab5fSopenharmony_ci if (newNode == nullptr) { 11093af6ab5fSopenharmony_ci throw Error(ErrorType::GENERIC, "Unsuccessful allocation during replacing const reference node"); 11103af6ab5fSopenharmony_ci } 11113af6ab5fSopenharmony_ci // Make sure the new node get the correct line number 11123af6ab5fSopenharmony_ci // Column number may be incorrect, but it doesn't matter in release mode 11133af6ab5fSopenharmony_ci newNode->SetRange(ident->Range()); 11143af6ab5fSopenharmony_ci 11153af6ab5fSopenharmony_ci auto *parentNode = const_cast<panda::es2panda::ir::AstNode *>(ident->Parent()); 11163af6ab5fSopenharmony_ci // update the reference node with initialization node 11173af6ab5fSopenharmony_ci parentNode->UpdateSelf([=](auto *childNode) { 11183af6ab5fSopenharmony_ci if (childNode == ident) { 11193af6ab5fSopenharmony_ci return static_cast<ir::AstNode *>(newNode); 11203af6ab5fSopenharmony_ci } 11213af6ab5fSopenharmony_ci return childNode; 11223af6ab5fSopenharmony_ci }, this); 11233af6ab5fSopenharmony_ci} 11243af6ab5fSopenharmony_ci 11253af6ab5fSopenharmony_civoid Binder::CheckPrivateDeclaration(const ir::PrivateIdentifier *privateIdent) 11263af6ab5fSopenharmony_ci{ 11273af6ab5fSopenharmony_ci auto name = privateIdent->Name(); 11283af6ab5fSopenharmony_ci auto scope = scope_; 11293af6ab5fSopenharmony_ci while (scope != nullptr) { 11303af6ab5fSopenharmony_ci if (scope->Type() == ScopeType::CLASS) { 11313af6ab5fSopenharmony_ci const auto *classScope = scope->AsClassScope(); 11323af6ab5fSopenharmony_ci if (classScope->HasPrivateName(name)) { 11333af6ab5fSopenharmony_ci return; 11343af6ab5fSopenharmony_ci } 11353af6ab5fSopenharmony_ci } 11363af6ab5fSopenharmony_ci scope = scope->Parent(); 11373af6ab5fSopenharmony_ci } 11383af6ab5fSopenharmony_ci 11393af6ab5fSopenharmony_ci auto pos = privateIdent->Start(); 11403af6ab5fSopenharmony_ci lexer::LineIndex index(program_->SourceCode()); 11413af6ab5fSopenharmony_ci lexer::SourceLocation loc = index.GetLocation(pos); 11423af6ab5fSopenharmony_ci 11433af6ab5fSopenharmony_ci throw Error{ErrorType::SYNTAX, "Use private property before declaration", loc.line, loc.col}; 11443af6ab5fSopenharmony_ci} 11453af6ab5fSopenharmony_ci 11463af6ab5fSopenharmony_ciClassTdz::ClassTdz(const ir::AstNode *parent, const ir::AstNode *childNode, Scope *scope) 11473af6ab5fSopenharmony_ci{ 11483af6ab5fSopenharmony_ci /* In ES2022, class element name's evaluation is before class's initialization. 11493af6ab5fSopenharmony_ci * So a computed property name can not access class object which leads to a reference error. 11503af6ab5fSopenharmony_ci * For example: 11513af6ab5fSopenharmony_ci * class A { 11523af6ab5fSopenharmony_ci * [A] 11533af6ab5fSopenharmony_ci * } 11543af6ab5fSopenharmony_ci */ 11553af6ab5fSopenharmony_ci bool isClassTdz = (parent->IsClassProperty() && childNode == parent->AsClassProperty()->Key()) || 11563af6ab5fSopenharmony_ci (parent->IsMethodDefinition() && childNode == parent->AsMethodDefinition()->Key()); 11573af6ab5fSopenharmony_ci if (!isClassTdz) { 11583af6ab5fSopenharmony_ci return; 11593af6ab5fSopenharmony_ci } 11603af6ab5fSopenharmony_ci 11613af6ab5fSopenharmony_ci ASSERT(parent->Parent()->IsClassDefinition()); 11623af6ab5fSopenharmony_ci auto classDef = parent->Parent()->AsClassDefinition(); 11633af6ab5fSopenharmony_ci if (!classDef->Ident()) { 11643af6ab5fSopenharmony_ci return; 11653af6ab5fSopenharmony_ci } 11663af6ab5fSopenharmony_ci 11673af6ab5fSopenharmony_ci ScopeFindResult res = scope->Find(classDef->Ident()->Name()); 11683af6ab5fSopenharmony_ci ASSERT(res.variable && res.variable->Declaration()->IsConstDecl()); 11693af6ab5fSopenharmony_ci variable_ = res.variable; 11703af6ab5fSopenharmony_ci variable_->RemoveFlag(VariableFlags::INITIALIZED); 11713af6ab5fSopenharmony_ci} 11723af6ab5fSopenharmony_ci 11733af6ab5fSopenharmony_ci} // namespace panda::es2panda::binder 1174