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/arrowFunctionExpression.h> 30 #include <ir/expressions/assignmentExpression.h> 31 #include <ir/expressions/functionExpression.h> 32 #include <ir/expressions/identifier.h> 33 #include <ir/expressions/literals/numberLiteral.h> 34 #include <ir/expressions/literals/stringLiteral.h> 35 #include <ir/statements/classDeclaration.h> 36 #include <ir/statements/functionDeclaration.h> 37 #include <ir/ts/tsArrayType.h> 38 #include <ir/ts/tsClassImplements.h> 39 #include <ir/ts/tsConstructorType.h> 40 #include <ir/ts/tsFunctionType.h> 41 #include <ir/ts/tsIndexSignature.h> 42 #include <ir/ts/tsInterfaceBody.h> 43 #include <ir/ts/tsInterfaceDeclaration.h> 44 #include <ir/ts/tsInterfaceHeritage.h> 45 #include <ir/ts/tsMethodSignature.h> 46 #include <ir/ts/tsParameterProperty.h> 47 #include <ir/ts/tsPrivateIdentifier.h> 48 #include <ir/ts/tsPropertySignature.h> 49 #include <ir/ts/tsSignatureDeclaration.h> 50 #include <ir/ts/tsTypeLiteral.h> 51 #include <ir/ts/tsTypeParameter.h> 52 #include <ir/ts/tsTypeParameterDeclaration.h> 53 #include <ir/ts/tsUnionType.h> 54 55 namespace panda::es2panda::extractor { 56 57 enum PrimitiveType : uint8_t { 58 ANY = 0, 59 NUMBER, 60 BOOLEAN, 61 VOID, 62 STRING, 63 SYMBOL, 64 NUL, 65 UNDEFINED, 66 INT, 67 }; 68 69 const std::unordered_map<ir::AstNodeType, PrimitiveType> PRIMITIVE_TYPE_MAP = { 70 {ir::AstNodeType::TS_ANY_KEYWORD, PrimitiveType::ANY}, 71 {ir::AstNodeType::TS_NUMBER_KEYWORD, PrimitiveType::NUMBER}, 72 {ir::AstNodeType::TS_BOOLEAN_KEYWORD, PrimitiveType::BOOLEAN}, 73 {ir::AstNodeType::TS_VOID_KEYWORD, PrimitiveType::VOID}, 74 {ir::AstNodeType::TS_STRING_KEYWORD, PrimitiveType::STRING}, 75 {ir::AstNodeType::TS_SYMBOL_KEYWORD, PrimitiveType::SYMBOL}, 76 {ir::AstNodeType::TS_NULL_KEYWORD, PrimitiveType::NUL}, 77 {ir::AstNodeType::TS_UNDEFINED_KEYWORD, PrimitiveType::UNDEFINED}, 78 // Placeholder for Type Inference INT 79 }; 80 81 enum BuiltinType : uint8_t { 82 BT_HEAD = 20, 83 BT_FUNCTION, 84 BT_RANGEERROR, 85 BT_ERROR, 86 BT_OBJECT, 87 BT_SYNTAXERROR, 88 BT_TYPEERROR, 89 BT_REFERENCEERROR, 90 BT_URIERROR, 91 BT_SYMBOL, 92 BT_EVALERROR, 93 BT_NUMBER, 94 BT_PARSEFLOAT, 95 BT_DATE, 96 BT_BOOLEAN, 97 BT_BIGINT, 98 BT_PARSEINT, 99 BT_WEAKMAP, 100 BT_REGEXP, 101 BT_SET, 102 BT_MAP, 103 BT_WEAKREF, 104 BT_WEAKSET, 105 BT_FINALIZATIONREGISTRY, 106 BT_ARRAY, 107 BT_UINT8CLAMPEDARRAY, 108 BT_UINT8ARRAY, 109 BT_TYPEDARRAY, 110 BT_INT8ARRAY, 111 BT_UINT16ARRAY, 112 BT_UINT32ARRAY, 113 BT_INT16ARRAY, 114 BT_INT32ARRAY, 115 BT_FLOAT32ARRAY, 116 BT_FLOAT64ARRAY, 117 BT_BIGINT64ARRAY, 118 BT_BIGUINT64ARRAY, 119 BT_SHAREDARRAYBUFFER, 120 BT_DATAVIEW, 121 BT_STRING, 122 BT_ARRAYBUFFER, 123 BT_EVAL, 124 BT_ISFINITE, 125 BT_ARKPRIVATE, 126 BT_PRINT, 127 BT_DECODEURI, 128 BT_DECODEURICOMPONENT, 129 BT_ISNAN, 130 BT_ENCODEURI, 131 BT_NAN, 132 BT_GLOBALTHIS, 133 BT_ENCODEURICOMPONENT, 134 BT_INFINITY, 135 BT_MATH, 136 BT_JSON, 137 BT_ATOMICS, 138 BT_UNDEFINED, 139 BT_REFLECT, 140 BT_PROMISE, 141 BT_PROXY, 142 BT_GENERATORFUNCTION, 143 BT_INTL, 144 }; 145 146 const std::unordered_map<std::string, BuiltinType> BUILTIN_TYPE_MAP = { 147 {"Function", BuiltinType::BT_FUNCTION}, 148 {"RangeError", BuiltinType::BT_RANGEERROR}, 149 {"Error", BuiltinType::BT_ERROR}, 150 {"Object", BuiltinType::BT_OBJECT}, 151 {"SyntaxError", BuiltinType::BT_SYNTAXERROR}, 152 {"TypeError", BuiltinType::BT_TYPEERROR}, 153 {"ReferenceError", BuiltinType::BT_REFERENCEERROR}, 154 {"URIError", BuiltinType::BT_URIERROR}, 155 {"Symbol", BuiltinType::BT_SYMBOL}, 156 {"EvalError", BuiltinType::BT_EVALERROR}, 157 {"Number", BuiltinType::BT_NUMBER}, 158 {"parseFloat", BuiltinType::BT_PARSEFLOAT}, 159 {"Date", BuiltinType::BT_DATE}, 160 {"Boolean", BuiltinType::BT_BOOLEAN}, 161 {"BigInt", BuiltinType::BT_BIGINT}, 162 {"parseInt", BuiltinType::BT_PARSEINT}, 163 {"WeakMap", BuiltinType::BT_WEAKMAP}, 164 {"RegExp", BuiltinType::BT_REGEXP}, 165 {"Set", BuiltinType::BT_SET}, 166 {"Map", BuiltinType::BT_MAP}, 167 {"WeakRef", BuiltinType::BT_WEAKREF}, 168 {"WeakSet", BuiltinType::BT_WEAKSET}, 169 {"FinalizationRegistry", BuiltinType::BT_FINALIZATIONREGISTRY}, 170 {"Array", BuiltinType::BT_ARRAY}, 171 {"Uint8ClampedArray", BuiltinType::BT_UINT8CLAMPEDARRAY}, 172 {"Uint8Array", BuiltinType::BT_UINT8ARRAY}, 173 {"TypedArray", BuiltinType::BT_TYPEDARRAY}, 174 {"Int8Array", BuiltinType::BT_INT8ARRAY}, 175 {"Uint16Array", BuiltinType::BT_UINT16ARRAY}, 176 {"Uint32Array", BuiltinType::BT_UINT32ARRAY}, 177 {"Int16Array", BuiltinType::BT_INT16ARRAY}, 178 {"Int32Array", BuiltinType::BT_INT32ARRAY}, 179 {"Float32Array", BuiltinType::BT_FLOAT32ARRAY}, 180 {"Float64Array", BuiltinType::BT_FLOAT64ARRAY}, 181 {"BigInt64Array", BuiltinType::BT_BIGINT64ARRAY}, 182 {"BigUint64Array", BuiltinType::BT_BIGUINT64ARRAY}, 183 {"SharedArrayBuffer", BuiltinType::BT_SHAREDARRAYBUFFER}, 184 {"DataView", BuiltinType::BT_DATAVIEW}, 185 {"String", BuiltinType::BT_STRING}, 186 {"ArrayBuffer", BuiltinType::BT_ARRAYBUFFER}, 187 {"eval", BuiltinType::BT_EVAL}, 188 {"isFinite", BuiltinType::BT_ISFINITE}, 189 {"ArkPrivate", BuiltinType::BT_ARKPRIVATE}, 190 {"print", BuiltinType::BT_PRINT}, 191 {"decodeURI", BuiltinType::BT_DECODEURI}, 192 {"decodeURIComponent", BuiltinType::BT_DECODEURICOMPONENT}, 193 {"isNaN", BuiltinType::BT_ISNAN}, 194 {"encodeURI", BuiltinType::BT_ENCODEURI}, 195 {"NaN", BuiltinType::BT_NAN}, 196 {"globalThis", BuiltinType::BT_GLOBALTHIS}, 197 {"encodeURIComponent", BuiltinType::BT_ENCODEURICOMPONENT}, 198 {"Infinity", BuiltinType::BT_INFINITY}, 199 {"Math", BuiltinType::BT_MATH}, 200 {"JSON", BuiltinType::BT_JSON}, 201 {"Atomics", BuiltinType::BT_ATOMICS}, 202 {"undefined", BuiltinType::BT_UNDEFINED}, 203 {"Reflect", BuiltinType::BT_REFLECT}, 204 {"Promise", BuiltinType::BT_PROMISE}, 205 {"Proxy", BuiltinType::BT_PROXY}, 206 {"GeneratorFunction", BuiltinType::BT_GENERATORFUNCTION}, 207 {"Intl", BuiltinType::BT_INTL}, 208 }; 209 210 enum UserType : uint8_t { 211 COUNTER, 212 CLASS, 213 CLASSINST, 214 FUNCTION, 215 UNION, 216 ARRAY, 217 OBJECT, 218 EXTERNAL, 219 INTERFACE, 220 BUILTININST, 221 GENERICINST, 222 INDEXSIG 223 }; 224 225 enum BuiltinFlag : int8_t { 226 NAMESPACE_FUNCTION = -1, 227 ENUM_FUNCTION = -2 228 }; 229 230 enum FuncModifier : uint8_t { 231 NOMODIFIER = 0, 232 STATIC = 1 << 2, 233 ASYNC = 1 << 3, 234 GENERATOR = 1 << 4, 235 ACCESSOR = 1 << 5, 236 ABSTRACT = 1 << 6, 237 OVERLOAD = 1 << 7 238 }; 239 240 enum AccessFlag : uint8_t { 241 PUBLIC, 242 PRIVATE, 243 PROTECTED 244 }; 245 246 class BaseType { 247 public: BaseType(TypeExtractor * extractor)248 explicit BaseType(TypeExtractor *extractor) 249 : extractor_(extractor), recorder_(extractor_->Recorder()), buffer_(recorder_->NewLiteralBuffer()) 250 { 251 } 252 ~BaseType() = default; 253 NO_COPY_SEMANTIC(BaseType); 254 NO_MOVE_SEMANTIC(BaseType); 255 256 protected: 257 TypeExtractor *extractor_; 258 TypeRecorder *recorder_; 259 compiler::LiteralBuffer *buffer_; 260 FillTypeIndexLiteralBuffer(int64_t typeIndex)261 void FillTypeIndexLiteralBuffer(int64_t typeIndex) 262 { 263 if (typeIndex >= recorder_->GetUserTypeIndexShift()) { 264 std::stringstream ss; 265 ss << std::string(recorder_->GetRecordName()) << "_" << (typeIndex - recorder_->GetUserTypeIndexShift()); 266 buffer_->Add(recorder_->Allocator()->New<ir::UserTypeIndexLiteral>(typeIndex, 267 util::UString(ss.str(), recorder_->Allocator()).View())); 268 } else if (typeIndex >= PrimitiveType::ANY) { 269 buffer_->Add(recorder_->Allocator()->New<ir::BuiltinTypeIndexLiteral>(typeIndex)); 270 } else { 271 buffer_->Add(recorder_->Allocator()->New<ir::NumberLiteral>(typeIndex)); 272 } 273 } 274 CalculateIndex(const util::StringView & name,int64_t & typeIndex,int64_t & typeIndexShift,bool forBuiltin)275 void CalculateIndex(const util::StringView &name, int64_t &typeIndex, int64_t &typeIndexShift, bool forBuiltin) 276 { 277 if (forBuiltin && extractor_->GetTypeDtsBuiltin()) { 278 auto t = BUILTIN_TYPE_MAP.find(std::string(name)); 279 if (t != BUILTIN_TYPE_MAP.end()) { 280 typeIndexShift = t->second; 281 typeIndex = typeIndexShift - BuiltinType::BT_HEAD; 282 } 283 } 284 285 if (typeIndex == PrimitiveType::ANY) { 286 typeIndex = recorder_->AddLiteralBuffer(buffer_); 287 typeIndexShift = typeIndex + recorder_->GetUserTypeIndexShift(); 288 } else { 289 recorder_->SetLiteralBuffer(typeIndex, buffer_); 290 } 291 } 292 CalculateName(const ir::Expression * expression)293 std::variant<util::StringView, const ir::Identifier *> CalculateName(const ir::Expression *expression) 294 { 295 if (expression->IsLiteral()) { 296 auto name = expression->AsLiteral()->GetName(); 297 if (name.has_value()) { 298 return name.value(); 299 } 300 return nullptr; 301 } else { 302 return extractor_->GetIdentifierFromExpression(expression); 303 } 304 } 305 CalculateStr(const ArenaVector<ir::Expression * > & expressions)306 std::string CalculateStr(const ArenaVector<ir::Expression *> &expressions) 307 { 308 std::vector<std::string> tmp; 309 for (const auto &t : expressions) { 310 ir::AstDumper dumper(t); 311 tmp.emplace_back(dumper.Str()); 312 } 313 std::sort(tmp.begin(), tmp.end()); 314 315 std::stringstream ss; 316 for (const auto &t : tmp) { 317 ss << t; 318 } 319 return ss.str(); 320 } 321 CalculateParamTypes(ArenaMap<util::StringView,int64_t> & paramTypes,const ir::TSTypeParameterDeclaration * typeParams)322 void CalculateParamTypes(ArenaMap<util::StringView, int64_t> ¶mTypes, 323 const ir::TSTypeParameterDeclaration *typeParams) 324 { 325 int64_t index = 0; 326 for (const auto &t : typeParams->Params()) { 327 paramTypes[t->Name()->Name()] = (--index); 328 } 329 } 330 }; 331 332 class TypeCounter : public BaseType { 333 public: TypeCounter(TypeExtractor * extractor)334 explicit TypeCounter(TypeExtractor *extractor) : BaseType(extractor) 335 { 336 typeIndexPlaceHolder_ = recorder_->AddLiteralBuffer(buffer_); 337 if (extractor_->GetTypeDtsExtractor()) { 338 // Make builtin type slots 339 for (int64_t i = 0; i < TypeRecorder::USERTYPEINDEXHEAD - BuiltinType::BT_HEAD; i++) { 340 auto buffer = recorder_->NewLiteralBuffer(); 341 (void)recorder_->AddLiteralBuffer(buffer); 342 } 343 recorder_->SetUserTypeIndexShift(BuiltinType::BT_HEAD); 344 } 345 } 346 ~TypeCounter() = default; 347 NO_COPY_SEMANTIC(TypeCounter); 348 NO_MOVE_SEMANTIC(TypeCounter); 349 GetTypeIndexPlaceHolder()350 int64_t GetTypeIndexPlaceHolder() const 351 { 352 return typeIndexPlaceHolder_; 353 } 354 FillLiteralBuffer()355 void FillLiteralBuffer() 356 { 357 const auto &userType = recorder_->GetUserType(); 358 if (extractor_->GetTypeDtsExtractor()) { 359 buffer_->Add(recorder_->Allocator()->New<ir::NumberLiteral>(userType.size() + 360 TypeRecorder::USERTYPEINDEXHEAD - BuiltinType::BT_HEAD)); 361 for (int builtinTypeOrder = BuiltinType::BT_HEAD; builtinTypeOrder < TypeRecorder::USERTYPEINDEXHEAD; 362 builtinTypeOrder++) { 363 FillTypeIndexLiteralBuffer(builtinTypeOrder + 1); 364 } 365 } else { 366 buffer_->Add(recorder_->Allocator()->New<ir::NumberLiteral>(userType.size())); 367 } 368 std::for_each(userType.begin(), userType.end(), [this](const auto &t) { 369 FillTypeIndexLiteralBuffer(t); 370 }); 371 const auto &anonymousReExport = recorder_->GetAnonymousReExport(); 372 buffer_->Add(recorder_->Allocator()->New<ir::NumberLiteral>(anonymousReExport.size())); 373 std::for_each(anonymousReExport.begin(), anonymousReExport.end(), [this](const auto &t) { 374 buffer_->Add(recorder_->Allocator()->New<ir::StringLiteral>(t)); 375 }); 376 recorder_->SetLiteralBuffer(typeIndexPlaceHolder_, buffer_); 377 } 378 379 private: 380 int64_t typeIndexPlaceHolder_ = PrimitiveType::ANY; 381 }; 382 383 class IndexSigType : public BaseType { 384 public: IndexSigType(TypeExtractor * extractor,int64_t typeIndexRefShift,const ArenaMap<int64_t,int64_t> * indexSignatures)385 explicit IndexSigType(TypeExtractor *extractor, int64_t typeIndexRefShift, 386 const ArenaMap<int64_t, int64_t> *indexSignatures) 387 : BaseType(extractor), typeIndexRefShift_(typeIndexRefShift) 388 { 389 typeIndex_ = recorder_->AddLiteralBuffer(buffer_); 390 typeIndexShift_ = typeIndex_ + recorder_->GetUserTypeIndexShift(); 391 recorder_->SetIndexSig(typeIndexRefShift_, typeIndexShift_); 392 recorder_->AddUserType(typeIndexShift_); 393 394 FillLiteralBuffer(indexSignatures); 395 } 396 ~IndexSigType() = default; 397 NO_COPY_SEMANTIC(IndexSigType); 398 NO_MOVE_SEMANTIC(IndexSigType); 399 GetTypeIndexShift()400 int64_t GetTypeIndexShift() const 401 { 402 return typeIndexShift_; 403 } 404 405 private: 406 int64_t typeIndexRefShift_ = PrimitiveType::ANY; 407 int64_t typeIndex_ = PrimitiveType::ANY; 408 int64_t typeIndexShift_ = PrimitiveType::ANY; 409 FillLiteralBuffer(const ArenaMap<int64_t,int64_t> * indexSignatures)410 void FillLiteralBuffer(const ArenaMap<int64_t, int64_t> *indexSignatures) 411 { 412 buffer_->Add(recorder_->Allocator()->New<ir::NumberLiteral>(UserType::INDEXSIG)); 413 FillTypeIndexLiteralBuffer(typeIndexRefShift_); 414 415 ASSERT(indexSignatures != nullptr); 416 buffer_->Add(recorder_->Allocator()->New<ir::NumberLiteral>(indexSignatures->size())); 417 std::for_each(indexSignatures->begin(), indexSignatures->end(), [this](const auto &t) { 418 FillTypeIndexLiteralBuffer(t.first); 419 FillTypeIndexLiteralBuffer(t.second); 420 }); 421 } 422 }; 423 424 // 8 types of AstNode to create FunctionType 425 // For { MethodDefinition / FunctionDeclaration / FunctionExpression / ArrowFunctionExpression } 426 // which contains ScriptFunction 427 // For { TSMethodSignature / TSSignatureDeclaration / TSFunctionType / TSConstructorType } 428 // which only contains Signature 429 class FunctionType : public BaseType { 430 public: FunctionType(TypeExtractor * extractor,const ir::AstNode * node,const util::StringView & name)431 explicit FunctionType(TypeExtractor *extractor, const ir::AstNode *node, const util::StringView &name) 432 : BaseType(extractor), paramsTypeIndex_(recorder_->Allocator()->Adapter()) 433 { 434 name_ = name; 435 436 auto fn = [this](const auto *func) { 437 typeIndexShift_ = recorder_->GetNodeTypeIndex(func); 438 if (typeIndexShift_ != PrimitiveType::ANY) { 439 return; 440 } 441 442 CalculateIndex(name_, typeIndex_, typeIndexShift_, !(func->IsTSMethodSignature())); 443 recorder_->SetNodeTypeIndex(func, typeIndexShift_); 444 recorder_->AddUserType(typeIndexShift_); 445 if constexpr (std::is_same_v<decltype(func), const ir::ScriptFunction *>) { 446 if (name_.Is("")) { 447 name_ = recorder_->GetAnonymousFunctionNames(func); 448 } 449 FillModifier(func); 450 if (func->ThisParams() != nullptr) { 451 auto identifier = func->ThisParams()->AsIdentifier(); 452 paramsTypeIndex_.emplace_back(extractor_->GetTypeIndexFromIdentifier(identifier)); 453 containThis_ = true; 454 } 455 } 456 FillParameters(func); 457 FillReturn(func); 458 FillLiteralBuffer(); 459 }; 460 461 if (node->IsMethodDefinition()) { 462 auto methodDef = node->AsMethodDefinition(); 463 auto modifiers = methodDef->Modifiers(); 464 if (modifiers & ir::ModifierFlags::PRIVATE) { 465 accessFlag_ = AccessFlag::PRIVATE; 466 } 467 if (modifiers & ir::ModifierFlags::PROTECTED) { 468 accessFlag_ = AccessFlag::PROTECTED; 469 } 470 FillMethodModifier(methodDef); 471 fn(methodDef->Function()); 472 } else if (node->IsFunctionDeclaration()) { 473 fn(node->AsFunctionDeclaration()->Function()); 474 } else if (node->IsFunctionExpression()) { 475 fn(node->AsFunctionExpression()->Function()); 476 } else if (node->IsArrowFunctionExpression()) { 477 fn(node->AsArrowFunctionExpression()->Function()); 478 } else if (node->IsTSMethodSignature()) { 479 fn(node->AsTSMethodSignature()); 480 } else if (node->IsTSSignatureDeclaration() || node->IsTSFunctionType() || node->IsTSConstructorType()) { 481 HandleFuncNodeWithoutName(node); 482 } 483 } 484 ~FunctionType() = default; 485 NO_COPY_SEMANTIC(FunctionType); 486 NO_MOVE_SEMANTIC(FunctionType); 487 GetModifier()488 uint8_t GetModifier() const 489 { 490 return modifier_; 491 } 492 GetTypeIndexShift()493 int64_t GetTypeIndexShift() const 494 { 495 return typeIndexShift_; 496 } 497 498 private: 499 util::StringView name_ {}; 500 AccessFlag accessFlag_ = AccessFlag::PUBLIC; 501 uint8_t modifier_ = FuncModifier::NOMODIFIER; 502 bool containThis_ = false; 503 ArenaVector<int64_t> paramsTypeIndex_; 504 int64_t typeIndexReturn_ = PrimitiveType::ANY; 505 int64_t typeIndex_ = PrimitiveType::ANY; 506 int64_t typeIndexShift_ = PrimitiveType::ANY; 507 HandleFuncNodeWithoutName(const ir::AstNode * node)508 void HandleFuncNodeWithoutName(const ir::AstNode *node) 509 { 510 ir::AstDumper dumper(node); 511 auto functionStr = dumper.Str(); 512 typeIndexShift_ = recorder_->GetFunctionType(functionStr); 513 if (typeIndexShift_ != PrimitiveType::ANY) { 514 return; 515 } 516 517 typeIndex_ = recorder_->AddLiteralBuffer(buffer_); 518 typeIndexShift_ = typeIndex_ + recorder_->GetUserTypeIndexShift(); 519 recorder_->SetFunctionType(functionStr, typeIndexShift_); 520 recorder_->AddUserType(typeIndexShift_); 521 522 if (node->IsTSSignatureDeclaration()) { 523 FillParameters(node->AsTSSignatureDeclaration()); 524 FillReturn(node->AsTSSignatureDeclaration()); 525 } else if (node->IsTSFunctionType()) { 526 FillParameters(node->AsTSFunctionType()); 527 FillReturn(node->AsTSFunctionType()); 528 } else { 529 FillParameters(node->AsTSConstructorType()); 530 FillReturn(node->AsTSConstructorType()); 531 } 532 FillLiteralBuffer(); 533 } 534 FillMethodModifier(const ir::MethodDefinition * methodDef)535 void FillMethodModifier(const ir::MethodDefinition *methodDef) 536 { 537 if (methodDef->IsStatic()) { 538 modifier_ += FuncModifier::STATIC; 539 } 540 if (methodDef->IsAccessor()) { 541 modifier_ += FuncModifier::ACCESSOR; 542 } 543 if (methodDef->IsAbstract()) { 544 modifier_ += FuncModifier::ABSTRACT; 545 } 546 } 547 FillModifier(const ir::ScriptFunction * scriptFunc)548 void FillModifier(const ir::ScriptFunction *scriptFunc) 549 { 550 if (scriptFunc->IsAsync()) { 551 modifier_ += FuncModifier::ASYNC; 552 } 553 if (scriptFunc->IsGenerator()) { 554 modifier_ += FuncModifier::GENERATOR; 555 } 556 if (scriptFunc->IsOverload()) { 557 modifier_ += FuncModifier::OVERLOAD; 558 } 559 } 560 561 template <typename T> FillParameters(const T * func)562 void FillParameters(const T *func) 563 { 564 for (const auto &t : func->Params()) { 565 auto param = t; 566 if (t->IsTSParameterProperty()) { 567 param = t->AsTSParameterProperty()->Parameter(); 568 } 569 if (param->IsAssignmentExpression()) { 570 param = param->AsAssignmentExpression()->Left(); 571 } 572 if (param->IsAssignmentPattern()) { 573 param = param->AsAssignmentPattern()->Left(); 574 } 575 576 // Identifier / SpreadElement / RestElement / ArrayExpression / ObjectExpression 577 auto identifier = extractor_->GetIdentifierFromExpression(param); 578 if (identifier != nullptr) { 579 if (identifier->Name().Is("this") && paramsTypeIndex_.size() == 0) { 580 containThis_ = true; 581 } 582 paramsTypeIndex_.emplace_back(extractor_->GetTypeIndexFromIdentifier(identifier)); 583 } else { 584 paramsTypeIndex_.emplace_back(PrimitiveType::ANY); 585 } 586 } 587 } 588 589 template <typename T> FillReturn(const T * func)590 void FillReturn(const T *func) 591 { 592 typeIndexReturn_ = extractor_->GetTypeIndexFromAnnotation(func->ReturnTypeAnnotation()); 593 } 594 FillLiteralBuffer()595 void FillLiteralBuffer() 596 { 597 buffer_->Add(recorder_->Allocator()->New<ir::NumberLiteral>(UserType::FUNCTION)); 598 buffer_->Add(recorder_->Allocator()->New<ir::NumberLiteral>(accessFlag_ + modifier_)); 599 buffer_->Add(recorder_->Allocator()->New<ir::StringLiteral>(name_)); 600 if (containThis_) { 601 buffer_->Add(recorder_->Allocator()->New<ir::NumberLiteral>(1)); 602 FillTypeIndexLiteralBuffer(paramsTypeIndex_.at(0)); 603 buffer_->Add(recorder_->Allocator()->New<ir::NumberLiteral>(paramsTypeIndex_.size() - 1)); 604 for (size_t i = 1; i < paramsTypeIndex_.size(); i++) { 605 FillTypeIndexLiteralBuffer(paramsTypeIndex_.at(i)); 606 } 607 } else { 608 buffer_->Add(recorder_->Allocator()->New<ir::NumberLiteral>(0)); 609 buffer_->Add(recorder_->Allocator()->New<ir::NumberLiteral>(paramsTypeIndex_.size())); 610 for (size_t i = 0; i < paramsTypeIndex_.size(); i++) { 611 FillTypeIndexLiteralBuffer(paramsTypeIndex_.at(i)); 612 } 613 } 614 FillTypeIndexLiteralBuffer(typeIndexReturn_); 615 } 616 }; 617 618 // 2 types of AstNode to create ClassType 619 // For { ClassDeclaration / ClassExpression } 620 // which contains ClassDefinition 621 class ClassType : public BaseType { 622 public: ClassType(TypeExtractor * extractor,const ir::ClassDefinition * classDef,const util::StringView & name)623 explicit ClassType(TypeExtractor *extractor, const ir::ClassDefinition *classDef, const util::StringView &name) 624 : BaseType(extractor), 625 implementsHeritages_(recorder_->Allocator()->Adapter()), 626 paramTypes_(recorder_->Allocator()->Adapter()), 627 staticFields_(recorder_->Allocator()->Adapter()), 628 staticMethods_(recorder_->Allocator()->Adapter()), 629 fields_(recorder_->Allocator()->Adapter()), 630 methods_(recorder_->Allocator()->Adapter()), 631 indexSignatures_(recorder_->Allocator()->Adapter()) 632 { 633 typeIndexShift_ = recorder_->GetNodeTypeIndex(classDef); 634 if (typeIndexShift_ != PrimitiveType::ANY) { 635 return; 636 } 637 638 if (classDef->TypeParams() != nullptr) { 639 CalculateParamTypes(paramTypes_, classDef->TypeParams()); 640 } 641 642 CalculateIndex(name, typeIndex_, typeIndexShift_, true); 643 recorder_->SetNodeTypeIndex(classDef, typeIndexShift_); 644 recorder_->AddUserType(typeIndexShift_); 645 646 GenericParamTypeBindScope scope(extractor, ¶mTypes_); 647 FillModifier(classDef); 648 FillHeritages(classDef); 649 FillFieldsandMethods(classDef); 650 FillIndexSignatures(classDef); 651 FillLiteralBuffer(); 652 } 653 ~ClassType() = default; 654 NO_COPY_SEMANTIC(ClassType); 655 NO_MOVE_SEMANTIC(ClassType); 656 GetTypeIndexShift()657 int64_t GetTypeIndexShift() const 658 { 659 return typeIndexShift_; 660 } 661 662 private: 663 bool modifierAB_ = false; 664 int64_t extendsHeritage_ = PrimitiveType::ANY; 665 ArenaVector<int64_t> implementsHeritages_; 666 ArenaMap<util::StringView, int64_t> paramTypes_; 667 // 3 field infos, typeIndex / accessFlag / modifier 668 ArenaMap<util::StringView, std::array<int64_t, 3>> staticFields_; 669 ArenaMap<int64_t, util::StringView> staticMethods_; 670 // 3 field infos, typeIndex / accessFlag / modifier 671 ArenaMap<util::StringView, std::array<int64_t, 3>> fields_; 672 ArenaMap<int64_t, util::StringView> methods_; 673 ArenaMap<int64_t, int64_t> indexSignatures_; 674 int64_t typeIndex_ = PrimitiveType::ANY; 675 int64_t typeIndexShift_ = PrimitiveType::ANY; 676 677 size_t fieldsWithInitNum_ = 0U; 678 size_t methodsWithBodyNum_ = 0U; 679 FillModifier(const ir::ClassDefinition * classDef)680 void FillModifier(const ir::ClassDefinition *classDef) 681 { 682 modifierAB_ = classDef->Abstract(); 683 } 684 FillHeritages(const ir::ClassDefinition * classDef)685 void FillHeritages(const ir::ClassDefinition *classDef) 686 { 687 auto super = classDef->Super(); 688 if (super != nullptr) { 689 extendsHeritage_ = extractor_->GetTypeIndexFromInitializer(super); 690 } 691 692 for (const auto &t : classDef->Implements()) { 693 if (t != nullptr) { 694 implementsHeritages_.emplace_back(extractor_->GetTypeIndexFromInitializer(t)); 695 } 696 } 697 } 698 FillField(const ir::ClassProperty * field)699 void FillField(const ir::ClassProperty *field) 700 { 701 auto modifiers = field->Modifiers(); 702 bool isStatic = (modifiers & ir::ModifierFlags::STATIC); 703 AccessFlag flag = AccessFlag::PUBLIC; 704 if (modifiers & ir::ModifierFlags::PRIVATE) { 705 flag = AccessFlag::PRIVATE; 706 } 707 if (modifiers & ir::ModifierFlags::PROTECTED) { 708 flag = AccessFlag::PROTECTED; 709 } 710 auto isReadonly = (modifiers & ir::ModifierFlags::READONLY); 711 712 int64_t typeIndex = extractor_->GetTypeIndexFromAnnotation(field->TypeAnnotation()); 713 if (typeIndex == PrimitiveType::ANY && field->Value() != nullptr) { 714 typeIndex = extractor_->GetTypeIndexFromInitializer(field->Value()); 715 } 716 717 // 3 field infos, typeIndex / accessFlag / modifier 718 std::array<int64_t, 3> fieldInfo = {typeIndex, flag, static_cast<int64_t>(isReadonly)}; 719 auto fn = [&fieldInfo, &isStatic, this](const util::StringView &name) { 720 if (isStatic) { 721 staticFields_[name] = fieldInfo; 722 } else { 723 fields_[name] = fieldInfo; 724 } 725 }; 726 727 const ir::Expression *expression; 728 if (field->Key()->IsTSPrivateIdentifier()) { 729 expression = field->Key()->AsTSPrivateIdentifier()->Key(); 730 } else { 731 expression = field->Key(); 732 } 733 auto res = CalculateName(expression); 734 if (std::holds_alternative<util::StringView>(res)) { 735 fn(std::get<util::StringView>(res)); 736 } else { 737 auto identifier = std::get<const ir::Identifier *>(res); 738 if (identifier != nullptr) { 739 recorder_->SetIdentifierTypeIndex(identifier, typeIndex); 740 fn(identifier->Name()); 741 } 742 } 743 744 if (field->Value() != nullptr) { 745 fieldsWithInitNum_++; 746 } 747 } 748 FillMethod(const ir::MethodDefinition * method)749 void FillMethod(const ir::MethodDefinition *method) 750 { 751 auto fn = [&method, this](const FunctionType &functionType, const util::StringView &name) { 752 if ((functionType.GetModifier() & FuncModifier::STATIC) == 0) { 753 methods_[recorder_->GetNodeTypeIndex(method->Function())] = name; 754 } else { 755 staticMethods_ [recorder_->GetNodeTypeIndex(method->Function())] = name; 756 } 757 }; 758 759 auto res = CalculateName(method->Key()); 760 if (std::holds_alternative<util::StringView>(res)) { 761 auto name = std::get<util::StringView>(res); 762 FunctionType functionType(extractor_, method, name); 763 fn(functionType, name); 764 } else { 765 auto identifier = std::get<const ir::Identifier *>(res); 766 if (identifier != nullptr) { 767 auto name = identifier->Name(); 768 FunctionType functionType(extractor_, method, name); 769 recorder_->SetIdentifierTypeIndex(identifier, functionType.GetTypeIndexShift()); 770 fn(functionType, name); 771 } 772 } 773 774 if (method->Function()->Body() != nullptr) { 775 methodsWithBodyNum_++; 776 } 777 } 778 FillFieldsandMethods(const ir::ClassDefinition * classDef)779 void FillFieldsandMethods(const ir::ClassDefinition *classDef) 780 { 781 auto methodDef = const_cast<ir::ClassDefinition *>(classDef)->Ctor(); 782 ASSERT(methodDef->IsMethodDefinition()); 783 // Filter Implicit Constructor 784 const auto &range = methodDef->Key()->Range(); 785 if (!(range.start.index == range.end.index && range.start.line == range.end.line && 786 range.start.index == range.start.line && range.end.index == range.end.line)) { 787 FillMethod(methodDef); 788 } 789 790 for (const auto &t : classDef->Body()) { 791 if (t->IsClassProperty()) { 792 FillField(t->AsClassProperty()); 793 } else if (t->IsMethodDefinition()) { 794 FillMethod(t->AsMethodDefinition()); 795 } 796 } 797 798 // Create class instance type stands for 'this' 799 if (!classDef->Abstract() && (fieldsWithInitNum_ > 0U || methodsWithBodyNum_ > 0U)) { 800 (void)extractor_->GetTypeIndexFromClassInst(typeIndexShift_, classDef); 801 } 802 } 803 FillIndexSignatures(const ir::ClassDefinition * classDef)804 void FillIndexSignatures(const ir::ClassDefinition *classDef) 805 { 806 for (const auto &t : classDef->IndexSignatures()) { 807 auto key = t->Param()->AsIdentifier()->TypeAnnotation(); 808 indexSignatures_[extractor_->GetTypeIndexFromAnnotation(key)] = 809 extractor_->GetTypeIndexFromAnnotation(t->TypeAnnotation()); 810 } 811 if (indexSignatures_.size() > 0U) { 812 // Update current type to IndexSignture Type 813 IndexSigType indexSigType(extractor_, typeIndexShift_, &indexSignatures_); 814 typeIndexShift_ = indexSigType.GetTypeIndexShift(); 815 recorder_->UpdateNodeTypeIndex(classDef, typeIndexShift_); 816 } 817 } 818 FillFieldsLiteralBuffer(bool isStatic)819 void FillFieldsLiteralBuffer(bool isStatic) 820 { 821 // 3 field infos, typeIndex / accessFlag / modifier 822 auto fn = [this](const ArenaMap<util::StringView, std::array<int64_t, 3>> &map) { 823 buffer_->Add(recorder_->Allocator()->New<ir::NumberLiteral>(map.size())); 824 std::for_each(map.begin(), map.end(), [this](const auto &t) { 825 buffer_->Add(recorder_->Allocator()->New<ir::StringLiteral>(t.first)); 826 FillTypeIndexLiteralBuffer(t.second[0]); // 0. typeIndex 827 buffer_->Add(recorder_->Allocator()->New<ir::NumberLiteral>(t.second[1])); // 1. accessFlag 828 buffer_->Add(recorder_->Allocator()->New<ir::NumberLiteral>(t.second[2])); // 2. modifier 829 }); 830 }; 831 832 if (isStatic) { 833 fn(staticFields_); 834 } else { 835 fn(fields_); 836 } 837 } 838 FillMethodsLiteralBuffer(bool isStatic)839 void FillMethodsLiteralBuffer(bool isStatic) 840 { 841 auto fn = [this](const ArenaMap<int64_t, util::StringView> &map) { 842 buffer_->Add(recorder_->Allocator()->New<ir::NumberLiteral>(map.size())); 843 std::for_each(map.begin(), map.end(), [this](const auto &t) { 844 buffer_->Add(recorder_->Allocator()->New<ir::StringLiteral>(t.second)); 845 FillTypeIndexLiteralBuffer(t.first); 846 }); 847 }; 848 849 if (isStatic) { 850 fn(staticMethods_); 851 } else { 852 fn(methods_); 853 } 854 } 855 FillLiteralBuffer()856 void FillLiteralBuffer() 857 { 858 buffer_->Add(recorder_->Allocator()->New<ir::NumberLiteral>(UserType::CLASS)); 859 buffer_->Add(recorder_->Allocator()->New<ir::NumberLiteral>(modifierAB_)); 860 FillTypeIndexLiteralBuffer(extendsHeritage_); 861 buffer_->Add(recorder_->Allocator()->New<ir::NumberLiteral>(implementsHeritages_.size())); 862 std::for_each(implementsHeritages_.begin(), implementsHeritages_.end(), [this](const auto &t) { 863 FillTypeIndexLiteralBuffer(t); 864 }); 865 866 FillFieldsLiteralBuffer(false); 867 FillMethodsLiteralBuffer(false); 868 FillFieldsLiteralBuffer(true); 869 FillMethodsLiteralBuffer(true); 870 } 871 }; 872 873 class ClassInstType : public BaseType { 874 public: ClassInstType(TypeExtractor * extractor,int64_t typeIndexRefShift)875 explicit ClassInstType(TypeExtractor *extractor, int64_t typeIndexRefShift) 876 : BaseType(extractor), typeIndexRefShift_(typeIndexRefShift) 877 { 878 typeIndex_ = recorder_->AddLiteralBuffer(buffer_); 879 typeIndexShift_ = typeIndex_ + recorder_->GetUserTypeIndexShift(); 880 recorder_->SetClassInst(typeIndexRefShift_, typeIndexShift_); 881 recorder_->SetClassType(typeIndexShift_, typeIndexRefShift_); 882 recorder_->AddUserType(typeIndexShift_); 883 884 FillLiteralBuffer(); 885 } 886 ~ClassInstType() = default; 887 NO_COPY_SEMANTIC(ClassInstType); 888 NO_MOVE_SEMANTIC(ClassInstType); 889 GetTypeIndexShift()890 int64_t GetTypeIndexShift() const 891 { 892 return typeIndexShift_; 893 } 894 895 private: 896 int64_t typeIndexRefShift_ = PrimitiveType::ANY; 897 int64_t typeIndex_ = PrimitiveType::ANY; 898 int64_t typeIndexShift_ = PrimitiveType::ANY; 899 FillLiteralBuffer()900 void FillLiteralBuffer() 901 { 902 buffer_->Add(recorder_->Allocator()->New<ir::NumberLiteral>(UserType::CLASSINST)); 903 FillTypeIndexLiteralBuffer(typeIndexRefShift_); 904 } 905 }; 906 907 class InterfaceType : public BaseType { 908 public: InterfaceType(TypeExtractor * extractor,const ir::TSInterfaceDeclaration * interfaceDef,const util::StringView & name)909 explicit InterfaceType(TypeExtractor *extractor, const ir::TSInterfaceDeclaration *interfaceDef, 910 const util::StringView &name) 911 : BaseType(extractor), 912 heritages_(recorder_->Allocator()->Adapter()), 913 paramTypes_(recorder_->Allocator()->Adapter()), 914 fields_(recorder_->Allocator()->Adapter()), 915 methods_(recorder_->Allocator()->Adapter()), 916 indexSignatures_(recorder_->Allocator()->Adapter()) 917 { 918 typeIndexShift_ = recorder_->GetNodeTypeIndex(interfaceDef); 919 if (typeIndexShift_ != PrimitiveType::ANY) { 920 return; 921 } 922 923 if (interfaceDef->TypeParams() != nullptr) { 924 CalculateParamTypes(paramTypes_, interfaceDef->TypeParams()); 925 } 926 927 CalculateIndex(name, typeIndex_, typeIndexShift_, true); 928 recorder_->SetNodeTypeIndex(interfaceDef, typeIndexShift_); 929 recorder_->AddUserType(typeIndexShift_); 930 931 GenericParamTypeBindScope scope(extractor, ¶mTypes_); 932 FillHeritages(interfaceDef); 933 FillMembers(interfaceDef); 934 FillLiteralBuffer(); 935 } 936 ~InterfaceType() = default; 937 NO_COPY_SEMANTIC(InterfaceType); 938 NO_MOVE_SEMANTIC(InterfaceType); 939 GetTypeIndexShift()940 int64_t GetTypeIndexShift() const 941 { 942 return typeIndexShift_; 943 } 944 945 private: 946 ArenaVector<int64_t> heritages_; 947 ArenaMap<util::StringView, int64_t> paramTypes_; 948 // 3 field infos, typeIndex / accessFlag / modifier 949 ArenaMap<util::StringView, std::array<int64_t, 3>> fields_; 950 ArenaVector<int64_t> methods_; 951 ArenaMap<int64_t, int64_t> indexSignatures_; 952 int64_t typeIndex_ = PrimitiveType::ANY; 953 int64_t typeIndexShift_ = PrimitiveType::ANY; 954 FillHeritages(const ir::TSInterfaceDeclaration * interfaceDef)955 void FillHeritages(const ir::TSInterfaceDeclaration *interfaceDef) 956 { 957 for (const auto &t : interfaceDef->Extends()) { 958 if (t != nullptr) { 959 // TSTypeReference 960 heritages_.emplace_back(extractor_->GetTypeIndexFromAnnotation(t->Expr(), false)); 961 } 962 } 963 } 964 FillField(const ir::TSPropertySignature * field)965 void FillField(const ir::TSPropertySignature *field) 966 { 967 AccessFlag flag = AccessFlag::PUBLIC; 968 auto isReadonly = field->Readonly(); 969 970 int64_t typeIndex = extractor_->GetTypeIndexFromAnnotation(field->TypeAnnotation()); 971 // 3 field infos, typeIndex / accessFlag / modifier 972 std::array<int64_t, 3> fieldInfo = {typeIndex, flag, static_cast<int64_t>(isReadonly)}; 973 974 auto res = CalculateName(field->Key()); 975 if (std::holds_alternative<util::StringView>(res)) { 976 fields_[std::get<util::StringView>(res)] = fieldInfo; 977 } else { 978 auto identifier = std::get<const ir::Identifier *>(res); 979 if (identifier != nullptr) { 980 recorder_->SetIdentifierTypeIndex(identifier, typeIndex); 981 fields_[identifier->Name()] = fieldInfo; 982 } 983 } 984 } 985 FillMethod(const ir::TSMethodSignature * method)986 void FillMethod(const ir::TSMethodSignature *method) 987 { 988 auto res = CalculateName(method->Key()); 989 if (std::holds_alternative<util::StringView>(res)) { 990 auto name = std::get<util::StringView>(res); 991 FunctionType functionType(extractor_, method, name); 992 methods_.emplace_back(recorder_->GetNodeTypeIndex(method)); 993 } else { 994 auto identifier = std::get<const ir::Identifier *>(res); 995 if (identifier != nullptr) { 996 auto name = identifier->Name(); 997 FunctionType functionType(extractor_, method, name); 998 recorder_->SetIdentifierTypeIndex(identifier, functionType.GetTypeIndexShift()); 999 methods_.emplace_back(recorder_->GetNodeTypeIndex(method)); 1000 } 1001 } 1002 } 1003 FillMethod(const ir::TSSignatureDeclaration * method)1004 void FillMethod(const ir::TSSignatureDeclaration *method) 1005 { 1006 FunctionType functionType(extractor_, method, ""); 1007 methods_.emplace_back(recorder_->GetNodeTypeIndex(method)); 1008 } 1009 FillIndexSignature(const ir::TSIndexSignature * indexSignature)1010 void FillIndexSignature(const ir::TSIndexSignature *indexSignature) 1011 { 1012 auto key = indexSignature->Param()->AsIdentifier()->TypeAnnotation(); 1013 indexSignatures_[extractor_->GetTypeIndexFromAnnotation(key)] = 1014 extractor_->GetTypeIndexFromAnnotation(indexSignature->TypeAnnotation()); 1015 } 1016 FillMembers(const ir::TSInterfaceDeclaration * interfaceDef)1017 void FillMembers(const ir::TSInterfaceDeclaration *interfaceDef) 1018 { 1019 for (const auto &t : interfaceDef->Body()->Body()) { 1020 if (t->IsTSPropertySignature()) { 1021 FillField(t->AsTSPropertySignature()); 1022 } else if (t->IsTSMethodSignature()) { 1023 FillMethod(t->AsTSMethodSignature()); 1024 } else if (t->IsTSSignatureDeclaration()) { 1025 FillMethod(t->AsTSSignatureDeclaration()); 1026 } else if (t->IsTSIndexSignature()) { 1027 FillIndexSignature(t->AsTSIndexSignature()); 1028 } 1029 } 1030 if (indexSignatures_.size() > 0U) { 1031 // Update current type to IndexSignture Type 1032 IndexSigType indexSigType(extractor_, typeIndexShift_, &indexSignatures_); 1033 typeIndexShift_ = indexSigType.GetTypeIndexShift(); 1034 recorder_->UpdateNodeTypeIndex(interfaceDef, typeIndexShift_); 1035 } 1036 } 1037 FillFieldsLiteralBuffer()1038 void FillFieldsLiteralBuffer() 1039 { 1040 buffer_->Add(recorder_->Allocator()->New<ir::NumberLiteral>(fields_.size())); 1041 std::for_each(fields_.begin(), fields_.end(), [this](const auto &t) { 1042 buffer_->Add(recorder_->Allocator()->New<ir::StringLiteral>(t.first)); 1043 FillTypeIndexLiteralBuffer(t.second[0]); // 0. typeIndex 1044 buffer_->Add(recorder_->Allocator()->New<ir::NumberLiteral>(t.second[1])); // 1. accessFlag 1045 buffer_->Add(recorder_->Allocator()->New<ir::NumberLiteral>(t.second[2])); // 2. modifier 1046 }); 1047 } 1048 FillMethodsLiteralBuffer()1049 void FillMethodsLiteralBuffer() 1050 { 1051 buffer_->Add(recorder_->Allocator()->New<ir::NumberLiteral>(methods_.size())); 1052 std::for_each(methods_.begin(), methods_.end(), [this](const auto &t) { 1053 FillTypeIndexLiteralBuffer(t); 1054 }); 1055 } 1056 FillLiteralBuffer()1057 void FillLiteralBuffer() 1058 { 1059 buffer_->Add(recorder_->Allocator()->New<ir::NumberLiteral>(UserType::INTERFACE)); 1060 buffer_->Add(recorder_->Allocator()->New<ir::NumberLiteral>(heritages_.size())); 1061 std::for_each(heritages_.begin(), heritages_.end(), [this](const auto &t) { 1062 FillTypeIndexLiteralBuffer(t); 1063 }); 1064 1065 FillFieldsLiteralBuffer(); 1066 FillMethodsLiteralBuffer(); 1067 } 1068 }; 1069 1070 class ExternalType : public BaseType { 1071 public: ExternalType(TypeExtractor * extractor,const util::StringView & importName,const util::StringView & redirectPath)1072 explicit ExternalType(TypeExtractor *extractor, const util::StringView &importName, 1073 const util::StringView &redirectPath) : BaseType(extractor) 1074 { 1075 std::stringstream ss; 1076 ss << "#" << std::string(importName) << "#" << std::string(redirectPath); 1077 redirectPath_ = util::UString(ss.str(), recorder_->Allocator()).View(); 1078 typeIndex_ = recorder_->AddLiteralBuffer(buffer_); 1079 typeIndexShift_ = typeIndex_ + recorder_->GetUserTypeIndexShift(); 1080 recorder_->AddUserType(typeIndexShift_); 1081 1082 FillLiteralBuffer(); 1083 } 1084 ~ExternalType() = default; 1085 NO_COPY_SEMANTIC(ExternalType); 1086 NO_MOVE_SEMANTIC(ExternalType); 1087 GetTypeIndexShift()1088 int64_t GetTypeIndexShift() const 1089 { 1090 return typeIndexShift_; 1091 } 1092 1093 private: 1094 util::StringView redirectPath_; 1095 int64_t typeIndex_ = PrimitiveType::ANY; 1096 int64_t typeIndexShift_ = PrimitiveType::ANY; 1097 FillLiteralBuffer()1098 void FillLiteralBuffer() 1099 { 1100 buffer_->Add(recorder_->Allocator()->New<ir::NumberLiteral>(UserType::EXTERNAL)); 1101 buffer_->Add(recorder_->Allocator()->New<ir::StringLiteral>(redirectPath_)); 1102 } 1103 }; 1104 1105 class UnionType : public BaseType { 1106 public: UnionType(TypeExtractor * extractor,const ir::TSUnionType * unionDef)1107 explicit UnionType(TypeExtractor *extractor, const ir::TSUnionType *unionDef) 1108 : BaseType(extractor), unionTypes_(recorder_->Allocator()->Adapter()) 1109 { 1110 auto unionStr = CalculateStr(unionDef->Types()); 1111 typeIndexShift_ = recorder_->GetUnionType(unionStr); 1112 if (typeIndexShift_ != PrimitiveType::ANY) { 1113 return; 1114 } 1115 1116 typeIndex_ = recorder_->AddLiteralBuffer(buffer_); 1117 typeIndexShift_ = typeIndex_ + recorder_->GetUserTypeIndexShift(); 1118 recorder_->SetUnionType(unionStr, typeIndexShift_); 1119 recorder_->AddUserType(typeIndexShift_); 1120 1121 FillTypes(unionDef); 1122 FillLiteralBuffer(); 1123 } 1124 ~UnionType() = default; 1125 NO_COPY_SEMANTIC(UnionType); 1126 NO_MOVE_SEMANTIC(UnionType); 1127 GetTypeIndexShift()1128 int64_t GetTypeIndexShift() const 1129 { 1130 return typeIndexShift_; 1131 } 1132 1133 private: 1134 ArenaVector<int64_t> unionTypes_; 1135 int64_t typeIndex_ = PrimitiveType::ANY; 1136 int64_t typeIndexShift_ = PrimitiveType::ANY; 1137 FillTypes(const ir::TSUnionType * unionDef)1138 void FillTypes(const ir::TSUnionType *unionDef) 1139 { 1140 for (const auto &t : unionDef->Types()) { 1141 unionTypes_.emplace_back(extractor_->GetTypeIndexFromAnnotation(t)); 1142 } 1143 } 1144 FillLiteralBuffer()1145 void FillLiteralBuffer() 1146 { 1147 buffer_->Add(recorder_->Allocator()->New<ir::NumberLiteral>(UserType::UNION)); 1148 buffer_->Add(recorder_->Allocator()->New<ir::NumberLiteral>(unionTypes_.size())); 1149 std::for_each(unionTypes_.begin(), unionTypes_.end(), [this](const auto &t) { 1150 FillTypeIndexLiteralBuffer(t); 1151 }); 1152 } 1153 }; 1154 1155 class ArrayType : public BaseType { 1156 public: ArrayType(TypeExtractor * extractor,const ir::TSArrayType * arrayDef)1157 explicit ArrayType(TypeExtractor *extractor, const ir::TSArrayType *arrayDef) : BaseType(extractor) 1158 { 1159 typeIndexRefShift_ = extractor_->GetTypeIndexFromAnnotation(arrayDef->ElementType()); 1160 typeIndexShift_ = recorder_->GetArrayType(typeIndexRefShift_); 1161 if (typeIndexShift_ != PrimitiveType::ANY) { 1162 return; 1163 } 1164 1165 typeIndex_ = recorder_->AddLiteralBuffer(buffer_); 1166 typeIndexShift_ = typeIndex_ + recorder_->GetUserTypeIndexShift(); 1167 recorder_->SetArrayType(typeIndexRefShift_, typeIndexShift_); 1168 recorder_->AddUserType(typeIndexShift_); 1169 1170 FillLiteralBuffer(); 1171 } 1172 ~ArrayType() = default; 1173 NO_COPY_SEMANTIC(ArrayType); 1174 NO_MOVE_SEMANTIC(ArrayType); 1175 GetTypeIndexShift()1176 int64_t GetTypeIndexShift() const 1177 { 1178 return typeIndexShift_; 1179 } 1180 1181 private: 1182 int64_t typeIndexRefShift_ = PrimitiveType::ANY; 1183 int64_t typeIndex_ = PrimitiveType::ANY; 1184 int64_t typeIndexShift_ = PrimitiveType::ANY; 1185 FillLiteralBuffer()1186 void FillLiteralBuffer() 1187 { 1188 buffer_->Add(recorder_->Allocator()->New<ir::NumberLiteral>(UserType::ARRAY)); 1189 FillTypeIndexLiteralBuffer(typeIndexRefShift_); 1190 } 1191 }; 1192 1193 class ObjectType : public BaseType { 1194 public: ObjectType(TypeExtractor * extractor,const ir::TSTypeLiteral * literalDef)1195 explicit ObjectType(TypeExtractor *extractor, const ir::TSTypeLiteral *literalDef) 1196 : BaseType(extractor), 1197 properties_(recorder_->Allocator()->Adapter()), 1198 methods_(recorder_->Allocator()->Adapter()), 1199 indexSignatures_(recorder_->Allocator()->Adapter()) 1200 { 1201 std::string objectStr = "object"; 1202 if (literalDef != nullptr) { 1203 objectStr = CalculateStr(literalDef->Members()); 1204 } 1205 typeIndexShift_ = recorder_->GetObjectType(objectStr); 1206 if (typeIndexShift_ != PrimitiveType::ANY) { 1207 return; 1208 } 1209 1210 typeIndex_ = recorder_->AddLiteralBuffer(buffer_); 1211 typeIndexShift_ = typeIndex_ + recorder_->GetUserTypeIndexShift(); 1212 recorder_->SetObjectType(objectStr, typeIndexShift_); 1213 recorder_->AddUserType(typeIndexShift_); 1214 1215 if (literalDef != nullptr) { 1216 FillMembers(literalDef, objectStr); 1217 } 1218 FillLiteralBuffer(); 1219 } 1220 ~ObjectType() = default; 1221 NO_COPY_SEMANTIC(ObjectType); 1222 NO_MOVE_SEMANTIC(ObjectType); 1223 GetTypeIndexShift()1224 int64_t GetTypeIndexShift() const 1225 { 1226 return typeIndexShift_; 1227 } 1228 1229 private: 1230 ArenaMap<util::StringView, int64_t> properties_; 1231 ArenaVector<int64_t> methods_; 1232 ArenaMap<int64_t, int64_t> indexSignatures_; 1233 int64_t typeIndex_ = PrimitiveType::ANY; 1234 int64_t typeIndexShift_ = PrimitiveType::ANY; 1235 FillMethod(const ir::TSMethodSignature * method)1236 void FillMethod(const ir::TSMethodSignature *method) 1237 { 1238 auto res = CalculateName(method->Key()); 1239 if (std::holds_alternative<util::StringView>(res)) { 1240 auto name = std::get<util::StringView>(res); 1241 FunctionType functionType(extractor_, method, name); 1242 methods_.emplace_back(recorder_->GetNodeTypeIndex(method)); 1243 } else { 1244 auto identifier = std::get<const ir::Identifier *>(res); 1245 if (identifier != nullptr) { 1246 auto name = identifier->Name(); 1247 FunctionType functionType(extractor_, method, name); 1248 recorder_->SetIdentifierTypeIndex(identifier, functionType.GetTypeIndexShift()); 1249 methods_.emplace_back(recorder_->GetNodeTypeIndex(method)); 1250 } 1251 } 1252 } 1253 FillMethod(const ir::TSSignatureDeclaration * method)1254 void FillMethod(const ir::TSSignatureDeclaration *method) 1255 { 1256 FunctionType functionType(extractor_, method, ""); 1257 methods_.emplace_back(recorder_->GetNodeTypeIndex(method)); 1258 } 1259 FillIndexSignature(const ir::TSIndexSignature * indexSignature)1260 void FillIndexSignature(const ir::TSIndexSignature *indexSignature) 1261 { 1262 auto key = indexSignature->Param()->AsIdentifier()->TypeAnnotation(); 1263 indexSignatures_[extractor_->GetTypeIndexFromAnnotation(key)] = 1264 extractor_->GetTypeIndexFromAnnotation(indexSignature->TypeAnnotation()); 1265 } 1266 FillMembers(const ir::TSTypeLiteral * literalDef,const std::string & objectStr)1267 void FillMembers(const ir::TSTypeLiteral *literalDef, const std::string &objectStr) 1268 { 1269 auto fn = [this](const auto *property, int64_t typeIndex) { 1270 auto res = CalculateName(property->Key()); 1271 if (std::holds_alternative<util::StringView>(res)) { 1272 properties_[std::get<util::StringView>(res)] = typeIndex; 1273 } else { 1274 auto identifier = std::get<const ir::Identifier *>(res); 1275 if (identifier != nullptr) { 1276 recorder_->SetIdentifierTypeIndex(identifier, typeIndex); 1277 properties_[identifier->Name()] = typeIndex; 1278 } 1279 } 1280 }; 1281 1282 for (const auto &t : literalDef->Members()) { 1283 if (t->IsTSPropertySignature()) { 1284 auto property = t->AsTSPropertySignature(); 1285 int64_t typeIndex = extractor_->GetTypeIndexFromAnnotation(property->TypeAnnotation()); 1286 fn(property, typeIndex); 1287 } else if (t->IsTSMethodSignature()) { 1288 FillMethod(t->AsTSMethodSignature()); 1289 } else if (t->IsTSSignatureDeclaration()) { 1290 FillMethod(t->AsTSSignatureDeclaration()); 1291 } else if (t->IsTSIndexSignature()) { 1292 FillIndexSignature(t->AsTSIndexSignature()); 1293 } 1294 } 1295 1296 if (indexSignatures_.size() > 0U) { 1297 // Update current type to IndexSignture Type 1298 IndexSigType indexSigType(extractor_, typeIndexShift_, &indexSignatures_); 1299 typeIndexShift_ = indexSigType.GetTypeIndexShift(); 1300 recorder_->SetObjectType(objectStr, typeIndexShift_); 1301 } 1302 } 1303 FillLiteralBuffer()1304 void FillLiteralBuffer() 1305 { 1306 buffer_->Add(recorder_->Allocator()->New<ir::NumberLiteral>(UserType::OBJECT)); 1307 buffer_->Add(recorder_->Allocator()->New<ir::NumberLiteral>(properties_.size())); 1308 std::for_each(properties_.begin(), properties_.end(), [this](const auto &t) { 1309 buffer_->Add(recorder_->Allocator()->New<ir::StringLiteral>(t.first)); 1310 FillTypeIndexLiteralBuffer(t.second); 1311 }); 1312 buffer_->Add(recorder_->Allocator()->New<ir::NumberLiteral>(methods_.size())); 1313 std::for_each(methods_.begin(), methods_.end(), [this](const auto &t) { 1314 FillTypeIndexLiteralBuffer(t); 1315 }); 1316 } 1317 }; 1318 1319 class BuiltinInstType : public BaseType { 1320 public: BuiltinInstType(TypeExtractor * extractor,const std::vector<int64_t> & allTypes)1321 explicit BuiltinInstType(TypeExtractor *extractor, const std::vector<int64_t> &allTypes) 1322 : BaseType(extractor), paramTypes_(recorder_->Allocator()->Adapter()) 1323 { 1324 typeIndexBuiltin_ = allTypes[0]; 1325 typeIndex_ = recorder_->AddLiteralBuffer(buffer_); 1326 typeIndexShift_ = typeIndex_ + recorder_->GetUserTypeIndexShift(); 1327 recorder_->SetBuiltinInst(allTypes, typeIndexShift_); 1328 recorder_->AddUserType(typeIndexShift_); 1329 1330 FillTypes(allTypes); 1331 FillLiteralBuffer(); 1332 } 1333 ~BuiltinInstType() = default; 1334 NO_COPY_SEMANTIC(BuiltinInstType); 1335 NO_MOVE_SEMANTIC(BuiltinInstType); 1336 GetTypeIndexShift()1337 int64_t GetTypeIndexShift() const 1338 { 1339 return typeIndexShift_; 1340 } 1341 1342 private: 1343 ArenaVector<int64_t> paramTypes_; 1344 int64_t typeIndexBuiltin_ = PrimitiveType::ANY; 1345 int64_t typeIndex_ = PrimitiveType::ANY; 1346 int64_t typeIndexShift_ = PrimitiveType::ANY; 1347 FillTypes(const std::vector<int64_t> & allTypes)1348 void FillTypes(const std::vector<int64_t> &allTypes) 1349 { 1350 for (size_t t = 1; t < allTypes.size(); t++) { 1351 paramTypes_.emplace_back(allTypes[t]); 1352 } 1353 } 1354 FillLiteralBuffer()1355 void FillLiteralBuffer() 1356 { 1357 buffer_->Add(recorder_->Allocator()->New<ir::NumberLiteral>(UserType::BUILTININST)); 1358 FillTypeIndexLiteralBuffer(typeIndexBuiltin_); 1359 buffer_->Add(recorder_->Allocator()->New<ir::NumberLiteral>(paramTypes_.size())); 1360 std::for_each(paramTypes_.begin(), paramTypes_.end(), [this](const auto &t) { 1361 FillTypeIndexLiteralBuffer(t); 1362 }); 1363 } 1364 }; 1365 1366 class GenericInstType : public BaseType { 1367 public: GenericInstType(TypeExtractor * extractor,const std::vector<int64_t> & allTypes)1368 explicit GenericInstType(TypeExtractor *extractor, const std::vector<int64_t> &allTypes) 1369 : BaseType(extractor), paramTypes_(recorder_->Allocator()->Adapter()) 1370 { 1371 typeIndexGeneric_ = allTypes[0]; 1372 typeIndex_ = recorder_->AddLiteralBuffer(buffer_); 1373 typeIndexShift_ = typeIndex_ + recorder_->GetUserTypeIndexShift(); 1374 recorder_->SetGenericInst(allTypes, typeIndexShift_); 1375 recorder_->AddUserType(typeIndexShift_); 1376 1377 FillTypes(allTypes); 1378 FillLiteralBuffer(); 1379 } 1380 ~GenericInstType() = default; 1381 NO_COPY_SEMANTIC(GenericInstType); 1382 NO_MOVE_SEMANTIC(GenericInstType); 1383 GetTypeIndexShift()1384 int64_t GetTypeIndexShift() const 1385 { 1386 return typeIndexShift_; 1387 } 1388 1389 private: 1390 ArenaVector<int64_t> paramTypes_; 1391 int64_t typeIndexGeneric_ = PrimitiveType::ANY; 1392 int64_t typeIndex_ = PrimitiveType::ANY; 1393 int64_t typeIndexShift_ = PrimitiveType::ANY; 1394 FillTypes(const std::vector<int64_t> & allTypes)1395 void FillTypes(const std::vector<int64_t> &allTypes) 1396 { 1397 for (size_t t = 1; t < allTypes.size(); t++) { 1398 paramTypes_.emplace_back(allTypes[t]); 1399 } 1400 } 1401 FillLiteralBuffer()1402 void FillLiteralBuffer() 1403 { 1404 buffer_->Add(recorder_->Allocator()->New<ir::NumberLiteral>(UserType::GENERICINST)); 1405 FillTypeIndexLiteralBuffer(typeIndexGeneric_); 1406 buffer_->Add(recorder_->Allocator()->New<ir::NumberLiteral>(paramTypes_.size())); 1407 std::for_each(paramTypes_.begin(), paramTypes_.end(), [this](const auto &t) { 1408 FillTypeIndexLiteralBuffer(t); 1409 }); 1410 } 1411 }; 1412 1413 } // namespace panda::es2panda::extractor 1414 1415 #endif // ES2PANDA_TYPESCRIPT_EXACTOR_TYPESYSTEM_H 1416