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_TYPEEXTRACTOR_H 17 #define ES2PANDA_TYPESCRIPT_EXACTOR_TYPEEXTRACTOR_H 18 19 #include <ir/statements/blockStatement.h> 20 #include <macros.h> 21 #include <unordered_set> 22 23 #include "typeRecorder.h" 24 25 namespace panda::es2panda::extractor { 26 27 using Getter = std::function<int64_t(const ir::AstNode *, bool isNewInstance)>; 28 using Handler = std::function<void(const ir::AstNode *)>; 29 30 class TypeExtractor { 31 public: 32 explicit TypeExtractor(const ir::BlockStatement *rootNode, bool typeDtsExtractor, bool typeDtsBuiltin, 33 ArenaAllocator *allocator, compiler::CompilerContext *context); 34 ~TypeExtractor() = default; 35 NO_COPY_SEMANTIC(TypeExtractor); 36 NO_MOVE_SEMANTIC(TypeExtractor); 37 38 void StartTypeExtractor(const parser::Program *program); 39 40 bool GetTypeDtsExtractor() const; 41 bool GetTypeDtsBuiltin() const; 42 TypeRecorder *Recorder() const; 43 44 const ir::Identifier *GetIdentifierFromExpression(const ir::Expression *expression); 45 const ir::AstNode *GetDeclNodeFromIdentifier(const ir::Identifier *identifier, const ir::Identifier **variable); 46 int64_t GetTypeIndexFromAnnotation(const ir::Expression *typeAnnotation, bool isNewInstance = true); 47 int64_t GetTypeIndexFromIdentifier(const ir::Identifier *identifier); 48 int64_t GetTypeIndexFromInitializer(const ir::Expression *initializer); 49 int64_t GetTypeIndexFromClassInst(int64_t typeIndex, const ir::AstNode *node, 50 int64_t builtinTypeIndex = TypeRecorder::PRIMITIVETYPE_ANY); 51 SetGenericParamTypeMap(const ArenaMap<util::StringView,int64_t> * genericParamTypeMap)52 void SetGenericParamTypeMap(const ArenaMap<util::StringView, int64_t> *genericParamTypeMap) 53 { 54 genericParamTypeMap_ = genericParamTypeMap; 55 } 56 GetGenericParamTypeMap()57 const ArenaMap<util::StringView, int64_t> *GetGenericParamTypeMap() const 58 { 59 return genericParamTypeMap_; 60 } 61 62 static int64_t GetBuiltinTypeIndex(util::StringView name); 63 AddSearchingTypeRefNodes(const ir::Expression * node)64 bool AddSearchingTypeRefNodes(const ir::Expression * node) 65 { 66 if (!IsInSearchingTypeRefNodes(node)) { 67 searchingTypeRefNodes_.insert(node); 68 return true; 69 } 70 return false; 71 } 72 RemoveSearchingTypeRefNodes(const ir::Expression * node)73 void RemoveSearchingTypeRefNodes(const ir::Expression * node) 74 { 75 if (IsInSearchingTypeRefNodes(node)) { 76 searchingTypeRefNodes_.erase(node); 77 } 78 } 79 IsInSearchingTypeRefNodes(const ir::Expression * node)80 bool IsInSearchingTypeRefNodes(const ir::Expression * node) 81 { 82 return searchingTypeRefNodes_.find(node) != searchingTypeRefNodes_.end(); 83 } 84 85 private: 86 const ir::BlockStatement *rootNode_; 87 std::unordered_set<const ir::Expression *> searchingTypeRefNodes_; 88 const bool typeDtsExtractor_; 89 const bool typeDtsBuiltin_; 90 std::unique_ptr<TypeRecorder> recorder_; 91 std::unordered_map<ir::AstNodeType, Getter> getterMap_; 92 std::unordered_map<ir::AstNodeType, Handler> handlerMap_; 93 const ArenaMap<util::StringView, int64_t> *genericParamTypeMap_ {nullptr}; 94 95 void ExtractNodesType(const ir::AstNode *parent); 96 void ExtractNodeType(const ir::AstNode *parent, const ir::AstNode *childNode); 97 void ExtractImport(const parser::Program *program); 98 void ExtractExport(const parser::Program *program); 99 void ExtractImportModuleRecord(parser::SourceTextModuleRecord *moduleRecord); 100 void ExtractExportModuleRecord(parser::SourceTextModuleRecord *moduleRecord); 101 102 const ir::AstNode *GetDeclNodeFromInitializer(const ir::Expression *initializer, const ir::Identifier **variable); 103 104 int64_t GetTypeIndexFromDeclNode(const ir::AstNode *node, bool isNewInstance); 105 int64_t GetTypeIndexFromIdentifierNode(const ir::AstNode *node, bool isNewInstance); 106 int64_t GetTypeIndexFromClassExpression(const ir::AstNode *node, bool isNewInstance); 107 int64_t GetTypeIndexFromClassDefinition(const ir::AstNode *node, bool isNewInstance); 108 int64_t GetTypeIndexFromInterfaceNode(const ir::AstNode *node, [[maybe_unused]] bool isNewInstance); 109 int64_t GetTypeIndexFromFunctionNode(const ir::AstNode *node, [[maybe_unused]] bool isNewInstance); 110 int64_t GetTypeIndexFromImportNode(const ir::AstNode *node, [[maybe_unused]] bool isNewInstance); 111 int64_t GetTypeIndexFromTypeAliasNode(const ir::AstNode *node, [[maybe_unused]] bool isNewInstance); 112 int64_t GetTypeIndexFromAsNode(const ir::AstNode *node, [[maybe_unused]] bool isNewInstance); 113 int64_t GetTypeIndexFromAssertionNode(const ir::AstNode *node, [[maybe_unused]] bool isNewInstance); 114 int64_t GetTypeIndexFromMemberNode(const ir::AstNode *node, [[maybe_unused]] bool isNewInstance); 115 int64_t GetTypeIndexFromTSQualifiedNode(const ir::AstNode *node, bool isNewInstance); 116 117 void HandleVariableDeclaration(const ir::AstNode *node); 118 void HandleFunctionDeclaration(const ir::AstNode *node); 119 void HandleClassDeclaration(const ir::AstNode *node); 120 void HandleInterfaceDeclaration(const ir::AstNode *node); 121 void HandleTypeAliasDeclaration(const ir::AstNode *node); 122 void HandleNewlyGenFuncExpression(const ir::AstNode *node); 123 void HandleArrowFunctionExpression(const ir::AstNode *node); 124 125 // Helpers 126 int64_t GetTypeIndexFromTypeReference(const ir::TSTypeReference *typeReference, bool isNewInstance); 127 int64_t GetTypeIndexFromTSLiteralType(const ir::TSLiteralType *tsLiteralType); 128 129 // Builtin and Generic Helpers 130 int64_t GetTypeIndexFromBuiltin(const util::StringView &name, const ir::TSTypeParameterInstantiation *node); 131 int64_t GetTypeIndexFromBuiltinInst(int64_t typeIndexBuiltin, const ir::TSTypeParameterInstantiation *node); 132 int64_t GetTypeIndexFromGenericInst(const ir::AstNode *declNode, const ir::TSTypeParameterInstantiation *node); 133 134 // Other Helpers 135 bool IsExportNode(const ir::AstNode *node) const; 136 bool IsDeclareNode(const ir::AstNode *node) const; 137 void GetVariablesFromTSQualifiedNodes(const binder::Variable *variable, 138 ArenaDeque<const ir::Identifier *> &identifiers, ArenaVector<const binder::Variable *> &variables) const; 139 void GetVariablesFromNamespace(const binder::NamespaceVariable *variable, ArenaVector<binder::Variable *> &findRes, 140 ArenaDeque<const ir::Identifier *> &identifiers, ArenaVector<const binder::Variable *> &variables) const; 141 }; 142 143 class GenericParamTypeBindScope { 144 public: 145 GenericParamTypeBindScope() = delete; 146 GenericParamTypeBindScope(TypeExtractor * extractor,const ArenaMap<util::StringView,int64_t> * genericParamTypeMap)147 explicit GenericParamTypeBindScope(TypeExtractor *extractor, 148 const ArenaMap<util::StringView, int64_t> *genericParamTypeMap) : extractor_(extractor) 149 { 150 ASSERT(extractor_ != nullptr); 151 extractor_->SetGenericParamTypeMap(genericParamTypeMap); 152 } 153 ~GenericParamTypeBindScope()154 ~GenericParamTypeBindScope() 155 { 156 extractor_->SetGenericParamTypeMap(nullptr); 157 } 158 159 NO_COPY_SEMANTIC(GenericParamTypeBindScope); 160 NO_MOVE_SEMANTIC(GenericParamTypeBindScope); 161 162 private: 163 TypeExtractor *extractor_; 164 }; 165 166 } // namespace panda::es2panda::extractor 167 168 #endif // ES2PANDA_TYPESCRIPT_EXACTOR_TYPEEXTRACTOR_H 169