1 /** 2 * Copyright (c) 2021-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_COMPILER_TYPESCRIPT_TYPES_TYPE_RELATION_H 17 #define ES2PANDA_COMPILER_TYPESCRIPT_TYPES_TYPE_RELATION_H 18 19 #include <lexer/token/sourceLocation.h> 20 #include <lexer/token/tokenType.h> 21 #include <macros.h> 22 #include <util/ustring.h> 23 24 #include <unordered_map> 25 #include <variant> 26 27 namespace panda::es2panda::checker { 28 29 class Signature; 30 class IndexInfo; 31 class Type; 32 class Checker; 33 34 enum class RelationResult { TRUE, FALSE, UNKNOWN, MAYBE, CACHE_MISS }; 35 36 enum class RelationType { COMPARABLE, ASSIGNABLE, IDENTICAL }; 37 38 class RelationKey { 39 public: 40 uint64_t sourceId; 41 uint64_t targetId; 42 }; 43 44 class RelationKeyHasher { 45 public: operator()46 size_t operator()(const RelationKey &key) const noexcept 47 { 48 return static_cast<size_t>(key.sourceId ^ key.targetId); 49 } 50 }; 51 52 class RelationKeyComparator { 53 public: operator()54 bool operator()(const RelationKey &lhs, const RelationKey &rhs) const 55 { 56 return lhs.sourceId == rhs.sourceId && lhs.targetId == rhs.targetId; 57 } 58 }; 59 60 class RealtionEntry { 61 public: 62 RelationResult result; 63 RelationType type; 64 }; 65 66 using RelationMap = std::unordered_map<RelationKey, RealtionEntry, RelationKeyHasher, RelationKeyComparator>; 67 68 class RelationHolder { 69 public: 70 RelationMap cached; 71 RelationType type {}; 72 }; 73 74 class AsSrc { 75 public: AsSrc(const Type * type)76 explicit AsSrc(const Type *type) : type_(const_cast<Type *>(type)) {} 77 78 const Type *GetType() const; 79 80 private: 81 Type *type_; 82 }; 83 84 using TypeErrorMessageElement = std::variant<const Type *, AsSrc, char *, util::StringView, lexer::TokenType, size_t>; 85 86 class TypeRelation { 87 public: 88 explicit TypeRelation(Checker *checker); 89 90 bool IsIdenticalTo(Type *source, Type *target); 91 bool IsIdenticalTo(Signature *source, Signature *target); 92 bool IsIdenticalTo(IndexInfo *source, IndexInfo *target); 93 bool IsAssignableTo(Type *source, Type *target); 94 bool IsComparableTo(Type *source, Type *target); 95 void RaiseError(const std::string &errMsg, const lexer::SourcePosition &loc) const; 96 void RaiseError(std::initializer_list<TypeErrorMessageElement> list, const lexer::SourcePosition &loc) const; 97 98 void Result(bool res); 99 const Checker *GetChecker() const; 100 Checker *GetChecker(); 101 ArenaAllocator *Allocator(); 102 bool IsTrue() const; 103 104 private: 105 RelationResult CacheLookup(const Type *source, const Type *target, const RelationHolder &holder, 106 RelationType type) const; 107 108 Checker *checker_; 109 RelationResult result_; 110 }; // namespace panda::es2panda::checker 111 112 } // namespace panda::es2panda::checker 113 114 #endif /* TYPESCRIPT_TYPES_TYPE_RELATION_H */ 115