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