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 "classProperty.h" 17 18#include "checker/ETSchecker.h" 19#include "checker/TSchecker.h" 20#include "compiler/core/ETSGen.h" 21#include "compiler/core/pandagen.h" 22#include "ir/astDump.h" 23#include "ir/srcDump.h" 24 25namespace ark::es2panda::ir { 26void ClassProperty::TransformChildren(const NodeTransformer &cb, std::string_view const transformationName) 27{ 28 if (auto *transformedNode = cb(key_); key_ != transformedNode) { 29 key_->SetTransformedNode(transformationName, transformedNode); 30 key_ = transformedNode->AsExpression(); 31 } 32 33 if (value_ != nullptr) { 34 if (auto *transformedNode = cb(value_); value_ != transformedNode) { 35 value_->SetTransformedNode(transformationName, transformedNode); 36 value_ = transformedNode->AsExpression(); 37 } 38 } 39 40 if (typeAnnotation_ != nullptr) { 41 if (auto *transformedNode = cb(typeAnnotation_); typeAnnotation_ != transformedNode) { 42 typeAnnotation_->SetTransformedNode(transformationName, transformedNode); 43 typeAnnotation_ = static_cast<TypeNode *>(transformedNode); 44 } 45 } 46 47 for (auto *&it : decorators_) { 48 if (auto *transformedNode = cb(it); it != transformedNode) { 49 it->SetTransformedNode(transformationName, transformedNode); 50 it = transformedNode->AsDecorator(); 51 } 52 } 53} 54 55void ClassProperty::Iterate(const NodeTraverser &cb) const 56{ 57 cb(key_); 58 59 if (value_ != nullptr) { 60 cb(value_); 61 } 62 63 if (typeAnnotation_ != nullptr) { 64 cb(typeAnnotation_); 65 } 66 67 for (auto *it : decorators_) { 68 cb(it); 69 } 70} 71 72void ClassProperty::Dump(ir::AstDumper *dumper) const 73{ 74 dumper->Add({{"type", "ClassProperty"}, 75 {"key", key_}, 76 {"value", AstDumper::Optional(value_)}, 77 {"accessibility", AstDumper::Optional(AstDumper::ModifierToString(flags_))}, 78 {"abstract", AstDumper::Optional(IsAbstract())}, 79 {"static", IsStatic()}, 80 {"readonly", IsReadonly()}, 81 {"declare", IsDeclare()}, 82 {"optional", IsOptionalDeclaration()}, 83 {"computed", isComputed_}, 84 {"typeAnnotation", AstDumper::Optional(typeAnnotation_)}, 85 {"definite", IsDefinite()}, 86 {"decorators", decorators_}}); 87} 88 89void ClassProperty::Dump(ir::SrcDumper *dumper) const 90{ 91 if (Parent() != nullptr && Parent()->IsClassDefinition() && !Parent()->AsClassDefinition()->IsLocal()) { 92 if (IsPrivate()) { 93 dumper->Add("private "); 94 } else if (IsProtected()) { 95 dumper->Add("protected "); 96 } else if (IsInternal()) { 97 dumper->Add("internal "); 98 } else { 99 dumper->Add("public "); 100 } 101 } 102 103 if (IsStatic()) { 104 dumper->Add("static "); 105 } 106 107 if (IsReadonly()) { 108 dumper->Add("readonly "); 109 } 110 111 if (key_ != nullptr) { 112 key_->Dump(dumper); 113 } 114 115 if (IsOptionalDeclaration()) { 116 dumper->Add("?"); 117 } 118 119 if (typeAnnotation_ != nullptr) { 120 dumper->Add(": "); 121 typeAnnotation_->Dump(dumper); 122 } 123 124 if (value_ != nullptr) { 125 dumper->Add(" = "); 126 value_->Dump(dumper); 127 } 128 129 dumper->Add(";"); 130 dumper->Endl(); 131} 132 133void ClassProperty::Compile(compiler::PandaGen *pg) const 134{ 135 pg->GetAstCompiler()->Compile(this); 136} 137 138void ClassProperty::Compile(compiler::ETSGen *etsg) const 139{ 140 etsg->GetAstCompiler()->Compile(this); 141} 142 143checker::Type *ClassProperty::Check(checker::TSChecker *checker) 144{ 145 return checker->GetAnalyzer()->Check(this); 146} 147 148checker::Type *ClassProperty::Check(checker::ETSChecker *checker) 149{ 150 return checker->GetAnalyzer()->Check(this); 151} 152 153ClassProperty *ClassProperty::Clone(ArenaAllocator *const allocator, AstNode *const parent) 154{ 155 auto *const key = key_->Clone(allocator, nullptr)->AsExpression(); 156 auto *const value = value_ != nullptr ? value_->Clone(allocator, nullptr)->AsExpression() : nullptr; 157 auto *const typeAnnotation = typeAnnotation_ != nullptr ? typeAnnotation_->Clone(allocator, nullptr) : nullptr; 158 159 if (auto *const clone = allocator->New<ClassProperty>(key, value, typeAnnotation, flags_, allocator, isComputed_); 160 clone != nullptr) { 161 if (parent != nullptr) { 162 clone->SetParent(parent); 163 } 164 165 key->SetParent(clone); 166 if (value != nullptr) { 167 value->SetParent(clone); 168 } 169 if (typeAnnotation != nullptr) { 170 typeAnnotation->SetParent(clone); 171 } 172 173 for (auto *const decorator : decorators_) { 174 clone->AddDecorator(decorator->Clone(allocator, clone)); 175 } 176 177 return clone; 178 } 179 180 throw Error(ErrorType::GENERIC, "", CLONE_ALLOCATION_ERROR); 181} 182} // namespace ark::es2panda::ir 183