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 "identifier.h" 17 18#include "checker/ETSchecker.h" 19#include "checker/TSchecker.h" 20#include "compiler/core/pandagen.h" 21#include "compiler/core/ETSGen.h" 22#include "ir/astDump.h" 23#include "ir/srcDump.h" 24 25namespace ark::es2panda::ir { 26Identifier::Identifier([[maybe_unused]] Tag const tag, Identifier const &other, ArenaAllocator *const allocator) 27 : AnnotatedExpression(static_cast<AnnotatedExpression const &>(other), allocator), decorators_(allocator->Adapter()) 28{ 29 name_ = other.name_; 30 flags_ = other.flags_; 31 32 for (auto *decorator : other.decorators_) { 33 decorators_.emplace_back(decorator->Clone(allocator, this)); 34 } 35} 36 37Identifier *Identifier::Clone(ArenaAllocator *const allocator, AstNode *const parent) 38{ 39 if (auto *const clone = allocator->New<Identifier>(Tag {}, *this, allocator); clone != nullptr) { 40 clone->SetTsType(TsType()); 41 if (parent != nullptr) { 42 clone->SetParent(parent); 43 } 44 45 if (this->IsReference()) { 46 clone->SetReference(); 47 } 48 49 clone->SetRange(Range()); 50 51 return clone; 52 } 53 throw Error(ErrorType::GENERIC, "", CLONE_ALLOCATION_ERROR); 54} 55 56void Identifier::TransformChildren(const NodeTransformer &cb, std::string_view const transformationName) 57{ 58 if (auto *typeAnnotation = TypeAnnotation(); typeAnnotation != nullptr) { 59 if (auto *transformedNode = cb(typeAnnotation); typeAnnotation != transformedNode) { 60 typeAnnotation->SetTransformedNode(transformationName, transformedNode); 61 SetTsTypeAnnotation(static_cast<TypeNode *>(transformedNode)); 62 } 63 } 64 65 for (auto *&it : decorators_) { 66 if (auto *transformedNode = cb(it); it != transformedNode) { 67 it->SetTransformedNode(transformationName, transformedNode); 68 it = transformedNode->AsDecorator(); 69 } 70 } 71} 72 73void Identifier::Iterate(const NodeTraverser &cb) const 74{ 75 if (TypeAnnotation() != nullptr) { 76 cb(TypeAnnotation()); 77 } 78 79 for (auto *it : decorators_) { 80 cb(it); 81 } 82} 83 84ValidationInfo Identifier::ValidateExpression() 85{ 86 if ((flags_ & IdentifierFlags::OPTIONAL) != 0U) { 87 return {"Unexpected token '?'.", Start()}; 88 } 89 90 if (TypeAnnotation() != nullptr) { 91 return {"Unexpected token.", TypeAnnotation()->Start()}; 92 } 93 94 ValidationInfo info; 95 return info; 96} 97 98void Identifier::Dump(ir::AstDumper *dumper) const 99{ 100 dumper->Add({{"type", IsPrivateIdent() ? "PrivateIdentifier" : "Identifier"}, 101 {"name", name_}, 102 {"typeAnnotation", AstDumper::Optional(TypeAnnotation())}, 103 {"optional", AstDumper::Optional(IsOptional())}, 104 {"decorators", decorators_}}); 105} 106 107void Identifier::Dump(ir::SrcDumper *dumper) const 108{ 109 if (IsPrivateIdent()) { 110 dumper->Add("private "); 111 } 112 dumper->Add(std::string(name_)); 113 if (IsOptional()) { 114 dumper->Add("?"); 115 } 116} 117 118void Identifier::Compile(compiler::PandaGen *pg) const 119{ 120 pg->GetAstCompiler()->Compile(this); 121} 122 123void Identifier::Compile(compiler::ETSGen *etsg) const 124{ 125 etsg->GetAstCompiler()->Compile(this); 126} 127 128checker::Type *Identifier::Check(checker::TSChecker *checker) 129{ 130 return checker->GetAnalyzer()->Check(this); 131} 132 133checker::Type *Identifier::Check(checker::ETSChecker *checker) 134{ 135 return checker->GetAnalyzer()->Check(this); 136} 137} // namespace ark::es2panda::ir 138