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#include "variableDeclaration.h" 17 18#include "macros.h" 19#include "varbinder/variable.h" 20#include "checker/TSchecker.h" 21#include "checker/ETSchecker.h" 22#include "compiler/core/ETSGen.h" 23#include "compiler/core/pandagen.h" 24#include "ir/astDump.h" 25#include "ir/srcDump.h" 26#include "ir/base/decorator.h" 27#include "ir/statements/variableDeclarator.h" 28 29namespace ark::es2panda::ir { 30void VariableDeclaration::TransformChildren(const NodeTransformer &cb, std::string_view transformationName) 31{ 32 for (auto *&it : decorators_) { 33 if (auto *transformedNode = cb(it); it != transformedNode) { 34 it->SetTransformedNode(transformationName, transformedNode); 35 it = transformedNode->AsDecorator(); 36 } 37 } 38 39 for (auto *&it : declarators_) { 40 if (auto *transformedNode = cb(it); it != transformedNode) { 41 it->SetTransformedNode(transformationName, transformedNode); 42 it = transformedNode->AsVariableDeclarator(); 43 } 44 } 45} 46 47void VariableDeclaration::Iterate(const NodeTraverser &cb) const 48{ 49 for (auto *it : decorators_) { 50 cb(it); 51 } 52 53 for (auto *it : declarators_) { 54 cb(it); 55 } 56} 57 58void VariableDeclaration::Dump(ir::AstDumper *dumper) const 59{ 60 const char *kind = nullptr; 61 62 switch (kind_) { 63 case VariableDeclarationKind::CONST: { 64 kind = "const"; 65 break; 66 } 67 case VariableDeclarationKind::LET: { 68 kind = "let"; 69 break; 70 } 71 case VariableDeclarationKind::VAR: { 72 kind = "var"; 73 break; 74 } 75 default: { 76 UNREACHABLE(); 77 } 78 } 79 80 dumper->Add({{"type", "VariableDeclaration"}, 81 {"declarations", declarators_}, 82 {"kind", kind}, 83 {"decorators", AstDumper::Optional(decorators_)}, 84 {"declare", AstDumper::Optional(declare_)}}); 85} 86 87void VariableDeclaration::Dump(ir::SrcDumper *dumper) const 88{ 89 switch (kind_) { 90 case VariableDeclarationKind::CONST: 91 dumper->Add("const "); 92 break; 93 case VariableDeclarationKind::LET: 94 dumper->Add("let "); 95 break; 96 case VariableDeclarationKind::VAR: 97 dumper->Add("var "); 98 break; 99 default: 100 UNREACHABLE(); 101 } 102 103 for (auto declarator : declarators_) { 104 declarator->Dump(dumper); 105 if (declarator != declarators_.back()) { 106 dumper->Add(", "); 107 } 108 } 109 110 if ((parent_ != nullptr) && 111 (parent_->IsBlockStatement() || parent_->IsBlockExpression() || parent_->IsSwitchCaseStatement())) { 112 dumper->Add(";"); 113 } 114} 115 116VariableDeclaration::VariableDeclaration([[maybe_unused]] Tag const tag, VariableDeclaration const &other, 117 ArenaAllocator *const allocator) 118 : Statement(static_cast<Statement const &>(other)), 119 kind_(other.kind_), 120 decorators_(allocator->Adapter()), 121 declarators_(allocator->Adapter()), 122 declare_(other.declare_) 123{ 124 for (auto const &d : other.decorators_) { 125 decorators_.emplace_back(d->Clone(allocator, nullptr)); 126 decorators_.back()->SetParent(this); 127 } 128 129 for (auto const &d : other.declarators_) { 130 declarators_.emplace_back(d->Clone(allocator, nullptr)->AsVariableDeclarator()); 131 declarators_.back()->SetParent(this); 132 } 133} 134 135VariableDeclaration *VariableDeclaration::Clone(ArenaAllocator *const allocator, AstNode *const parent) 136{ 137 if (auto *const clone = allocator->New<VariableDeclaration>(Tag {}, *this, allocator); clone != nullptr) { 138 if (parent != nullptr) { 139 clone->SetParent(parent); 140 } 141 return clone; 142 } 143 throw Error(ErrorType::GENERIC, "", CLONE_ALLOCATION_ERROR); 144} 145 146void VariableDeclaration::Compile(compiler::PandaGen *pg) const 147{ 148 pg->GetAstCompiler()->Compile(this); 149} 150 151void VariableDeclaration::Compile(compiler::ETSGen *etsg) const 152{ 153 etsg->GetAstCompiler()->Compile(this); 154} 155 156checker::Type *VariableDeclaration::Check(checker::TSChecker *checker) 157{ 158 return checker->GetAnalyzer()->Check(this); 159} 160 161checker::Type *VariableDeclaration::Check([[maybe_unused]] checker::ETSChecker *checker) 162{ 163 return checker->GetAnalyzer()->Check(this); 164} 165} // namespace ark::es2panda::ir 166