• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022 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 #ifndef ES2PANDA_TYPESCRIPT_EXACTOR_TYPESYSTEM_H
17 #define ES2PANDA_TYPESCRIPT_EXACTOR_TYPESYSTEM_H
18 
19 #include <cstdint>
20 
21 #include <binder/variable.h>
22 #include <compiler/base/literals.h>
23 #include <ir/astDump.h>
24 #include <ir/astNode.h>
25 #include <ir/base/classDefinition.h>
26 #include <ir/base/classProperty.h>
27 #include <ir/base/methodDefinition.h>
28 #include <ir/base/scriptFunction.h>
29 #include <ir/expressions/assignmentExpression.h>
30 #include <ir/expressions/functionExpression.h>
31 #include <ir/expressions/identifier.h>
32 #include <ir/expressions/literals/numberLiteral.h>
33 #include <ir/expressions/literals/stringLiteral.h>
34 #include <ir/statements/classDeclaration.h>
35 #include <ir/statements/functionDeclaration.h>
36 #include <ir/ts/tsArrayType.h>
37 #include <ir/ts/tsClassImplements.h>
38 #include <ir/ts/tsInterfaceBody.h>
39 #include <ir/ts/tsInterfaceDeclaration.h>
40 #include <ir/ts/tsInterfaceHeritage.h>
41 #include <ir/ts/tsMethodSignature.h>
42 #include <ir/ts/tsParameterProperty.h>
43 #include <ir/ts/tsPrivateIdentifier.h>
44 #include <ir/ts/tsPropertySignature.h>
45 #include <ir/ts/tsTypeLiteral.h>
46 #include <ir/ts/tsUnionType.h>
47 
48 namespace panda::es2panda::extractor {
49 
50 enum PrimitiveType : uint8_t {
51     ANY = 0,
52     NUMBER,
53     BOOLEAN,
54     VOID,
55     STRING,
56     SYMBOL,
57     NUL,
58     UNDEFINED,
59     INT,
60 };
61 
62 const std::unordered_map<ir::AstNodeType, PrimitiveType> PRIMITIVE_TYPE_MAP = {
63     {ir::AstNodeType::TS_ANY_KEYWORD, PrimitiveType::ANY},
64     {ir::AstNodeType::TS_NUMBER_KEYWORD, PrimitiveType::NUMBER},
65     {ir::AstNodeType::TS_BOOLEAN_KEYWORD, PrimitiveType::BOOLEAN},
66     {ir::AstNodeType::TS_VOID_KEYWORD, PrimitiveType::VOID},
67     {ir::AstNodeType::TS_STRING_KEYWORD, PrimitiveType::STRING},
68     {ir::AstNodeType::TS_SYMBOL_KEYWORD, PrimitiveType::SYMBOL},
69     {ir::AstNodeType::TS_NULL_KEYWORD, PrimitiveType::NUL},
70     {ir::AstNodeType::TS_UNDEFINED_KEYWORD, PrimitiveType::UNDEFINED},
71     // Placeholder for Type Inference INT
72 };
73 
74 enum BuiltinType : uint8_t {
75     BT_HEAD = 20,
76     BT_FUNCTION,
77     BT_RANGEERROR,
78     BT_ERROR,
79     BT_OBJECT,
80     BT_SYNTAXERROR,
81     BT_TYPEERROR,
82     BT_REFERENCEERROR,
83     BT_URIERROR,
84     BT_SYMBOL,
85     BT_EVALERROR,
86     BT_NUMBER,
87     BT_PARSEFLOAT,
88     BT_DATE,
89     BT_BOOLEAN,
90     BT_BIGINT,
91     BT_PARSEINT,
92     BT_WEAKMAP,
93     BT_REGEXP,
94     BT_SET,
95     BT_MAP,
96     BT_WEAKREF,
97     BT_WEAKSET,
98     BT_FINALIZATIONREGISTRY,
99     BT_ARRAY,
100     BT_UINT8CLAMPEDARRAY,
101     BT_UINT8ARRAY,
102     BT_TYPEDARRAY,
103     BT_INT8ARRAY,
104     BT_UINT16ARRAY,
105     BT_UINT32ARRAY,
106     BT_INT16ARRAY,
107     BT_INT32ARRAY,
108     BT_FLOAT32ARRAY,
109     BT_FLOAT64ARRAY,
110     BT_BIGINT64ARRAY,
111     BT_BIGUINT64ARRAY,
112     BT_SHAREDARRAYBUFFER,
113     BT_DATAVIEW,
114     BT_STRING,
115     BT_ARRAYBUFFER,
116     BT_EVAL,
117     BT_ISFINITE,
118     BT_ARKPRIVATE,
119     BT_PRINT,
120     BT_DECODEURI,
121     BT_DECODEURICOMPONENT,
122     BT_ISNAN,
123     BT_ENCODEURI,
124     BT_NAN,
125     BT_GLOBALTHIS,
126     BT_ENCODEURICOMPONENT,
127     BT_INFINITY,
128     BT_MATH,
129     BT_JSON,
130     BT_ATOMICS,
131     BT_UNDEFINED,
132     BT_REFLECT,
133     BT_PROMISE,
134     BT_PROXY,
135     BT_GENERATORFUNCTION,
136     BT_INTL,
137 };
138 
139 const std::unordered_map<std::string, BuiltinType> BUILTIN_TYPE_MAP = {
140     {"Function", BuiltinType::BT_FUNCTION},
141     {"RangeError", BuiltinType::BT_RANGEERROR},
142     {"Error", BuiltinType::BT_ERROR},
143     {"Object", BuiltinType::BT_OBJECT},
144     {"SyntaxError", BuiltinType::BT_SYNTAXERROR},
145     {"TypeError", BuiltinType::BT_TYPEERROR},
146     {"ReferenceError", BuiltinType::BT_REFERENCEERROR},
147     {"URIError", BuiltinType::BT_URIERROR},
148     {"Symbol", BuiltinType::BT_SYMBOL},
149     {"EvalError", BuiltinType::BT_EVALERROR},
150     {"Number", BuiltinType::BT_NUMBER},
151     {"parseFloat", BuiltinType::BT_PARSEFLOAT},
152     {"Date", BuiltinType::BT_DATE},
153     {"Boolean", BuiltinType::BT_BOOLEAN},
154     {"BigInt", BuiltinType::BT_BIGINT},
155     {"parseInt", BuiltinType::BT_PARSEINT},
156     {"WeakMap", BuiltinType::BT_WEAKMAP},
157     {"RegExp", BuiltinType::BT_REGEXP},
158     {"Set", BuiltinType::BT_SET},
159     {"Map", BuiltinType::BT_MAP},
160     {"WeakRef", BuiltinType::BT_WEAKREF},
161     {"WeakSet", BuiltinType::BT_WEAKSET},
162     {"FinalizationRegistry", BuiltinType::BT_FINALIZATIONREGISTRY},
163     {"Array", BuiltinType::BT_ARRAY},
164     {"Uint8ClampedArray", BuiltinType::BT_UINT8CLAMPEDARRAY},
165     {"Uint8Array", BuiltinType::BT_UINT8ARRAY},
166     {"TypedArray", BuiltinType::BT_TYPEDARRAY},
167     {"Int8Array", BuiltinType::BT_INT8ARRAY},
168     {"Uint16Array", BuiltinType::BT_UINT16ARRAY},
169     {"Uint32Array", BuiltinType::BT_UINT32ARRAY},
170     {"Int16Array", BuiltinType::BT_INT16ARRAY},
171     {"Int32Array", BuiltinType::BT_INT32ARRAY},
172     {"Float32Array", BuiltinType::BT_FLOAT32ARRAY},
173     {"Float64Array", BuiltinType::BT_FLOAT64ARRAY},
174     {"BigInt64Array", BuiltinType::BT_BIGINT64ARRAY},
175     {"BigUint64Array", BuiltinType::BT_BIGUINT64ARRAY},
176     {"SharedArrayBuffer", BuiltinType::BT_SHAREDARRAYBUFFER},
177     {"DataView", BuiltinType::BT_DATAVIEW},
178     {"String", BuiltinType::BT_STRING},
179     {"ArrayBuffer", BuiltinType::BT_ARRAYBUFFER},
180     {"eval", BuiltinType::BT_EVAL},
181     {"isFinite", BuiltinType::BT_ISFINITE},
182     {"ArkPrivate", BuiltinType::BT_ARKPRIVATE},
183     {"print", BuiltinType::BT_PRINT},
184     {"decodeURI", BuiltinType::BT_DECODEURI},
185     {"decodeURIComponent", BuiltinType::BT_DECODEURICOMPONENT},
186     {"isNaN", BuiltinType::BT_ISNAN},
187     {"encodeURI", BuiltinType::BT_ENCODEURI},
188     {"NaN", BuiltinType::BT_NAN},
189     {"globalThis", BuiltinType::BT_GLOBALTHIS},
190     {"encodeURIComponent", BuiltinType::BT_ENCODEURICOMPONENT},
191     {"Infinity", BuiltinType::BT_INFINITY},
192     {"Math", BuiltinType::BT_MATH},
193     {"JSON", BuiltinType::BT_JSON},
194     {"Atomics", BuiltinType::BT_ATOMICS},
195     {"undefined", BuiltinType::BT_UNDEFINED},
196     {"Reflect", BuiltinType::BT_REFLECT},
197     {"Promise", BuiltinType::BT_PROMISE},
198     {"Proxy", BuiltinType::BT_PROXY},
199     {"GeneratorFunction", BuiltinType::BT_GENERATORFUNCTION},
200     {"Intl", BuiltinType::BT_INTL},
201 };
202 
203 enum UserType : uint8_t {
204     COUNTER,
205     CLASS,
206     CLASSINST,
207     FUNCTION,
208     UNION,
209     ARRAY,
210     OBJECT,
211     EXTERNAL,
212     INTERFACE,
213     BUILTININST
214 };
215 
216 enum Modifier : uint8_t {
217     NONSTATIC = 0,
218     STATIC = 1 << 2,
219     ASYNC = 1 << 3,
220     GENERATOR = 1 << 4
221 };
222 
223 enum ModifierAB : uint8_t {
224     NONABSTRACT,
225     ABSTRACT
226 };
227 
228 enum ModifierRO : uint8_t {
229     NONREADONLY,
230     READONLY
231 };
232 
233 enum AccessFlag : uint8_t {
234     PUBLIC,
235     PRIVATE,
236     PROTECTED
237 };
238 
239 class BaseType {
240 public:
BaseType(TypeExtractor * extractor)241     explicit BaseType(TypeExtractor *extractor)
242         : extractor_(extractor), recorder_(extractor_->Recorder()), buffer_(recorder_->NewLiteralBuffer())
243     {
244     }
245     ~BaseType() = default;
246     NO_COPY_SEMANTIC(BaseType);
247     NO_MOVE_SEMANTIC(BaseType);
248 
249 protected:
250     TypeExtractor *extractor_;
251     TypeRecorder *recorder_;
252     compiler::LiteralBuffer *buffer_;
253 
CalculateIndex(const util::StringView & name,int64_t & typeIndex,int64_t & typeIndexShift,bool forBuiltin)254     void CalculateIndex(const util::StringView &name, int64_t &typeIndex, int64_t &typeIndexShift, bool forBuiltin)
255     {
256         if (forBuiltin && extractor_->GetTypeDtsBuiltin()) {
257             auto t = BUILTIN_TYPE_MAP.find(std::string(name));
258             if (t != BUILTIN_TYPE_MAP.end()) {
259                 typeIndexShift = t->second;
260                 typeIndex = typeIndexShift - BuiltinType::BT_HEAD;
261             }
262         }
263 
264         if (typeIndex == PrimitiveType::ANY) {
265             typeIndex = recorder_->AddLiteralBuffer(buffer_);
266             typeIndexShift = typeIndex + recorder_->GetUserTypeIndexShift();
267         } else {
268             recorder_->SetLiteralBuffer(typeIndex, buffer_);
269         }
270     }
271 
CalculateName(const ir::Expression * expression)272     std::variant<util::StringView, const ir::Identifier *> CalculateName(const ir::Expression *expression)
273     {
274         if (expression->IsLiteral()) {
275             auto name = expression->AsLiteral()->GetName();
276             if (name.has_value()) {
277                 return name.value();
278             }
279             return nullptr;
280         } else {
281             return extractor_->GetIdentifierFromExpression(expression);
282         }
283     }
284 
CalculateStr(const ArenaVector<ir::Expression * > & expressions)285     std::string CalculateStr(const ArenaVector<ir::Expression *> &expressions)
286     {
287         std::vector<std::string> tmp;
288         for (const auto &t : expressions) {
289             ir::AstDumper dumper(t);
290             tmp.emplace_back(dumper.Str());
291         }
292         std::sort(tmp.begin(), tmp.end());
293 
294         std::stringstream ss;
295         for (const auto &t : tmp) {
296             ss << t;
297         }
298         return ss.str();
299     }
300 };
301 
302 class TypeCounter : public BaseType {
303 public:
TypeCounter(TypeExtractor * extractor)304     explicit TypeCounter(TypeExtractor *extractor) : BaseType(extractor)
305     {
306         typeIndexPlaceHolder_ = recorder_->AddLiteralBuffer(buffer_);
307         if (extractor_->GetTypeDtsExtractor()) {
308             // Make builtin type slots
309             for (int64_t i = 0; i < TypeRecorder::USERTYPEINDEXHEAD - BuiltinType::BT_HEAD; i++) {
310                 auto buffer = recorder_->NewLiteralBuffer();
311                 (void)recorder_->AddLiteralBuffer(buffer);
312             }
313             recorder_->SetUserTypeIndexShift(BuiltinType::BT_HEAD);
314         }
315     }
316     ~TypeCounter() = default;
317     NO_COPY_SEMANTIC(TypeCounter);
318     NO_MOVE_SEMANTIC(TypeCounter);
319 
GetTypeIndexPlaceHolder()320     int64_t GetTypeIndexPlaceHolder() const
321     {
322         return typeIndexPlaceHolder_;
323     }
324 
FillLiteralBuffer()325     void FillLiteralBuffer()
326     {
327         int64_t userTypeNumber = recorder_->CalculateUserType();
328         buffer_->Add(recorder_->Allocator()->New<ir::NumberLiteral>(UserType::COUNTER));
329         if (extractor_->GetTypeDtsExtractor()) {
330             buffer_->Add(recorder_->Allocator()->New<ir::NumberLiteral>(userTypeNumber +
331                 TypeRecorder::USERTYPEINDEXHEAD - BuiltinType::BT_HEAD));
332         } else {
333             buffer_->Add(recorder_->Allocator()->New<ir::NumberLiteral>(userTypeNumber));
334         }
335         const auto &anonymousReExport = recorder_->GetAnonymousReExport();
336         buffer_->Add(recorder_->Allocator()->New<ir::NumberLiteral>(anonymousReExport.size()));
337         std::for_each(anonymousReExport.begin(), anonymousReExport.end(), [this](const auto &t) {
338             buffer_->Add(recorder_->Allocator()->New<ir::StringLiteral>(t));
339         });
340         recorder_->SetLiteralBuffer(typeIndexPlaceHolder_, buffer_);
341     }
342 
343 private:
344     int64_t typeIndexPlaceHolder_ = PrimitiveType::ANY;
345 };
346 
347 // For { MethodDefinition / FunctionDeclaration / FunctionExpression } -> ScriptFunction / TSMethodSignature
348 class FunctionType : public BaseType {
349 public:
FunctionType(TypeExtractor * extractor,const ir::AstNode * node,const util::StringView & name)350     explicit FunctionType(TypeExtractor *extractor, const ir::AstNode *node, const util::StringView &name)
351         : BaseType(extractor), paramsTypeIndex_(recorder_->Allocator()->Adapter())
352     {
353         CalculateIndex(name, typeIndex_, typeIndexShift_, !(node->IsTSMethodSignature()));
354         name_ = name;
355 
356         auto fn = [this](const auto *func) {
357             recorder_->SetNodeTypeIndex(func, typeIndexShift_);
358             recorder_->AddUserType(typeIndexShift_);
359             if constexpr (std::is_same_v<decltype(func), const ir::ScriptFunction *>) {
360                 if (name_.Is("")) {
361                     name_ = recorder_->GetAnonymousFunctionNames(func);
362                 }
363                 FillModifier(func);
364             }
365             FillParameters(func);
366             FillReturn(func);
367             FillLiteralBuffer();
368         };
369         if (node->IsMethodDefinition()) {
370             auto methodDef = node->AsMethodDefinition();
371             auto modifiers = methodDef->Modifiers();
372             if (modifiers & ir::ModifierFlags::PRIVATE) {
373                 accessFlag_ = AccessFlag::PRIVATE;
374             }
375             if (modifiers & ir::ModifierFlags::PROTECTED) {
376                 accessFlag_ = AccessFlag::PROTECTED;
377             }
378             if (methodDef->IsStatic()) {
379                 modifier_ += Modifier::STATIC;
380             }
381             fn(node->AsMethodDefinition()->Function());
382         } else if (node->IsFunctionDeclaration()) {
383             fn(node->AsFunctionDeclaration()->Function());
384         } else if (node->IsFunctionExpression()) {
385             fn(node->AsFunctionExpression()->Function());
386         } else if (node->IsTSMethodSignature()) {
387             fn(node->AsTSMethodSignature());
388         }
389     }
390     ~FunctionType() = default;
391     NO_COPY_SEMANTIC(FunctionType);
392     NO_MOVE_SEMANTIC(FunctionType);
393 
GetModifier()394     uint8_t GetModifier() const
395     {
396         return modifier_;
397     }
398 
GetTypeIndexShift()399     int64_t GetTypeIndexShift() const
400     {
401         return typeIndexShift_;
402     }
403 
404 private:
405     util::StringView name_ {};
406     AccessFlag accessFlag_ = AccessFlag::PUBLIC;
407     uint8_t modifier_ = Modifier::NONSTATIC;
408     bool containThis_ = false;
409     ArenaVector<int64_t> paramsTypeIndex_;
410     int64_t typeIndexReturn_ = PrimitiveType::ANY;
411     int64_t typeIndex_ = PrimitiveType::ANY;
412     int64_t typeIndexShift_ = PrimitiveType::ANY;
413 
FillModifier(const ir::ScriptFunction * scriptFunc)414     void FillModifier(const ir::ScriptFunction *scriptFunc)
415     {
416         if (scriptFunc->IsAsync()) {
417             modifier_ += Modifier::ASYNC;
418         }
419         if (scriptFunc->IsGenerator()) {
420             modifier_ += Modifier::GENERATOR;
421         }
422     }
423 
424     template <typename T>
FillParameters(const T * func)425     void FillParameters(const T *func)
426     {
427         for (const auto &t : func->Params()) {
428             auto param = t;
429             if (t->IsTSParameterProperty()) {
430                 param = t->AsTSParameterProperty()->Parameter();
431             }
432             if (param->IsAssignmentExpression()) {
433                 param = param->AsAssignmentExpression()->Left();
434             }
435 
436             // Identifier / SpreadElement / RestElement / ArrayExpression / ObjectExpression
437             auto identifier = extractor_->GetIdentifierFromExpression(param);
438             if (identifier != nullptr) {
439                 if (identifier->Name().Is("this") && paramsTypeIndex_.size() == 0) {
440                     containThis_ = true;
441                 }
442                 paramsTypeIndex_.emplace_back(extractor_->GetTypeIndexFromIdentifier(identifier));
443             } else {
444                 paramsTypeIndex_.emplace_back(PrimitiveType::ANY);
445             }
446         }
447     }
448 
449     template <typename T>
FillReturn(const T * func)450     void FillReturn(const T *func)
451     {
452         typeIndexReturn_ = extractor_->GetTypeIndexFromAnnotation(func->ReturnTypeAnnotation());
453     }
454 
FillLiteralBuffer()455     void FillLiteralBuffer()
456     {
457         buffer_->Add(recorder_->Allocator()->New<ir::NumberLiteral>(UserType::FUNCTION));
458         buffer_->Add(recorder_->Allocator()->New<ir::NumberLiteral>(accessFlag_ + modifier_));
459         buffer_->Add(recorder_->Allocator()->New<ir::StringLiteral>(name_));
460         if (containThis_) {
461             buffer_->Add(recorder_->Allocator()->New<ir::NumberLiteral>(1));
462             buffer_->Add(recorder_->Allocator()->New<ir::NumberLiteral>(paramsTypeIndex_.at(0)));
463             buffer_->Add(recorder_->Allocator()->New<ir::NumberLiteral>(paramsTypeIndex_.size() - 1));
464             for (size_t i = 1; i < paramsTypeIndex_.size(); i++) {
465                 buffer_->Add(recorder_->Allocator()->New<ir::NumberLiteral>(paramsTypeIndex_.at(i)));
466             }
467         } else {
468             buffer_->Add(recorder_->Allocator()->New<ir::NumberLiteral>(0));
469             buffer_->Add(recorder_->Allocator()->New<ir::NumberLiteral>(paramsTypeIndex_.size()));
470             for (size_t i = 0; i < paramsTypeIndex_.size(); i++) {
471                 buffer_->Add(recorder_->Allocator()->New<ir::NumberLiteral>(paramsTypeIndex_.at(i)));
472             }
473         }
474         buffer_->Add(recorder_->Allocator()->New<ir::NumberLiteral>(typeIndexReturn_));
475     }
476 };
477 
478 // For { ClassDeclaration / ClassExpression } -> ClassDefinition
479 class ClassType : public BaseType {
480 public:
ClassType(TypeExtractor * extractor,const ir::ClassDefinition * classDef,const util::StringView & name)481     explicit ClassType(TypeExtractor *extractor, const ir::ClassDefinition *classDef, const util::StringView &name)
482         : BaseType(extractor),
483           implementsHeritages_(recorder_->Allocator()->Adapter()),
484           staticFields_(recorder_->Allocator()->Adapter()),
485           staticMethods_(recorder_->Allocator()->Adapter()),
486           fields_(recorder_->Allocator()->Adapter()),
487           methods_(recorder_->Allocator()->Adapter())
488     {
489         CalculateIndex(name, typeIndex_, typeIndexShift_, true);
490         recorder_->SetNodeTypeIndex(classDef, typeIndexShift_);
491         recorder_->AddUserType(typeIndexShift_);
492 
493         FillModifier(classDef);
494         FillHeritages(classDef);
495         FillFieldsandMethods(classDef);
496         FillLiteralBuffer();
497     }
498     ~ClassType() = default;
499     NO_COPY_SEMANTIC(ClassType);
500     NO_MOVE_SEMANTIC(ClassType);
501 
GetTypeIndexShift()502     int64_t GetTypeIndexShift()
503     {
504         return typeIndexShift_;
505     }
506 
507 private:
508     ModifierAB modifierAB_ = ModifierAB::NONABSTRACT;
509     int64_t extendsHeritage_ = PrimitiveType::ANY;
510     ArenaVector<int64_t> implementsHeritages_;
511     // 3 field infos, typeIndex / accessFlag / modifier
512     ArenaMap<util::StringView, std::array<int64_t, 3>> staticFields_;
513     ArenaMap<util::StringView, int64_t> staticMethods_;
514     // 3 field infos, typeIndex / accessFlag / modifier
515     ArenaMap<util::StringView, std::array<int64_t, 3>> fields_;
516     ArenaMap<util::StringView, int64_t> methods_;
517     int64_t typeIndex_ = PrimitiveType::ANY;
518     int64_t typeIndexShift_ = PrimitiveType::ANY;
519 
FillModifier(const ir::ClassDefinition * classDef)520     void FillModifier(const ir::ClassDefinition *classDef)
521     {
522         if (classDef->Abstract()) {
523             modifierAB_ = ModifierAB::ABSTRACT;
524         }
525     }
526 
FillHeritages(const ir::ClassDefinition * classDef)527     void FillHeritages(const ir::ClassDefinition *classDef)
528     {
529         auto super = classDef->Super();
530         if (super != nullptr) {
531             extendsHeritage_ = extractor_->GetTypeIndexFromInitializer(super);
532         }
533 
534         for (const auto &t : classDef->Implements()) {
535             if (t != nullptr) {
536                 implementsHeritages_.emplace_back(extractor_->GetTypeIndexFromInitializer(t));
537             }
538         }
539     }
540 
FillField(const ir::ClassProperty * field)541     void FillField(const ir::ClassProperty *field)
542     {
543         auto modifiers = field->Modifiers();
544         bool isStatic = (modifiers & ir::ModifierFlags::STATIC);
545         AccessFlag flag = AccessFlag::PUBLIC;
546         if (modifiers & ir::ModifierFlags::PRIVATE) {
547             flag = AccessFlag::PRIVATE;
548         }
549         if (modifiers & ir::ModifierFlags::PROTECTED) {
550             flag = AccessFlag::PROTECTED;
551         }
552         ModifierRO modifier = ModifierRO::NONREADONLY;
553         if (modifiers & ir::ModifierFlags::READONLY) {
554             modifier = ModifierRO::READONLY;
555         }
556 
557         int64_t typeIndex = extractor_->GetTypeIndexFromAnnotation(field->TypeAnnotation());
558         // 3 field infos, typeIndex / accessFlag / modifier
559         std::array<int64_t, 3> fieldInfo = {typeIndex, flag, modifier};
560         auto fn = [&fieldInfo, &isStatic, this](const util::StringView &name) {
561             if (isStatic) {
562                 staticFields_[name] = fieldInfo;
563             } else {
564                 fields_[name] = fieldInfo;
565             }
566         };
567 
568         const ir::Expression *expression;
569         if (field->Key()->IsTSPrivateIdentifier()) {
570             expression = field->Key()->AsTSPrivateIdentifier()->Key();
571         } else {
572             expression = field->Key();
573         }
574         auto res = CalculateName(expression);
575         if (std::holds_alternative<util::StringView>(res)) {
576             fn(std::get<util::StringView>(res));
577         } else {
578             auto identifier = std::get<const ir::Identifier *>(res);
579             if (identifier != nullptr) {
580                 recorder_->SetIdentifierTypeIndex(identifier, typeIndex);
581                 fn(identifier->Name());
582             }
583         }
584     }
585 
FillMethod(const ir::MethodDefinition * method)586     void FillMethod(const ir::MethodDefinition *method)
587     {
588         auto fn = [&method, this](const FunctionType &functionType, const util::StringView &name) {
589             if (functionType.GetModifier() == Modifier::NONSTATIC) {
590                 methods_[name] = recorder_->GetNodeTypeIndex(method->Function());
591             } else {
592                 staticMethods_[name] = recorder_->GetNodeTypeIndex(method->Function());
593             }
594         };
595 
596         auto res = CalculateName(method->Key());
597         if (std::holds_alternative<util::StringView>(res)) {
598             auto name = std::get<util::StringView>(res);
599             FunctionType functionType(extractor_, method, name);
600             fn(functionType, name);
601         } else {
602             auto identifier = std::get<const ir::Identifier *>(res);
603             if (identifier != nullptr) {
604                 auto name = identifier->Name();
605                 FunctionType functionType(extractor_, method, name);
606                 recorder_->SetIdentifierTypeIndex(identifier, functionType.GetTypeIndexShift());
607                 fn(functionType, name);
608             }
609         }
610     }
611 
FillFieldsandMethods(const ir::ClassDefinition * classDef)612     void FillFieldsandMethods(const ir::ClassDefinition *classDef)
613     {
614         auto methodDef = const_cast<ir::ClassDefinition *>(classDef)->Ctor();
615         ASSERT(methodDef->IsMethodDefinition());
616         // Filter Implicit Constructor
617         const auto &range = methodDef->Key()->Range();
618         if (!(range.start.index == range.end.index && range.start.line == range.end.line &&
619             range.start.index == range.start.line && range.end.index == range.end.line)) {
620             FillMethod(methodDef);
621         }
622 
623         for (const auto &t : classDef->Body()) {
624             if (t->IsClassProperty()) {
625                 FillField(t->AsClassProperty());
626             } else if (t->IsMethodDefinition()) {
627                 FillMethod(t->AsMethodDefinition());
628             }
629         }
630     }
631 
FillFieldsLiteralBuffer(bool isStatic)632     void FillFieldsLiteralBuffer(bool isStatic)
633     {
634         // 3 field infos, typeIndex / accessFlag / modifier
635         auto fn = [this](const ArenaMap<util::StringView, std::array<int64_t, 3>> &map) {
636             buffer_->Add(recorder_->Allocator()->New<ir::NumberLiteral>(map.size()));
637             std::for_each(map.begin(), map.end(), [this](const auto &t) {
638                 buffer_->Add(recorder_->Allocator()->New<ir::StringLiteral>(t.first));
639                 buffer_->Add(recorder_->Allocator()->New<ir::NumberLiteral>(t.second[0]));  // 0. typeIndex
640                 buffer_->Add(recorder_->Allocator()->New<ir::NumberLiteral>(t.second[1]));  // 1. accessFlag
641                 buffer_->Add(recorder_->Allocator()->New<ir::NumberLiteral>(t.second[2]));  // 2. modifier
642             });
643         };
644 
645         if (isStatic) {
646             fn(staticFields_);
647         } else {
648             fn(fields_);
649         }
650     }
651 
FillMethodsLiteralBuffer(bool isStatic)652     void FillMethodsLiteralBuffer(bool isStatic)
653     {
654         auto fn = [this](const ArenaMap<util::StringView, int64_t> &map) {
655             buffer_->Add(recorder_->Allocator()->New<ir::NumberLiteral>(map.size()));
656             std::for_each(map.begin(), map.end(), [this](const auto &t) {
657                 buffer_->Add(recorder_->Allocator()->New<ir::StringLiteral>(t.first));
658                 buffer_->Add(recorder_->Allocator()->New<ir::NumberLiteral>(t.second));
659             });
660         };
661 
662         if (isStatic) {
663             fn(staticMethods_);
664         } else {
665             fn(methods_);
666         }
667     }
668 
FillLiteralBuffer()669     void FillLiteralBuffer()
670     {
671         buffer_->Add(recorder_->Allocator()->New<ir::NumberLiteral>(UserType::CLASS));
672         buffer_->Add(recorder_->Allocator()->New<ir::NumberLiteral>(modifierAB_));
673         buffer_->Add(recorder_->Allocator()->New<ir::NumberLiteral>(extendsHeritage_));
674         buffer_->Add(recorder_->Allocator()->New<ir::NumberLiteral>(implementsHeritages_.size()));
675         std::for_each(implementsHeritages_.begin(), implementsHeritages_.end(), [this](const auto &t) {
676             buffer_->Add(recorder_->Allocator()->New<ir::NumberLiteral>(t));
677         });
678 
679         FillFieldsLiteralBuffer(false);
680         FillMethodsLiteralBuffer(false);
681         FillFieldsLiteralBuffer(true);
682         FillMethodsLiteralBuffer(true);
683     }
684 };
685 
686 class ClassInstType : public BaseType {
687 public:
ClassInstType(TypeExtractor * extractor,int64_t typeIndexRefShift)688     explicit ClassInstType(TypeExtractor *extractor, int64_t typeIndexRefShift)
689         : BaseType(extractor), typeIndexRefShift_(typeIndexRefShift)
690     {
691         typeIndex_ = recorder_->AddLiteralBuffer(buffer_);
692         typeIndexShift_ = typeIndex_ + recorder_->GetUserTypeIndexShift();
693         recorder_->SetClassInst(typeIndexRefShift_, typeIndexShift_);
694         recorder_->SetClassType(typeIndexShift_, typeIndexRefShift_);
695         recorder_->AddUserType(typeIndexShift_);
696 
697         FillLiteralBuffer();
698     }
699     ~ClassInstType() = default;
700     NO_COPY_SEMANTIC(ClassInstType);
701     NO_MOVE_SEMANTIC(ClassInstType);
702 
GetTypeIndexShift()703     int64_t GetTypeIndexShift() const
704     {
705         return typeIndexShift_;
706     }
707 
708 private:
709     int64_t typeIndexRefShift_ = PrimitiveType::ANY;
710     int64_t typeIndex_ = PrimitiveType::ANY;
711     int64_t typeIndexShift_ = PrimitiveType::ANY;
712 
FillLiteralBuffer()713     void FillLiteralBuffer()
714     {
715         buffer_->Add(recorder_->Allocator()->New<ir::NumberLiteral>(UserType::CLASSINST));
716         buffer_->Add(recorder_->Allocator()->New<ir::NumberLiteral>(typeIndexRefShift_));
717     }
718 };
719 
720 class InterfaceType : public BaseType {
721 public:
InterfaceType(TypeExtractor * extractor,const ir::TSInterfaceDeclaration * interfaceDef,const util::StringView & name)722     explicit InterfaceType(TypeExtractor *extractor, const ir::TSInterfaceDeclaration *interfaceDef,
723                            const util::StringView &name)
724         : BaseType(extractor),
725           heritages_(recorder_->Allocator()->Adapter()),
726           fields_(recorder_->Allocator()->Adapter()),
727           methods_(recorder_->Allocator()->Adapter())
728     {
729         CalculateIndex(name, typeIndex_, typeIndexShift_, true);
730         recorder_->SetNodeTypeIndex(interfaceDef, typeIndexShift_);
731         recorder_->AddUserType(typeIndexShift_);
732 
733         FillHeritages(interfaceDef);
734         FillFieldsandMethods(interfaceDef);
735         FillLiteralBuffer();
736     }
737     ~InterfaceType() = default;
738     NO_COPY_SEMANTIC(InterfaceType);
739     NO_MOVE_SEMANTIC(InterfaceType);
740 
GetTypeIndexShift()741     int64_t GetTypeIndexShift()
742     {
743         return typeIndexShift_;
744     }
745 
746 private:
747     ArenaVector<int64_t> heritages_;
748     // 3 field infos, typeIndex / accessFlag / modifier
749     ArenaMap<util::StringView, std::array<int64_t, 3>> fields_;
750     ArenaMap<util::StringView, int64_t> methods_;
751     int64_t typeIndex_ = PrimitiveType::ANY;
752     int64_t typeIndexShift_ = PrimitiveType::ANY;
753 
FillHeritages(const ir::TSInterfaceDeclaration * interfaceDef)754     void FillHeritages(const ir::TSInterfaceDeclaration *interfaceDef)
755     {
756         for (const auto &t : interfaceDef->Extends()) {
757             if (t != nullptr) {
758                 heritages_.emplace_back(extractor_->GetTypeIndexFromInitializer(t));
759             }
760         }
761     }
762 
FillField(const ir::TSPropertySignature * field)763     void FillField(const ir::TSPropertySignature *field)
764     {
765         AccessFlag flag = AccessFlag::PUBLIC;
766         ModifierRO modifier = ModifierRO::NONREADONLY;
767         if (field->Readonly()) {
768             modifier = ModifierRO::READONLY;
769         }
770 
771         int64_t typeIndex = extractor_->GetTypeIndexFromAnnotation(field->TypeAnnotation());
772         // 3 field infos, typeIndex / accessFlag / modifier
773         std::array<int64_t, 3> fieldInfo = {typeIndex, flag, modifier};
774 
775         auto res = CalculateName(field->Key());
776         if (std::holds_alternative<util::StringView>(res)) {
777             fields_[std::get<util::StringView>(res)] = fieldInfo;
778         } else {
779             auto identifier = std::get<const ir::Identifier *>(res);
780             if (identifier != nullptr) {
781                 recorder_->SetIdentifierTypeIndex(identifier, typeIndex);
782                 fields_[identifier->Name()] = fieldInfo;
783             }
784         }
785     }
786 
FillMethod(const ir::TSMethodSignature * method)787     void FillMethod(const ir::TSMethodSignature *method)
788     {
789         auto res = CalculateName(method->Key());
790         if (std::holds_alternative<util::StringView>(res)) {
791             auto name = std::get<util::StringView>(res);
792             FunctionType functionType(extractor_, method, name);
793             methods_[name] = recorder_->GetNodeTypeIndex(method);
794         } else {
795             auto identifier = std::get<const ir::Identifier *>(res);
796             if (identifier != nullptr) {
797                 auto name = identifier->Name();
798                 FunctionType functionType(extractor_, method, name);
799                 recorder_->SetIdentifierTypeIndex(identifier, functionType.GetTypeIndexShift());
800                 methods_[name] = recorder_->GetNodeTypeIndex(method);
801             }
802         }
803     }
804 
FillFieldsandMethods(const ir::TSInterfaceDeclaration * interfaceDef)805     void FillFieldsandMethods(const ir::TSInterfaceDeclaration *interfaceDef)
806     {
807         for (const auto &t : interfaceDef->Body()->Body()) {
808             if (t->IsTSPropertySignature()) {
809                 FillField(t->AsTSPropertySignature());
810             } else if (t->IsTSMethodSignature()) {
811                 FillMethod(t->AsTSMethodSignature());
812             }
813         }
814     }
815 
FillFieldsLiteralBuffer()816     void FillFieldsLiteralBuffer()
817     {
818         buffer_->Add(recorder_->Allocator()->New<ir::NumberLiteral>(fields_.size()));
819         std::for_each(fields_.begin(), fields_.end(), [this](const auto &t) {
820             buffer_->Add(recorder_->Allocator()->New<ir::StringLiteral>(t.first));
821             buffer_->Add(recorder_->Allocator()->New<ir::NumberLiteral>(t.second[0]));  // 0. typeIndex
822             buffer_->Add(recorder_->Allocator()->New<ir::NumberLiteral>(t.second[1]));  // 1. accessFlag
823             buffer_->Add(recorder_->Allocator()->New<ir::NumberLiteral>(t.second[2]));  // 2. modifier
824         });
825     }
826 
FillMethodsLiteralBuffer()827     void FillMethodsLiteralBuffer()
828     {
829         buffer_->Add(recorder_->Allocator()->New<ir::NumberLiteral>(methods_.size()));
830         std::for_each(methods_.begin(), methods_.end(), [this](const auto &t) {
831             buffer_->Add(recorder_->Allocator()->New<ir::StringLiteral>(t.first));
832             buffer_->Add(recorder_->Allocator()->New<ir::NumberLiteral>(t.second));
833         });
834     }
835 
FillLiteralBuffer()836     void FillLiteralBuffer()
837     {
838         buffer_->Add(recorder_->Allocator()->New<ir::NumberLiteral>(UserType::INTERFACE));
839         buffer_->Add(recorder_->Allocator()->New<ir::NumberLiteral>(heritages_.size()));
840         std::for_each(heritages_.begin(), heritages_.end(), [this](const auto &t) {
841             buffer_->Add(recorder_->Allocator()->New<ir::NumberLiteral>(t));
842         });
843 
844         FillFieldsLiteralBuffer();
845         FillMethodsLiteralBuffer();
846     }
847 };
848 
849 class ExternalType : public BaseType {
850 public:
ExternalType(TypeExtractor * extractor,const util::StringView & importName,const util::StringView & redirectPath)851     explicit ExternalType(TypeExtractor *extractor, const util::StringView &importName,
852                           const util::StringView &redirectPath) : BaseType(extractor)
853     {
854         std::stringstream ss;
855         ss << "#" + std::string(importName) + "#" + std::string(redirectPath);
856         redirectPath_ = util::UString(ss.str(), recorder_->Allocator()).View();
857         typeIndex_ = recorder_->AddLiteralBuffer(buffer_);
858         typeIndexShift_ = typeIndex_ + recorder_->GetUserTypeIndexShift();
859         recorder_->AddUserType(typeIndexShift_);
860 
861         FillLiteralBuffer();
862     }
863     ~ExternalType() = default;
864     NO_COPY_SEMANTIC(ExternalType);
865     NO_MOVE_SEMANTIC(ExternalType);
866 
GetTypeIndexShift()867     int64_t GetTypeIndexShift()
868     {
869         return typeIndexShift_;
870     }
871 
872 private:
873     util::StringView redirectPath_;
874     int64_t typeIndex_ = PrimitiveType::ANY;
875     int64_t typeIndexShift_ = PrimitiveType::ANY;
876 
FillLiteralBuffer()877     void FillLiteralBuffer()
878     {
879         buffer_->Add(recorder_->Allocator()->New<ir::NumberLiteral>(UserType::EXTERNAL));
880         buffer_->Add(recorder_->Allocator()->New<ir::StringLiteral>(redirectPath_));
881     }
882 };
883 
884 class UnionType : public BaseType {
885 public:
UnionType(TypeExtractor * extractor,const ir::TSUnionType * unionDef)886     explicit UnionType(TypeExtractor *extractor, const ir::TSUnionType *unionDef)
887         : BaseType(extractor), unionTypes_(recorder_->Allocator()->Adapter())
888     {
889         auto unionStr = CalculateStr(unionDef->Types());
890         typeIndexShift_ = recorder_->GetUnionType(unionStr);
891         if (typeIndexShift_ != PrimitiveType::ANY) {
892             return;
893         }
894 
895         typeIndex_ = recorder_->AddLiteralBuffer(buffer_);
896         typeIndexShift_ = typeIndex_ + recorder_->GetUserTypeIndexShift();
897         recorder_->SetUnionType(unionStr, typeIndexShift_);
898         recorder_->AddUserType(typeIndexShift_);
899 
900         FillTypes(unionDef);
901         FillLiteralBuffer();
902     }
903     ~UnionType() = default;
904     NO_COPY_SEMANTIC(UnionType);
905     NO_MOVE_SEMANTIC(UnionType);
906 
GetTypeIndexShift()907     int64_t GetTypeIndexShift()
908     {
909         return typeIndexShift_;
910     }
911 
912 private:
913     ArenaVector<int64_t> unionTypes_;
914     int64_t typeIndex_ = PrimitiveType::ANY;
915     int64_t typeIndexShift_ = PrimitiveType::ANY;
916 
FillTypes(const ir::TSUnionType * unionDef)917     void FillTypes(const ir::TSUnionType *unionDef)
918     {
919         for (const auto &t : unionDef->Types()) {
920             unionTypes_.emplace_back(extractor_->GetTypeIndexFromAnnotation(t));
921         }
922     }
923 
FillLiteralBuffer()924     void FillLiteralBuffer()
925     {
926         buffer_->Add(recorder_->Allocator()->New<ir::NumberLiteral>(UserType::UNION));
927         buffer_->Add(recorder_->Allocator()->New<ir::NumberLiteral>(unionTypes_.size()));
928         std::for_each(unionTypes_.begin(), unionTypes_.end(), [this](const auto &t) {
929             buffer_->Add(recorder_->Allocator()->New<ir::NumberLiteral>(t));
930         });
931     }
932 };
933 
934 class ArrayType : public BaseType {
935 public:
ArrayType(TypeExtractor * extractor,const ir::TSArrayType * arrayDef)936     explicit ArrayType(TypeExtractor *extractor, const ir::TSArrayType *arrayDef) : BaseType(extractor)
937     {
938         typeIndexRefShift_ = extractor_->GetTypeIndexFromAnnotation(arrayDef->ElementType());
939         typeIndexShift_ = recorder_->GetArrayType(typeIndexRefShift_);
940         if (typeIndexShift_ != PrimitiveType::ANY) {
941             return;
942         }
943 
944         typeIndex_ = recorder_->AddLiteralBuffer(buffer_);
945         typeIndexShift_ = typeIndex_ + recorder_->GetUserTypeIndexShift();
946         recorder_->SetArrayType(typeIndexRefShift_, typeIndexShift_);
947         recorder_->AddUserType(typeIndexShift_);
948 
949         FillLiteralBuffer();
950     }
951     ~ArrayType() = default;
952     NO_COPY_SEMANTIC(ArrayType);
953     NO_MOVE_SEMANTIC(ArrayType);
954 
GetTypeIndexShift()955     int64_t GetTypeIndexShift()
956     {
957         return typeIndexShift_;
958     }
959 
960 private:
961     int64_t typeIndexRefShift_ = PrimitiveType::ANY;
962     int64_t typeIndex_ = PrimitiveType::ANY;
963     int64_t typeIndexShift_ = PrimitiveType::ANY;
964 
FillLiteralBuffer()965     void FillLiteralBuffer()
966     {
967         buffer_->Add(recorder_->Allocator()->New<ir::NumberLiteral>(UserType::ARRAY));
968         buffer_->Add(recorder_->Allocator()->New<ir::NumberLiteral>(typeIndexRefShift_));
969     }
970 };
971 
972 class ObjectType : public BaseType {
973 public:
ObjectType(TypeExtractor * extractor,const ir::TSTypeLiteral * literalDef)974     explicit ObjectType(TypeExtractor *extractor, const ir::TSTypeLiteral *literalDef)
975         : BaseType(extractor), properties_(recorder_->Allocator()->Adapter())
976     {
977         std::string objectStr = "object";
978         if (literalDef != nullptr) {
979             objectStr = CalculateStr(literalDef->Members());
980         }
981         typeIndexShift_ = recorder_->GetObjectType(objectStr);
982         if (typeIndexShift_ != PrimitiveType::ANY) {
983             return;
984         }
985 
986         typeIndex_ = recorder_->AddLiteralBuffer(buffer_);
987         typeIndexShift_ = typeIndex_ + recorder_->GetUserTypeIndexShift();
988         recorder_->SetObjectType(objectStr, typeIndexShift_);
989         recorder_->AddUserType(typeIndexShift_);
990 
991         if (literalDef != nullptr) {
992             FillMembers(literalDef);
993         }
994         FillLiteralBuffer();
995     }
996     ~ObjectType() = default;
997     NO_COPY_SEMANTIC(ObjectType);
998     NO_MOVE_SEMANTIC(ObjectType);
999 
GetTypeIndexShift()1000     int64_t GetTypeIndexShift()
1001     {
1002         return typeIndexShift_;
1003     }
1004 
1005 private:
1006     ArenaMap<util::StringView, int64_t> properties_;
1007     int64_t typeIndex_ = PrimitiveType::ANY;
1008     int64_t typeIndexShift_ = PrimitiveType::ANY;
1009 
FillMembers(const ir::TSTypeLiteral * literalDef)1010     void FillMembers(const ir::TSTypeLiteral *literalDef)
1011     {
1012         auto fn = [this](const auto *property, int64_t typeIndex) {
1013             auto res = CalculateName(property->Key());
1014             if (std::holds_alternative<util::StringView>(res)) {
1015                 properties_[std::get<util::StringView>(res)] = typeIndex;
1016             } else {
1017                 auto identifier = std::get<const ir::Identifier *>(res);
1018                 if (identifier != nullptr) {
1019                     recorder_->SetIdentifierTypeIndex(identifier, typeIndex);
1020                     properties_[identifier->Name()] = typeIndex;
1021                 }
1022             }
1023         };
1024 
1025         for (const auto &t : literalDef->Members()) {
1026             if (t->IsTSPropertySignature()) {
1027                 auto property = t->AsTSPropertySignature();
1028                 int64_t typeIndex = extractor_->GetTypeIndexFromAnnotation(property->TypeAnnotation());
1029                 fn(property, typeIndex);
1030             } else if (t->IsTSMethodSignature()) {
1031                 auto property = t->AsTSMethodSignature();
1032                 int64_t typeIndex = extractor_->GetTypeIndexFromAnnotation(property->ReturnTypeAnnotation());
1033                 fn(property, typeIndex);
1034             }
1035         }
1036     }
1037 
FillLiteralBuffer()1038     void FillLiteralBuffer()
1039     {
1040         buffer_->Add(recorder_->Allocator()->New<ir::NumberLiteral>(UserType::OBJECT));
1041         buffer_->Add(recorder_->Allocator()->New<ir::NumberLiteral>(properties_.size()));
1042         std::for_each(properties_.begin(), properties_.end(), [this](const auto &t) {
1043             buffer_->Add(recorder_->Allocator()->New<ir::StringLiteral>(t.first));
1044             buffer_->Add(recorder_->Allocator()->New<ir::NumberLiteral>(t.second));
1045         });
1046     }
1047 };
1048 
1049 class BuiltinInstType : public BaseType {
1050 public:
BuiltinInstType(TypeExtractor * extractor,const std::vector<int64_t> & allTypes)1051     explicit BuiltinInstType(TypeExtractor *extractor, const std::vector<int64_t> &allTypes)
1052         : BaseType(extractor), paramTypes_(recorder_->Allocator()->Adapter())
1053     {
1054         typeIndexBuiltin_ = allTypes[0];
1055         typeIndex_ = recorder_->AddLiteralBuffer(buffer_);
1056         typeIndexShift_ = typeIndex_ + recorder_->GetUserTypeIndexShift();
1057         recorder_->SetBuiltinInst(allTypes, typeIndexShift_);
1058         recorder_->AddUserType(typeIndexShift_);
1059 
1060         FillTypes(allTypes);
1061         FillLiteralBuffer();
1062     }
1063     ~BuiltinInstType() = default;
1064     NO_COPY_SEMANTIC(BuiltinInstType);
1065     NO_MOVE_SEMANTIC(BuiltinInstType);
1066 
GetTypeIndexShift()1067     int64_t GetTypeIndexShift()
1068     {
1069         return typeIndexShift_;
1070     }
1071 
1072 private:
1073     ArenaVector<int64_t> paramTypes_;
1074     int64_t typeIndexBuiltin_ = PrimitiveType::ANY;
1075     int64_t typeIndex_ = PrimitiveType::ANY;
1076     int64_t typeIndexShift_ = PrimitiveType::ANY;
1077 
FillTypes(const std::vector<int64_t> & allTypes)1078     void FillTypes(const std::vector<int64_t> &allTypes)
1079     {
1080         for (size_t t = 1; t < allTypes.size(); t++) {
1081             paramTypes_.emplace_back(allTypes[t]);
1082         }
1083     }
1084 
FillLiteralBuffer()1085     void FillLiteralBuffer()
1086     {
1087         buffer_->Add(recorder_->Allocator()->New<ir::NumberLiteral>(UserType::BUILTININST));
1088         buffer_->Add(recorder_->Allocator()->New<ir::NumberLiteral>(typeIndexBuiltin_));
1089         buffer_->Add(recorder_->Allocator()->New<ir::NumberLiteral>(paramTypes_.size()));
1090         std::for_each(paramTypes_.begin(), paramTypes_.end(), [this](const auto &t) {
1091             buffer_->Add(recorder_->Allocator()->New<ir::NumberLiteral>(t));
1092         });
1093     }
1094 };
1095 
1096 }  // namespace panda::es2panda::extractor
1097 
1098 #endif  // ES2PANDA_TYPESCRIPT_EXACTOR_TYPESYSTEM_H
1099