• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "tupleType.h"
17 
18 #include "checker/TSchecker.h"
19 
20 namespace ark::es2panda::checker {
ConvertToArrayType(TSChecker * checker)21 Type *TupleType::ConvertToArrayType(TSChecker *checker)
22 {
23     ArenaVector<Type *> unionTypes(checker->Allocator()->Adapter());
24 
25     for (const auto *it : desc_->properties) {
26         unionTypes.push_back(it->TsType());
27     }
28 
29     Type *arrayType = checker->CreateUnionType(std::move(unionTypes));
30     return checker->Allocator()->New<ArrayType>(arrayType);
31 }
32 
ToString(std::stringstream & ss,bool precise) const33 void TupleType::ToString(std::stringstream &ss, bool precise) const
34 {
35     if (readonly_) {
36         ss << "readonly ";
37     }
38     ss << "[";
39 
40     if (namedMembers_.empty()) {
41         for (auto it = desc_->properties.begin(); it != desc_->properties.end(); it++) {
42             (*it)->TsType()->ToString(ss, precise);
43             if ((*it)->HasFlag(varbinder::VariableFlags::OPTIONAL)) {
44                 ss << "?";
45             }
46 
47             if (std::next(it) != desc_->properties.end()) {
48                 ss << ", ";
49             }
50         }
51     } else {
52         for (auto it = desc_->properties.begin(); it != desc_->properties.end(); it++) {
53             const util::StringView &memberName = FindNamedMemberName(*it);
54             ss << memberName;
55 
56             if ((*it)->HasFlag(varbinder::VariableFlags::OPTIONAL)) {
57                 ss << "?";
58             }
59 
60             ss << ": ";
61             (*it)->TsType()->ToString(ss, precise);
62             if (std::next(it) != desc_->properties.end()) {
63                 ss << ", ";
64             }
65         }
66     }
67 
68     ss << "]";
69 }
70 
Identical(TypeRelation * relation,Type * other)71 void TupleType::Identical(TypeRelation *relation, Type *other)
72 {
73     if (!other->IsObjectType() || !other->AsObjectType()->IsTupleType()) {
74         return;
75     }
76 
77     TupleType *otherTuple = other->AsObjectType()->AsTupleType();
78     if (kind_ == otherTuple->Kind() && desc_->properties.size() == otherTuple->Properties().size()) {
79         for (size_t i = 0; i < desc_->properties.size(); i++) {
80             varbinder::LocalVariable *targetProp = desc_->properties[i];
81             varbinder::LocalVariable *sourceProp = otherTuple->Properties()[i];
82 
83             if (targetProp->Flags() != sourceProp->Flags()) {
84                 relation->Result(false);
85                 return;
86             }
87 
88             relation->IsIdenticalTo(targetProp->TsType(), sourceProp->TsType());
89 
90             if (!relation->IsTrue()) {
91                 return;
92             }
93         }
94         relation->Result(true);
95     }
96 }
97 
AssignmentTarget(TypeRelation * relation,Type * source)98 void TupleType::AssignmentTarget(TypeRelation *relation, Type *source)
99 {
100     if (!source->IsObjectType() || !source->AsObjectType()->IsTupleType()) {
101         relation->Result(false);
102         return;
103     }
104 
105     TupleType *sourceTuple = source->AsObjectType()->AsTupleType();
106     if (FixedLength() < sourceTuple->MinLength()) {
107         relation->Result(false);
108         return;
109     }
110 
111     relation->Result(true);
112 
113     const auto &sourceProperties = sourceTuple->Properties();
114     for (size_t i = 0; i < desc_->properties.size(); i++) {
115         auto *targetProp = desc_->properties[i];
116 
117         if (i < sourceProperties.size()) {
118             if (!targetProp->HasFlag(varbinder::VariableFlags::OPTIONAL) &&
119                 sourceProperties[i]->HasFlag(varbinder::VariableFlags::OPTIONAL)) {
120                 relation->Result(false);
121                 return;
122             }
123 
124             Type *targetPropType = targetProp->TsType();
125             Type *sourcePropType = sourceProperties[i]->TsType();
126             if (!relation->IsAssignableTo(sourcePropType, targetPropType)) {
127                 return;
128             }
129 
130             continue;
131         }
132 
133         if (!targetProp->HasFlag(varbinder::VariableFlags::OPTIONAL)) {
134             relation->Result(false);
135             return;
136         }
137     }
138 
139     if (relation->IsTrue()) {
140         AssignIndexInfo(relation, sourceTuple);
141     }
142 }
143 
GetTypeFacts() const144 TypeFacts TupleType::GetTypeFacts() const
145 {
146     if (desc_->properties.empty()) {
147         return TypeFacts::EMPTY_OBJECT_FACTS;
148     }
149 
150     return TypeFacts::OBJECT_FACTS;
151 }
152 
Instantiate(ArenaAllocator * allocator,TypeRelation * relation,GlobalTypesHolder * globalTypes)153 Type *TupleType::Instantiate(ArenaAllocator *allocator, TypeRelation *relation, GlobalTypesHolder *globalTypes)
154 {
155     ObjectDescriptor *copiedDesc = allocator->New<ObjectDescriptor>(allocator);
156 
157     desc_->Copy(allocator, copiedDesc, relation, globalTypes);
158 
159     NamedTupleMemberPool copiedNamedMemberPool = namedMembers_;
160     ArenaVector<ElementFlags> copiedElementFlags(allocator->Adapter());
161 
162     for (auto it : elementFlags_) {
163         copiedElementFlags.push_back(it);
164     }
165 
166     return allocator->New<TupleType>(
167         std::make_tuple(copiedDesc, std::move(copiedElementFlags), combinedFlags_, std::move(copiedNamedMemberPool)),
168         minLength_, fixedLength_, readonly_);
169 }
170 }  // namespace ark::es2panda::checker
171