1 /*
2 * Copyright (c) 2023-2025 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "scopesInitPhase.h"
17 #include "util/diagnosticEngine.h"
18 #include "compiler/lowering/util.h"
19
20 namespace ark::es2panda::compiler {
21
22 template <typename T>
LexicalScopeCreateOrEnter(varbinder::VarBinder * varBinder,ir::AstNode * ast)23 varbinder::LexicalScope<T> LexicalScopeCreateOrEnter(varbinder::VarBinder *varBinder, ir::AstNode *ast)
24 {
25 if (ast != nullptr && ast->Scope() != nullptr) {
26 return varbinder::LexicalScope<T>::Enter(varBinder, reinterpret_cast<T *>(ast->Scope()));
27 }
28 return varbinder::LexicalScope<T>(varBinder);
29 }
30
31 template <typename T, typename... Args>
AddOrGetDecl(varbinder::VarBinder * varBinder,util::StringView name,ir::AstNode * ast,const lexer::SourcePosition & pos,Args &&...args)32 T *AddOrGetDecl(varbinder::VarBinder *varBinder, util::StringView name, ir::AstNode *ast,
33 const lexer::SourcePosition &pos, Args &&...args)
34 {
35 if (name.Is(ERROR_LITERAL)) {
36 return nullptr;
37 }
38
39 if (auto *var = varBinder->GetScope()->FindLocal(name, varbinder::ResolveBindingOptions::BINDINGS);
40 var != nullptr && var->Declaration() != nullptr && var->Declaration()->Node() == ast) {
41 return reinterpret_cast<T *>(var->Declaration());
42 }
43
44 return varBinder->AddDecl<T>(pos, args...);
45 }
46
Perform(PhaseContext * ctx,parser::Program * program)47 bool ScopesInitPhase::Perform(PhaseContext *ctx, parser::Program *program)
48 {
49 Prepare(ctx, program);
50 program->VarBinder()->InitTopScope();
51 HandleBlockStmt(program->Ast(), GetScope());
52 Finalize();
53 return true;
54 }
55
VisitScriptFunction(ir::ScriptFunction * scriptFunction)56 void ScopesInitPhase::VisitScriptFunction(ir::ScriptFunction *scriptFunction)
57 {
58 if (auto *const id = scriptFunction->Id(); id != nullptr && id->Variable() == nullptr) {
59 auto const *const curScope = VarBinder()->GetScope();
60 auto const &functionName = id->Name();
61 auto const res =
62 curScope->Find(functionName, scriptFunction->IsStatic() ? varbinder::ResolveBindingOptions::ALL_STATIC
63 : varbinder::ResolveBindingOptions::ALL_NON_STATIC);
64 if (res.variable != nullptr && res.variable->Declaration()->IsFunctionDecl()) {
65 id->SetVariable(res.variable);
66 }
67 }
68
69 HandleFunction(scriptFunction);
70 }
71
VisitBlockStatement(ir::BlockStatement * blockStmt)72 void ScopesInitPhase::VisitBlockStatement(ir::BlockStatement *blockStmt)
73 {
74 auto localCtx = LexicalScopeCreateOrEnter<varbinder::LocalScope>(VarBinder(), blockStmt);
75 HandleBlockStmt(blockStmt, GetScope());
76 }
77
VisitImportDeclaration(ir::ImportDeclaration * importDeclaration)78 void ScopesInitPhase::VisitImportDeclaration(ir::ImportDeclaration *importDeclaration)
79 {
80 ImportDeclarationContext importCtx(VarBinder());
81 Iterate(importDeclaration);
82 importCtx.BindImportDecl(importDeclaration);
83 }
84
VisitClassStaticBlock(ir::ClassStaticBlock * staticBlock)85 void ScopesInitPhase::VisitClassStaticBlock(ir::ClassStaticBlock *staticBlock)
86 {
87 Iterate(staticBlock);
88 }
89
VisitMethodDefinition(ir::MethodDefinition * methodDefinition)90 void ScopesInitPhase::VisitMethodDefinition(ir::MethodDefinition *methodDefinition)
91 {
92 Iterate(methodDefinition);
93 }
94
HandleFunctionSig(ir::TSTypeParameterDeclaration * typeParams,const ArenaVector<ir::Expression * > & params,ir::TypeNode * returnType)95 varbinder::FunctionParamScope *ScopesInitPhase::HandleFunctionSig(ir::TSTypeParameterDeclaration *typeParams,
96 const ArenaVector<ir::Expression *> ¶ms,
97 ir::TypeNode *returnType)
98 {
99 auto typeParamsCtx = varbinder::LexicalScope<varbinder::LocalScope>(VarBinder());
100 CallNode(typeParams);
101
102 auto lexicalScope = varbinder::LexicalScope<varbinder::FunctionParamScope>(VarBinder());
103 CallFuncParams(params);
104 CallNode(returnType);
105
106 return lexicalScope.GetScope();
107 }
108
HandleFunction(ir::ScriptFunction * function)109 void ScopesInitPhase::HandleFunction(ir::ScriptFunction *function)
110 {
111 CallNode(function->Id());
112
113 // NOTE(gogabr): this will skip type/value parameters when they are added to an existing function sig
114 auto funcParamScope = (function->Scope() == nullptr) ? HandleFunctionSig(function->TypeParams(), function->Params(),
115 function->ReturnTypeAnnotation())
116 : function->Scope()->ParamScope();
117 auto paramCtx = varbinder::LexicalScope<varbinder::FunctionParamScope>::Enter(VarBinder(), funcParamScope, false);
118
119 auto functionCtx = LexicalScopeCreateOrEnter<varbinder::FunctionScope>(VarBinder(), function);
120 auto *functionScope = functionCtx.GetScope();
121 BindFunctionScopes(functionScope, funcParamScope);
122
123 if (function->Body() != nullptr && function->Body()->IsBlockStatement()) {
124 HandleBlockStmt(function->Body()->AsBlockStatement(), functionScope);
125 } else {
126 Iterate(function->Body());
127 }
128 BindScopeNode(functionScope, function);
129 funcParamScope->BindNode(function);
130
131 CallNode(function->Annotations());
132 }
133
HandleBlockStmt(ir::BlockStatement * block,varbinder::Scope * scope)134 void ScopesInitPhase::HandleBlockStmt(ir::BlockStatement *block, varbinder::Scope *scope)
135 {
136 if (block->Scope() == nullptr) {
137 BindScopeNode(scope, block);
138 }
139 Iterate(block);
140 }
141
VisitClassDefinition(ir::ClassDefinition * classDef)142 void ScopesInitPhase::VisitClassDefinition(ir::ClassDefinition *classDef)
143 {
144 auto classCtx = LexicalScopeCreateOrEnter<varbinder::LocalScope>(VarBinder(), classDef);
145 AddOrGetDecl<varbinder::ConstDecl>(VarBinder(), classDef->InternalName(), classDef, classDef->Start(),
146 classDef->InternalName());
147 BindClassName(classDef);
148
149 auto *classScope = classCtx.GetScope();
150 BindScopeNode(classScope, classDef);
151 Iterate(classDef);
152 }
153
VisitForUpdateStatement(ir::ForUpdateStatement * forUpdateStmt)154 void ScopesInitPhase::VisitForUpdateStatement(ir::ForUpdateStatement *forUpdateStmt)
155 {
156 auto declCtx = (forUpdateStmt->Scope() == nullptr)
157 ? varbinder::LexicalScope<varbinder::LoopDeclarationScope>(VarBinder())
158 : varbinder::LexicalScope<varbinder::LoopDeclarationScope>::Enter(
159 // CC-OFFNXT(G.FMT.06-CPP) project code style
160 VarBinder(), forUpdateStmt->Scope()->DeclScope());
161 CallNode(forUpdateStmt->Init());
162
163 auto lexicalScope = LexicalScopeCreateOrEnter<varbinder::LoopScope>(VarBinder(), forUpdateStmt);
164 AttachLabelToScope(forUpdateStmt);
165 CallNode(forUpdateStmt->Test());
166 CallNode(forUpdateStmt->Update());
167 CallNode(forUpdateStmt->Body());
168 lexicalScope.GetScope()->BindDecls(declCtx.GetScope());
169 HandleFor(declCtx.GetScope(), lexicalScope.GetScope(), forUpdateStmt);
170 }
171
VisitForInStatement(ir::ForInStatement * forInStmt)172 void ScopesInitPhase::VisitForInStatement(ir::ForInStatement *forInStmt)
173 {
174 auto declCtx = (forInStmt->Scope() == nullptr)
175 ? varbinder::LexicalScope<varbinder::LoopDeclarationScope>(VarBinder())
176 : varbinder::LexicalScope<varbinder::LoopDeclarationScope>::Enter(
177 // CC-OFFNXT(G.FMT.06-CPP) project code style
178 VarBinder(), forInStmt->Scope()->DeclScope());
179 CallNode(forInStmt->Left());
180
181 auto lexicalScope = LexicalScopeCreateOrEnter<varbinder::LoopScope>(VarBinder(), forInStmt);
182 CallNode(forInStmt->Right());
183 CallNode(forInStmt->Body());
184 HandleFor(declCtx.GetScope(), lexicalScope.GetScope(), forInStmt);
185 }
186
VisitForOfStatement(ir::ForOfStatement * forOfStmt)187 void ScopesInitPhase::VisitForOfStatement(ir::ForOfStatement *forOfStmt)
188 {
189 auto declCtx = (forOfStmt->Scope() == nullptr)
190 ? varbinder::LexicalScope<varbinder::LoopDeclarationScope>(VarBinder())
191 : varbinder::LexicalScope<varbinder::LoopDeclarationScope>::Enter(
192 // CC-OFFNXT(G.FMT.06-CPP) project code style
193 VarBinder(), forOfStmt->Scope()->DeclScope());
194 CallNode(forOfStmt->Left());
195
196 auto lexicalScope = LexicalScopeCreateOrEnter<varbinder::LoopScope>(VarBinder(), forOfStmt);
197 AttachLabelToScope(forOfStmt);
198 CallNode(forOfStmt->Right());
199 CallNode(forOfStmt->Body());
200 HandleFor(declCtx.GetScope(), lexicalScope.GetScope(), forOfStmt);
201 }
202
VisitCatchClause(ir::CatchClause * catchClause)203 void ScopesInitPhase::VisitCatchClause(ir::CatchClause *catchClause)
204 {
205 auto catchParamCtx = (catchClause->Scope() == nullptr)
206 ? varbinder::LexicalScope<varbinder::CatchParamScope>(VarBinder())
207 : varbinder::LexicalScope<varbinder::CatchParamScope>::Enter(
208 // CC-OFFNXT(G.FMT.06-CPP) project code style
209 VarBinder(), catchClause->Scope()->ParamScope());
210 auto *catchParamScope = catchParamCtx.GetScope();
211 auto *param = catchClause->Param();
212
213 CallNode(param);
214
215 if (param != nullptr) {
216 auto *const var = VarBinder()->AddParamDecl(param);
217 if (param->IsIdentifier()) {
218 var->SetScope(catchParamScope);
219 param->AsIdentifier()->SetVariable(var);
220 }
221 }
222
223 // Catch Clause is scope bearer
224 catchParamScope->BindNode(catchClause);
225
226 auto catchCtx = LexicalScopeCreateOrEnter<varbinder::CatchScope>(VarBinder(), catchClause);
227 auto *catchScope = catchCtx.GetScope();
228
229 catchScope->AssignParamScope(catchParamScope);
230 auto body = catchClause->Body();
231 HandleBlockStmt(body, catchScope);
232
233 BindScopeNode(catchScope, catchClause);
234 }
235
VisitVariableDeclarator(ir::VariableDeclarator * varDecl)236 void ScopesInitPhase::VisitVariableDeclarator(ir::VariableDeclarator *varDecl)
237 {
238 auto init = varDecl->Id();
239 std::vector<ir::Identifier *> bindings = util::Helpers::CollectBindingNames(VarBinder(), init);
240 for (auto *binding : bindings) {
241 auto [decl, var] = AddOrGetVarDecl(varDecl->Flag(), binding);
242 BindVarDecl(binding, init, decl, var);
243 }
244 Iterate(varDecl);
245 }
246
VisitSwitchStatement(ir::SwitchStatement * switchStmt)247 void ScopesInitPhase::VisitSwitchStatement(ir::SwitchStatement *switchStmt)
248 {
249 CallNode(switchStmt->Discriminant());
250 auto localCtx = LexicalScopeCreateOrEnter<varbinder::LocalScope>(VarBinder(), switchStmt);
251 AttachLabelToScope(switchStmt);
252 BindScopeNode(localCtx.GetScope(), switchStmt);
253 CallNode(switchStmt->Cases());
254 }
255
VisitWhileStatement(ir::WhileStatement * whileStmt)256 void ScopesInitPhase::VisitWhileStatement(ir::WhileStatement *whileStmt)
257 {
258 CallNode(whileStmt->Test());
259 auto lexicalScope = LexicalScopeCreateOrEnter<varbinder::LoopScope>(VarBinder(), whileStmt);
260 AttachLabelToScope(whileStmt);
261 BindScopeNode(lexicalScope.GetScope(), whileStmt);
262 CallNode(whileStmt->Body());
263 }
264
VisitETSStructDeclaration(ir::ETSStructDeclaration * structDecl)265 void ScopesInitPhase::VisitETSStructDeclaration(ir::ETSStructDeclaration *structDecl)
266 {
267 LogDiagnostic(diagnostic::UNEXPECTED_STRUCT, structDecl->Start());
268 // For multiple error report
269 Iterate(structDecl);
270 BindClassDefinition(structDecl->Definition());
271 }
272
VisitClassDeclaration(ir::ClassDeclaration * classDecl)273 void ScopesInitPhase::VisitClassDeclaration(ir::ClassDeclaration *classDecl)
274 {
275 Iterate(classDecl);
276 BindClassDefinition(classDecl->Definition());
277 }
278
VisitAnnotationDeclaration(ir::AnnotationDeclaration * annoDecl)279 void ScopesInitPhase::VisitAnnotationDeclaration(ir::AnnotationDeclaration *annoDecl)
280 {
281 // First check if there is any redefinition in the current scope
282 const auto locStart = annoDecl->GetBaseName()->Start();
283 const auto &annoName = annoDecl->GetBaseName()->Name();
284 AddOrGetDecl<varbinder::AnnotationDecl>(VarBinder(), annoName, annoDecl, locStart, annoName, annoDecl);
285 // Create and enter annotation scope
286 auto annoCtx = LexicalScopeCreateOrEnter<varbinder::AnnotationScope>(VarBinder(), annoDecl);
287 auto *classScope = annoCtx.GetScope();
288 BindScopeNode(classScope, annoDecl);
289 Iterate(annoDecl);
290 }
291
VisitAnnotationUsage(ir::AnnotationUsage * annoUsage)292 void ScopesInitPhase::VisitAnnotationUsage(ir::AnnotationUsage *annoUsage)
293 {
294 auto annoCtx = LexicalScopeCreateOrEnter<varbinder::AnnotationParamScope>(VarBinder(), annoUsage);
295 auto *curScope = annoCtx.GetScope();
296 BindScopeNode(curScope, annoUsage);
297 Iterate(annoUsage);
298 }
299
VisitDoWhileStatement(ir::DoWhileStatement * doWhileStmt)300 void ScopesInitPhase::VisitDoWhileStatement(ir::DoWhileStatement *doWhileStmt)
301 {
302 auto lexicalScope = LexicalScopeCreateOrEnter<varbinder::LoopScope>(VarBinder(), doWhileStmt);
303 AttachLabelToScope(doWhileStmt);
304 BindScopeNode(lexicalScope.GetScope(), doWhileStmt);
305 Iterate(doWhileStmt);
306 }
307
VisitFunctionDeclaration(ir::FunctionDeclaration * funcDecl)308 void ScopesInitPhase::VisitFunctionDeclaration(ir::FunctionDeclaration *funcDecl)
309 {
310 const auto func = funcDecl->Function();
311 if (!funcDecl->IsAnonymous()) {
312 CreateFuncDecl(func);
313 }
314 Iterate(funcDecl);
315 }
316
VisitExportAllDeclaration(ir::ExportAllDeclaration * exportAllDecl)317 void ScopesInitPhase::VisitExportAllDeclaration(ir::ExportAllDeclaration *exportAllDecl)
318 {
319 Iterate(exportAllDecl);
320 const auto name = exportAllDecl->Exported() != nullptr ? exportAllDecl->Exported()->Name() : "*";
321 auto *decl =
322 AddOrGetDecl<varbinder::ExportDecl>(VarBinder(), name, exportAllDecl, exportAllDecl->Start(), name, "*");
323 VarBinder()->GetScope()->AsModuleScope()->AddExportDecl(exportAllDecl, decl);
324 }
325
VisitImportNamespaceSpecifier(ir::ImportNamespaceSpecifier * importSpec)326 void ScopesInitPhase::VisitImportNamespaceSpecifier(ir::ImportNamespaceSpecifier *importSpec)
327 {
328 Iterate(importSpec);
329 AddOrGetDecl<varbinder::ImportDecl>(VarBinder(), importSpec->Local()->Name(), importSpec, importSpec->Start(), "*",
330 importSpec->Local()->Name(), importSpec);
331 }
332
VisitImportSpecifier(ir::ImportSpecifier * importSpec)333 void ScopesInitPhase::VisitImportSpecifier(ir::ImportSpecifier *importSpec)
334 {
335 Iterate(importSpec);
336 const auto *imported = importSpec->Imported();
337 AddOrGetDecl<varbinder::ImportDecl>(VarBinder(), importSpec->Local()->Name(), importSpec, importSpec->Start(),
338 imported->Name(), importSpec->Local()->Name(), importSpec);
339 }
340
VisitImportDefaultSpecifier(ir::ImportDefaultSpecifier * importSpec)341 void ScopesInitPhase::VisitImportDefaultSpecifier(ir::ImportDefaultSpecifier *importSpec)
342 {
343 Iterate(importSpec);
344 const auto *local = importSpec->Local();
345 AddOrGetDecl<varbinder::ImportDecl>(VarBinder(), local->Name(), importSpec, local->Start(), "default",
346 local->Name(), importSpec);
347 }
348
VisitExportDefaultDeclaration(ir::ExportDefaultDeclaration * exportDecl)349 void ScopesInitPhase::VisitExportDefaultDeclaration(ir::ExportDefaultDeclaration *exportDecl)
350 {
351 ExportDeclarationContext exportDeclCtx(VarBinder());
352 Iterate(exportDecl);
353 exportDeclCtx.BindExportDecl(exportDecl);
354 }
355
VisitArrowFunctionExpression(ir::ArrowFunctionExpression * arrowExpr)356 void ScopesInitPhase::VisitArrowFunctionExpression(ir::ArrowFunctionExpression *arrowExpr)
357 {
358 Iterate(arrowExpr);
359 }
360
VisitDirectEvalExpression(ir::DirectEvalExpression * directCallExpr)361 void ScopesInitPhase::VisitDirectEvalExpression(ir::DirectEvalExpression *directCallExpr)
362 {
363 VarBinder()->PropagateDirectEval();
364 Iterate(directCallExpr);
365 }
366
VisitExportNamedDeclaration(ir::ExportNamedDeclaration * exportDecl)367 void ScopesInitPhase::VisitExportNamedDeclaration(ir::ExportNamedDeclaration *exportDecl)
368 {
369 if (exportDecl->Decl() != nullptr) {
370 ExportDeclarationContext exportDeclCtx(VarBinder());
371 Iterate(exportDecl);
372 exportDeclCtx.BindExportDecl(exportDecl);
373 } else {
374 varbinder::ModuleScope::ExportDeclList exportDecls(program_->Allocator()->Adapter());
375
376 for (auto *spec : exportDecl->Specifiers()) {
377 auto *decl =
378 AddOrGetDecl<varbinder::ExportDecl>(VarBinder(), spec->Local()->Name(), spec, exportDecl->Start(),
379 spec->Exported()->Name(), spec->Local()->Name(), spec);
380 exportDecls.push_back(decl);
381 }
382 VarBinder()->GetScope()->AsModuleScope()->AddExportDecl(exportDecl, std::move(exportDecls));
383 }
384 }
385
VisitTSFunctionType(ir::TSFunctionType * funcType)386 void ScopesInitPhase::VisitTSFunctionType(ir::TSFunctionType *funcType)
387 {
388 auto lexicalScope = LexicalScopeCreateOrEnter<varbinder::FunctionParamScope>(VarBinder(), funcType);
389 auto *funcParamScope = lexicalScope.GetScope();
390 BindScopeNode(funcParamScope, funcType);
391 Iterate(funcType);
392 }
393
SetProgram(parser::Program * program)394 void ScopesInitPhase::SetProgram(parser::Program *program) noexcept
395 {
396 program_ = program;
397 }
398
CallFuncParams(const ArenaVector<ir::Expression * > & params)399 void ScopesInitPhase::CallFuncParams(const ArenaVector<ir::Expression *> ¶ms)
400 {
401 // NOTE: extract params to separate class
402 for (auto *param : params) {
403 if (!param->IsETSParameterExpression()) {
404 VarBinder()->AddParamDecl(param);
405 }
406 }
407 CallNode(params);
408 }
409
IterateNoTParams(ir::ClassDefinition * classDef)410 void ScopesInitPhase::IterateNoTParams(ir::ClassDefinition *classDef)
411 {
412 CallNode(classDef->Super());
413 CallNode(classDef->SuperTypeParams());
414 CallNode(classDef->Annotations());
415 CallNode(classDef->Implements());
416 CallNode(classDef->Ctor());
417 CallNode(classDef->Body());
418 }
419
LogDiagnostic(const diagnostic::DiagnosticKind & kind,const util::DiagnosticMessageParams & params,const lexer::SourcePosition & pos) const420 void ScopesInitPhase::LogDiagnostic(const diagnostic::DiagnosticKind &kind, const util::DiagnosticMessageParams ¶ms,
421 const lexer::SourcePosition &pos) const
422 {
423 ctx_->diagnosticEngine->LogDiagnostic(kind, params, pos);
424 }
425
CreateFuncDecl(ir::ScriptFunction * func)426 void ScopesInitPhase::CreateFuncDecl(ir::ScriptFunction *func)
427 {
428 AddOrGetDecl<varbinder::FunctionDecl>(VarBinder(), func->Id()->Name(), func, func->Id()->Start(), Allocator(),
429 func->Id()->Name(), func);
430 }
431
FormInterfaceOrEnumDeclarationIdBinding(ir::Identifier * id)432 util::StringView ScopesInitPhase::FormInterfaceOrEnumDeclarationIdBinding(ir::Identifier *id)
433 {
434 return id->Name();
435 }
436
BindClassName(ir::ClassDefinition * classDef)437 varbinder::Decl *ScopesInitPhase::BindClassName(ir::ClassDefinition *classDef)
438 {
439 const auto identNode = classDef->Ident();
440 if (identNode == nullptr) {
441 return nullptr;
442 }
443
444 auto identDecl = AddOrGetDecl<varbinder::ConstDecl>(VarBinder(), identNode->Name(), classDef, identNode->Start(),
445 identNode->Name());
446 if (identDecl != nullptr) {
447 identDecl->BindNode(classDef);
448 }
449 return identDecl;
450 }
451
BindFunctionScopes(varbinder::FunctionScope * scope,varbinder::FunctionParamScope * paramScope)452 void ScopesInitPhase::BindFunctionScopes(varbinder::FunctionScope *scope, varbinder::FunctionParamScope *paramScope)
453 {
454 scope->BindParamScope(paramScope);
455 paramScope->BindFunctionScope(scope);
456 }
457
BindClassDefinition(ir::ClassDefinition * classDef)458 void ScopesInitPhase::BindClassDefinition(ir::ClassDefinition *classDef)
459 {
460 if (classDef->IsGlobal()) {
461 return; // We handle it in ClassDeclaration
462 }
463 const auto locStart = classDef->Ident()->Start();
464 const auto &className = classDef->Ident()->Name();
465 if ((classDef->Modifiers() & ir::ClassDefinitionModifiers::CLASS_DECL) != 0U) {
466 AddOrGetDecl<varbinder::ClassDecl>(VarBinder(), className, classDef, locStart, className, classDef);
467 } else {
468 AddOrGetDecl<varbinder::LetDecl>(VarBinder(), className, classDef, locStart, className, classDef);
469 }
470 }
471
AddOrGetVarDecl(ir::VariableDeclaratorFlag flag,const ir::Identifier * id)472 std::tuple<varbinder::Decl *, varbinder::Variable *> ScopesInitPhase::AddOrGetVarDecl(ir::VariableDeclaratorFlag flag,
473 const ir::Identifier *id)
474 {
475 auto name = id->Name();
476 auto scope = VarBinder()->GetScope();
477 if (auto var = id->Variable(); var != nullptr) {
478 if (!name.Is(ERROR_LITERAL) &&
479 (scope->FindLocal(name, varbinder::ResolveBindingOptions::ALL_VARIABLES) == nullptr)) {
480 var = scope->AddDecl(Allocator(), var->Declaration(), VarBinder()->Extension());
481 }
482 return {var->Declaration(), var};
483 }
484
485 if (name.Is(ERROR_LITERAL)) {
486 name = compiler::GenName(Allocator()).View();
487 } else if (VarBinder()->IsETSBinder()) {
488 if (auto var = scope->FindLocal(name, varbinder::ResolveBindingOptions::ALL_VARIABLES); var != nullptr) {
489 VarBinder()->ThrowRedeclaration(id->Start(), name, var->Declaration()->Type());
490 return {var->Declaration(), var};
491 }
492 }
493
494 switch (flag) {
495 case ir::VariableDeclaratorFlag::LET:
496 return VarBinder()->NewVarDecl<varbinder::LetDecl>(id->Start(), name);
497 case ir::VariableDeclaratorFlag::VAR:
498 return VarBinder()->NewVarDecl<varbinder::VarDecl>(id->Start(), name);
499 case ir::VariableDeclaratorFlag::CONST:
500 return VarBinder()->NewVarDecl<varbinder::ConstDecl>(id->Start(), name);
501 default:
502 ES2PANDA_UNREACHABLE();
503 }
504 }
505
BindVarDecl(ir::Identifier * binding,ir::Expression * init,varbinder::Decl * decl,varbinder::Variable * var)506 void ScopesInitPhase::BindVarDecl([[maybe_unused]] ir::Identifier *binding, ir::Expression *init, varbinder::Decl *decl,
507 [[maybe_unused]] varbinder::Variable *var)
508 {
509 decl->BindNode(init);
510 }
511
AttachLabelToScope(ir::AstNode * node)512 void ScopesInitPhase::AttachLabelToScope([[maybe_unused]] ir::AstNode *node) {}
513
VisitFunctionExpression(ir::FunctionExpression * funcExpr)514 void ScopesInitPhase::VisitFunctionExpression(ir::FunctionExpression *funcExpr)
515 {
516 Iterate(funcExpr);
517 if (!funcExpr->IsAnonymous()) {
518 auto func = funcExpr->Function();
519 auto id = funcExpr->Id();
520 auto *funcParamScope = func->Scope()->ParamScope();
521 funcParamScope->BindName(Allocator(), id->Name());
522 func->SetIdent(id->Clone(Allocator(), nullptr));
523 }
524 }
525
Prepare(ScopesInitPhase::PhaseContext * ctx,parser::Program * program)526 void ScopesInitPhase::Prepare(ScopesInitPhase::PhaseContext *ctx, parser::Program *program)
527 {
528 ctx_ = ctx;
529 program_ = program;
530 }
531
Finalize()532 void ScopesInitPhase::Finalize()
533 {
534 ES2PANDA_ASSERT(program_->Ast() != nullptr);
535
536 auto const removeDuplicates = [](ir::AstNode *ast) -> void {
537 if (!ast->IsTSInterfaceBody()) {
538 return;
539 }
540
541 auto &body = ast->AsTSInterfaceBody()->Body();
542 auto it = body.begin();
543 while (it != body.end()) {
544 if ((*it)->IsMethodDefinition() &&
545 ((*it)->AsMethodDefinition()->Function()->Flags() &
546 (ir::ScriptFunctionFlags::OVERLOAD | ir::ScriptFunctionFlags::EXTERNAL_OVERLOAD)) != 0U) {
547 it = body.erase(it);
548 } else {
549 ++it;
550 }
551 }
552 };
553
554 // Remove duplicates for overloaded methods.
555 program_->Ast()->IterateRecursively(removeDuplicates);
556
557 AnalyzeExports();
558 }
559
AnalyzeExports()560 void ScopesInitPhase::AnalyzeExports()
561 {
562 if (Program()->Kind() == parser::ScriptKind::MODULE && VarBinder()->TopScope()->IsModuleScope() &&
563 !VarBinder()->TopScope()->AsModuleScope()->ExportAnalysis()) {
564 LogDiagnostic(diagnostic::INVALID_EXPORT, Program()->Ast()->End());
565 }
566 }
567
VisitTSModuleDeclaration(ir::TSModuleDeclaration * moduleDecl)568 void ScopeInitTyped::VisitTSModuleDeclaration(ir::TSModuleDeclaration *moduleDecl)
569 {
570 if (!moduleDecl->IsExternalOrAmbient()) {
571 auto name = moduleDecl->Name()->AsIdentifier()->Name();
572 auto *decl = AddOrGetDecl<varbinder::VarDecl>(VarBinder(), name, moduleDecl, moduleDecl->Name()->Start(), name);
573 ES2PANDA_ASSERT(decl != nullptr);
574 decl->BindNode(moduleDecl);
575 }
576 auto localCtx = LexicalScopeCreateOrEnter<varbinder::LocalScope>(VarBinder(), moduleDecl);
577 BindScopeNode(localCtx.GetScope(), moduleDecl);
578 Iterate(moduleDecl);
579 }
580
VisitTSModuleBlock(ir::TSModuleBlock * block)581 void ScopeInitTyped::VisitTSModuleBlock(ir::TSModuleBlock *block)
582 {
583 auto localCtx = LexicalScopeCreateOrEnter<varbinder::LocalScope>(VarBinder(), block);
584 Iterate(block);
585 BindScopeNode(localCtx.GetScope(), block);
586 }
587
VisitTSTypeAliasDeclaration(ir::TSTypeAliasDeclaration * typeAliasDecl)588 void ScopeInitTyped::VisitTSTypeAliasDeclaration(ir::TSTypeAliasDeclaration *typeAliasDecl)
589 {
590 const auto id = typeAliasDecl->Id();
591 varbinder::TSBinding tsBinding(Allocator(), id->Name());
592 auto *decl = VarBinder()->AddTsDecl<varbinder::TypeAliasDecl>(id->Start(), tsBinding.View());
593 auto typeParamsCtx = LexicalScopeCreateOrEnter<varbinder::LocalScope>(VarBinder(), typeAliasDecl->TypeParams());
594 decl->BindNode(typeAliasDecl);
595 Iterate(typeAliasDecl);
596 }
597
FormInterfaceOrEnumDeclarationIdBinding(ir::Identifier * id)598 util::StringView ScopeInitTyped::FormInterfaceOrEnumDeclarationIdBinding(ir::Identifier *id)
599 {
600 varbinder::TSBinding tsBinding(Allocator(), id->Name());
601 return tsBinding.View();
602 }
603
VisitTSInterfaceDeclaration(ir::TSInterfaceDeclaration * interfDecl)604 void ScopeInitTyped::VisitTSInterfaceDeclaration(ir::TSInterfaceDeclaration *interfDecl)
605 {
606 const auto &bindings = VarBinder()->GetScope()->Bindings();
607 const auto ident = interfDecl->Id();
608 const auto name = FormInterfaceOrEnumDeclarationIdBinding(ident);
609 auto res = bindings.find(name);
610
611 varbinder::InterfaceDecl *decl {};
612
613 bool alreadyExists = false;
614 if (res == bindings.end()) {
615 decl = VarBinder()->AddTsDecl<varbinder::InterfaceDecl>(ident->Start(), Allocator(), name);
616 } else if (!AllowInterfaceRedeclaration()) {
617 LogDiagnostic(diagnostic::INTERFACE_REDECLARED, interfDecl->Start());
618 return;
619 } else if (!res->second->Declaration()->IsInterfaceDecl()) {
620 VarBinder()->ThrowRedeclaration(ident->Start(), ident->Name(), res->second->Declaration()->Type());
621 return;
622 } else {
623 decl = res->second->Declaration()->AsInterfaceDecl();
624 alreadyExists = true;
625 }
626
627 CallNode(ident);
628 auto typeParamsCtx = LexicalScopeCreateOrEnter<varbinder::LocalScope>(VarBinder(), interfDecl->TypeParams());
629 CallNode(interfDecl->TypeParams());
630 CallNode(interfDecl->Extends());
631
632 auto localScope = LexicalScopeCreateOrEnter<varbinder::LocalScope>(VarBinder(), interfDecl);
633 auto *identDecl =
634 AddOrGetDecl<varbinder::ConstDecl>(VarBinder(), ident->Name(), interfDecl, ident->Start(), ident->Name());
635 ES2PANDA_ASSERT(identDecl != nullptr);
636 identDecl->BindNode(interfDecl);
637 BindScopeNode(localScope.GetScope(), interfDecl);
638
639 CallNode(interfDecl->Body());
640 if (decl == nullptr) { // Error processing.
641 return;
642 }
643
644 if (!alreadyExists) {
645 decl->BindNode(interfDecl);
646 }
647 decl->Add(interfDecl);
648 }
649
VisitTSEnumMember(ir::TSEnumMember * enumMember)650 void ScopeInitTyped::VisitTSEnumMember(ir::TSEnumMember *enumMember)
651 {
652 const auto key = enumMember->Key();
653 util::StringView name;
654 if (key->IsIdentifier()) {
655 name = key->AsIdentifier()->Name();
656 } else if (key->IsStringLiteral()) {
657 name = key->AsStringLiteral()->Str();
658 } else {
659 ES2PANDA_UNREACHABLE();
660 }
661 if (auto *decl = AddOrGetDecl<varbinder::EnumDecl>(VarBinder(), name, enumMember, key->Start(), name);
662 decl != nullptr) {
663 decl->BindNode(enumMember);
664 }
665 }
666
VisitTSEnumDeclaration(ir::TSEnumDeclaration * enumDecl)667 void ScopeInitTyped::VisitTSEnumDeclaration(ir::TSEnumDeclaration *enumDecl)
668 {
669 util::StringView ident = FormInterfaceOrEnumDeclarationIdBinding(enumDecl->Key());
670 const auto &bindings = VarBinder()->GetScope()->Bindings();
671 varbinder::EnumLiteralDecl *decl {};
672
673 if (auto res = bindings.find(ident); res == bindings.end()) {
674 decl = VarBinder()->AddTsDecl<varbinder::EnumLiteralDecl>(enumDecl->Start(), ident, enumDecl->IsConst());
675 varbinder::LexicalScope enumCtx = LexicalScopeCreateOrEnter<varbinder::LocalScope>(VarBinder(), enumDecl);
676 decl->BindScope(enumCtx.GetScope());
677 BindScopeNode(VarBinder()->GetScope()->AsLocalScope(), enumDecl);
678 } else {
679 if (!res->second->Declaration()->IsEnumLiteralDecl() ||
680 (enumDecl->IsConst() ^ res->second->Declaration()->AsEnumLiteralDecl()->IsConst()) != 0) {
681 VarBinder()->ThrowRedeclaration(enumDecl->Key()->Start(), enumDecl->Key()->Name(),
682 res->second->Declaration()->Type());
683 return;
684 }
685 decl = res->second->Declaration()->AsEnumLiteralDecl();
686 auto scopeCtx = varbinder::LexicalScope<varbinder::LocalScope>::Enter(VarBinder(), decl->Scope());
687 }
688 decl->BindNode(enumDecl);
689 Iterate(enumDecl);
690 }
691
VisitTSTypeParameter(ir::TSTypeParameter * typeParam)692 void ScopeInitTyped::VisitTSTypeParameter(ir::TSTypeParameter *typeParam)
693 {
694 auto name = typeParam->Name()->Name();
695 if (auto *decl = AddOrGetDecl<varbinder::TypeParameterDecl>(VarBinder(), name, typeParam, typeParam->Start(), name);
696 decl != nullptr) {
697 decl->BindNode(typeParam);
698 }
699 Iterate(typeParam);
700 }
701
VisitTSTypeParameterDeclaration(ir::TSTypeParameterDeclaration * paramDecl)702 void ScopeInitTyped::VisitTSTypeParameterDeclaration(ir::TSTypeParameterDeclaration *paramDecl)
703 {
704 BindScopeNode(VarBinder()->GetScope()->AsLocalScope(), paramDecl);
705 Iterate(paramDecl);
706 }
707
VisitClassDefinition(ir::ClassDefinition * classDef)708 void ScopeInitTyped::VisitClassDefinition(ir::ClassDefinition *classDef)
709 {
710 auto typeParamsCtx = LexicalScopeCreateOrEnter<varbinder::LocalScope>(VarBinder(), classDef->TypeParams());
711 CallNode(classDef->TypeParams());
712
713 auto classCtx = LexicalScopeCreateOrEnter<varbinder::LocalScope>(VarBinder(), classDef);
714 BindClassName(classDef);
715 AddOrGetDecl<varbinder::ConstDecl>(VarBinder(), classDef->InternalName(), classDef, classDef->Start(),
716 classDef->InternalName());
717 BindScopeNode(classCtx.GetScope(), classDef);
718 IterateNoTParams(classDef);
719 }
720
VisitExportDefaultDeclaration(ir::ExportDefaultDeclaration * exportDecl)721 void InitScopesPhaseTs::VisitExportDefaultDeclaration(ir::ExportDefaultDeclaration *exportDecl)
722 {
723 ExportDeclarationContext exportDeclCtx(VarBinder());
724 Iterate(exportDecl);
725 }
726
VisitExportNamedDeclaration(ir::ExportNamedDeclaration * exportDecl)727 void InitScopesPhaseTs::VisitExportNamedDeclaration(ir::ExportNamedDeclaration *exportDecl)
728 {
729 ExportDeclarationContext exportDeclCtx(VarBinder());
730 Iterate(exportDecl);
731 }
732
VisitImportDeclaration(ir::ImportDeclaration * importDeclaration)733 void InitScopesPhaseTs::VisitImportDeclaration(ir::ImportDeclaration *importDeclaration)
734 {
735 ImportDeclarationContext importCtx(VarBinder());
736 Iterate(importDeclaration);
737 }
738
VisitTSFunctionType(ir::TSFunctionType * constrType)739 void InitScopesPhaseTs::VisitTSFunctionType(ir::TSFunctionType *constrType)
740 {
741 auto lexicalScope =
742 (constrType->Scope() == nullptr)
743 ? HandleFunctionSig(constrType->TypeParams(), constrType->Params(), constrType->ReturnType())
744 : constrType->Scope();
745 BindScopeNode(lexicalScope, constrType);
746 }
747
CreateFuncDecl(ir::ScriptFunction * func)748 void InitScopesPhaseTs::CreateFuncDecl(ir::ScriptFunction *func)
749 {
750 const auto identNode = func->Id();
751 const auto startLoc = identNode->Start();
752 const auto &bindings = VarBinder()->GetScope()->Bindings();
753 auto res = bindings.find(identNode->Name());
754 varbinder::FunctionDecl *decl {};
755
756 if (res == bindings.end()) {
757 decl = VarBinder()->AddDecl<varbinder::FunctionDecl>(startLoc, Allocator(), identNode->Name(), func);
758 } else {
759 varbinder::Decl *currentDecl = res->second->Declaration();
760
761 auto &existing = currentDecl->AsFunctionDecl()->Decls();
762 if (std::find(existing.begin(), existing.end(), func) != existing.end()) {
763 return;
764 }
765
766 if (!currentDecl->IsFunctionDecl() ||
767 !currentDecl->AsFunctionDecl()->Node()->AsScriptFunction()->IsOverload()) {
768 VarBinder()->ThrowRedeclaration(startLoc, currentDecl->Name(), currentDecl->Type());
769 return;
770 }
771 decl = currentDecl->AsFunctionDecl();
772 }
773
774 ES2PANDA_ASSERT(decl != nullptr);
775 decl->Add(func);
776 }
777
VisitTSConstructorType(ir::TSConstructorType * constrT)778 void InitScopesPhaseTs::VisitTSConstructorType(ir::TSConstructorType *constrT)
779 {
780 auto funcParamScope = (constrT->Scope() == nullptr)
781 ? HandleFunctionSig(constrT->TypeParams(), constrT->Params(), constrT->ReturnType())
782 : constrT->Scope();
783 BindScopeNode(funcParamScope, constrT);
784 }
785
VisitArrowFunctionExpression(ir::ArrowFunctionExpression * arrowFExpr)786 void InitScopesPhaseTs::VisitArrowFunctionExpression(ir::ArrowFunctionExpression *arrowFExpr)
787 {
788 auto typeParamsCtx =
789 LexicalScopeCreateOrEnter<varbinder::LocalScope>(VarBinder(), arrowFExpr->Function()->TypeParams());
790 Iterate(arrowFExpr);
791 }
792
VisitTSSignatureDeclaration(ir::TSSignatureDeclaration * signDecl)793 void InitScopesPhaseTs::VisitTSSignatureDeclaration(ir::TSSignatureDeclaration *signDecl)
794 {
795 auto funcParamScope = (signDecl->Scope() == nullptr) ? HandleFunctionSig(signDecl->TypeParams(), signDecl->Params(),
796 signDecl->ReturnTypeAnnotation())
797 : signDecl->Scope();
798 BindScopeNode(funcParamScope, signDecl);
799 }
800
VisitTSMethodSignature(ir::TSMethodSignature * methodSign)801 void InitScopesPhaseTs::VisitTSMethodSignature(ir::TSMethodSignature *methodSign)
802 {
803 auto funcParamScope =
804 (methodSign->Scope() == nullptr)
805 ? HandleFunctionSig(methodSign->TypeParams(), methodSign->Params(), methodSign->ReturnTypeAnnotation())
806 : methodSign->Scope();
807 BindScopeNode(funcParamScope, methodSign);
808 }
809
RunExternalNode(ir::AstNode * node,varbinder::VarBinder * varbinder)810 void InitScopesPhaseETS::RunExternalNode(ir::AstNode *node, varbinder::VarBinder *varbinder)
811 {
812 auto program = parser::Program(varbinder->Allocator(), varbinder);
813 RunExternalNode(node, &program);
814 }
815
RunExternalNode(ir::AstNode * node,parser::Program * ctx)816 void InitScopesPhaseETS::RunExternalNode(ir::AstNode *node, parser::Program *ctx)
817 {
818 auto scopesPhase = InitScopesPhaseETS();
819 scopesPhase.SetProgram(ctx);
820 scopesPhase.CallNode(node);
821 }
822
Perform(PhaseContext * ctx,parser::Program * program)823 bool InitScopesPhaseETS::Perform(PhaseContext *ctx, parser::Program *program)
824 {
825 Prepare(ctx, program);
826
827 if (program->VarBinder()->TopScope() == nullptr) {
828 program->VarBinder()->InitTopScope();
829 BindScopeNode(GetScope(), program->Ast());
830 AddGlobalToBinder(program);
831 } else if ((ctx->compilingState == public_lib::CompilingState::MULTI_COMPILING_FOLLOW) &&
832 program->GlobalClass()->Scope() == nullptr) {
833 BindScopeNode(GetScope(), program->Ast());
834 AddGlobalToBinder(program);
835 }
836 HandleProgram(program);
837 Finalize();
838 return true;
839 }
840
HandleProgram(parser::Program * program)841 void InitScopesPhaseETS::HandleProgram(parser::Program *program)
842 {
843 for (auto &[_, progList] : program->ExternalSources()) {
844 (void)_;
845 auto savedTopScope(program->VarBinder()->TopScope());
846 auto mainProg = progList.front();
847 mainProg->VarBinder()->InitTopScope();
848 AddGlobalToBinder(mainProg);
849 BindScopeNode(mainProg->VarBinder()->GetScope(), mainProg->Ast());
850 auto globalClass = mainProg->GlobalClass();
851 auto globalScope = mainProg->GlobalScope();
852 for (auto &prog : progList) {
853 if (prog->GetFlag(parser::ProgramFlags::AST_HAS_SCOPES_INITIALIZED)) {
854 continue;
855 }
856 prog->SetGlobalClass(globalClass);
857 BindScopeNode(prog->VarBinder()->GetScope(), prog->Ast());
858 prog->VarBinder()->ResetTopScope(globalScope);
859 if (mainProg->Ast() != nullptr) {
860 InitScopesPhaseETS().Perform(Context(), prog);
861 prog->SetFlag(parser::ProgramFlags::AST_HAS_SCOPES_INITIALIZED);
862 }
863 }
864 program->VarBinder()->ResetTopScope(savedTopScope);
865 }
866 ES2PANDA_ASSERT(program->Ast() != nullptr);
867
868 auto *ast = program->Ast();
869 HandleETSModule(ast);
870 }
871
BindVarDecl(ir::Identifier * binding,ir::Expression * init,varbinder::Decl * decl,varbinder::Variable * var)872 void InitScopesPhaseETS::BindVarDecl(ir::Identifier *binding, ir::Expression *init, varbinder::Decl *decl,
873 varbinder::Variable *var)
874 {
875 binding->SetVariable(var);
876 var->SetScope(VarBinder()->GetScope());
877 var->AddFlag(varbinder::VariableFlags::LOCAL);
878 decl->BindNode(init);
879 }
880
VisitBlockExpression(ir::BlockExpression * blockExpr)881 void InitScopesPhaseETS::VisitBlockExpression(ir::BlockExpression *blockExpr)
882 {
883 auto localCtx = LexicalScopeCreateOrEnter<varbinder::LocalScope>(VarBinder(), blockExpr);
884 if (blockExpr->Scope() == nullptr) {
885 BindScopeNode(GetScope(), blockExpr);
886 }
887 Iterate(blockExpr);
888 }
889
VisitClassStaticBlock(ir::ClassStaticBlock * staticBlock)890 void InitScopesPhaseETS::VisitClassStaticBlock(ir::ClassStaticBlock *staticBlock)
891 {
892 const auto func = staticBlock->Function();
893
894 {
895 auto funcParamCtx = (func->Scope() == nullptr)
896 ? varbinder::LexicalScope<varbinder::FunctionParamScope>(VarBinder())
897 : varbinder::LexicalScope<varbinder::FunctionParamScope>::Enter(
898 // CC-OFFNXT(G.FMT.06-CPP) project code style
899 VarBinder(), func->Scope()->ParamScope());
900 auto *funcParamScope = funcParamCtx.GetScope();
901 auto funcCtx = LexicalScopeCreateOrEnter<varbinder::FunctionScope>(VarBinder(), func);
902 auto *funcScope = funcCtx.GetScope();
903
904 func->Body()->AsBlockStatement()->SetScope(funcScope);
905 BindScopeNode(funcScope, func);
906 funcParamScope->BindNode(func);
907 BindFunctionScopes(funcScope, funcParamScope);
908 Iterate(func->Body()->AsBlockStatement());
909 }
910
911 auto classCtx = varbinder::LexicalScope<varbinder::LocalScope>::Enter(
912 VarBinder(), VarBinder()->GetScope()->AsClassScope()->StaticMethodScope());
913
914 if (func->Id()->Variable() != nullptr) {
915 return;
916 }
917
918 varbinder::Variable *var;
919 if (var = VarBinder()->GetScope()->FindLocal(func->Id()->Name(), varbinder::ResolveBindingOptions::STATIC_METHODS);
920 var == nullptr) {
921 var = std::get<1>(VarBinder()->NewVarDecl<varbinder::FunctionDecl>(func->Id()->Start(), Allocator(),
922 func->Id()->Name(), staticBlock));
923 var->AddFlag(varbinder::VariableFlags::METHOD);
924 }
925
926 func->Id()->SetVariable(var);
927 }
928
VisitImportNamespaceSpecifier(ir::ImportNamespaceSpecifier * importSpec)929 void InitScopesPhaseETS::VisitImportNamespaceSpecifier(ir::ImportNamespaceSpecifier *importSpec)
930 {
931 if (importSpec->Local()->Name().Empty()) {
932 return;
933 }
934 AddOrGetDecl<varbinder::ImportDecl>(VarBinder(), importSpec->Local()->Name(), importSpec, importSpec->Start(),
935 importSpec->Local()->Name(), importSpec->Local()->Name(), importSpec);
936 auto var =
937 VarBinder()->GetScope()->FindLocal(importSpec->Local()->Name(), varbinder::ResolveBindingOptions::BINDINGS);
938 importSpec->Local()->SetVariable(var);
939 Iterate(importSpec);
940 }
941
VisitImportSpecifier(ir::ImportSpecifier * importSpec)942 void InitScopesPhaseETS::VisitImportSpecifier(ir::ImportSpecifier *importSpec)
943 {
944 if (importSpec->Parent()->IsETSImportDeclaration() &&
945 importSpec->Parent()->AsETSImportDeclaration()->IsPureDynamic()) {
946 auto [decl, var] = VarBinder()->NewVarDecl<varbinder::LetDecl>(importSpec->Local()->Start(),
947 importSpec->Local()->Name(), importSpec);
948 var->AddFlag(varbinder::VariableFlags::INITIALIZED);
949 }
950 Iterate(importSpec);
951 }
952
953 // Auxiliary method to avoid extra nested levels and too large function size
AddOverload(ir::MethodDefinition * overload,varbinder::Variable * variable)954 void AddOverload(ir::MethodDefinition *overload, varbinder::Variable *variable) noexcept
955 {
956 auto *currentNode = variable->Declaration()->Node();
957 currentNode->AsMethodDefinition()->AddOverload(overload);
958 ES2PANDA_ASSERT(overload->Id() != nullptr);
959 overload->Id()->SetVariable(variable);
960 overload->SetParent(currentNode);
961 }
962
DeclareClassMethod(ir::MethodDefinition * method)963 void InitScopesPhaseETS::DeclareClassMethod(ir::MethodDefinition *method)
964 {
965 ES2PANDA_ASSERT(VarBinder()->GetScope()->IsClassScope() && method->AsMethodDefinition()->Function() != nullptr);
966
967 if ((method->AsMethodDefinition()->Function()->Flags() & ir::ScriptFunctionFlags::OVERLOAD) != 0) {
968 return;
969 }
970
971 const auto methodName = method->Id();
972 auto *const clsScope = VarBinder()->GetScope()->AsClassScope();
973 auto options =
974 method->IsStatic()
975 ? varbinder::ResolveBindingOptions::STATIC_VARIABLES | varbinder::ResolveBindingOptions::STATIC_DECLARATION
976 : varbinder::ResolveBindingOptions::VARIABLES | varbinder::ResolveBindingOptions::DECLARATION;
977 auto variable = clsScope->FindLocal(methodName->Name(), options);
978 if (variable != nullptr) {
979 VarBinder()->ThrowRedeclaration(methodName->Start(), methodName->Name(), variable->Declaration()->Type());
980 }
981
982 varbinder::LocalScope *targetScope {};
983 if (method->IsStatic() || method->IsConstructor()) {
984 targetScope = clsScope->StaticMethodScope();
985 } else {
986 targetScope = clsScope->InstanceMethodScope();
987 }
988 auto *found = targetScope->FindLocal(methodName->Name(), varbinder::ResolveBindingOptions::BINDINGS);
989
990 MaybeAddOverload(method, methodName, found, clsScope, targetScope);
991 }
992
MaybeAddOverload(ir::MethodDefinition * method,ir::Identifier * methodName,varbinder::Variable * found,varbinder::ClassScope * clsScope,varbinder::LocalScope * targetScope)993 void InitScopesPhaseETS::MaybeAddOverload(ir::MethodDefinition *method, ir::Identifier *methodName,
994 varbinder::Variable *found, varbinder::ClassScope *clsScope,
995 varbinder::LocalScope *targetScope)
996 {
997 if (found == nullptr) {
998 auto classCtx = varbinder::LexicalScope<varbinder::LocalScope>::Enter(VarBinder(), targetScope);
999
1000 auto *var = methodName->Variable();
1001 if (var == nullptr) {
1002 var = std::get<1>(VarBinder()->NewVarDecl<varbinder::FunctionDecl>(methodName->Start(), Allocator(),
1003 methodName->Name(), method));
1004 var->SetScope(clsScope);
1005 if (targetScope->HasFlag(varbinder::ScopeFlags::STATIC)) {
1006 var->AddFlag(varbinder::VariableFlags::STATIC);
1007 }
1008 var->AddFlag(varbinder::VariableFlags::METHOD);
1009 methodName->SetVariable(var);
1010 }
1011 for (auto *overload : method->Overloads()) {
1012 ES2PANDA_ASSERT((overload->Function()->Flags() & ir::ScriptFunctionFlags::OVERLOAD) ||
1013 (overload->Function()->Flags() & ir::ScriptFunctionFlags::EXTERNAL_OVERLOAD));
1014 overload->Id()->SetVariable(var);
1015 overload->SetParent(var->Declaration()->Node());
1016 }
1017 } else {
1018 if (methodName->Name().Is(compiler::Signatures::MAIN) && clsScope->Parent()->IsGlobalScope()) {
1019 LogDiagnostic(diagnostic::OVERLOADED_MAIN, methodName->Start());
1020 }
1021 ES2PANDA_ASSERT(method->Function() != nullptr &&
1022 (method->Function()->Flags() & ir::ScriptFunctionFlags::OVERLOAD) == 0U);
1023
1024 AddOverload(method, found);
1025 method->Function()->AddFlag(ir::ScriptFunctionFlags::OVERLOAD);
1026
1027 // default params overloads
1028 for (auto *overload : method->Overloads()) {
1029 ES2PANDA_ASSERT((overload->Function()->Flags() & ir::ScriptFunctionFlags::OVERLOAD) != 0U);
1030 AddOverload(overload, found);
1031 }
1032 method->ClearOverloads();
1033 }
1034 }
1035
VisitETSReExportDeclaration(ir::ETSReExportDeclaration * reExport)1036 void InitScopesPhaseETS::VisitETSReExportDeclaration(ir::ETSReExportDeclaration *reExport)
1037 {
1038 if (!reExport->GetETSImportDeclarations()->IsValid()) {
1039 return;
1040 }
1041 if (reExport->GetETSImportDeclarations()->Language().IsDynamic()) {
1042 VarBinder()->AsETSBinder()->AddDynamicImport(reExport->GetETSImportDeclarations());
1043 }
1044 VarBinder()->AsETSBinder()->AddReExportImport(reExport);
1045 Iterate(reExport);
1046 }
1047
VisitETSParameterExpression(ir::ETSParameterExpression * paramExpr)1048 void InitScopesPhaseETS::VisitETSParameterExpression(ir::ETSParameterExpression *paramExpr)
1049 {
1050 auto *const var = VarBinder()->AddParamDecl(paramExpr);
1051 paramExpr->SetVariable(var);
1052 var->SetScope(VarBinder()->GetScope());
1053 var->AddFlag(varbinder::VariableFlags::INITIALIZED);
1054 Iterate(paramExpr);
1055 }
1056
VisitETSImportDeclaration(ir::ETSImportDeclaration * importDecl)1057 void InitScopesPhaseETS::VisitETSImportDeclaration(ir::ETSImportDeclaration *importDecl)
1058 {
1059 if (!importDecl->IsValid()) {
1060 return;
1061 }
1062 ImportDeclarationContext importCtx(VarBinder());
1063 if (importDecl->Language().IsDynamic()) {
1064 VarBinder()->AsETSBinder()->AddDynamicImport(importDecl);
1065 }
1066 Iterate(importDecl);
1067 }
1068
VisitTSEnumMember(ir::TSEnumMember * enumMember)1069 void InitScopesPhaseETS::VisitTSEnumMember(ir::TSEnumMember *enumMember)
1070 {
1071 auto ident = enumMember->Key()->AsIdentifier();
1072 if (ident->Variable() != nullptr) {
1073 return;
1074 }
1075
1076 auto const &name = ident->Name();
1077 varbinder::Variable *var = nullptr;
1078
1079 if (var = VarBinder()->GetScope()->FindLocal(name, varbinder::ResolveBindingOptions::STATIC_VARIABLES);
1080 var == nullptr) {
1081 varbinder::Decl *decl = nullptr;
1082 std::tie(decl, var) = VarBinder()->NewVarDecl<varbinder::LetDecl>(ident->Start(), name);
1083 var->SetScope(VarBinder()->GetScope());
1084 var->AddFlag(varbinder::VariableFlags::STATIC);
1085 decl->BindNode(enumMember);
1086 } else {
1087 VarBinder()->ThrowRedeclaration(ident->Start(), name, var->Declaration()->Type());
1088 }
1089
1090 ident->SetVariable(var);
1091 Iterate(enumMember);
1092 }
1093
VisitMethodDefinition(ir::MethodDefinition * method)1094 void InitScopesPhaseETS::VisitMethodDefinition(ir::MethodDefinition *method)
1095 {
1096 ES2PANDA_ASSERT(method->Function() != nullptr);
1097 if (method->Function()->Scope() != nullptr) {
1098 return;
1099 }
1100
1101 auto *curScope = VarBinder()->GetScope();
1102 const auto methodName = method->Id();
1103 auto res =
1104 curScope->Find(methodName->Name(), method->IsStatic() ? varbinder::ResolveBindingOptions::ALL_STATIC
1105 : varbinder::ResolveBindingOptions::ALL_NON_STATIC);
1106 if (res.variable != nullptr && !res.variable->Declaration()->IsFunctionDecl() && res.scope == curScope) {
1107 VarBinder()->ThrowRedeclaration(methodName->Start(), res.name, varbinder::DeclType::METHOD);
1108 }
1109
1110 auto result = curScope->FindLocal(methodName->Name(), varbinder::ResolveBindingOptions::ALL_DECLARATION);
1111 if (result != nullptr) {
1112 VarBinder()->ThrowLocalRedeclaration(methodName->Start(), result->Name());
1113 }
1114
1115 Iterate(method);
1116 DeclareClassMethod(method);
1117 }
1118
VisitETSFunctionType(ir::ETSFunctionType * funcType)1119 void InitScopesPhaseETS::VisitETSFunctionType(ir::ETSFunctionType *funcType)
1120 {
1121 auto typeParamsCtx = LexicalScopeCreateOrEnter<varbinder::LocalScope>(VarBinder(), funcType->TypeParams());
1122
1123 // Check for existing scope
1124 // In some cases we can visit function again with scope that already exists
1125 // Example: async lambda, we "move" original function to another place and visit it again
1126 if (funcType->Scope() == nullptr) {
1127 varbinder::LexicalScope<varbinder::FunctionParamScope> lexicalScope(VarBinder());
1128 auto *funcParamScope = lexicalScope.GetScope();
1129 BindScopeNode(funcParamScope, funcType);
1130 Iterate(funcType);
1131 }
1132 }
1133
VisitETSNewClassInstanceExpression(ir::ETSNewClassInstanceExpression * newClassExpr)1134 void InitScopesPhaseETS::VisitETSNewClassInstanceExpression(ir::ETSNewClassInstanceExpression *newClassExpr)
1135 {
1136 CallNode(newClassExpr->GetArguments());
1137 CallNode(newClassExpr->GetTypeRef());
1138 }
1139
VisitTSTypeParameter(ir::TSTypeParameter * typeParam)1140 void InitScopesPhaseETS::VisitTSTypeParameter(ir::TSTypeParameter *typeParam)
1141 {
1142 if (typeParam->Name()->Variable() != nullptr) {
1143 return;
1144 }
1145 auto [decl, var] =
1146 VarBinder()->NewVarDecl<varbinder::TypeParameterDecl>(typeParam->Name()->Start(), typeParam->Name()->Name());
1147 typeParam->Name()->SetVariable(var);
1148 var->SetScope(VarBinder()->GetScope());
1149 var->AddFlag(varbinder::VariableFlags::TYPE_PARAMETER);
1150 decl->BindNode(typeParam);
1151 CallNode(typeParam->Annotations());
1152 CallNode(typeParam->DefaultType());
1153 }
1154
VisitTSInterfaceDeclaration(ir::TSInterfaceDeclaration * interfaceDecl)1155 void InitScopesPhaseETS::VisitTSInterfaceDeclaration(ir::TSInterfaceDeclaration *interfaceDecl)
1156 {
1157 {
1158 auto typeParamsCtx = LexicalScopeCreateOrEnter<varbinder::LocalScope>(VarBinder(), interfaceDecl->TypeParams());
1159 CallNode(interfaceDecl->TypeParams());
1160 CallNode(interfaceDecl->Extends());
1161 auto localScope = LexicalScopeCreateOrEnter<varbinder::ClassScope>(VarBinder(), interfaceDecl);
1162 CallNode(interfaceDecl->Body());
1163 CallNode(interfaceDecl->Annotations());
1164 BindScopeNode(localScope.GetScope(), interfaceDecl);
1165 }
1166 auto name = FormInterfaceOrEnumDeclarationIdBinding(interfaceDecl->Id());
1167 if (auto *decl = AddOrGetDecl<varbinder::InterfaceDecl>(VarBinder(), name, interfaceDecl, interfaceDecl->Start(),
1168 Allocator(), name, interfaceDecl);
1169 decl != nullptr) {
1170 decl->AsInterfaceDecl()->Add(interfaceDecl);
1171 }
1172 }
1173
VisitTSEnumDeclaration(ir::TSEnumDeclaration * enumDecl)1174 void InitScopesPhaseETS::VisitTSEnumDeclaration(ir::TSEnumDeclaration *enumDecl)
1175 {
1176 {
1177 const auto enumCtx = LexicalScopeCreateOrEnter<varbinder::LocalScope>(VarBinder(), enumDecl);
1178 BindScopeNode(enumCtx.GetScope(), enumDecl);
1179 Iterate(enumDecl);
1180 }
1181 auto name = FormInterfaceOrEnumDeclarationIdBinding(enumDecl->Key());
1182 if (auto *decl = AddOrGetDecl<varbinder::EnumLiteralDecl>(VarBinder(), name, enumDecl, enumDecl->Key()->Start(),
1183 name, enumDecl, enumDecl->IsConst());
1184 decl != nullptr) {
1185 decl->BindScope(enumDecl->Scope());
1186 }
1187 }
1188
VisitTSTypeAliasDeclaration(ir::TSTypeAliasDeclaration * typeAlias)1189 void InitScopesPhaseETS::VisitTSTypeAliasDeclaration(ir::TSTypeAliasDeclaration *typeAlias)
1190 {
1191 AddOrGetDecl<varbinder::TypeAliasDecl>(VarBinder(), typeAlias->Id()->Name(), typeAlias, typeAlias->Id()->Start(),
1192 typeAlias->Id()->Name(), typeAlias);
1193 auto typeParamsCtx = LexicalScopeCreateOrEnter<varbinder::LocalScope>(VarBinder(), typeAlias->TypeParams());
1194 Iterate(typeAlias);
1195 }
1196
AddGlobalToBinder(parser::Program * program)1197 void InitScopesPhaseETS::AddGlobalToBinder(parser::Program *program)
1198 {
1199 auto globalId = program->GlobalClass()->Ident();
1200 if (globalId->Variable() != nullptr) {
1201 return;
1202 }
1203
1204 auto start = globalId->Start();
1205 auto name = globalId->Name();
1206 auto *varBinder = program->VarBinder();
1207 auto *ctx = varBinder->GetContext();
1208 if (ctx->compilingState == public_lib::CompilingState::MULTI_COMPILING_FOLLOW) {
1209 auto *scope = varBinder->GetScope();
1210 auto bindings = scope->Bindings();
1211 auto res = bindings.find(name);
1212 if (res != bindings.end()) {
1213 auto classCtx =
1214 LexicalScopeCreateOrEnter<varbinder::ClassScope>(program->VarBinder(), program->GlobalClass());
1215 classCtx.GetScope()->BindNode(program->GlobalClass());
1216 program->GlobalClass()->SetScope(classCtx.GetScope());
1217 globalId->SetVariable(res->second);
1218 return;
1219 }
1220 }
1221 auto [decl2, var] = varBinder->NewVarDecl<varbinder::ClassDecl>(start, name);
1222
1223 auto classCtx = LexicalScopeCreateOrEnter<varbinder::ClassScope>(program->VarBinder(), program->GlobalClass());
1224 classCtx.GetScope()->BindNode(program->GlobalClass());
1225 program->GlobalClass()->SetScope(classCtx.GetScope());
1226
1227 auto *classDecl = program->GlobalClass()->Parent();
1228 decl2->BindNode(classDecl);
1229 globalId->SetVariable(var);
1230 }
1231
HandleETSModule(ir::BlockStatement * script)1232 void InitScopesPhaseETS::HandleETSModule(ir::BlockStatement *script)
1233 {
1234 for (auto decl : script->Statements()) {
1235 if (decl->IsETSImportDeclaration() || decl->IsETSReExportDeclaration()) {
1236 CallNode(decl);
1237 } else {
1238 auto classCtx =
1239 varbinder::LexicalScope<varbinder::ClassScope>::Enter(VarBinder(), Program()->GlobalClassScope());
1240 CallNode(decl);
1241 }
1242 }
1243 auto classCtx = varbinder::LexicalScope<varbinder::ClassScope>::Enter(VarBinder(), Program()->GlobalClassScope());
1244
1245 for (auto decl : script->Statements()) {
1246 AddGlobalDeclaration(decl);
1247 }
1248 }
1249
VisitClassDefinition(ir::ClassDefinition * classDef)1250 void InitScopesPhaseETS::VisitClassDefinition(ir::ClassDefinition *classDef)
1251 {
1252 if (classDef->IsGlobal()) {
1253 ParseGlobalClass(classDef);
1254 return;
1255 }
1256 auto typeParamsCtx = LexicalScopeCreateOrEnter<varbinder::LocalScope>(VarBinder(), classDef->TypeParams());
1257 CallNode(classDef->TypeParams());
1258 auto classCtx = LexicalScopeCreateOrEnter<varbinder::ClassScope>(VarBinder(), classDef);
1259
1260 IterateNoTParams(classDef);
1261 FilterOverloads(classDef->Body());
1262 auto *classScope = classCtx.GetScope();
1263 BindScopeNode(classScope, classDef);
1264 }
1265
VisitTSInterfaceBody(ir::TSInterfaceBody * interfBody)1266 void InitScopesPhaseETS::VisitTSInterfaceBody(ir::TSInterfaceBody *interfBody)
1267 {
1268 Iterate(interfBody);
1269 FilterInterfaceOverloads(interfBody->Body());
1270 }
1271
FilterInterfaceOverloads(ArenaVector<ir::AstNode *,false> & props)1272 void InitScopesPhaseETS::FilterInterfaceOverloads(ArenaVector<ir::AstNode *, false> &props)
1273 {
1274 auto condition = [](ir::AstNode *prop) {
1275 if (prop->IsMethodDefinition()) {
1276 const auto func = prop->AsMethodDefinition()->Function();
1277 return func->IsOverload() && func->Body() != nullptr;
1278 }
1279 return false;
1280 };
1281 props.erase(std::remove_if(props.begin(), props.end(), condition), props.end());
1282 }
1283
FilterOverloads(ArenaVector<ir::AstNode *,false> & props)1284 void InitScopesPhaseETS::FilterOverloads(ArenaVector<ir::AstNode *, false> &props)
1285 {
1286 auto condition = [](ir::AstNode *prop) {
1287 if (prop->IsMethodDefinition()) {
1288 const auto func = prop->AsMethodDefinition()->Function();
1289 return func->IsOverload();
1290 }
1291 return false;
1292 };
1293 props.erase(std::remove_if(props.begin(), props.end(), condition), props.end());
1294 }
1295
VisitClassProperty(ir::ClassProperty * classProp)1296 void InitScopesPhaseETS::VisitClassProperty(ir::ClassProperty *classProp)
1297 {
1298 auto curScope = VarBinder()->GetScope();
1299 const auto name = classProp->Key()->AsIdentifier()->Name();
1300
1301 ES2PANDA_ASSERT(!classProp->IsClassStaticBlock());
1302
1303 if (classProp->IsConst()) {
1304 ES2PANDA_ASSERT(curScope->Parent() != nullptr);
1305 const auto initializer = classProp->Value();
1306 if (initializer == nullptr && curScope->Parent()->IsGlobalScope() && !classProp->IsDeclare() &&
1307 !classProp->NeedInitInStaticBlock()) {
1308 auto pos = classProp->End();
1309 // NOTE: Just use property Name?
1310 if (classProp->TypeAnnotation() != nullptr && !classProp->TypeAnnotation()->IsETSPrimitiveType()) {
1311 --(pos.index);
1312 }
1313 LogDiagnostic(diagnostic::CONST_WITHOUT_INIT, pos);
1314 }
1315 AddOrGetDecl<varbinder::ConstDecl>(VarBinder(), name, classProp, classProp->Key()->Start(), name, classProp);
1316 } else if (classProp->IsReadonly()) {
1317 AddOrGetDecl<varbinder::ReadonlyDecl>(VarBinder(), name, classProp, classProp->Key()->Start(), name, classProp);
1318 } else {
1319 AddOrGetDecl<varbinder::LetDecl>(VarBinder(), name, classProp, classProp->Key()->Start(), name, classProp);
1320 }
1321 Iterate(classProp);
1322 }
1323
VisitBreakStatement(ir::BreakStatement * stmt)1324 void InitScopesPhaseETS::VisitBreakStatement(ir::BreakStatement *stmt)
1325 {
1326 auto label = stmt->Ident();
1327 if (label != nullptr) {
1328 auto scope = VarBinder()->GetScope();
1329 auto var = scope->FindInFunctionScope(label->Name(), varbinder::ResolveBindingOptions::ALL).variable;
1330 label->SetVariable(var);
1331 }
1332 }
1333
VisitContinueStatement(ir::ContinueStatement * stmt)1334 void InitScopesPhaseETS::VisitContinueStatement(ir::ContinueStatement *stmt)
1335 {
1336 auto label = stmt->Ident();
1337 if (label != nullptr) {
1338 auto scope = VarBinder()->GetScope();
1339 auto var = scope->FindInFunctionScope(label->Name(), varbinder::ResolveBindingOptions::ALL).variable;
1340 label->SetVariable(var);
1341 }
1342 }
1343
AttachLabelToScope(ir::AstNode * node)1344 void InitScopesPhaseETS::AttachLabelToScope(ir::AstNode *node)
1345 {
1346 if (node->Parent() == nullptr) {
1347 return;
1348 }
1349
1350 if (!node->Parent()->IsLabelledStatement()) {
1351 return;
1352 }
1353
1354 auto stmt = node->Parent()->AsLabelledStatement();
1355 auto label = stmt->Ident();
1356 if (label == nullptr) {
1357 return;
1358 }
1359
1360 auto decl = AddOrGetDecl<varbinder::LabelDecl>(VarBinder(), label->Name(), stmt, label->Start(), label->Name());
1361 if (decl == nullptr) {
1362 return;
1363 }
1364
1365 decl->BindNode(stmt);
1366
1367 auto var = VarBinder()->GetScope()->FindLocal(label->Name(), varbinder::ResolveBindingOptions::BINDINGS);
1368 if (var != nullptr) {
1369 label->SetVariable(var);
1370 var->SetScope(VarBinder()->GetScope());
1371 var->AddFlag(varbinder::VariableFlags::LOCAL);
1372 }
1373 }
1374
ParseGlobalClass(ir::ClassDefinition * global)1375 void InitScopesPhaseETS::ParseGlobalClass(ir::ClassDefinition *global)
1376 {
1377 bool defaultExported = false;
1378 for (auto decl : global->Body()) {
1379 if (decl->IsDefaultExported()) {
1380 if (defaultExported) {
1381 LogDiagnostic(diagnostic::MULTIPLE_DEFAULT_EXPORTS, decl->Start());
1382 }
1383 defaultExported = true;
1384 }
1385 CallNode(decl);
1386 }
1387 CallNode(global->Annotations());
1388 FilterOverloads(global->Body());
1389 }
1390
AddGlobalDeclaration(ir::AstNode * node)1391 void InitScopesPhaseETS::AddGlobalDeclaration(ir::AstNode *node)
1392 {
1393 ir::Identifier *ident = nullptr;
1394 bool isBuiltin = false;
1395 switch (node->Type()) {
1396 case ir::AstNodeType::CLASS_DECLARATION: {
1397 auto def = node->AsClassDeclaration()->Definition();
1398 if (def->IsGlobal()) {
1399 return;
1400 }
1401 ident = def->Ident();
1402 isBuiltin = def->IsFromExternal();
1403 break;
1404 }
1405 case ir::AstNodeType::ANNOTATION_DECLARATION: {
1406 ident = node->AsAnnotationDeclaration()->GetBaseName();
1407 isBuiltin = false;
1408 break;
1409 }
1410 case ir::AstNodeType::STRUCT_DECLARATION: {
1411 ident = node->AsETSStructDeclaration()->Definition()->Ident();
1412 isBuiltin = node->AsETSStructDeclaration()->Definition()->IsFromExternal();
1413 break;
1414 }
1415 case ir::AstNodeType::TS_INTERFACE_DECLARATION: {
1416 ident = node->AsTSInterfaceDeclaration()->Id();
1417 isBuiltin = node->AsTSInterfaceDeclaration()->IsFromExternal();
1418 break;
1419 }
1420 case ir::AstNodeType::TS_TYPE_ALIAS_DECLARATION: {
1421 ident = node->AsTSTypeAliasDeclaration()->Id();
1422 break;
1423 }
1424 default: {
1425 break;
1426 }
1427 }
1428 if (ident != nullptr && ident->Variable() != nullptr) {
1429 VarBinder()->TopScope()->InsertBinding(ident->Name(), ident->Variable());
1430 if (isBuiltin) {
1431 ident->Variable()->AddFlag(varbinder::VariableFlags::BUILTIN_TYPE);
1432 }
1433 }
1434 }
1435
VisitArrowFunctionExpression(ir::ArrowFunctionExpression * arrowExpr)1436 void InitScopesPhaseAS::VisitArrowFunctionExpression(ir::ArrowFunctionExpression *arrowExpr)
1437 {
1438 Iterate(arrowExpr);
1439 }
1440
VisitExportNamedDeclaration(ir::ExportNamedDeclaration * exportDecl)1441 void InitScopesPhaseAS::VisitExportNamedDeclaration(ir::ExportNamedDeclaration *exportDecl)
1442 {
1443 ExportDeclarationContext exportDeclCtx(VarBinder());
1444 Iterate(exportDecl);
1445 }
1446
1447 } // namespace ark::es2panda::compiler
1448