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 "newExpression.h" 17 18#include <util/helpers.h> 19#include <compiler/core/pandagen.h> 20#include <compiler/core/regScope.h> 21#include <typescript/checker.h> 22#include <ir/astDump.h> 23#include <ir/ts/tsTypeParameterInstantiation.h> 24 25namespace panda::es2panda::ir { 26 27void NewExpression::Iterate(const NodeTraverser &cb) const 28{ 29 cb(callee_); 30 31 if (typeParams_) { 32 cb(typeParams_); 33 } 34 35 for (auto *it : arguments_) { 36 cb(it); 37 } 38} 39 40void NewExpression::Dump(ir::AstDumper *dumper) const 41{ 42 dumper->Add({{"type", "NewExpression"}, {"callee", callee_}, {"typeParameters", AstDumper::Optional(typeParams_)}, 43 {"arguments", arguments_}}); 44} 45 46void NewExpression::Compile(compiler::PandaGen *pg) const 47{ 48 compiler::RegScope rs(pg); 49 compiler::VReg ctor = pg->AllocReg(); 50 51 callee_->Compile(pg); 52 pg->StoreAccumulator(this, ctor); 53 54 if (!util::Helpers::ContainSpreadElement(arguments_)) { 55 for (const auto *it : arguments_) { 56 compiler::VReg arg = pg->AllocReg(); 57 it->Compile(pg); 58 pg->StoreAccumulator(this, arg); 59 } 60 61 pg->NewObject(this, ctor, arguments_.size() + 1); 62 } else { 63 compiler::VReg argsObj = pg->AllocReg(); 64 65 pg->CreateArray(this, arguments_, argsObj); 66 pg->NewObjSpread(this, ctor); 67 } 68} 69 70checker::Type *NewExpression::Check(checker::Checker *checker) const 71{ 72 checker::Type *calleeType = callee_->Check(checker); 73 74 // TODO(aszilagyi): handle optional chain 75 if (calleeType->IsObjectType()) { 76 checker::ObjectType *calleeObj = calleeType->AsObjectType(); 77 return checker->resolveCallOrNewExpression(calleeObj->ConstructSignatures(), arguments_, Start()); 78 } 79 80 checker->ThrowTypeError("This expression is not callable.", Start()); 81 return nullptr; 82} 83 84void NewExpression::UpdateSelf(const NodeUpdater &cb, [[maybe_unused]] binder::Binder *binder) 85{ 86 callee_ = std::get<ir::AstNode *>(cb(callee_))->AsExpression(); 87 88 for (auto iter = arguments_.begin(); iter != arguments_.end(); iter++) { 89 *iter = std::get<ir::AstNode *>(cb(*iter))->AsExpression(); 90 } 91} 92 93} // namespace panda::es2panda::ir 94