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 "catchClause.h" 17 18#include <binder/binder.h> 19#include <binder/scope.h> 20#include <compiler/core/pandagen.h> 21#include <compiler/base/lreference.h> 22#include <typescript/checker.h> 23#include <typescript/types/type.h> 24#include <ir/astDump.h> 25#include <ir/expression.h> 26#include <ir/expressions/arrayExpression.h> 27#include <ir/expressions/identifier.h> 28#include <ir/expressions/objectExpression.h> 29#include <ir/statements/blockStatement.h> 30 31namespace panda::es2panda::ir { 32 33void CatchClause::Iterate(const NodeTraverser &cb) const 34{ 35 if (param_) { 36 cb(param_); 37 } 38 39 cb(body_); 40} 41 42void CatchClause::Dump(ir::AstDumper *dumper) const 43{ 44 dumper->Add({{"type", "CatchClause"}, {"body", body_}, {"param", AstDumper::Nullable(param_)}}); 45} 46 47void CatchClause::Compile(compiler::PandaGen *pg) const 48{ 49 compiler::LocalRegScope lrs(pg, scope_->ParamScope()); 50 51 if (param_) { 52 auto lref = compiler::LReference::CreateLRef(pg, param_, true); 53 lref.SetValue(); 54 } 55 56 ASSERT(scope_ == body_->Scope()); 57 body_->Compile(pg); 58} 59 60checker::Type *CatchClause::Check(checker::Checker *checker) const 61{ 62 const ir::Expression *typeAnnotation = nullptr; 63 64 if (param_->IsIdentifier()) { 65 typeAnnotation = param_->AsIdentifier()->TypeAnnotation(); 66 } else if (param_->IsArrayPattern()) { 67 typeAnnotation = param_->AsArrayPattern()->TypeAnnotation(); 68 } else { 69 ASSERT(param_->IsObjectPattern()); 70 typeAnnotation = param_->AsObjectPattern()->TypeAnnotation(); 71 } 72 73 if (typeAnnotation) { 74 checker::Type *catchParamType = typeAnnotation->Check(checker); 75 76 if (!catchParamType->HasTypeFlag(checker::TypeFlag::ANY_OR_UNKNOWN)) { 77 checker->ThrowTypeError("Catch clause variable type annotation must be 'any' or 'unknown' if specified", 78 Start()); 79 } 80 } 81 82 body_->Check(checker); 83 84 return nullptr; 85} 86 87void CatchClause::UpdateSelf(const NodeUpdater &cb, binder::Binder *binder) 88{ 89 if (param_) { 90 auto paramScopeCtx = binder::LexicalScope<binder::CatchParamScope>::Enter(binder, scope_->ParamScope()); 91 param_ = std::get<ir::AstNode *>(cb(param_))->AsExpression(); 92 } 93 94 auto scopeCtx = binder::LexicalScope<binder::CatchScope>::Enter(binder, scope_); 95 body_ = std::get<ir::AstNode *>(cb(body_))->AsBlockStatement(); 96} 97 98} // namespace panda::es2panda::ir 99