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 <functional>
17 #include "checker/ETSchecker.h"
18 #include "checker/ets/boxingConverter.h"
19 #include "checker/types/ets/byteType.h"
20 #include "checker/types/ets/charType.h"
21 #include "checker/types/ets/etsDynamicFunctionType.h"
22 #include "checker/types/ets/etsDynamicType.h"
23 #include "checker/types/ets/etsStringType.h"
24 #include "checker/types/ets/etsUnionType.h"
25 #include "checker/types/ets/shortType.h"
26 #include "generated/signatures.h"
27 #include "ir/base/classDefinition.h"
28 #include "ir/base/scriptFunction.h"
29 #include "ir/ets/etsScript.h"
30 #include "ir/expressions/identifier.h"
31 #include "ir/ts/tsEnumDeclaration.h"
32 #include "ir/ts/tsEnumMember.h"
33 #include "ir/ts/tsInterfaceDeclaration.h"
34 #include "varbinder/varbinder.h"
35 #include "varbinder/ETSBinder.h"
36 #include "parser/program/program.h"
37 #include "util/helpers.h"
38 #include "checker/types/ts/bigintType.h"
39
40 namespace panda::es2panda::checker {
CreateByteType(int8_t value)41 ByteType *ETSChecker::CreateByteType(int8_t value)
42 {
43 return Allocator()->New<ByteType>(value);
44 }
45
CreateETSBooleanType(bool value)46 ETSBooleanType *ETSChecker::CreateETSBooleanType(bool value)
47 {
48 return Allocator()->New<ETSBooleanType>(value);
49 }
50
CreateDoubleType(double value)51 DoubleType *ETSChecker::CreateDoubleType(double value)
52 {
53 return Allocator()->New<DoubleType>(value);
54 }
55
CreateFloatType(float value)56 FloatType *ETSChecker::CreateFloatType(float value)
57 {
58 return Allocator()->New<FloatType>(value);
59 }
60
CreateIntType(int32_t value)61 IntType *ETSChecker::CreateIntType(int32_t value)
62 {
63 return Allocator()->New<IntType>(value);
64 }
65
CreateIntTypeFromType(Type * type)66 IntType *ETSChecker::CreateIntTypeFromType(Type *type)
67 {
68 if (!type->HasTypeFlag(TypeFlag::CONSTANT)) {
69 return GlobalIntType()->AsIntType();
70 }
71
72 if (type->IsIntType()) {
73 return type->AsIntType();
74 }
75
76 switch (ETSType(type)) {
77 case TypeFlag::CHAR: {
78 return CreateIntType(static_cast<int32_t>(type->AsCharType()->GetValue()));
79 }
80 case TypeFlag::BYTE: {
81 return CreateIntType(static_cast<int32_t>(type->AsByteType()->GetValue()));
82 }
83 case TypeFlag::SHORT: {
84 return CreateIntType(static_cast<int32_t>(type->AsShortType()->GetValue()));
85 }
86 default: {
87 return nullptr;
88 }
89 }
90 }
91
CreateLongType(int64_t value)92 LongType *ETSChecker::CreateLongType(int64_t value)
93 {
94 return Allocator()->New<LongType>(value);
95 }
96
CreateShortType(int16_t value)97 ShortType *ETSChecker::CreateShortType(int16_t value)
98 {
99 return Allocator()->New<ShortType>(value);
100 }
101
CreateCharType(char16_t value)102 CharType *ETSChecker::CreateCharType(char16_t value)
103 {
104 return Allocator()->New<CharType>(value);
105 }
106
CreateETSBigIntLiteralType(util::StringView value)107 ETSBigIntType *ETSChecker::CreateETSBigIntLiteralType(util::StringView value)
108 {
109 return Allocator()->New<ETSBigIntType>(Allocator(), GlobalBuiltinETSBigIntType(), value);
110 }
111
CreateETSStringLiteralType(util::StringView value)112 ETSStringType *ETSChecker::CreateETSStringLiteralType(util::StringView value)
113 {
114 return Allocator()->New<ETSStringType>(Allocator(), GlobalBuiltinETSStringType(), value);
115 }
116
CreateETSArrayType(Type * elementType)117 ETSArrayType *ETSChecker::CreateETSArrayType(Type *elementType)
118 {
119 auto res = arrayTypes_.find(elementType);
120 if (res != arrayTypes_.end()) {
121 return res->second;
122 }
123
124 auto *arrayType = Allocator()->New<ETSArrayType>(elementType);
125 auto it = arrayTypes_.insert({elementType, arrayType});
126 if (it.second && !elementType->IsETSTypeParameter()) {
127 CreateBuiltinArraySignature(arrayType, arrayType->Rank());
128 }
129
130 return arrayType;
131 }
132
CreateETSUnionType(ArenaVector<Type * > && constituentTypes)133 Type *ETSChecker::CreateETSUnionType(ArenaVector<Type *> &&constituentTypes)
134 {
135 if (constituentTypes.empty()) {
136 return nullptr;
137 }
138
139 ArenaVector<Type *> newConstituentTypes(Allocator()->Adapter());
140
141 for (auto *it : constituentTypes) {
142 newConstituentTypes.push_back(
143 it->HasTypeFlag(checker::TypeFlag::ETS_PRIMITIVE) ? BoxingConverter::ETSTypeFromSource(this, it) : it);
144 }
145
146 ETSUnionType::NormalizeTypes(Relation(), newConstituentTypes);
147 if (newConstituentTypes.size() == 1) {
148 return newConstituentTypes[0];
149 }
150 return Allocator()->New<ETSUnionType>(this, std::move(newConstituentTypes));
151 }
152
CreateETSFunctionType(ArenaVector<Signature * > & signatures)153 ETSFunctionType *ETSChecker::CreateETSFunctionType(ArenaVector<Signature *> &signatures)
154 {
155 auto *funcType = Allocator()->New<ETSFunctionType>(signatures[0]->Function()->Id()->Name(), Allocator());
156
157 for (auto *it : signatures) {
158 funcType->AddCallSignature(it);
159 }
160
161 return funcType;
162 }
163
CreateETSFunctionType(Signature * signature)164 ETSFunctionType *ETSChecker::CreateETSFunctionType(Signature *signature)
165 {
166 return Allocator()->New<ETSFunctionType>(signature->Function()->Id()->Name(), signature, Allocator());
167 }
168
CreateETSFunctionType(Signature * signature,util::StringView name)169 ETSFunctionType *ETSChecker::CreateETSFunctionType(Signature *signature, util::StringView name)
170 {
171 return Allocator()->New<ETSFunctionType>(name, signature, Allocator());
172 }
173
CreateETSFunctionType(ir::ScriptFunction * func,Signature * signature,util::StringView name)174 ETSFunctionType *ETSChecker::CreateETSFunctionType(ir::ScriptFunction *func, Signature *signature,
175 util::StringView name)
176 {
177 if (func->IsDynamic()) {
178 return Allocator()->New<ETSDynamicFunctionType>(name, signature, Allocator(), func->Language());
179 }
180
181 return Allocator()->New<ETSFunctionType>(name, signature, Allocator());
182 }
183
CreateSignature(SignatureInfo * info,Type * returnType,ir::ScriptFunction * func)184 Signature *ETSChecker::CreateSignature(SignatureInfo *info, Type *returnType, ir::ScriptFunction *func)
185 {
186 return Allocator()->New<Signature>(info, returnType, func);
187 }
188
CreateSignature(SignatureInfo * info,Type * returnType,util::StringView internalName)189 Signature *ETSChecker::CreateSignature(SignatureInfo *info, Type *returnType, util::StringView internalName)
190 {
191 return Allocator()->New<Signature>(info, returnType, internalName);
192 }
193
CreateSignatureInfo()194 SignatureInfo *ETSChecker::CreateSignatureInfo()
195 {
196 return Allocator()->New<SignatureInfo>(Allocator());
197 }
198
CreateTypeParameter()199 ETSTypeParameter *ETSChecker::CreateTypeParameter()
200 {
201 return Allocator()->New<ETSTypeParameter>();
202 }
203
CreateETSFunctionType(util::StringView name)204 ETSFunctionType *ETSChecker::CreateETSFunctionType(util::StringView name)
205 {
206 return Allocator()->New<ETSFunctionType>(name, Allocator());
207 }
208
CreateETSExtensionFuncHelperType(ETSFunctionType * classMethodType,ETSFunctionType * extensionFunctionType)209 ETSExtensionFuncHelperType *ETSChecker::CreateETSExtensionFuncHelperType(ETSFunctionType *classMethodType,
210 ETSFunctionType *extensionFunctionType)
211 {
212 return Allocator()->New<ETSExtensionFuncHelperType>(classMethodType, extensionFunctionType);
213 }
214
GetNameToTypeIdMap()215 std::map<util::StringView, GlobalTypeId> &GetNameToTypeIdMap()
216 {
217 static std::map<util::StringView, GlobalTypeId> nameToTypeId = {
218 {compiler::Signatures::BUILTIN_BIGINT_CLASS, GlobalTypeId::ETS_BIG_INT_BUILTIN},
219 {compiler::Signatures::BUILTIN_STRING_CLASS, GlobalTypeId::ETS_STRING_BUILTIN},
220 {compiler::Signatures::BUILTIN_OBJECT_CLASS, GlobalTypeId::ETS_OBJECT_BUILTIN},
221 {compiler::Signatures::BUILTIN_EXCEPTION_CLASS, GlobalTypeId::ETS_EXCEPTION_BUILTIN},
222 {compiler::Signatures::BUILTIN_ERROR_CLASS, GlobalTypeId::ETS_ERROR_BUILTIN},
223 {compiler::Signatures::BUILTIN_TYPE_CLASS, GlobalTypeId::ETS_TYPE_BUILTIN},
224 {compiler::Signatures::BUILTIN_PROMISE_CLASS, GlobalTypeId::ETS_PROMISE_BUILTIN},
225 {compiler::Signatures::BUILTIN_BOX_CLASS, GlobalTypeId::ETS_BOX_BUILTIN},
226 {compiler::Signatures::BUILTIN_BOOLEAN_BOX_CLASS, GlobalTypeId::ETS_BOOLEAN_BOX_BUILTIN},
227 {compiler::Signatures::BUILTIN_BYTE_BOX_CLASS, GlobalTypeId::ETS_BYTE_BOX_BUILTIN},
228 {compiler::Signatures::BUILTIN_CHAR_BOX_CLASS, GlobalTypeId::ETS_CHAR_BOX_BUILTIN},
229 {compiler::Signatures::BUILTIN_SHORT_BOX_CLASS, GlobalTypeId::ETS_SHORT_BOX_BUILTIN},
230 {compiler::Signatures::BUILTIN_INT_BOX_CLASS, GlobalTypeId::ETS_INT_BOX_BUILTIN},
231 {compiler::Signatures::BUILTIN_LONG_BOX_CLASS, GlobalTypeId::ETS_LONG_BOX_BUILTIN},
232 {compiler::Signatures::BUILTIN_FLOAT_BOX_CLASS, GlobalTypeId::ETS_FLOAT_BOX_BUILTIN},
233 {compiler::Signatures::BUILTIN_DOUBLE_BOX_CLASS, GlobalTypeId::ETS_DOUBLE_BOX_BUILTIN},
234 {compiler::Signatures::BUILTIN_VOID_CLASS, GlobalTypeId::ETS_VOID_BUILTIN},
235 };
236
237 return nameToTypeId;
238 }
239
GetNameToGlobalTypeMap()240 std::map<util::StringView, std::function<ETSObjectType *(const ETSChecker *)>> &GetNameToGlobalTypeMap()
241 {
242 static std::map<util::StringView, std::function<ETSObjectType *(const ETSChecker *)>> nameToGlobalType = {
243 {compiler::Signatures::BUILTIN_BIGINT_CLASS, &ETSChecker::GlobalBuiltinETSBigIntType},
244 {compiler::Signatures::BUILTIN_STRING_CLASS, &ETSChecker::GlobalBuiltinETSStringType},
245 {compiler::Signatures::BUILTIN_OBJECT_CLASS, &ETSChecker::GlobalETSObjectType},
246 {compiler::Signatures::BUILTIN_EXCEPTION_CLASS, &ETSChecker::GlobalBuiltinExceptionType},
247 {compiler::Signatures::BUILTIN_ERROR_CLASS, &ETSChecker::GlobalBuiltinErrorType},
248 {compiler::Signatures::BUILTIN_TYPE_CLASS, &ETSChecker::GlobalBuiltinTypeType},
249 {compiler::Signatures::BUILTIN_PROMISE_CLASS, &ETSChecker::GlobalBuiltinPromiseType},
250 {compiler::Signatures::BUILTIN_VOID_CLASS, &ETSChecker::GlobalBuiltinVoidType},
251 };
252
253 return nameToGlobalType;
254 }
255
GetNameToGlobalBoxTypeMap()256 std::map<util::StringView, std::function<Type *(const ETSChecker *)>> &GetNameToGlobalBoxTypeMap()
257 {
258 static std::map<util::StringView, std::function<Type *(const ETSChecker *)>> nameToGlobalBoxType = {
259 {compiler::Signatures::BUILTIN_BOX_CLASS, &ETSChecker::GlobalETSObjectType},
260 {compiler::Signatures::BUILTIN_BOOLEAN_BOX_CLASS, &ETSChecker::GlobalETSBooleanType},
261 {compiler::Signatures::BUILTIN_BYTE_BOX_CLASS, &ETSChecker::GlobalByteType},
262 {compiler::Signatures::BUILTIN_CHAR_BOX_CLASS, &ETSChecker::GlobalCharType},
263 {compiler::Signatures::BUILTIN_SHORT_BOX_CLASS, &ETSChecker::GlobalShortType},
264 {compiler::Signatures::BUILTIN_INT_BOX_CLASS, &ETSChecker::GlobalIntType},
265 {compiler::Signatures::BUILTIN_LONG_BOX_CLASS, &ETSChecker::GlobalLongType},
266 {compiler::Signatures::BUILTIN_FLOAT_BOX_CLASS, &ETSChecker::GlobalFloatType},
267 {compiler::Signatures::BUILTIN_DOUBLE_BOX_CLASS, &ETSChecker::GlobalDoubleType},
268 };
269
270 return nameToGlobalBoxType;
271 }
272
UpdateBoxedGlobalType(ETSObjectType * objType,util::StringView name)273 ETSObjectType *ETSChecker::UpdateBoxedGlobalType(ETSObjectType *objType, util::StringView name)
274 {
275 auto nameToGlobalBoxType = GetNameToGlobalBoxTypeMap();
276 auto nameToTypeId = GetNameToTypeIdMap();
277
278 if (nameToGlobalBoxType.find(name) != nameToGlobalBoxType.end()) {
279 std::function<Type *(const ETSChecker *)> globalType = nameToGlobalBoxType[name];
280 if (GlobalBuiltinBoxType(globalType(this)) != nullptr) {
281 return GlobalBuiltinBoxType(globalType(this));
282 }
283
284 auto id = nameToTypeId.find(name);
285 if (id != nameToTypeId.end()) {
286 GetGlobalTypesHolder()->GlobalTypes()[static_cast<size_t>(id->second)] = objType;
287 }
288 }
289
290 return objType;
291 }
292
UpdateGlobalType(ETSObjectType * objType,util::StringView name)293 ETSObjectType *ETSChecker::UpdateGlobalType(ETSObjectType *objType, util::StringView name)
294 {
295 auto nameToGlobalType = GetNameToGlobalTypeMap();
296 auto nameToTypeId = GetNameToTypeIdMap();
297
298 if (nameToGlobalType.find(name) != nameToGlobalType.end()) {
299 std::function<ETSObjectType *(const ETSChecker *)> globalType = nameToGlobalType[name];
300 if (globalType(this) != nullptr) {
301 return globalType(this);
302 }
303
304 auto id = nameToTypeId.find(name);
305 if (id != nameToTypeId.end()) {
306 GetGlobalTypesHolder()->GlobalTypes()[static_cast<size_t>(id->second)] = objType;
307 }
308
309 if (name == compiler::Signatures::BUILTIN_OBJECT_CLASS) {
310 auto *nullish =
311 CreateNullishType(objType, checker::TypeFlag::NULLISH, Allocator(), Relation(), GetGlobalTypesHolder());
312 GetGlobalTypesHolder()->GlobalTypes()[static_cast<size_t>(GlobalTypeId::ETS_NULLISH_OBJECT)] = nullish;
313 }
314 }
315
316 return objType;
317 }
318
CreateETSObjectTypeCheckBuiltins(util::StringView name,ir::AstNode * declNode,ETSObjectFlags flags)319 ETSObjectType *ETSChecker::CreateETSObjectTypeCheckBuiltins(util::StringView name, ir::AstNode *declNode,
320 ETSObjectFlags flags)
321 {
322 if (name == compiler::Signatures::BUILTIN_BIGINT_CLASS) {
323 if (GlobalBuiltinETSBigIntType() != nullptr) {
324 return GlobalBuiltinETSBigIntType();
325 }
326
327 GetGlobalTypesHolder()->GlobalTypes()[static_cast<size_t>(GlobalTypeId::ETS_BIG_INT_BUILTIN)] =
328 CreateNewETSObjectType(name, declNode, flags | ETSObjectFlags::BUILTIN_BIGINT);
329 GetGlobalTypesHolder()->GlobalTypes()[static_cast<size_t>(GlobalTypeId::ETS_BIG_INT)] =
330 Allocator()->New<ETSBigIntType>(Allocator(), GlobalBuiltinETSBigIntType());
331
332 return GlobalBuiltinETSBigIntType();
333 }
334
335 if (name == compiler::Signatures::BUILTIN_STRING_CLASS) {
336 if (GlobalBuiltinETSStringType() != nullptr) {
337 return GlobalBuiltinETSStringType();
338 }
339 GetGlobalTypesHolder()->GlobalTypes()[static_cast<size_t>(GlobalTypeId::ETS_STRING_BUILTIN)] =
340 CreateNewETSObjectType(name, declNode, flags | ETSObjectFlags::BUILTIN_STRING | ETSObjectFlags::STRING);
341
342 GetGlobalTypesHolder()->GlobalTypes()[static_cast<size_t>(GlobalTypeId::ETS_STRING)] =
343 Allocator()->New<ETSStringType>(Allocator(), GlobalBuiltinETSStringType());
344 return GlobalBuiltinETSStringType();
345 }
346
347 auto *objType = CreateNewETSObjectType(name, declNode, flags);
348 auto nameToGlobalBoxType = GetNameToGlobalBoxTypeMap();
349 if (nameToGlobalBoxType.find(name) != nameToGlobalBoxType.end()) {
350 return UpdateBoxedGlobalType(objType, name);
351 }
352
353 return UpdateGlobalType(objType, name);
354 }
355
CreateETSObjectType(util::StringView name,ir::AstNode * declNode,ETSObjectFlags flags)356 ETSObjectType *ETSChecker::CreateETSObjectType(util::StringView name, ir::AstNode *declNode, ETSObjectFlags flags)
357 {
358 auto res = primitiveWrappers_.Wrappers().find(name);
359 if (res == primitiveWrappers_.Wrappers().end()) {
360 return CreateETSObjectTypeCheckBuiltins(name, declNode, flags);
361 }
362
363 if (res->second.first != nullptr) {
364 return res->second.first;
365 }
366
367 auto *objType = CreateNewETSObjectType(name, declNode, flags | res->second.second);
368 primitiveWrappers_.Wrappers().at(name).first = objType;
369 return objType;
370 }
371
CreateETSEnumType(ir::TSEnumDeclaration const * const enumDecl)372 ETSEnumType *ETSChecker::CreateETSEnumType(ir::TSEnumDeclaration const *const enumDecl)
373 {
374 varbinder::Variable *enumVar = enumDecl->Key()->Variable();
375 ASSERT(enumVar != nullptr);
376
377 ETSEnumType::UType ordinal = -1;
378 auto *const enumType = Allocator()->New<ETSEnumType>(enumDecl, ordinal++);
379 enumType->SetVariable(enumVar);
380 enumVar->SetTsType(enumType);
381
382 for (auto *const member : enumType->GetMembers()) {
383 auto *const memberVar = member->AsTSEnumMember()->Key()->AsIdentifier()->Variable();
384 auto *const enumLiteralType = Allocator()->New<ETSEnumType>(enumDecl, ordinal++, member->AsTSEnumMember());
385 enumLiteralType->SetVariable(memberVar);
386 memberVar->SetTsType(enumLiteralType);
387 }
388
389 auto *const namesArrayIdent = CreateEnumNamesArray(enumType);
390
391 auto const getNameMethod = CreateEnumGetNameMethod(namesArrayIdent, enumType);
392 enumType->SetGetNameMethod(getNameMethod);
393
394 auto const valueOfMethod = CreateEnumValueOfMethod(namesArrayIdent, enumType);
395 enumType->SetValueOfMethod(valueOfMethod);
396
397 auto const fromIntMethod = CreateEnumFromIntMethod(namesArrayIdent, enumType);
398 enumType->SetFromIntMethod(fromIntMethod);
399
400 auto *const valuesArrayIdent = CreateEnumValuesArray(enumType);
401
402 auto const getValueMethod = CreateEnumGetValueMethod(valuesArrayIdent, enumType);
403 enumType->SetGetValueMethod(getValueMethod);
404
405 auto *const stringValuesArrayIdent = CreateEnumStringValuesArray(enumType);
406
407 auto const toStringMethod = CreateEnumToStringMethod(stringValuesArrayIdent, enumType);
408 enumType->SetToStringMethod(toStringMethod);
409
410 auto *const itemsArrayIdent = CreateEnumItemsArray(enumType);
411
412 auto const valuesMethod = CreateEnumValuesMethod(itemsArrayIdent, enumType);
413 enumType->SetValuesMethod(valuesMethod);
414
415 for (auto *const member : enumType->GetMembers()) {
416 auto *const enumLiteralType =
417 member->AsTSEnumMember()->Key()->AsIdentifier()->Variable()->TsType()->AsETSEnumType();
418 enumLiteralType->SetGetValueMethod(getValueMethod);
419 enumLiteralType->SetGetNameMethod(getNameMethod);
420 enumLiteralType->SetToStringMethod(toStringMethod);
421 }
422
423 return enumType;
424 }
425
CreateETSStringEnumType(ir::TSEnumDeclaration const * const enumDecl)426 ETSStringEnumType *ETSChecker::CreateETSStringEnumType(ir::TSEnumDeclaration const *const enumDecl)
427 {
428 varbinder::Variable *enumVar = enumDecl->Key()->Variable();
429 ASSERT(enumVar != nullptr);
430
431 ETSEnumType::UType ordinal = -1;
432 auto *const enumType = Allocator()->New<ETSStringEnumType>(enumDecl, ordinal++);
433 enumType->SetVariable(enumVar);
434 enumVar->SetTsType(enumType);
435
436 for (auto *const member : enumType->GetMembers()) {
437 auto *const memberVar = member->AsTSEnumMember()->Key()->AsIdentifier()->Variable();
438 auto *const enumLiteralType =
439 Allocator()->New<ETSStringEnumType>(enumDecl, ordinal++, member->AsTSEnumMember());
440 enumLiteralType->SetVariable(memberVar);
441 memberVar->SetTsType(enumLiteralType);
442 }
443
444 auto *const namesArrayIdent = CreateEnumNamesArray(enumType);
445
446 auto const getNameMethod = CreateEnumGetNameMethod(namesArrayIdent, enumType);
447 enumType->SetGetNameMethod(getNameMethod);
448
449 auto const valueOfMethod = CreateEnumValueOfMethod(namesArrayIdent, enumType);
450 enumType->SetValueOfMethod(valueOfMethod);
451
452 auto const fromIntMethod = CreateEnumFromIntMethod(namesArrayIdent, enumType);
453 enumType->SetFromIntMethod(fromIntMethod);
454
455 auto *const stringValuesArrayIdent = CreateEnumStringValuesArray(enumType);
456
457 auto const toStringMethod = CreateEnumToStringMethod(stringValuesArrayIdent, enumType);
458 enumType->SetToStringMethod(toStringMethod);
459 enumType->SetGetValueMethod(toStringMethod);
460
461 auto *const itemsArrayIdent = CreateEnumItemsArray(enumType);
462
463 auto const valuesMethod = CreateEnumValuesMethod(itemsArrayIdent, enumType);
464 enumType->SetValuesMethod(valuesMethod);
465
466 for (auto *const member : enumType->GetMembers()) {
467 auto *const enumLiteralType =
468 member->AsTSEnumMember()->Key()->AsIdentifier()->Variable()->TsType()->AsETSStringEnumType();
469 enumLiteralType->SetGetValueMethod(toStringMethod);
470 enumLiteralType->SetGetNameMethod(getNameMethod);
471 enumLiteralType->SetToStringMethod(toStringMethod);
472 }
473
474 return enumType;
475 }
476
CreateNewETSObjectType(util::StringView name,ir::AstNode * declNode,ETSObjectFlags flags)477 ETSObjectType *ETSChecker::CreateNewETSObjectType(util::StringView name, ir::AstNode *declNode, ETSObjectFlags flags)
478 {
479 util::StringView assemblerName = name;
480 util::StringView prefix {};
481
482 auto *containingObjType = util::Helpers::GetContainingObjectType(declNode->Parent());
483
484 if (containingObjType != nullptr) {
485 prefix = containingObjType->AssemblerName();
486 } else if (const auto *topStatement = declNode->GetTopStatement();
487 topStatement->Type() !=
488 ir::AstNodeType::ETS_SCRIPT) { // NOTE: should not occur, fix for TS_INTERFACE_DECLARATION
489 ASSERT(declNode->IsTSInterfaceDeclaration());
490 assemblerName = declNode->AsTSInterfaceDeclaration()->InternalName();
491 } else {
492 auto *program = static_cast<ir::ETSScript *>(declNode->GetTopStatement())->Program();
493 prefix = program->GetPackageName();
494 }
495
496 if (!prefix.Empty()) {
497 util::UString fullPath(prefix, Allocator());
498 fullPath.Append('.');
499 fullPath.Append(name);
500 assemblerName = fullPath.View();
501 }
502
503 Language lang(Language::Id::ETS);
504 bool hasDecl = false;
505
506 if (declNode->IsClassDefinition()) {
507 auto *clsDef = declNode->AsClassDefinition();
508 lang = clsDef->Language();
509 hasDecl = clsDef->IsDeclare();
510 }
511
512 if (declNode->IsTSInterfaceDeclaration()) {
513 auto *ifaceDecl = declNode->AsTSInterfaceDeclaration();
514 lang = ifaceDecl->Language();
515 hasDecl = ifaceDecl->IsDeclare();
516 }
517
518 auto res = compiler::Signatures::Dynamic::LanguageFromType(assemblerName.Utf8());
519 if (res) {
520 lang = *res;
521 }
522
523 if (lang.IsDynamic()) {
524 return Allocator()->New<ETSDynamicType>(Allocator(), name, assemblerName, declNode, flags, lang, hasDecl);
525 }
526
527 return Allocator()->New<ETSObjectType>(Allocator(), name, assemblerName, declNode, flags);
528 }
529
CreateBuiltinArraySignatureInfo(ETSArrayType * arrayType,size_t dim)530 std::tuple<util::StringView, SignatureInfo *> ETSChecker::CreateBuiltinArraySignatureInfo(ETSArrayType *arrayType,
531 size_t dim)
532 {
533 std::stringstream ss;
534 arrayType->ToAssemblerTypeWithRank(ss);
535 ss << compiler::Signatures::METHOD_SEPARATOR << compiler::Signatures::CTOR << compiler::Signatures::MANGLE_BEGIN;
536 arrayType->ToAssemblerTypeWithRank(ss);
537
538 auto *info = CreateSignatureInfo();
539 info->minArgCount = dim;
540
541 for (size_t i = 0; i < dim; i++) {
542 util::UString param(std::to_string(i), Allocator());
543 auto *paramVar =
544 varbinder::Scope::CreateVar(Allocator(), param.View(), varbinder::VariableFlags::NONE, nullptr);
545 paramVar->SetTsType(GlobalIntType());
546
547 info->params.push_back(paramVar);
548
549 ss << compiler::Signatures::MANGLE_SEPARATOR << compiler::Signatures::PRIMITIVE_INT;
550 }
551
552 ss << compiler::Signatures::MANGLE_SEPARATOR << compiler::Signatures::PRIMITIVE_VOID
553 << compiler::Signatures::MANGLE_SEPARATOR;
554 auto internalName = util::UString(ss.str(), Allocator()).View();
555
556 return {internalName, info};
557 }
558
CreateBuiltinArraySignature(ETSArrayType * arrayType,size_t dim)559 Signature *ETSChecker::CreateBuiltinArraySignature(ETSArrayType *arrayType, size_t dim)
560 {
561 auto res = globalArraySignatures_.find(arrayType);
562 if (res != globalArraySignatures_.end()) {
563 return res->second;
564 }
565
566 auto [internalName, info] = CreateBuiltinArraySignatureInfo(arrayType, dim);
567 auto *signature = CreateSignature(info, GlobalVoidType(), internalName);
568 globalArraySignatures_.insert({arrayType, signature});
569
570 return signature;
571 }
572 } // namespace panda::es2panda::checker
573