1 /** 2 * Copyright (c) 2021-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_PARSER_INCLUDE_AST_SCRIPT_FUNCTION_H 17 #define ES2PANDA_PARSER_INCLUDE_AST_SCRIPT_FUNCTION_H 18 19 #include "checker/types/signature.h" 20 #include "ir/annotationAllowed.h" 21 #include "ir/jsDocAllowed.h" 22 #include "ir/statements/returnStatement.h" 23 #include "ir/astNode.h" 24 #include "scriptFunctionSignature.h" 25 #include "util/enumbitops.h" 26 #include "util/language.h" 27 #include "varbinder/scope.h" 28 29 namespace ark::es2panda::checker { 30 class Signature; 31 32 } // namespace ark::es2panda::checker 33 34 namespace ark::es2panda::ir { 35 class TSTypeParameterDeclaration; 36 class TypeNode; 37 class AnnotationUsage; 38 class FunctionSignature; 39 40 class ScriptFunction : public JsDocAllowed<AnnotationAllowed<AstNode>> { 41 public: 42 // Need to reduce the number of constructor parameters to pass OHOS CI code check 43 struct ScriptFunctionData { 44 AstNode *body = nullptr; 45 FunctionSignature &&signature; 46 ir::ScriptFunctionFlags funcFlags = ir::ScriptFunctionFlags::NONE; 47 ir::ModifierFlags flags = ir::ModifierFlags::NONE; 48 ark::es2panda::Language lang {Language::Id::ETS}; 49 }; 50 51 ScriptFunction() = delete; 52 ~ScriptFunction() override = default; 53 54 NO_COPY_SEMANTIC(ScriptFunction); 55 NO_MOVE_SEMANTIC(ScriptFunction); 56 57 explicit ScriptFunction(ArenaAllocator *allocator, ScriptFunctionData &&data); 58 Id()59 [[nodiscard]] const Identifier *Id() const noexcept 60 { 61 return id_; 62 } 63 Id()64 [[nodiscard]] Identifier *Id() noexcept 65 { 66 return id_; 67 } 68 Signature()69 [[nodiscard]] const checker::Signature *Signature() const noexcept 70 { 71 return signature_; 72 } 73 Signature()74 [[nodiscard]] checker::Signature *Signature() noexcept 75 { 76 return signature_; 77 } 78 Params()79 [[nodiscard]] const ArenaVector<ir::Expression *> &Params() const noexcept 80 { 81 return irSignature_.Params(); 82 } 83 Params()84 [[nodiscard]] ArenaVector<ir::Expression *> &Params() noexcept 85 { 86 return irSignature_.Params(); 87 } 88 ReturnStatements()89 const ArenaVector<ReturnStatement *> &ReturnStatements() const 90 { 91 return returnStatements_; 92 } 93 ReturnStatements()94 ArenaVector<ReturnStatement *> &ReturnStatements() 95 { 96 return returnStatements_; 97 } 98 TypeParams()99 [[nodiscard]] const TSTypeParameterDeclaration *TypeParams() const noexcept 100 { 101 return irSignature_.TypeParams(); 102 } 103 TypeParams()104 [[nodiscard]] TSTypeParameterDeclaration *TypeParams() noexcept 105 { 106 return irSignature_.TypeParams(); 107 } 108 Body()109 [[nodiscard]] const AstNode *Body() const noexcept 110 { 111 return body_; 112 } 113 Body()114 [[nodiscard]] AstNode *Body() noexcept 115 { 116 return body_; 117 } 118 AddReturnStatement(ReturnStatement * returnStatement)119 void AddReturnStatement(ReturnStatement *returnStatement) 120 { 121 returnStatements_.push_back(returnStatement); 122 } 123 SetBody(AstNode * body)124 void SetBody(AstNode *body) noexcept 125 { 126 body_ = body; 127 } 128 ReturnTypeAnnotation()129 [[nodiscard]] const TypeNode *ReturnTypeAnnotation() const noexcept 130 { 131 return irSignature_.ReturnType(); 132 } 133 ReturnTypeAnnotation()134 [[nodiscard]] TypeNode *ReturnTypeAnnotation() noexcept 135 { 136 return irSignature_.ReturnType(); 137 } 138 139 void SetReturnTypeAnnotation(TypeNode *node) noexcept; 140 IsEntryPoint()141 [[nodiscard]] bool IsEntryPoint() const noexcept 142 { 143 return (funcFlags_ & ir::ScriptFunctionFlags::ENTRY_POINT) != 0; 144 } 145 IsGenerator()146 [[nodiscard]] bool IsGenerator() const noexcept 147 { 148 return (funcFlags_ & ir::ScriptFunctionFlags::GENERATOR) != 0; 149 } 150 IsAsyncFunc()151 [[nodiscard]] bool IsAsyncFunc() const noexcept 152 { 153 return (funcFlags_ & ir::ScriptFunctionFlags::ASYNC) != 0; 154 } 155 IsAsyncImplFunc()156 [[nodiscard]] bool IsAsyncImplFunc() const noexcept 157 { 158 return (funcFlags_ & ir::ScriptFunctionFlags::ASYNC_IMPL) != 0; 159 } 160 IsArrow()161 [[nodiscard]] bool IsArrow() const noexcept 162 { 163 return (funcFlags_ & ir::ScriptFunctionFlags::ARROW) != 0; 164 } 165 IsOverload()166 [[nodiscard]] bool IsOverload() const noexcept 167 { 168 return (funcFlags_ & ir::ScriptFunctionFlags::OVERLOAD) != 0; 169 } 170 IsExternalOverload()171 [[nodiscard]] bool IsExternalOverload() const 172 { 173 return (funcFlags_ & ir::ScriptFunctionFlags::EXTERNAL_OVERLOAD) != 0; 174 } 175 IsConstructor()176 [[nodiscard]] bool IsConstructor() const noexcept 177 { 178 return (funcFlags_ & ir::ScriptFunctionFlags::CONSTRUCTOR) != 0; 179 } 180 IsGetter()181 [[nodiscard]] bool IsGetter() const noexcept 182 { 183 return (funcFlags_ & ir::ScriptFunctionFlags::GETTER) != 0; 184 } 185 IsSetter()186 [[nodiscard]] bool IsSetter() const noexcept 187 { 188 return (funcFlags_ & ir::ScriptFunctionFlags::SETTER) != 0; 189 } 190 IsExtensionAccessor()191 [[nodiscard]] bool IsExtensionAccessor() const noexcept 192 { 193 return IsExtensionMethod() && (IsGetter() || IsSetter()); 194 } 195 IsMethod()196 [[nodiscard]] bool IsMethod() const noexcept 197 { 198 return (funcFlags_ & ir::ScriptFunctionFlags::METHOD) != 0; 199 } 200 IsProxy()201 [[nodiscard]] bool IsProxy() const noexcept 202 { 203 return (funcFlags_ & ir::ScriptFunctionFlags::PROXY) != 0; 204 } 205 IsStaticBlock()206 [[nodiscard]] bool IsStaticBlock() const noexcept 207 { 208 return (funcFlags_ & ir::ScriptFunctionFlags::STATIC_BLOCK) != 0; 209 } 210 IsEnum()211 [[nodiscard]] bool IsEnum() const noexcept 212 { 213 return (funcFlags_ & ir::ScriptFunctionFlags::ENUM) != 0; 214 } 215 IsHidden()216 [[nodiscard]] bool IsHidden() const noexcept 217 { 218 return (funcFlags_ & ir::ScriptFunctionFlags::HIDDEN) != 0; 219 } 220 IsExternal()221 [[nodiscard]] bool IsExternal() const noexcept 222 { 223 return (funcFlags_ & ir::ScriptFunctionFlags::EXTERNAL) != 0; 224 } 225 IsImplicitSuperCallNeeded()226 [[nodiscard]] bool IsImplicitSuperCallNeeded() const noexcept 227 { 228 return (funcFlags_ & ir::ScriptFunctionFlags::IMPLICIT_SUPER_CALL_NEEDED) != 0; 229 } 230 HasBody()231 [[nodiscard]] bool HasBody() const noexcept 232 { 233 return body_ != nullptr; 234 } 235 HasRestParameter()236 [[nodiscard]] bool HasRestParameter() const noexcept 237 { 238 return signature_->RestVar() != nullptr; 239 } 240 HasReturnStatement()241 [[nodiscard]] bool HasReturnStatement() const noexcept 242 { 243 return (funcFlags_ & ir::ScriptFunctionFlags::HAS_RETURN) != 0; 244 } 245 HasThrowStatement()246 [[nodiscard]] bool HasThrowStatement() const noexcept 247 { 248 return (funcFlags_ & ir::ScriptFunctionFlags::HAS_THROW) != 0; 249 } 250 IsThrowing()251 [[nodiscard]] bool IsThrowing() const noexcept 252 { 253 return (funcFlags_ & ir::ScriptFunctionFlags::THROWS) != 0; 254 } 255 IsRethrowing()256 [[nodiscard]] bool IsRethrowing() const noexcept 257 { 258 return (funcFlags_ & ir::ScriptFunctionFlags::RETHROWS) != 0; 259 } 260 IsDynamic()261 [[nodiscard]] bool IsDynamic() const noexcept 262 { 263 return lang_.IsDynamic(); 264 } 265 266 // Note: This method has been written into CAPI, cannot remove it simply. IsExtensionMethod()267 [[nodiscard]] bool IsExtensionMethod() const noexcept 268 { 269 return HasReceiver(); 270 } 271 Flags()272 [[nodiscard]] ir::ScriptFunctionFlags Flags() const noexcept 273 { 274 return funcFlags_; 275 } 276 HasReceiver()277 [[nodiscard]] bool HasReceiver() const noexcept 278 { 279 return irSignature_.HasReceiver(); 280 } 281 282 void SetIdent(Identifier *id) noexcept; 283 SetSignature(checker::Signature * signature)284 void SetSignature(checker::Signature *signature) noexcept 285 { 286 signature_ = signature; 287 } 288 AddFlag(ir::ScriptFunctionFlags flags)289 void AddFlag(ir::ScriptFunctionFlags flags) noexcept 290 { 291 funcFlags_ |= flags; 292 } 293 ClearFlag(ir::ScriptFunctionFlags flags)294 void ClearFlag(ir::ScriptFunctionFlags flags) noexcept 295 { 296 funcFlags_ &= (~flags); 297 } 298 AddModifier(ir::ModifierFlags flags)299 void AddModifier(ir::ModifierFlags flags) noexcept 300 { 301 flags_ |= flags; 302 } 303 304 [[nodiscard]] std::size_t FormalParamsLength() const noexcept; 305 IsScopeBearer()306 [[nodiscard]] bool IsScopeBearer() const noexcept override 307 { 308 return true; 309 } 310 Scope()311 [[nodiscard]] varbinder::FunctionScope *Scope() const noexcept override 312 { 313 return scope_; 314 } 315 SetScope(varbinder::FunctionScope * scope)316 void SetScope(varbinder::FunctionScope *scope) noexcept 317 { 318 scope_ = scope; 319 } 320 ClearScope()321 void ClearScope() noexcept override 322 { 323 scope_ = nullptr; 324 } 325 Language()326 [[nodiscard]] es2panda::Language Language() const noexcept 327 { 328 return lang_; 329 } 330 SetPreferredReturnType(checker::Type * preferredReturnType)331 void SetPreferredReturnType(checker::Type *preferredReturnType) noexcept 332 { 333 preferredReturnType_ = preferredReturnType; 334 } 335 GetPreferredReturnType()336 [[nodiscard]] checker::Type *GetPreferredReturnType() noexcept 337 { 338 return preferredReturnType_; 339 } 340 GetPreferredReturnType()341 [[nodiscard]] checker::Type const *GetPreferredReturnType() const noexcept 342 { 343 return preferredReturnType_; 344 } 345 346 [[nodiscard]] ScriptFunction *Clone(ArenaAllocator *allocator, AstNode *parent) override; 347 348 void TransformChildren(const NodeTransformer &cb, std::string_view transformationName) override; 349 void Iterate(const NodeTraverser &cb) const override; 350 351 void Dump(ir::AstDumper *dumper) const override; 352 void Dump(ir::SrcDumper *dumper) const override; 353 void Compile(compiler::PandaGen *pg) const override; 354 void Compile(compiler::ETSGen *etsg) const override; 355 checker::Type *Check(checker::TSChecker *checker) override; 356 checker::VerifiedType Check(checker::ETSChecker *checker) override; 357 SetIsolatedDeclgenReturnType(std::string type)358 void SetIsolatedDeclgenReturnType(std::string type) noexcept 359 { 360 isolatedDeclGenInferType_ = std::move(type); 361 } 362 GetIsolatedDeclgenReturnType()363 [[nodiscard]] std::string GetIsolatedDeclgenReturnType() const noexcept 364 { 365 return isolatedDeclGenInferType_; 366 } 367 Accept(ASTVisitorT * v)368 void Accept(ASTVisitorT *v) override 369 { 370 v->Accept(this); 371 } 372 CleanUp()373 void CleanUp() override 374 { 375 AstNode::CleanUp(); 376 signature_ = nullptr; 377 preferredReturnType_ = nullptr; 378 } 379 380 protected: 381 ScriptFunction *Construct(ArenaAllocator *allocator) override; 382 void CopyTo(AstNode *other) const override; 383 384 private: 385 void DumpBody(ir::SrcDumper *dumper) const; 386 void DumpCheckerTypeForDeclGen(ir::SrcDumper *dumper) const; 387 friend class SizeOfNodeTest; 388 Identifier *id_ {}; 389 FunctionSignature irSignature_; 390 AstNode *body_; 391 varbinder::FunctionScope *scope_ {nullptr}; 392 ir::ScriptFunctionFlags funcFlags_; 393 checker::Signature *signature_ {}; 394 checker::Type *preferredReturnType_ {}; 395 es2panda::Language lang_; 396 ArenaVector<ReturnStatement *> returnStatements_; 397 std::string isolatedDeclGenInferType_; 398 }; 399 } // namespace ark::es2panda::ir 400 401 #endif 402