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