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 "checker/TSchecker.h"
17 #include "checker/types/ts/indexInfo.h"
18
19 namespace ark::es2panda::checker {
CreateNumberLiteralType(double value)20 Type *TSChecker::CreateNumberLiteralType(double value)
21 {
22 auto search = numberLiteralMap_.find(value);
23 if (search != numberLiteralMap_.end()) {
24 return search->second;
25 }
26
27 auto *newNumLiteralType = Allocator()->New<NumberLiteralType>(value);
28 numberLiteralMap_.insert({value, newNumLiteralType});
29 return newNumLiteralType;
30 }
31
CreateBigintLiteralType(const util::StringView & str,bool negative)32 Type *TSChecker::CreateBigintLiteralType(const util::StringView &str, bool negative)
33 {
34 auto search = bigintLiteralMap_.find(str);
35 if (search != bigintLiteralMap_.end()) {
36 return search->second;
37 }
38
39 auto *newBigintLiteralType = Allocator()->New<BigintLiteralType>(str, negative);
40 bigintLiteralMap_.insert({str, newBigintLiteralType});
41 return newBigintLiteralType;
42 }
43
CreateStringLiteralType(const util::StringView & str)44 Type *TSChecker::CreateStringLiteralType(const util::StringView &str)
45 {
46 auto search = stringLiteralMap_.find(str);
47 if (search != stringLiteralMap_.end()) {
48 return search->second;
49 }
50
51 auto *newStrLiteralType = Allocator()->New<StringLiteralType>(str);
52 stringLiteralMap_.insert({str, newStrLiteralType});
53 return newStrLiteralType;
54 }
55
CreateUnionType(std::initializer_list<Type * > constituentTypes)56 Type *TSChecker::CreateUnionType(std::initializer_list<Type *> constituentTypes)
57 {
58 ArenaVector<Type *> newConstituentTypes(Allocator()->Adapter());
59
60 for (auto *it : constituentTypes) {
61 newConstituentTypes.push_back(it);
62 }
63
64 return CreateUnionType(std::move(newConstituentTypes));
65 }
66
CreateUnionType(ArenaVector<Type * > & constituentTypes)67 Type *TSChecker::CreateUnionType(ArenaVector<Type *> &constituentTypes)
68 {
69 ArenaVector<Type *> newConstituentTypes(Allocator()->Adapter());
70
71 for (auto *it : constituentTypes) {
72 if (it->IsUnionType()) {
73 for (auto *type : it->AsUnionType()->ConstituentTypes()) {
74 newConstituentTypes.push_back(type);
75 }
76
77 continue;
78 }
79
80 newConstituentTypes.push_back(it);
81 }
82
83 UnionType::RemoveDuplicatedTypes(Relation(), newConstituentTypes);
84
85 if (newConstituentTypes.size() == 1) {
86 return newConstituentTypes[0];
87 }
88
89 auto *newUnionType = Allocator()->New<UnionType>(Allocator(), newConstituentTypes);
90
91 return UnionType::HandleUnionType(newUnionType, GetGlobalTypesHolder());
92 }
93
CreateUnionType(ArenaVector<Type * > && constituentTypes)94 Type *TSChecker::CreateUnionType(ArenaVector<Type *> &&constituentTypes)
95 {
96 if (constituentTypes.empty()) {
97 return nullptr;
98 }
99
100 ArenaVector<Type *> newConstituentTypes(Allocator()->Adapter());
101
102 for (auto *it : constituentTypes) {
103 if (it->IsUnionType()) {
104 for (auto *type : it->AsUnionType()->ConstituentTypes()) {
105 newConstituentTypes.push_back(type);
106 }
107
108 continue;
109 }
110
111 newConstituentTypes.push_back(it);
112 }
113
114 UnionType::RemoveDuplicatedTypes(Relation(), newConstituentTypes);
115
116 if (newConstituentTypes.size() == 1) {
117 return newConstituentTypes[0];
118 }
119
120 auto *newUnionType = Allocator()->New<UnionType>(Allocator(), std::move(newConstituentTypes));
121
122 return UnionType::HandleUnionType(newUnionType, GetGlobalTypesHolder());
123 }
124
CreateObjectTypeWithCallSignature(Signature * callSignature)125 Type *TSChecker::CreateObjectTypeWithCallSignature(Signature *callSignature)
126 {
127 auto *objType = Allocator()->New<ObjectLiteralType>(Allocator()->New<ObjectDescriptor>(Allocator()));
128 ES2PANDA_ASSERT(objType != nullptr);
129 objType->AddCallSignature(callSignature);
130 return objType;
131 }
132
CreateObjectTypeWithConstructSignature(Signature * constructSignature)133 Type *TSChecker::CreateObjectTypeWithConstructSignature(Signature *constructSignature)
134 {
135 auto *objType = Allocator()->New<ObjectLiteralType>(Allocator()->New<ObjectDescriptor>(Allocator()));
136 ES2PANDA_ASSERT(objType != nullptr);
137 objType->AddConstructSignature(constructSignature);
138 return objType;
139 }
140
CreateFunctionTypeWithSignature(Signature * callSignature)141 Type *TSChecker::CreateFunctionTypeWithSignature(Signature *callSignature)
142 {
143 auto *funcObjType = Allocator()->New<FunctionType>(Allocator()->New<ObjectDescriptor>(Allocator()));
144 ES2PANDA_ASSERT(funcObjType != nullptr);
145 funcObjType->AddCallSignature(callSignature);
146 return funcObjType;
147 }
148
CreateConstructorTypeWithSignature(Signature * constructSignature)149 Type *TSChecker::CreateConstructorTypeWithSignature(Signature *constructSignature)
150 {
151 auto *constructObjType = Allocator()->New<ConstructorType>(Allocator()->New<ObjectDescriptor>(Allocator()));
152 ES2PANDA_ASSERT(constructObjType != nullptr);
153 constructObjType->AddConstructSignature(constructSignature);
154 return constructObjType;
155 }
156
CreateTupleType(ObjectDescriptor * desc,ArenaVector<ElementFlags> && elementFlags,const TupleTypeInfo & tupleTypeInfo)157 Type *TSChecker::CreateTupleType(ObjectDescriptor *desc, ArenaVector<ElementFlags> &&elementFlags,
158 const TupleTypeInfo &tupleTypeInfo)
159 {
160 desc->stringIndexInfo = Allocator()->New<IndexInfo>(GlobalAnyType(), "x", tupleTypeInfo.readonly);
161 checker::NamedTupleMemberPool namedMembers(Allocator()->Adapter());
162 return Allocator()->New<TupleType>(
163 std::make_tuple(desc, std::move(elementFlags), tupleTypeInfo.combinedFlags, std::move(namedMembers)),
164 tupleTypeInfo.minLength, tupleTypeInfo.fixedLength, tupleTypeInfo.readonly);
165 }
166
CreateTupleType(ObjectDescriptor * desc,ArenaVector<ElementFlags> && elementFlags,const TupleTypeInfo & tupleTypeInfo,NamedTupleMemberPool && namedMembers)167 Type *TSChecker::CreateTupleType(ObjectDescriptor *desc, ArenaVector<ElementFlags> &&elementFlags,
168 const TupleTypeInfo &tupleTypeInfo, NamedTupleMemberPool &&namedMembers)
169 {
170 desc->stringIndexInfo = Allocator()->New<IndexInfo>(GlobalAnyType(), "x", tupleTypeInfo.readonly);
171
172 return Allocator()->New<TupleType>(
173 std::make_tuple(desc, std::move(elementFlags), tupleTypeInfo.combinedFlags, std::move(namedMembers)),
174 tupleTypeInfo.minLength, tupleTypeInfo.fixedLength, tupleTypeInfo.readonly);
175 }
176 } // namespace ark::es2panda::checker
177