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