• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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