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#include "scriptFunction.h" 17 18#include <binder/binder.h> 19#include <binder/scope.h> 20#include <ir/astDump.h> 21#include <ir/base/methodDefinition.h> 22#include <ir/expression.h> 23#include <ir/expressions/identifier.h> 24#include <ir/statements/blockStatement.h> 25#include <ir/ts/tsTypeParameter.h> 26#include <ir/ts/tsTypeParameterDeclaration.h> 27 28namespace panda::es2panda::ir { 29 30size_t ScriptFunction::FormalParamsLength() const 31{ 32 size_t length = 0; 33 34 for (const auto *param : params_) { 35 if (param->IsRestElement() || param->IsAssignmentPattern()) { 36 break; 37 } 38 39 length++; 40 } 41 42 return length; 43} 44 45util::StringView ScriptFunction::GetName() const 46{ 47 if (id_) { 48 return id_->Name(); 49 } 50 51 if (exportDefault_) { 52 return parser::SourceTextModuleRecord::DEFAULT_LOCAL_NAME; 53 } 54 55 return ""; 56} 57 58void ScriptFunction::Iterate(const NodeTraverser &cb) const 59{ 60 if (id_) { 61 cb(id_); 62 } 63 64 if (typeParams_) { 65 cb(typeParams_); 66 } 67 68 if (thisParam_) { 69 cb(thisParam_); 70 } 71 72 for (auto *it : params_) { 73 cb(it); 74 } 75 76 if (returnTypeAnnotation_) { 77 cb(returnTypeAnnotation_); 78 } 79 80 if (body_) { 81 cb(body_); 82 } 83} 84 85void ScriptFunction::Dump(ir::AstDumper *dumper) const 86{ 87 dumper->Add({{"type", "ScriptFunction"}, 88 {"id", AstDumper::Nullable(id_)}, 89 {"generator", IsGenerator()}, 90 {"async", IsAsync()}, 91 {"expression", ((flags_ & ir::ScriptFunctionFlags::EXPRESSION) != 0)}, 92 {"thisParam", AstDumper::Optional(thisParam_)}, 93 {"params", params_}, 94 {"returnType", AstDumper::Optional(returnTypeAnnotation_)}, 95 {"typeParameters", AstDumper::Optional(typeParams_)}, 96 {"declare", AstDumper::Optional(declare_)}, 97 {"body", AstDumper::Optional(body_)}}); 98} 99 100void ScriptFunction::Compile([[maybe_unused]] compiler::PandaGen *pg) const {} 101 102checker::Type *ScriptFunction::Check([[maybe_unused]] checker::Checker *checker) const 103{ 104 return nullptr; 105} 106 107void ScriptFunction::UpdateSelf(const NodeUpdater &cb, binder::Binder *binder) 108{ 109 if (id_) { 110 id_ = std::get<ir::AstNode *>(cb(id_))->AsIdentifier(); 111 } 112 113 auto paramScopeCtx = binder::LexicalScope<binder::FunctionParamScope>::Enter(binder, scope_->ParamScope()); 114 115 if (typeParams_) { 116 typeParams_ = std::get<ir::AstNode *>(cb(typeParams_))->AsTSTypeParameterDeclaration(); 117 } 118 119 if (thisParam_) { 120 thisParam_ = std::get<ir::AstNode *>(cb(thisParam_))->AsExpression(); 121 } 122 123 for (auto iter = params_.begin(); iter != params_.end(); iter++) { 124 *iter = std::get<ir::AstNode *>(cb(*iter))->AsExpression(); 125 } 126 127 if (returnTypeAnnotation_) { 128 returnTypeAnnotation_ = std::get<ir::AstNode *>(cb(returnTypeAnnotation_))->AsExpression(); 129 } 130 131 auto scopeCtx = binder::LexicalScope<binder::FunctionScope>::Enter(binder, scope_); 132 133 if (body_) { 134 body_ = std::get<ir::AstNode *>(cb(body_)); 135 } 136} 137 138util::StringView ScriptFunction::SourceCode(binder::Binder *binder) const 139{ 140 auto *funcNode = this->Parent(); 141 if (funcNode->IsFunctionExpression() && 142 funcNode->Parent()->IsMethodDefinition() && 143 funcNode->Parent()->AsMethodDefinition()->Value() == funcNode->AsFunctionExpression()) { 144 funcNode = funcNode->Parent(); 145 } 146 147 auto startIndex = funcNode->Start().index; 148 auto endIndex = funcNode->End().index; 149 return binder->Program()->SourceCode().Substr(startIndex, endIndex); 150} 151 152} // namespace panda::es2panda::ir 153