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 #ifndef ES2PANDA_COMPILER_CORE_SCOPES_INIT_PHASE_H 17 #define ES2PANDA_COMPILER_CORE_SCOPES_INIT_PHASE_H 18 19 #include "compiler/lowering/phase.h" 20 #include "util/helpers.h" 21 #include "parser/parserFlags.h" 22 #include "varbinder/tsBinding.h" 23 #include "varbinder/ETSBinder.h" 24 #include "compiler/lowering/scopesInit/savedBindingsCtx.h" 25 #include "checker/checker.h" 26 #include "ir/visitor/IterateAstVisitor.h" 27 #include "ir/expressions/literals/undefinedLiteral.h" 28 #include "ir/expressions/blockExpression.h" 29 #include "ir/ets/etsUnionType.h" 30 #include "ir/ets/etsTuple.h" 31 32 namespace ark::es2panda::compiler { 33 34 /** 35 * Responsible for initialization of scopes. Should be called right after Parser stage. 36 */ 37 // NOLINTNEXTLINE(fuchsia-multiple-inheritance) 38 class ScopesInitPhase : public Phase, public ir::visitor::IterateAstVisitor { 39 public: 40 using PhaseContext = public_lib::Context; 41 42 static constexpr std::string_view NAME = "ScopesInitPhase"; 43 Name()44 std::string_view Name() const override 45 { 46 return NAME; 47 } 48 49 bool Perform(PhaseContext *ctx, parser::Program *program) override; 50 51 protected: 52 void SetProgram(parser::Program *program) noexcept; 53 54 void Prepare(PhaseContext *ctx, parser::Program *program); 55 56 /** 57 * Should be called at the end of each program perform 58 */ 59 void Finalize(); 60 61 /** 62 * Check if there's only one default export and no named export redeclaration, 63 * throw error if so. 64 * Side effect: fill local_exports_ 65 */ 66 void AnalyzeExports(); 67 68 protected: 69 template <typename T> CallNode(T * node)70 void CallNode(T *node) 71 { 72 if (node) { 73 node->Accept(this); 74 } 75 } 76 77 template <typename T> CallNode(const ArenaVector<T * > & nodes)78 void CallNode(const ArenaVector<T *> &nodes) 79 { 80 for (auto *node : nodes) { 81 CallNode(node); 82 } 83 } 84 85 void CallFuncParams(const ArenaVector<ir::Expression *> ¶ms); 86 void IterateNoTParams(ir::ClassDefinition *classDef); 87 88 protected: 89 void LogDiagnostic(const diagnostic::DiagnosticKind &kind, const util::DiagnosticMessageParams ¶ms, 90 const lexer::SourcePosition &pos) const; 91 LogDiagnostic(const diagnostic::DiagnosticKind & kind,const lexer::SourcePosition & pos)92 void LogDiagnostic(const diagnostic::DiagnosticKind &kind, const lexer::SourcePosition &pos) const 93 { 94 LogDiagnostic(kind, util::DiagnosticMessageParams {}, pos); 95 } 96 97 void VisitFunctionExpression(ir::FunctionExpression *funcExpr) override; 98 void VisitScriptFunction(ir::ScriptFunction *scriptFunction) override; 99 void VisitBlockStatement(ir::BlockStatement *blockStmt) override; 100 void VisitImportDeclaration(ir::ImportDeclaration *importDeclaration) override; 101 void VisitClassStaticBlock(ir::ClassStaticBlock *staticBlock) override; 102 void VisitClassDefinition(ir::ClassDefinition *classDef) override; 103 void VisitMethodDefinition(ir::MethodDefinition *methodDefinition) override; 104 void VisitForUpdateStatement(ir::ForUpdateStatement *forUpdateStmt) override; 105 void VisitForInStatement(ir::ForInStatement *forInStmt) override; 106 void VisitForOfStatement(ir::ForOfStatement *forOfStmt) override; 107 void VisitCatchClause(ir::CatchClause *catchClause) override; 108 void VisitVariableDeclarator(ir::VariableDeclarator *varDecl) override; 109 void VisitSwitchStatement(ir::SwitchStatement *switchStmt) override; 110 void VisitWhileStatement(ir::WhileStatement *whileStmt) override; 111 void VisitETSStructDeclaration(ir::ETSStructDeclaration *structDecl) override; 112 void VisitClassDeclaration(ir::ClassDeclaration *classDecl) override; 113 void VisitDoWhileStatement(ir::DoWhileStatement *doWhileStmt) override; 114 void VisitFunctionDeclaration(ir::FunctionDeclaration *funcDecl) override; 115 void VisitExportAllDeclaration(ir::ExportAllDeclaration *exportAllDecl) override; 116 void VisitImportNamespaceSpecifier(ir::ImportNamespaceSpecifier *importSpec) override; 117 void VisitImportSpecifier(ir::ImportSpecifier *importSpec) override; 118 void VisitImportDefaultSpecifier(ir::ImportDefaultSpecifier *importSpec) override; 119 void VisitExportDefaultDeclaration(ir::ExportDefaultDeclaration *exportDecl) override; 120 void VisitExportNamedDeclaration(ir::ExportNamedDeclaration *exportDecl) override; 121 void VisitArrowFunctionExpression(ir::ArrowFunctionExpression *arrowExpr) override; 122 void VisitDirectEvalExpression(ir::DirectEvalExpression *directCallExpr) override; 123 void VisitTSFunctionType(ir::TSFunctionType *funcType) override; 124 void VisitAnnotationDeclaration(ir::AnnotationDeclaration *annoDecl) override; 125 void VisitAnnotationUsage(ir::AnnotationUsage *annoUsage) override; 126 127 protected: GetScope()128 varbinder::Scope *GetScope() 129 { 130 return VarBinder()->GetScope(); 131 } 132 Allocator()133 ArenaAllocator *Allocator() 134 { 135 return program_->Allocator(); 136 } 137 Program()138 parser::Program *Program() 139 { 140 return program_; 141 } 142 Program()143 const parser::Program *Program() const 144 { 145 return program_; 146 } 147 Context()148 PhaseContext *Context() 149 { 150 return ctx_; 151 } 152 VarBinder()153 [[nodiscard]] varbinder::VarBinder *VarBinder() const 154 { 155 return program_->VarBinder(); 156 } 157 158 protected: 159 virtual void CreateFuncDecl(ir::ScriptFunction *func); 160 virtual util::StringView FormInterfaceOrEnumDeclarationIdBinding(ir::Identifier *id); 161 void HandleFunction(ir::ScriptFunction *function); 162 varbinder::FunctionParamScope *HandleFunctionSig(ir::TSTypeParameterDeclaration *typeParams, 163 const ArenaVector<ir::Expression *> ¶ms, 164 ir::TypeNode *returnType); 165 166 /** 167 * Handle block from existing scope 168 */ 169 void HandleBlockStmt(ir::BlockStatement *block, varbinder::Scope *scope); 170 171 template <typename ForT> HandleFor(varbinder::LoopDeclarationScope * declScope,varbinder::LoopScope * loopScope,ForT * forStmt)172 void HandleFor(varbinder::LoopDeclarationScope *declScope, varbinder::LoopScope *loopScope, ForT *forStmt) 173 { 174 loopScope->BindDecls(declScope); 175 BindScopeNode(loopScope, forStmt); 176 loopScope->DeclScope()->BindNode(forStmt); 177 } 178 179 protected: 180 virtual varbinder::Decl *BindClassName(ir::ClassDefinition *classDef); 181 182 template <class Scope, class Node> BindScopeNode(Scope * scope,Node * node)183 static void BindScopeNode(Scope *scope, Node *node) 184 { 185 if (node->Scope() == nullptr || node->IsBlockStatement()) { 186 scope->BindNode(node); 187 node->SetScope(scope); 188 } 189 } 190 191 static void BindFunctionScopes(varbinder::FunctionScope *scope, varbinder::FunctionParamScope *paramScope); 192 193 void BindClassDefinition(ir::ClassDefinition *classDef); 194 195 std::tuple<varbinder::Decl *, varbinder::Variable *> AddOrGetVarDecl(ir::VariableDeclaratorFlag flag, 196 const ir::Identifier *id); 197 198 virtual void BindVarDecl([[maybe_unused]] ir::Identifier *binding, ir::Expression *init, varbinder::Decl *decl, 199 [[maybe_unused]] varbinder::Variable *var); 200 virtual void AttachLabelToScope(ir::AstNode *node); 201 202 private: 203 PhaseContext *ctx_ {}; 204 parser::Program *program_ {}; 205 }; 206 207 /** 208 * Specialization for typed script languages (typescript, ets) 209 */ 210 class ScopeInitTyped : public ScopesInitPhase { 211 protected: 212 public: 213 void VisitTSModuleDeclaration(ir::TSModuleDeclaration *moduleDecl) override; 214 215 void VisitTSModuleBlock(ir::TSModuleBlock *block) override; 216 217 void VisitTSTypeAliasDeclaration(ir::TSTypeAliasDeclaration *typeAliasDecl) override; 218 219 util::StringView FormInterfaceOrEnumDeclarationIdBinding(ir::Identifier *id) override; 220 AllowInterfaceRedeclaration()221 virtual bool AllowInterfaceRedeclaration() 222 { 223 return false; 224 } 225 226 void VisitTSInterfaceDeclaration(ir::TSInterfaceDeclaration *interfDecl) override; 227 228 void VisitTSEnumMember(ir::TSEnumMember *enumMember) override; 229 230 void VisitTSEnumDeclaration(ir::TSEnumDeclaration *enumDecl) override; 231 232 void VisitTSTypeParameter(ir::TSTypeParameter *typeParam) override; 233 234 void VisitTSTypeParameterDeclaration(ir::TSTypeParameterDeclaration *paramDecl) override; 235 236 void VisitClassDefinition(ir::ClassDefinition *classDef) override; 237 }; 238 239 class InitScopesPhaseJs : public ScopesInitPhase { 240 public: 241 InitScopesPhaseJs() = default; 242 NO_COPY_SEMANTIC(InitScopesPhaseJs); 243 NO_MOVE_SEMANTIC(InitScopesPhaseJs); 244 245 ~InitScopesPhaseJs() override = default; 246 }; 247 248 class InitScopesPhaseTs : public ScopeInitTyped { 249 protected: AllowInterfaceRedeclaration()250 bool AllowInterfaceRedeclaration() override 251 { 252 return true; 253 } 254 VisitTSMappedType(ir::TSMappedType * mapped)255 void VisitTSMappedType([[maybe_unused]] ir::TSMappedType *mapped) override {} VisitTSInferType(ir::TSInferType * infer)256 void VisitTSInferType([[maybe_unused]] ir::TSInferType *infer) override {} 257 void VisitExportDefaultDeclaration(ir::ExportDefaultDeclaration *exportDecl) override; 258 void VisitExportNamedDeclaration(ir::ExportNamedDeclaration *exportDecl) override; 259 void VisitImportDeclaration(ir::ImportDeclaration *importDeclaration) override; 260 void VisitTSFunctionType(ir::TSFunctionType *constrType) override; 261 void VisitTSConstructorType(ir::TSConstructorType *constrT) override; 262 void VisitArrowFunctionExpression(ir::ArrowFunctionExpression *arrowFExpr) override; 263 void VisitTSSignatureDeclaration(ir::TSSignatureDeclaration *signDecl) override; 264 void VisitTSMethodSignature(ir::TSMethodSignature *methodSign) override; 265 266 void CreateFuncDecl(ir::ScriptFunction *func) override; 267 }; 268 269 class InitScopesPhaseETS : public ScopeInitTyped { 270 public: 271 InitScopesPhaseETS() = default; 272 NO_COPY_SEMANTIC(InitScopesPhaseETS); 273 NO_MOVE_SEMANTIC(InitScopesPhaseETS); 274 275 /** 276 * Set scopes for ast-subtree 277 * @param node ast-subtree, for this node and all children scopes will be initialized. 278 * @param varbinder ref to VarBinder. All varbinder scopes should be set to current context. 279 * Note: It's programmer responsibility to prepare VarBinder (remove previous names, set current scope, etc...) 280 * 281 * Example: // CC-OFF(G.CMT.04) false positive 282 * f<T>(x: Int) : { 283 * let y = 0; 284 * } 285 * After ScopesInitPhase scope structure will look something like this: 286 * global_scope: 287 * [f], 288 * local_scope: 289 * [T], 290 * function_param_scope: 291 * [x], 292 * function_scope: 293 * [y] 294 * Suppose you want to rewrite function body in some lowering later to 295 * { 296 * let z = 123; 297 * } 298 * 299 * Then you should pass your new created node = ir::BlockStatement() to RunExternalNode, 300 * set varbinder to previous `function_scope` and call RunExternalNode(node, varbinder). 301 * It will update scopes to: // CC-OFF(G.CMT.04) false positive 302 * global_scope: 303 * [f], 304 * local_scope: 305 * [T], 306 * function_param_scope: 307 * [x], 308 * function_scope: 309 * [z] 310 */ 311 static void RunExternalNode(ir::AstNode *node, varbinder::VarBinder *varbinder); 312 /** 313 * Same as previous, just uses varbinder from ctx->VarBinder() 314 */ 315 static void RunExternalNode(ir::AstNode *node, parser::Program *ctx); 316 317 /** 318 * Run scope initialization on program. 319 * It's not same as RunExternalNode(program->Ast()), because there's some specific handling for top scope. 320 * @param ctx 321 * @param program - program you want to set scopes on. 322 * @return true if successful. 323 */ 324 bool Perform(PhaseContext *ctx, parser::Program *program) override; 325 326 ~InitScopesPhaseETS() override = default; 327 328 private: 329 void HandleProgram(parser::Program *program); 330 331 void HandleETSModule(ir::BlockStatement *script); 332 333 void ParseGlobalClass(ir::ClassDefinition *global); 334 335 void AddGlobalDeclaration(ir::AstNode *node); 336 BindClassName(ir::ClassDefinition * identNode)337 varbinder::Decl *BindClassName([[maybe_unused]] ir::ClassDefinition *identNode) override 338 { 339 return nullptr; 340 } 341 342 void BindVarDecl(ir::Identifier *binding, ir::Expression *init, varbinder::Decl *decl, 343 varbinder::Variable *var) override; 344 void DeclareClassMethod(ir::MethodDefinition *method); 345 void MaybeAddOverload(ir::MethodDefinition *method, ir::Identifier *methodName, varbinder::Variable *found, 346 varbinder::ClassScope *clsScope, varbinder::LocalScope *targetScope); 347 348 void VisitClassStaticBlock(ir::ClassStaticBlock *staticBlock) override; 349 void VisitBlockExpression(ir::BlockExpression *blockExpr) override; 350 void VisitImportNamespaceSpecifier(ir::ImportNamespaceSpecifier *importSpec) override; 351 void VisitImportSpecifier([[maybe_unused]] ir::ImportSpecifier *importSpec) override; VisitImportDefaultSpecifier(ir::ImportDefaultSpecifier * importSpec)352 void VisitImportDefaultSpecifier([[maybe_unused]] ir::ImportDefaultSpecifier *importSpec) override {}; 353 void VisitETSReExportDeclaration(ir::ETSReExportDeclaration *reExport) override; 354 void VisitETSParameterExpression(ir::ETSParameterExpression *paramExpr) override; 355 void VisitETSImportDeclaration(ir::ETSImportDeclaration *importDecl) override; 356 void VisitTSEnumMember(ir::TSEnumMember *enumMember) override; 357 void VisitMethodDefinition(ir::MethodDefinition *method) override; 358 void VisitETSFunctionType(ir::ETSFunctionType *funcType) override; 359 void VisitETSNewClassInstanceExpression(ir::ETSNewClassInstanceExpression *newClassExpr) override; 360 void VisitTSTypeParameter(ir::TSTypeParameter *typeParam) override; 361 void VisitTSInterfaceDeclaration(ir::TSInterfaceDeclaration *interfaceDecl) override; 362 void VisitTSEnumDeclaration(ir::TSEnumDeclaration *enumDecl) override; 363 void VisitTSTypeAliasDeclaration(ir::TSTypeAliasDeclaration *typeAlias) override; 364 void VisitClassDefinition(ir::ClassDefinition *classDef) override; 365 void VisitTSInterfaceBody(ir::TSInterfaceBody *interfBody) override; 366 void VisitClassProperty(ir::ClassProperty *classProp) override; 367 void VisitBreakStatement(ir::BreakStatement *stmt) override; 368 void VisitContinueStatement(ir::ContinueStatement *stmt) override; 369 void AttachLabelToScope(ir::AstNode *node) override; VisitArrowFunctionExpression(ir::ArrowFunctionExpression * arrowExpr)370 void VisitArrowFunctionExpression(ir::ArrowFunctionExpression *arrowExpr) override 371 { 372 Iterate(arrowExpr); 373 } 374 FormInterfaceOrEnumDeclarationIdBinding(ir::Identifier * id)375 util::StringView FormInterfaceOrEnumDeclarationIdBinding(ir::Identifier *id) override 376 { 377 return id->Name(); 378 } 379 380 static void AddGlobalToBinder(parser::Program *program); 381 382 void FilterInterfaceOverloads(ArenaVector<ir::AstNode *> &props); 383 384 void FilterOverloads(ArenaVector<ir::AstNode *> &props); 385 }; 386 387 class InitScopesPhaseAS : public ScopesInitPhase { 388 public: 389 NO_COPY_SEMANTIC(InitScopesPhaseAS); 390 NO_MOVE_SEMANTIC(InitScopesPhaseAS); 391 InitScopesPhaseAS() = default; 392 ~InitScopesPhaseAS() override = default; 393 394 private: 395 void VisitArrowFunctionExpression(ir::ArrowFunctionExpression *arrowExpr) override; 396 void VisitExportNamedDeclaration(ir::ExportNamedDeclaration *exportDecl) override; 397 }; 398 } // namespace ark::es2panda::compiler 399 400 #endif 401