• 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 <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