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