1 /** 2 * Copyright (c) 2021 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/astNode.h> 20 #include <ir/expressions/identifier.h> 21 #include <util/enumbitops.h> 22 23 namespace panda::es2panda::compiler { 24 class PandaGen; 25 } // namespace panda::es2panda::compiler 26 27 namespace panda::es2panda::checker { 28 class Checker; 29 class Type; 30 } // namespace panda::es2panda::checker 31 32 namespace panda::es2panda::binder { 33 class FunctionScope; 34 } // namespace panda::es2panda::binder 35 36 namespace panda::es2panda::ir { 37 38 class TSTypeParameterDeclaration; 39 40 class ScriptFunction : public AstNode { 41 public: ScriptFunction(binder::FunctionScope * scope,ArenaVector<Expression * > && params,TSTypeParameterDeclaration * typeParams,AstNode * body,Expression * returnTypeAnnotation,ir::ScriptFunctionFlags flags,bool declare,bool isTsFunction)42 explicit ScriptFunction(binder::FunctionScope *scope, ArenaVector<Expression *> &¶ms, 43 TSTypeParameterDeclaration *typeParams, AstNode *body, Expression *returnTypeAnnotation, 44 ir::ScriptFunctionFlags flags, bool declare, bool isTsFunction) 45 : AstNode(AstNodeType::SCRIPT_FUNCTION), 46 scope_(scope), 47 id_(nullptr), 48 params_(std::move(params)), 49 typeParams_(typeParams), 50 body_(body), 51 returnTypeAnnotation_(returnTypeAnnotation), 52 flags_(flags), 53 declare_(declare), 54 exportDefault_(false) 55 { 56 thisParam_ = nullptr; 57 if (isTsFunction && !params_.empty()) { 58 auto *firstParam = params_.front(); 59 if (firstParam->IsIdentifier() && firstParam->AsIdentifier()->Name().Is(THIS_PARAM)) { 60 thisParam_ = firstParam; 61 params_.erase(params_.begin()); 62 scope_->ParamScope()->RemoveThisParam(THIS_PARAM); 63 scope_->Bindings().erase(THIS_PARAM); 64 } 65 } 66 } 67 Id()68 const Identifier *Id() const 69 { 70 return id_; 71 } 72 Id()73 Identifier *Id() 74 { 75 return id_; 76 } 77 Params()78 const ArenaVector<Expression *> &Params() const 79 { 80 return params_; 81 } 82 Params()83 ArenaVector<Expression *> &Params() 84 { 85 return params_; 86 } 87 TypeParams()88 const TSTypeParameterDeclaration *TypeParams() const 89 { 90 return typeParams_; 91 } 92 TypeParams()93 TSTypeParameterDeclaration *TypeParams() 94 { 95 return typeParams_; 96 } 97 ThisParams()98 const Expression *ThisParams() const 99 { 100 return thisParam_; 101 } 102 ThisParams()103 Expression *ThisParams() 104 { 105 return thisParam_; 106 } 107 Body()108 const AstNode *Body() const 109 { 110 return body_; 111 } 112 Body()113 AstNode *Body() 114 { 115 return body_; 116 } 117 ReturnTypeAnnotation()118 const Expression *ReturnTypeAnnotation() const 119 { 120 return returnTypeAnnotation_; 121 } 122 ReturnTypeAnnotation()123 Expression *ReturnTypeAnnotation() 124 { 125 return returnTypeAnnotation_; 126 } 127 IsGenerator()128 bool IsGenerator() const 129 { 130 return (flags_ & ir::ScriptFunctionFlags::GENERATOR) != 0; 131 } 132 IsAsync()133 bool IsAsync() const 134 { 135 return (flags_ & ir::ScriptFunctionFlags::ASYNC) != 0; 136 } 137 IsArrow()138 bool IsArrow() const 139 { 140 return (flags_ & ir::ScriptFunctionFlags::ARROW) != 0; 141 } 142 IsOverload()143 bool IsOverload() const 144 { 145 return (flags_ & ir::ScriptFunctionFlags::OVERLOAD) != 0; 146 } 147 IsConstructor()148 bool IsConstructor() const 149 { 150 return (flags_ & ir::ScriptFunctionFlags::CONSTRUCTOR) != 0; 151 } 152 IsStaticInitializer()153 bool IsStaticInitializer() const 154 { 155 return (flags_ & ir::ScriptFunctionFlags::STATIC_INITIALIZER) != 0; 156 } 157 IsInstanceInitializer()158 bool IsInstanceInitializer() const 159 { 160 return (flags_ & ir::ScriptFunctionFlags::INSTANCE_INITIALIZER) != 0; 161 } 162 IsMethod()163 bool IsMethod() const 164 { 165 return (flags_ & ir::ScriptFunctionFlags::METHOD) != 0 || IsInstanceInitializer() || IsStaticInitializer(); 166 } 167 FunctionBodyIsExpression()168 bool FunctionBodyIsExpression() const 169 { 170 return (flags_ & ir::ScriptFunctionFlags::EXPRESSION) != 0; 171 } 172 Declare()173 bool Declare() const 174 { 175 return declare_; 176 } 177 SetIdent(Identifier * id)178 void SetIdent(Identifier *id) 179 { 180 id_ = id; 181 } 182 SetAsExportDefault()183 void SetAsExportDefault() 184 { 185 exportDefault_ = true; 186 } 187 AddFlag(ir::ScriptFunctionFlags flags)188 void AddFlag(ir::ScriptFunctionFlags flags) 189 { 190 flags_ |= flags; 191 } 192 193 size_t FormalParamsLength() const; 194 util::StringView GetName() const; 195 Scope()196 binder::FunctionScope *Scope() const 197 { 198 return scope_; 199 } 200 IsConcurrent()201 bool IsConcurrent() const 202 { 203 return (flags_ & ir::ScriptFunctionFlags::CONCURRENT) != 0; 204 } 205 ShowSource()206 bool ShowSource() const 207 { 208 return (flags_ & ir::ScriptFunctionFlags::SHOW_SOURCE) != 0; 209 } 210 CanBeConcurrent()211 bool CanBeConcurrent() const 212 { 213 return !(IsGenerator() || IsArrow()); 214 } 215 AddConcurrentModuleRequest(int moduleRequestId)216 void AddConcurrentModuleRequest(int moduleRequestId) 217 { 218 if (!IsConcurrent()) { 219 return; 220 } 221 222 concurrentModuleRequests_.emplace_back(moduleRequestId); 223 } 224 GetConcurrentModuleRequests()225 std::vector<int> GetConcurrentModuleRequests() const 226 { 227 return concurrentModuleRequests_; 228 } 229 230 void Iterate(const NodeTraverser &cb) const override; 231 void Dump(ir::AstDumper *dumper) const override; 232 void Compile([[maybe_unused]] compiler::PandaGen *pg) const override; 233 checker::Type *Check([[maybe_unused]] checker::Checker *checker) const override; 234 void UpdateSelf(const NodeUpdater &cb, binder::Binder *binder) override; 235 util::StringView SourceCode(binder::Binder *binder) const; 236 237 private: 238 static constexpr std::string_view THIS_PARAM = "this"; 239 240 binder::FunctionScope *scope_; 241 Identifier *id_; 242 Expression *thisParam_; 243 ArenaVector<Expression *> params_; 244 TSTypeParameterDeclaration *typeParams_; 245 AstNode *body_; 246 Expression *returnTypeAnnotation_; 247 ir::ScriptFunctionFlags flags_; 248 bool declare_; 249 bool exportDefault_; 250 std::vector<int> concurrentModuleRequests_; 251 }; 252 253 } // namespace panda::es2panda::ir 254 255 #endif 256