1 /*
2 * Copyright (c) 2021-2025 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 "etsUnionType.h"
17
18 #include "checker/ETSchecker.h"
19
20 namespace ark::es2panda::ir {
TransformChildren(const NodeTransformer & cb,std::string_view const transformationName)21 void ETSUnionType::TransformChildren(const NodeTransformer &cb, std::string_view const transformationName)
22 {
23 for (auto *&it : VectorIterationGuard(types_)) {
24 if (auto *transformedNode = cb(it); it != transformedNode) {
25 it->SetTransformedNode(transformationName, transformedNode);
26 it = static_cast<TypeNode *>(transformedNode);
27 }
28 }
29 for (auto *&it : VectorIterationGuard(Annotations())) {
30 if (auto *transformedNode = cb(it); it != transformedNode) {
31 it->SetTransformedNode(transformationName, transformedNode);
32 it = transformedNode->AsAnnotationUsage();
33 }
34 }
35 }
36
Iterate(const NodeTraverser & cb) const37 void ETSUnionType::Iterate(const NodeTraverser &cb) const
38 {
39 for (auto *it : VectorIterationGuard(types_)) {
40 cb(it);
41 }
42
43 for (auto *it : VectorIterationGuard(Annotations())) {
44 cb(it);
45 }
46 }
47
Dump(ir::AstDumper * dumper) const48 void ETSUnionType::Dump(ir::AstDumper *dumper) const
49 {
50 dumper->Add({{"type", "ETSUnionType"}, {"types", types_}, {"annotations", AstDumper::Optional(Annotations())}});
51 }
52
Dump(ir::SrcDumper * dumper) const53 void ETSUnionType::Dump(ir::SrcDumper *dumper) const
54 {
55 for (auto *anno : Annotations()) {
56 anno->Dump(dumper);
57 }
58 for (auto type : types_) {
59 type->Dump(dumper);
60 if (type != types_.back()) {
61 dumper->Add(" | ");
62 }
63 }
64 }
65
Compile(compiler::PandaGen * pg) const66 void ETSUnionType::Compile([[maybe_unused]] compiler::PandaGen *pg) const {}
67
Check(checker::TSChecker * checker)68 checker::Type *ETSUnionType::Check([[maybe_unused]] checker::TSChecker *checker)
69 {
70 return nullptr;
71 }
72
Check(checker::ETSChecker * checker)73 checker::VerifiedType ETSUnionType::Check(checker::ETSChecker *checker)
74 {
75 for (auto *it : types_) {
76 it->Check(checker);
77 }
78
79 return {this, GetType(checker)};
80 }
81
CheckConstituentTypesValid(ArenaVector<checker::Type * > const & constituentTypes)82 static bool CheckConstituentTypesValid(ArenaVector<checker::Type *> const &constituentTypes)
83 {
84 for (auto &it : constituentTypes) {
85 if (it->IsTypeError()) {
86 return false;
87 }
88 }
89 return true;
90 }
91
GetType(checker::ETSChecker * checker)92 checker::Type *ETSUnionType::GetType(checker::ETSChecker *checker)
93 {
94 if (TsType() != nullptr) {
95 return TsType();
96 }
97 checker->CheckAnnotations(Annotations());
98
99 ArenaVector<checker::Type *> types(checker->Allocator()->Adapter());
100
101 for (auto *it : types_) {
102 types.push_back(it->GetType(checker));
103 }
104
105 checker->Relation()->SetNode(this);
106 if (!CheckConstituentTypesValid(types)) {
107 SetTsType(checker->GlobalTypeError());
108 } else {
109 SetTsType(checker->CreateETSUnionType(std::move(types)));
110 }
111 checker->Relation()->SetNode(nullptr);
112 return TsType();
113 }
114
Clone(ArenaAllocator * const allocator,AstNode * const parent)115 ETSUnionType *ETSUnionType::Clone(ArenaAllocator *const allocator, AstNode *const parent)
116 {
117 ArenaVector<ir::TypeNode *> types(allocator->Adapter());
118 for (auto *it : types_) {
119 auto *type = it->Clone(allocator, nullptr);
120 types.push_back(type);
121 }
122 ETSUnionType *const clone = allocator->New<ir::ETSUnionType>(std::move(types), allocator);
123
124 if (parent != nullptr) {
125 clone->SetParent(parent);
126 }
127 if (!Annotations().empty()) {
128 ArenaVector<AnnotationUsage *> annotationUsages {allocator->Adapter()};
129 for (auto *annotationUsage : Annotations()) {
130 ES2PANDA_ASSERT(annotationUsage->Clone(allocator, clone));
131 annotationUsages.push_back(annotationUsage->Clone(allocator, clone)->AsAnnotationUsage());
132 }
133 clone->SetAnnotations(std::move(annotationUsages));
134 }
135 for (auto *it : clone->types_) {
136 it->SetParent(clone);
137 }
138
139 clone->SetRange(Range());
140 return clone;
141 }
142 } // namespace ark::es2panda::ir
143