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