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