• 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         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