1 /**
2 * Copyright (c) 2021 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_TYPE_H
17 #define ES2PANDA_COMPILER_TYPESCRIPT_TYPES_TYPE_H
18
19 #include <typescript/types/typeFacts.h>
20 #include <typescript/types/typeMapping.h>
21 #include <typescript/types/typeRelation.h>
22
23 #include <macros.h>
24 #include <sstream>
25 #include <variant>
26
27 namespace panda::es2panda::binder {
28 class Variable;
29 } // namespace panda::es2panda::binder
30
31 namespace panda::es2panda::checker {
32
33 class ObjectDescriptor;
34 class GlobalTypesHolder;
35
36 #define DECLARE_TYPENAMES(typeFlag, typeName) class typeName;
TYPE_MAPPING(DECLARE_TYPENAMES)37 TYPE_MAPPING(DECLARE_TYPENAMES)
38 #undef DECLARE_TYPENAMES
39
40 class Type {
41 public:
42 explicit Type(TypeFlag flag) : typeFlags_(flag), variable_(nullptr)
43 {
44 static uint64_t typeId_ = 0;
45 id_ = ++typeId_;
46 }
47
48 NO_COPY_SEMANTIC(Type);
49 NO_MOVE_SEMANTIC(Type);
50
51 virtual ~Type() = default;
52
53 #define TYPE_IS_CHECKS(typeFlag, typeName) \
54 bool Is##typeName() const \
55 { \
56 return HasTypeFlag(typeFlag); \
57 }
58 TYPE_MAPPING(TYPE_IS_CHECKS)
59 #undef DECLARE_IS_CHECKS
60
61 #define TYPE_AS_CASTS(typeFlag, typeName) \
62 typeName *As##typeName() \
63 { \
64 ASSERT(Is##typeName()); \
65 return reinterpret_cast<typeName *>(this); \
66 } \
67 const typeName *As##typeName() const \
68 { \
69 ASSERT(Is##typeName()); \
70 return reinterpret_cast<const typeName *>(this); \
71 }
72 TYPE_MAPPING(TYPE_AS_CASTS)
73 #undef TYPE_AS_CASTS
74
75 TypeFlag TypeFlags() const
76 {
77 return typeFlags_;
78 }
79
80 bool HasTypeFlag(TypeFlag typeFlag) const
81 {
82 return (typeFlags_ & typeFlag) != 0;
83 }
84
85 void AddTypeFlag(TypeFlag typeFlag)
86 {
87 typeFlags_ |= typeFlag;
88 }
89
90 void RemoveTypeFlag(TypeFlag typeFlag)
91 {
92 typeFlags_ &= ~typeFlag;
93 }
94
95 uint64_t Id() const
96 {
97 return id_;
98 }
99
100 void SetVariable(binder::Variable *variable)
101 {
102 variable_ = variable;
103 }
104
105 binder::Variable *Variable()
106 {
107 return variable_;
108 }
109
110 const binder::Variable *Variable() const
111 {
112 return variable_;
113 }
114
115 virtual void ToString(std::stringstream &ss) const = 0;
116 virtual void ToStringAsSrc(std::stringstream &ss) const;
117 virtual TypeFacts GetTypeFacts() const = 0;
118
119 virtual void Identical(TypeRelation *relation, Type *other);
120 virtual void AssignmentTarget(TypeRelation *relation, Type *source) = 0;
121 virtual bool AssignmentSource(TypeRelation *relation, Type *target);
122 virtual void Compare(TypeRelation *relation, Type *other);
123
124 virtual Type *Instantiate(ArenaAllocator *allocator, TypeRelation *relation, GlobalTypesHolder *globalTypes) = 0;
125
126 protected:
127 TypeFlag typeFlags_;
128 binder::Variable *variable_; // Variable associated with the type if any
129 uint64_t id_;
130 };
131
132 } // namespace panda::es2panda::checker
133
134 #endif /* TYPESCRIPT_TYPES_TYPE_H */
135