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 if ((HasConstituentFlag(TypeFlag::NUMBER) && type->IsNumberLiteralType()) || 68 (HasConstituentFlag(TypeFlag::STRING) && type->IsStringLiteralType()) || 69 (HasConstituentFlag(TypeFlag::BIGINT) && type->IsBigintLiteralType()) || 70 (HasConstituentFlag(TypeFlag::BOOLEAN) && type->IsBooleanLiteralType())) { 71 return; 72 } 73 74 for (auto *it : constituentTypes_) { 75 if (relation->IsIdenticalTo(it, type)) { 76 return; 77 } 78 } 79 80 AddConstituentFlag(type->TypeFlags()); 81 constituentTypes_.push_back(type); 82 } 83 AddConstituentFlag(TypeFlag flag)84 void AddConstituentFlag(TypeFlag flag) 85 { 86 constituentFlags_ |= flag; 87 } 88 RemoveConstituentFlag(TypeFlag flag)89 void RemoveConstituentFlag(TypeFlag flag) 90 { 91 constituentFlags_ &= ~flag; 92 } 93 HasConstituentFlag(TypeFlag flag)94 bool HasConstituentFlag(TypeFlag flag) const 95 { 96 return (constituentFlags_ & flag) != 0; 97 } 98 CachedSyntheticPropertis()99 std::unordered_map<util::StringView, binder::Variable *> &CachedSyntheticPropertis() 100 { 101 return cachedSynthecticProperties_; 102 } 103 MergedObjectType()104 ObjectType *MergedObjectType() 105 { 106 return mergedObjectType_; 107 } 108 SetMergedObjectType(ObjectType * type)109 void SetMergedObjectType(ObjectType *type) 110 { 111 mergedObjectType_ = type; 112 } 113 114 void ToString(std::stringstream &ss) const override; 115 void Identical(TypeRelation *relation, Type *other) override; 116 void AssignmentTarget(TypeRelation *relation, Type *source) override; 117 bool AssignmentSource(TypeRelation *relation, Type *target) override; 118 TypeFacts GetTypeFacts() const override; 119 Type *Instantiate(ArenaAllocator *allocator, TypeRelation *relation, GlobalTypesHolder *globalTypes) override; 120 121 static void RemoveDuplicatedTypes(TypeRelation *relation, ArenaVector<Type *> &constituentTypes); 122 static Type *HandleUnionType(UnionType *unionType, GlobalTypesHolder *globalTypesHolder); 123 static void RemoveRedundantLiteralTypesFromUnion(UnionType *type); 124 125 private: 126 static bool EachTypeRelatedToSomeType(TypeRelation *relation, UnionType *source, UnionType *target); 127 static bool TypeRelatedToSomeType(TypeRelation *relation, Type *source, UnionType *target); 128 129 ArenaVector<Type *> constituentTypes_; 130 TypeFlag constituentFlags_ {TypeFlag::NONE}; 131 std::unordered_map<util::StringView, binder::Variable *> cachedSynthecticProperties_ {}; 132 ObjectType *mergedObjectType_ {nullptr}; 133 }; 134 135 } // namespace panda::es2panda::checker 136 137 #endif /* TYPESCRIPT_TYPES_UNION_TYPE_H */ 138