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_UNION_TYPE_H 17 #define ES2PANDA_COMPILER_TYPESCRIPT_TYPES_UNION_TYPE_H 18 19 #include "type.h" 20 21 namespace panda::es2panda::checker { 22 23 class GlobalTypesHolder; 24 25 class UnionType : public Type { 26 public: UnionType(ArenaAllocator * allocator,std::initializer_list<Type * > types)27 UnionType(ArenaAllocator *allocator, std::initializer_list<Type *> types) 28 : Type(TypeFlag::UNION), constituentTypes_(allocator->Adapter()) 29 { 30 for (auto *it : types) { 31 constituentTypes_.push_back(it); 32 } 33 34 for (auto *it : constituentTypes_) { 35 AddConstituentFlag(it->TypeFlags()); 36 } 37 } 38 UnionType(ArenaVector<Type * > && constituentTypes)39 explicit UnionType(ArenaVector<Type *> &&constituentTypes) 40 : Type(TypeFlag::UNION), constituentTypes_(std::move(constituentTypes)) 41 { 42 for (auto *it : constituentTypes_) { 43 AddConstituentFlag(it->TypeFlags()); 44 } 45 } 46 UnionType(ArenaVector<Type * > & constituentTypes)47 explicit UnionType(ArenaVector<Type *> &constituentTypes) 48 : Type(TypeFlag::UNION), constituentTypes_(constituentTypes) 49 { 50 for (auto *it : constituentTypes_) { 51 AddConstituentFlag(it->TypeFlags()); 52 } 53 } 54 ConstituentTypes()55 const ArenaVector<Type *> &ConstituentTypes() const 56 { 57 return constituentTypes_; 58 } 59 ConstituentTypes()60 ArenaVector<Type *> &ConstituentTypes() 61 { 62 return constituentTypes_; 63 } 64 AddConstituentType(Type * type,TypeRelation * relation)65 void AddConstituentType(Type *type, TypeRelation *relation) 66 { 67 CHECK_NOT_NULL(type); 68 if ((HasConstituentFlag(TypeFlag::NUMBER) && type->IsNumberLiteralType()) || 69 (HasConstituentFlag(TypeFlag::STRING) && type->IsStringLiteralType()) || 70 (HasConstituentFlag(TypeFlag::BIGINT) && type->IsBigintLiteralType()) || 71 (HasConstituentFlag(TypeFlag::BOOLEAN) && type->IsBooleanLiteralType())) { 72 return; 73 } 74 75 for (auto *it : constituentTypes_) { 76 if (relation->IsIdenticalTo(it, type)) { 77 return; 78 } 79 } 80 81 AddConstituentFlag(type->TypeFlags()); 82 constituentTypes_.push_back(type); 83 } 84 AddConstituentFlag(TypeFlag flag)85 void AddConstituentFlag(TypeFlag flag) 86 { 87 constituentFlags_ |= flag; 88 } 89 RemoveConstituentFlag(TypeFlag flag)90 void RemoveConstituentFlag(TypeFlag flag) 91 { 92 constituentFlags_ &= ~flag; 93 } 94 HasConstituentFlag(TypeFlag flag)95 bool HasConstituentFlag(TypeFlag flag) const 96 { 97 return (constituentFlags_ & flag) != 0; 98 } 99 CachedSyntheticPropertis()100 std::unordered_map<util::StringView, binder::Variable *> &CachedSyntheticPropertis() 101 { 102 return cachedSynthecticProperties_; 103 } 104 MergedObjectType()105 ObjectType *MergedObjectType() 106 { 107 return mergedObjectType_; 108 } 109 SetMergedObjectType(ObjectType * type)110 void SetMergedObjectType(ObjectType *type) 111 { 112 mergedObjectType_ = type; 113 } 114 115 void ToString(std::stringstream &ss) const override; 116 void Identical(TypeRelation *relation, Type *other) override; 117 void AssignmentTarget(TypeRelation *relation, Type *source) override; 118 bool AssignmentSource(TypeRelation *relation, Type *target) override; 119 TypeFacts GetTypeFacts() const override; 120 Type *Instantiate(ArenaAllocator *allocator, TypeRelation *relation, GlobalTypesHolder *globalTypes) override; 121 122 static void RemoveDuplicatedTypes(TypeRelation *relation, ArenaVector<Type *> &constituentTypes); 123 static Type *HandleUnionType(UnionType *unionType, GlobalTypesHolder *globalTypesHolder); 124 static void RemoveRedundantLiteralTypesFromUnion(UnionType *type); 125 126 private: 127 static bool EachTypeRelatedToSomeType(TypeRelation *relation, UnionType *source, UnionType *target); 128 static bool TypeRelatedToSomeType(TypeRelation *relation, Type *source, UnionType *target); 129 130 ArenaVector<Type *> constituentTypes_; 131 TypeFlag constituentFlags_ {TypeFlag::NONE}; 132 std::unordered_map<util::StringView, binder::Variable *> cachedSynthecticProperties_ {}; 133 ObjectType *mergedObjectType_ {nullptr}; 134 }; 135 136 } // namespace panda::es2panda::checker 137 138 #endif /* TYPESCRIPT_TYPES_UNION_TYPE_H */ 139