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