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