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 "etsUnionType.h"
17
18 #include "checker/ETSchecker.h"
19 #include "ir/astDump.h"
20 #include "ir/srcDump.h"
21 #include "utils/arena_containers.h"
22
23 namespace ark::es2panda::ir {
TransformChildren(const NodeTransformer & cb,std::string_view const transformationName)24 void ETSUnionType::TransformChildren(const NodeTransformer &cb, std::string_view const transformationName)
25 {
26 for (auto *&it : types_) {
27 if (auto *transformedNode = cb(it); it != transformedNode) {
28 it->SetTransformedNode(transformationName, transformedNode);
29 it = static_cast<TypeNode *>(transformedNode);
30 }
31 }
32 }
33
Iterate(const NodeTraverser & cb) const34 void ETSUnionType::Iterate(const NodeTraverser &cb) const
35 {
36 for (auto *it : types_) {
37 cb(it);
38 }
39 }
40
Dump(ir::AstDumper * dumper) const41 void ETSUnionType::Dump(ir::AstDumper *dumper) const
42 {
43 dumper->Add({{"type", "ETSUnionType"}, {"types", types_}});
44 }
45
Dump(ir::SrcDumper * dumper) const46 void ETSUnionType::Dump(ir::SrcDumper *dumper) const
47 {
48 for (auto type : types_) {
49 type->Dump(dumper);
50 if (type != types_.back()) {
51 dumper->Add(" | ");
52 }
53 }
54 }
55
Compile(compiler::PandaGen * pg) const56 void ETSUnionType::Compile([[maybe_unused]] compiler::PandaGen *pg) const {}
57
Check(checker::TSChecker * checker)58 checker::Type *ETSUnionType::Check([[maybe_unused]] checker::TSChecker *checker)
59 {
60 return nullptr;
61 }
62
Check(checker::ETSChecker * checker)63 checker::Type *ETSUnionType::Check(checker::ETSChecker *checker)
64 {
65 for (auto *it : types_) {
66 it->Check(checker);
67 }
68
69 return GetType(checker);
70 }
71
CheckConstituentTypesValid(ArenaVector<checker::Type * > const & constituentTypes)72 static bool CheckConstituentTypesValid(ArenaVector<checker::Type *> const &constituentTypes)
73 {
74 for (auto &it : constituentTypes) {
75 if (it->IsTypeError()) {
76 return false;
77 }
78 }
79 return true;
80 }
81
GetType(checker::ETSChecker * checker)82 checker::Type *ETSUnionType::GetType(checker::ETSChecker *checker)
83 {
84 if (TsType() != nullptr) {
85 return TsType();
86 }
87
88 ArenaVector<checker::Type *> types(checker->Allocator()->Adapter());
89
90 for (auto *it : types_) {
91 types.push_back(it->GetType(checker));
92 }
93
94 checker->Relation()->SetNode(this);
95 if (!CheckConstituentTypesValid(types)) {
96 SetTsType(checker->GlobalTypeError());
97 } else {
98 SetTsType(checker->CreateETSUnionType(std::move(types)));
99 }
100 checker->Relation()->SetNode(nullptr);
101 return TsType();
102 }
103
Clone(ArenaAllocator * const allocator,AstNode * const parent)104 ETSUnionType *ETSUnionType::Clone(ArenaAllocator *const allocator, AstNode *const parent)
105 {
106 ArenaVector<ir::TypeNode *> types(allocator->Adapter());
107 for (auto *it : types_) {
108 auto *type = it->Clone(allocator, nullptr);
109 types.push_back(type);
110 }
111 ETSUnionType *const clone = allocator->New<ir::ETSUnionType>(std::move(types));
112 if (parent != nullptr) {
113 clone->SetParent(parent);
114 }
115 for (auto *it : clone->types_) {
116 it->SetParent(clone);
117 }
118 return clone;
119 }
120 } // namespace ark::es2panda::ir
121