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_CHECKER_TYPES_SIGNATURE_H
17 #define ES2PANDA_COMPILER_CHECKER_TYPES_SIGNATURE_H
18
19 #include "type.h"
20
21 #include "varbinder/variable.h"
22 #include "compiler/core/compilerContext.h"
23
24 namespace panda::es2panda::checker {
25 // For use in Signature::ToAssemblerType
26 Type const *MaybeBoxedType(Checker *checker, varbinder::Variable const *var);
27
28 class SignatureInfo {
29 public:
SignatureInfo(ArenaAllocator * allocator)30 explicit SignatureInfo(ArenaAllocator *allocator) : typeParams {allocator->Adapter()}, params {allocator->Adapter()}
31 {
32 }
33
SignatureInfo(const SignatureInfo * other,ArenaAllocator * allocator)34 SignatureInfo(const SignatureInfo *other, ArenaAllocator *allocator)
35 : typeParams(allocator->Adapter()), params(allocator->Adapter())
36 {
37 for (auto *it : other->typeParams) {
38 typeParams.push_back(it);
39 }
40 for (auto *it : other->params) {
41 params.push_back(it->Copy(allocator, it->Declaration()));
42 params.back()->SetTsType(it->TsType());
43 }
44
45 minArgCount = other->minArgCount;
46
47 if (other->restVar != nullptr) {
48 restVar = other->restVar->Copy(allocator, other->restVar->Declaration());
49 }
50 }
51
52 ~SignatureInfo() = default;
53 NO_COPY_SEMANTIC(SignatureInfo);
54 NO_MOVE_SEMANTIC(SignatureInfo);
55
56 // NOLINTBEGIN(misc-non-private-member-variables-in-classes)
57 ArenaVector<Type *> typeParams;
58 uint32_t minArgCount {};
59 varbinder::LocalVariable *restVar {};
60 ArenaVector<varbinder::LocalVariable *> params;
61 // NOLINTEND(misc-non-private-member-variables-in-classes)
62 };
63
64 enum class SignatureFlags : uint32_t {
65 NO_OPTS = 0U,
66 VIRTUAL = 1U << 0U,
67 ABSTRACT = 1U << 1U,
68 CALL = 1U << 2U,
69 CONSTRUCT = 1U << 3U,
70 PUBLIC = 1U << 4U,
71 PROTECTED = 1U << 5U,
72 PRIVATE = 1U << 6U,
73 STATIC = 1U << 7U,
74 FINAL = 1U << 8U,
75 CONSTRUCTOR = 1U << 9U,
76 TYPE = 1U << 10U,
77 PROXY = 1U << 11U,
78 INTERNAL = 1U << 12U,
79 NEED_RETURN_TYPE = 1U << 13U,
80 INFERRED_RETURN_TYPE = 1U << 14U,
81 THIS_RETURN_TYPE = 1U << 15U,
82 GETTER = 1U << 16U,
83 SETTER = 1U << 17U,
84
85 INTERNAL_PROTECTED = INTERNAL | PROTECTED,
86 GETTER_OR_SETTER = GETTER | SETTER,
87 FUNCTIONAL_INTERFACE_SIGNATURE = VIRTUAL | ABSTRACT | CALL | PUBLIC | TYPE
88 };
89
DEFINE_BITOPS(SignatureFlags)90 DEFINE_BITOPS(SignatureFlags)
91
92 class Signature {
93 public:
94 Signature(SignatureInfo *signatureInfo, Type *returnType) : signatureInfo_(signatureInfo), returnType_(returnType)
95 {
96 }
97
98 Signature(SignatureInfo *signatureInfo, Type *returnType, util::StringView internalName)
99 : signatureInfo_(signatureInfo), returnType_(returnType), internalName_(internalName)
100 {
101 }
102
103 Signature(SignatureInfo *signatureInfo, Type *returnType, ir::ScriptFunction *func)
104 : signatureInfo_(signatureInfo), returnType_(returnType), func_(func)
105 {
106 }
107
108 ~Signature() = default;
109 NO_COPY_SEMANTIC(Signature);
110 NO_MOVE_SEMANTIC(Signature);
111
112 const SignatureInfo *GetSignatureInfo() const
113 {
114 return signatureInfo_;
115 }
116
117 SignatureInfo *GetSignatureInfo()
118 {
119 return signatureInfo_;
120 }
121
122 const ArenaVector<varbinder::LocalVariable *> &Params() const
123 {
124 return signatureInfo_->params;
125 }
126
127 ArenaVector<varbinder::LocalVariable *> &Params()
128 {
129 return signatureInfo_->params;
130 }
131
132 const Type *ReturnType() const
133 {
134 return returnType_;
135 }
136
137 Type *ReturnType()
138 {
139 return returnType_;
140 }
141
142 uint32_t MinArgCount() const
143 {
144 return signatureInfo_->minArgCount;
145 }
146
147 uint32_t OptionalArgCount() const
148 {
149 return signatureInfo_->params.size() - signatureInfo_->minArgCount;
150 }
151
152 void SetReturnType(Type *type)
153 {
154 returnType_ = type;
155 }
156
157 void SetOwner(ETSObjectType *owner)
158 {
159 ownerObj_ = owner;
160 }
161
162 void SetOwnerVar(varbinder::Variable *owner)
163 {
164 ownerVar_ = owner;
165 }
166
167 void SetFunction(ir::ScriptFunction *const function) noexcept
168 {
169 func_ = function;
170 }
171
172 ir::ScriptFunction *Function()
173 {
174 return func_;
175 }
176
177 ETSObjectType *Owner()
178 {
179 return ownerObj_;
180 }
181
182 varbinder::Variable *OwnerVar()
183 {
184 return ownerVar_;
185 }
186
187 const ir::ScriptFunction *Function() const
188 {
189 return func_;
190 }
191
192 const varbinder::LocalVariable *RestVar() const
193 {
194 return signatureInfo_->restVar;
195 }
196
197 uint8_t ProtectionFlag() const
198 {
199 if ((flags_ & SignatureFlags::PRIVATE) != 0) {
200 return 2U;
201 }
202
203 if ((flags_ & SignatureFlags::PROTECTED) != 0) {
204 return 1U;
205 }
206
207 return 0;
208 }
209
210 void AddSignatureFlag(SignatureFlags const flag) noexcept
211 {
212 flags_ |= flag;
213 }
214
215 void RemoveSignatureFlag(SignatureFlags const flag) noexcept
216 {
217 flags_ &= ~flag;
218 }
219
220 bool HasSignatureFlag(SignatureFlags const flag) const noexcept
221 {
222 return (flags_ & flag) != 0U;
223 }
224
225 bool IsFinal() const noexcept
226 {
227 return HasSignatureFlag(SignatureFlags::FINAL);
228 }
229
230 void ToAssemblerType(compiler::CompilerContext *context, std::stringstream &ss) const
231 {
232 ss << compiler::Signatures::MANGLE_BEGIN;
233
234 for (const auto *param : signatureInfo_->params) {
235 MaybeBoxedType(context->Checker(), param)->ToAssemblerTypeWithRank(ss);
236 ss << compiler::Signatures::MANGLE_SEPARATOR;
237 }
238
239 returnType_->ToAssemblerTypeWithRank(ss);
240 ss << compiler::Signatures::MANGLE_SEPARATOR;
241 }
242
243 util::StringView InternalName() const;
244
245 Signature *Copy(ArenaAllocator *allocator, TypeRelation *relation, GlobalTypesHolder *globalTypes);
246 Signature *Substitute(TypeRelation *relation, const Substitution *substitution);
247
248 void ToString(std::stringstream &ss, const varbinder::Variable *variable, bool printAsMethod = false) const;
249 void Identical(TypeRelation *relation, Signature *other);
250 bool CheckFunctionalInterfaces(TypeRelation *relation, Type *source, Type *target);
251 void AssignmentTarget(TypeRelation *relation, Signature *source);
252
253 private:
254 bool IdenticalParameter(TypeRelation *relation, Type *type1, Type *type2);
255 checker::SignatureInfo *signatureInfo_;
256 Type *returnType_;
257 ir::ScriptFunction *func_ {};
258 SignatureFlags flags_ {SignatureFlags::NO_OPTS};
259 util::StringView internalName_ {};
260 ETSObjectType *ownerObj_ {};
261 varbinder::Variable *ownerVar_ {};
262 };
263 } // namespace panda::es2panda::checker
264
265 #endif /* TYPESCRIPT_TYPES_SIGNATURE_H */
266