• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2024 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_CHECKER_ETS_CHECKER_H
17 #define ES2PANDA_CHECKER_ETS_CHECKER_H
18 
19 #include "checker/checkerContext.h"
20 #include "varbinder/enumMemberResult.h"
21 #include "varbinder/scope.h"
22 #include "checker/checker.h"
23 #include "checker/ets/primitiveWrappers.h"
24 #include "checker/ets/typeConverter.h"
25 #include "checker/types/ets/etsObjectType.h"
26 #include "checker/types/ets/etsTupleType.h"
27 #include "checker/types/ets/types.h"
28 #include "checker/types/globalTypesHolder.h"
29 #include "ir/ts/tsTypeParameter.h"
30 #include "ir/ts/tsTypeParameterInstantiation.h"
31 #include "lexer/token/tokenType.h"
32 #include "util/enumbitops.h"
33 #include "util/ustring.h"
34 #include "utils/bit_utils.h"
35 #include "checker/resolveResult.h"
36 #include "macros.h"
37 
38 #include <cstdint>
39 #include <initializer_list>
40 #include <tuple>
41 #include <unordered_map>
42 #include <unordered_set>
43 #include <type_traits>
44 
45 namespace panda::es2panda::varbinder {
46 class VarBinder;
47 class Decl;
48 class EnumVariable;
49 class FunctionDecl;
50 class LocalVariable;
51 class Scope;
52 class Variable;
53 class ETSBinder;
54 class RecordTable;
55 class FunctionParamScope;
56 }  // namespace panda::es2panda::varbinder
57 
58 namespace panda::es2panda::checker {
59 
60 using ComputedAbstracts =
61     ArenaUnorderedMap<ETSObjectType *, std::pair<ArenaVector<ETSFunctionType *>, std::unordered_set<ETSObjectType *>>>;
62 using ArrayMap = ArenaUnorderedMap<Type *, ETSArrayType *>;
63 using GlobalArraySignatureMap = ArenaUnorderedMap<ETSArrayType *, Signature *>;
64 using DynamicCallIntrinsicsMap = ArenaUnorderedMap<Language, ArenaUnorderedMap<util::StringView, ir::ScriptFunction *>>;
65 using DynamicLambdaObjectSignatureMap = ArenaUnorderedMap<std::string, Signature *>;
66 
67 class ETSChecker final : public Checker {
68 public:
ETSChecker()69     explicit ETSChecker()
70         // NOLINTNEXTLINE(readability-redundant-member-init)
71         : Checker(),
72           arrayTypes_(Allocator()->Adapter()),
73           globalArraySignatures_(Allocator()->Adapter()),
74           primitiveWrappers_(Allocator()),
75           cachedComputedAbstracts_(Allocator()->Adapter()),
76           dynamicCallIntrinsics_(Allocator()->Adapter()),
77           dynamicNewIntrinsics_(Allocator()->Adapter()),
78           dynamicLambdaSignatureCache_(Allocator()->Adapter())
79     {
80     }
81 
ETSType(const Type * const type)82     [[nodiscard]] static inline TypeFlag ETSType(const Type *const type) noexcept
83     {
84         return static_cast<TypeFlag>(type->TypeFlags() & TypeFlag::ETS_TYPE);
85     }
86 
TypeKind(const Type * const type)87     [[nodiscard]] static inline TypeFlag TypeKind(const Type *const type) noexcept
88     {
89         return static_cast<checker::TypeFlag>(type->TypeFlags() & checker::TypeFlag::ETS_TYPE);
90     }
91 
92     Type *GlobalByteType() const;
93     Type *GlobalShortType() const;
94     Type *GlobalIntType() const;
95     Type *GlobalLongType() const;
96     Type *GlobalFloatType() const;
97     Type *GlobalDoubleType() const;
98     Type *GlobalCharType() const;
99     Type *GlobalETSBooleanType() const;
100     Type *GlobalVoidType() const;
101     Type *GlobalETSNullType() const;
102     Type *GlobalETSUndefinedType() const;
103     Type *GlobalETSStringLiteralType() const;
104     Type *GlobalETSBigIntType() const;
105     Type *GlobalWildcardType() const;
106 
107     ETSObjectType *GlobalETSObjectType() const;
108     ETSObjectType *GlobalETSNullishObjectType() const;
109     ETSObjectType *GlobalBuiltinETSStringType() const;
110     ETSObjectType *GlobalBuiltinETSBigIntType() const;
111     ETSObjectType *GlobalBuiltinTypeType() const;
112     ETSObjectType *GlobalBuiltinExceptionType() const;
113     ETSObjectType *GlobalBuiltinErrorType() const;
114     ETSObjectType *GlobalStringBuilderBuiltinType() const;
115     ETSObjectType *GlobalBuiltinPromiseType() const;
116     ETSObjectType *GlobalBuiltinJSRuntimeType() const;
117     ETSObjectType *GlobalBuiltinJSValueType() const;
118     ETSObjectType *GlobalBuiltinBoxType(const Type *contents) const;
119     ETSObjectType *GlobalBuiltinVoidType() const;
120 
121     ETSObjectType *GlobalBuiltinDynamicType(Language lang) const;
122 
123     const checker::WrapperDesc &PrimitiveWrapper() const;
124 
125     GlobalArraySignatureMap &GlobalArrayTypes();
126     const GlobalArraySignatureMap &GlobalArrayTypes() const;
127 
128     void InitializeBuiltins(varbinder::ETSBinder *varbinder);
129     void InitializeBuiltin(varbinder::Variable *var, const util::StringView &name);
130     bool StartChecker([[maybe_unused]] varbinder::VarBinder *varbinder, const CompilerOptions &options) override;
131     Type *CheckTypeCached(ir::Expression *expr) override;
ResolveStructuredTypeMembers(Type * type)132     void ResolveStructuredTypeMembers([[maybe_unused]] Type *type) override {}
133     Type *GetTypeOfVariable([[maybe_unused]] varbinder::Variable *var) override;
134     Type *GuaranteedTypeForUncheckedCast(Type *base, Type *substituted);
135     Type *GuaranteedTypeForUncheckedCallReturn(Signature *sig);
136     Type *GuaranteedTypeForUncheckedPropertyAccess(varbinder::Variable *prop);
IsETSChecker()137     bool IsETSChecker() override
138     {
139         return true;
140     }
141 
142     // Object
143     ETSObjectType *BuildClassProperties(ir::ClassDefinition *classDef);
144     ETSObjectType *BuildAnonymousClassProperties(ir::ClassDefinition *classDef, ETSObjectType *superType);
145     ETSObjectType *BuildInterfaceProperties(ir::TSInterfaceDeclaration *interfaceDecl);
146     ETSObjectType *GetSuperType(ETSObjectType *type);
147     ArenaVector<ETSObjectType *> GetInterfaces(ETSObjectType *type);
148     ArenaVector<ETSObjectType *> GetInterfacesOfClass(ETSObjectType *type);
149     ArenaVector<ETSObjectType *> GetInterfacesOfInterface(ETSObjectType *type);
150     void ValidateImplementedInterface(ETSObjectType *type, Type *interface, std::unordered_set<Type *> *extendsSet,
151                                       const lexer::SourcePosition &pos);
152     void ResolveDeclaredMembersOfObject(ETSObjectType *type);
153     int32_t GetTupleElementAccessValue(const Type *type) const;
154     void ValidateArrayIndex(ir::Expression *expr, bool relaxed = false);
155     void ValidateTupleIndex(const ETSTupleType *tuple, const ir::MemberExpression *expr);
156     ETSObjectType *CheckThisOrSuperAccess(ir::Expression *node, ETSObjectType *classType, std::string_view msg);
157     void CreateTypeForClassOrInterfaceTypeParameters(ETSObjectType *type);
158     ETSTypeParameter *SetUpParameterType(ir::TSTypeParameter *param);
159     void ValidateOverriding(ETSObjectType *classType, const lexer::SourcePosition &pos);
160     void AddImplementedSignature(std::vector<Signature *> *implementedSignatures, varbinder::LocalVariable *function,
161                                  ETSFunctionType *it);
162     void CheckInnerClassMembers(const ETSObjectType *classType);
163     void CheckClassDefinition(ir::ClassDefinition *classDef);
164     void FindAssignment(const ir::AstNode *node, const varbinder::LocalVariable *classVar, bool &initialized);
165     void FindAssignments(const ir::AstNode *node, const varbinder::LocalVariable *classVar, bool &initialized);
166     void CheckConstFields(const ETSObjectType *classType);
167     void CheckConstFieldInitialized(const ETSObjectType *classType, varbinder::LocalVariable *classVar);
168     void CheckConstFieldInitialized(const Signature *signature, varbinder::LocalVariable *classVar);
169     void ComputeAbstractsFromInterface(ETSObjectType *interfaceType);
170     ArenaVector<ETSFunctionType *> &GetAbstractsForClass(ETSObjectType *classType);
171     std::vector<Signature *> CollectAbstractSignaturesFromObject(const ETSObjectType *objType);
172     void CreateFunctionTypesFromAbstracts(const std::vector<Signature *> &abstracts,
173                                           ArenaVector<ETSFunctionType *> *target);
174     void CheckCyclicConstructorCall(Signature *signature);
175     std::vector<ResolveResult *> ResolveMemberReference(const ir::MemberExpression *memberExpr,
176                                                         const ETSObjectType *target);
177     varbinder::Variable *ResolveInstanceExtension(const ir::MemberExpression *memberExpr);
178     void CheckImplicitSuper(ETSObjectType *classType, Signature *ctorSig);
179     void CheckValidInheritance(ETSObjectType *classType, ir::ClassDefinition *classDef);
180     void CheckGetterSetterProperties(ETSObjectType *classType);
181     void AddElementsToModuleObject(ETSObjectType *moduleObj, const util::StringView &str);
182     Type *FindLeastUpperBound(Type *source, Type *target);
183     static Type *GetApparentType(Type *type);
184     static Type const *GetApparentType(Type const *type);
185     Type *MaybePromotedBuiltinType(Type *type) const;
186     Type *GetCommonClass(Type *source, Type *target);
187     ETSObjectType *GetClosestCommonAncestor(ETSObjectType *source, ETSObjectType *target);
188     ETSObjectType *GetTypeargumentedLUB(ETSObjectType *source, ETSObjectType *target);
189     bool HasETSFunctionType(ir::TypeNode *typeAnnotation);
190 
191     // Type creation
192     ByteType *CreateByteType(int8_t value);
193     ETSBooleanType *CreateETSBooleanType(bool value);
194     DoubleType *CreateDoubleType(double value);
195     FloatType *CreateFloatType(float value);
196     IntType *CreateIntType(int32_t value);
197     LongType *CreateLongType(int64_t value);
198     ShortType *CreateShortType(int16_t value);
199     CharType *CreateCharType(char16_t value);
200     ETSBigIntType *CreateETSBigIntLiteralType(util::StringView value);
201     ETSStringType *CreateETSStringLiteralType(util::StringView value);
202     ETSArrayType *CreateETSArrayType(Type *elementType);
203     Type *CreateETSUnionType(ArenaVector<Type *> &&constituentTypes);
204     template <class... Types>
CreateETSUnionType(Types &&...types)205     Type *CreateETSUnionType(Types &&...types)
206     {
207         ArenaVector<Type *> constituentTypes(Allocator()->Adapter());
208         (constituentTypes.push_back(types), ...);
209         return CreateETSUnionType(std::move(constituentTypes));
210     }
211     ETSFunctionType *CreateETSFunctionType(Signature *signature);
212     ETSFunctionType *CreateETSFunctionType(Signature *signature, util::StringView name);
213     ETSFunctionType *CreateETSFunctionType(ir::ScriptFunction *func, Signature *signature, util::StringView name);
214     ETSFunctionType *CreateETSFunctionType(util::StringView name);
215     ETSFunctionType *CreateETSFunctionType(ArenaVector<Signature *> &signatures);
216     ETSExtensionFuncHelperType *CreateETSExtensionFuncHelperType(ETSFunctionType *classMethodType,
217                                                                  ETSFunctionType *extensionFunctionType);
218     ETSTypeParameter *CreateTypeParameter();
219     ETSObjectType *CreateETSObjectType(util::StringView name, ir::AstNode *declNode, ETSObjectFlags flags);
220     ETSEnumType *CreateETSEnumType(ir::TSEnumDeclaration const *enumDecl);
221     ETSStringEnumType *CreateETSStringEnumType(ir::TSEnumDeclaration const *enumDecl);
222     std::tuple<util::StringView, SignatureInfo *> CreateBuiltinArraySignatureInfo(ETSArrayType *arrayType, size_t dim);
223     Signature *CreateBuiltinArraySignature(ETSArrayType *arrayType, size_t dim);
224     IntType *CreateIntTypeFromType(Type *type);
225     ETSObjectType *CreateNewETSObjectType(util::StringView name, ir::AstNode *declNode, ETSObjectFlags flags);
226 
227     Signature *CreateSignature(SignatureInfo *info, Type *returnType, ir::ScriptFunction *func);
228     Signature *CreateSignature(SignatureInfo *info, Type *returnType, util::StringView internalName);
229     SignatureInfo *CreateSignatureInfo();
230 
231     // Arithmetic
232     Type *NegateNumericType(Type *type, ir::Expression *node);
233     Type *BitwiseNegateNumericType(Type *type, ir::Expression *node);
234     bool CheckBinaryOperatorForBigInt(Type *left, Type *right, ir::Expression *expr, lexer::TokenType op);
235     std::tuple<Type *, Type *> CheckBinaryOperator(ir::Expression *left, ir::Expression *right, ir::Expression *expr,
236                                                    lexer::TokenType operationType, lexer::SourcePosition pos,
237                                                    bool forcePromotion = false);
238     checker::Type *CheckBinaryOperatorMulDivMod(ir::Expression *left, ir::Expression *right,
239                                                 lexer::TokenType operationType, lexer::SourcePosition pos,
240                                                 bool isEqualOp, checker::Type *leftType, checker::Type *rightType,
241                                                 Type *unboxedL, Type *unboxedR);
242     checker::Type *CheckBinaryOperatorPlus(ir::Expression *left, ir::Expression *right, lexer::TokenType operationType,
243                                            lexer::SourcePosition pos, bool isEqualOp, checker::Type *leftType,
244                                            checker::Type *rightType, Type *unboxedL, Type *unboxedR);
245     checker::Type *CheckBinaryOperatorShift(ir::Expression *left, ir::Expression *right, lexer::TokenType operationType,
246                                             lexer::SourcePosition pos, bool isEqualOp, checker::Type *leftType,
247                                             checker::Type *rightType, Type *unboxedL, Type *unboxedR);
248     checker::Type *CheckBinaryOperatorBitwise(ir::Expression *left, ir::Expression *right,
249                                               lexer::TokenType operationType, lexer::SourcePosition pos, bool isEqualOp,
250                                               checker::Type *leftType, checker::Type *rightType, Type *unboxedL,
251                                               Type *unboxedR);
252     checker::Type *CheckBinaryOperatorLogical(ir::Expression *left, ir::Expression *right, ir::Expression *expr,
253                                               lexer::SourcePosition pos, checker::Type *leftType,
254                                               checker::Type *rightType, Type *unboxedL, Type *unboxedR);
255     std::tuple<Type *, Type *> CheckBinaryOperatorStrictEqual(ir::Expression *left, lexer::SourcePosition pos,
256                                                               checker::Type *leftType, checker::Type *rightType);
257     std::tuple<Type *, Type *> CheckBinaryOperatorEqual(ir::Expression *left, ir::Expression *right,
258                                                         lexer::TokenType operationType, lexer::SourcePosition pos,
259                                                         checker::Type *leftType, checker::Type *rightType,
260                                                         Type *unboxedL, Type *unboxedR);
261     std::tuple<Type *, Type *> CheckBinaryOperatorEqualDynamic(ir::Expression *left, ir::Expression *right,
262                                                                lexer::SourcePosition pos);
263     std::tuple<Type *, Type *> CheckBinaryOperatorLessGreater(ir::Expression *left, ir::Expression *right,
264                                                               lexer::TokenType operationType, lexer::SourcePosition pos,
265                                                               bool isEqualOp, checker::Type *leftType,
266                                                               checker::Type *rightType, Type *unboxedL, Type *unboxedR);
267     std::tuple<Type *, Type *> CheckBinaryOperatorInstanceOf(lexer::SourcePosition pos, checker::Type *leftType,
268                                                              checker::Type *rightType);
269     checker::Type *CheckBinaryOperatorNullishCoalescing(ir::Expression *right, lexer::SourcePosition pos,
270                                                         checker::Type *leftType, checker::Type *rightType);
271     Type *HandleArithmeticOperationOnTypes(Type *left, Type *right, lexer::TokenType operationType);
272     Type *HandleBitwiseOperationOnTypes(Type *left, Type *right, lexer::TokenType operationType);
273     void FlagExpressionWithUnboxing(Type *type, Type *unboxedType, ir::Expression *typeExpression);
274     template <typename ValueType>
275     Type *PerformArithmeticOperationOnTypes(Type *left, Type *right, lexer::TokenType operationType);
276 
277     Type *HandleRelationOperationOnTypes(Type *left, Type *right, lexer::TokenType operationType);
278     template <typename TargetType>
279     Type *PerformRelationOperationOnTypes(Type *left, Type *right, lexer::TokenType operationType);
280 
281     // Function
282     bool NeedTypeInference(const ir::ScriptFunction *lambda);
283     std::vector<bool> FindTypeInferenceArguments(const ArenaVector<ir::Expression *> &arguments);
284     void InferTypesForLambda(ir::ScriptFunction *lambda, ir::ETSFunctionType *calleeType);
285     bool TypeInference(Signature *signature, const ArenaVector<ir::Expression *> &arguments,
286                        TypeRelationFlag flags = TypeRelationFlag::NONE);
287     bool CheckLambdaAssignable(ir::Expression *param, ir::ScriptFunction *lambda);
288     bool IsCompatibleTypeArgument(ETSTypeParameter *typeParam, Type *typeArgument, const Substitution *substitution);
NewSubstitution()289     Substitution *NewSubstitution()
290     {
291         return Allocator()->New<Substitution>(Allocator()->Adapter());
292     }
CopySubstitution(const Substitution * src)293     Substitution *CopySubstitution(const Substitution *src)
294     {
295         return Allocator()->New<Substitution>(*src);
296     }
297     static void EmplaceSubstituted(Substitution *substitution, ETSTypeParameter *tparam, Type *typeArg);
NewInstantiatedTypeParamsSet()298     ArenaUnorderedSet<ETSTypeParameter *> *NewInstantiatedTypeParamsSet()
299     {
300         return Allocator()->New<ArenaUnorderedSet<ETSTypeParameter *>>(Allocator()->Adapter());
301     }
302     ArenaVector<Type *> CreateTypeForTypeParameters(ir::TSTypeParameterDeclaration const *typeParams);
303     [[nodiscard]] bool EnhanceSubstitutionForType(const ArenaVector<Type *> &typeParams, Type *paramType,
304                                                   Type *argumentType, Substitution *substitution,
305                                                   ArenaUnorderedSet<ETSTypeParameter *> *instantiatedTypeParams);
306     [[nodiscard]] bool EnhanceSubstitutionForObject(const ArenaVector<Type *> &typeParams, ETSObjectType *paramType,
307                                                     Type *argumentType, Substitution *substitution,
308                                                     ArenaUnorderedSet<ETSTypeParameter *> *instantiatedTypeParams);
309     Signature *ValidateParameterlessConstructor(Signature *signature, const lexer::SourcePosition &pos,
310                                                 TypeRelationFlag flags);
311     Signature *CollectParameterlessConstructor(ArenaVector<Signature *> &signatures, const lexer::SourcePosition &pos,
312                                                TypeRelationFlag resolveFlags = TypeRelationFlag::NONE);
313     Signature *ValidateSignature(Signature *signature, const ir::TSTypeParameterInstantiation *typeArguments,
314                                  const ArenaVector<ir::Expression *> &arguments, const lexer::SourcePosition &pos,
315                                  TypeRelationFlag initialFlags, const std::vector<bool> &argTypeInferenceRequired);
316     Signature *ValidateSignatures(ArenaVector<Signature *> &signatures,
317                                   const ir::TSTypeParameterInstantiation *typeArguments,
318                                   const ArenaVector<ir::Expression *> &arguments, const lexer::SourcePosition &pos,
319                                   std::string_view signatureKind,
320                                   TypeRelationFlag resolveFlags = TypeRelationFlag::NONE);
321     bool ValidateProxySignature(Signature *signature, const ir::TSTypeParameterInstantiation *typeArguments,
322                                 const ArenaVector<ir::Expression *> &arguments,
323                                 const std::vector<bool> &argTypeInferenceRequired);
324     Signature *ChooseMostSpecificSignature(ArenaVector<Signature *> &signatures,
325                                            const std::vector<bool> &argTypeInferenceRequired,
326                                            const lexer::SourcePosition &pos, size_t argumentsSize = ULONG_MAX);
327     Signature *ChooseMostSpecificProxySignature(ArenaVector<Signature *> &signatures,
328                                                 const std::vector<bool> &argTypeInferenceRequired,
329                                                 const lexer::SourcePosition &pos, size_t argumentsSize);
330     Signature *ResolveCallExpression(ArenaVector<Signature *> &signatures,
331                                      const ir::TSTypeParameterInstantiation *typeArguments,
332                                      const ArenaVector<ir::Expression *> &arguments, const lexer::SourcePosition &pos);
333     Signature *ResolveCallExpressionAndTrailingLambda(ArenaVector<Signature *> &signatures,
334                                                       ir::CallExpression *callExpr, const lexer::SourcePosition &pos,
335                                                       TypeRelationFlag throwFlag = TypeRelationFlag::NONE);
336     Signature *ResolveConstructExpression(ETSObjectType *type, const ArenaVector<ir::Expression *> &arguments,
337                                           const lexer::SourcePosition &pos);
338     void CheckObjectLiteralArguments(Signature *sig, ArenaVector<ir::Expression *> const &arguments);
339     Signature *ComposeSignature(ir::ScriptFunction *func, SignatureInfo *signatureInfo, Type *returnType,
340                                 varbinder::Variable *nameVar);
341     Type *ComposeReturnType(ir::ScriptFunction *func, util::StringView funcName, bool isConstructSig);
342     SignatureInfo *ComposeSignatureInfo(ir::ScriptFunction *func);
343     void ValidateMainSignature(ir::ScriptFunction *func);
344     checker::ETSFunctionType *BuildFunctionSignature(ir::ScriptFunction *func, bool isConstructSig = false);
345     checker::ETSFunctionType *BuildMethodSignature(ir::MethodDefinition *method);
346     Signature *CheckEveryAbstractSignatureIsOverridden(ETSFunctionType *target, ETSFunctionType *source);
347     Signature *GetSignatureFromMethodDefinition(const ir::MethodDefinition *methodDef);
348     void CheckIdenticalOverloads(ETSFunctionType *func, ETSFunctionType *overload,
349                                  const ir::MethodDefinition *currentFunc);
350     Signature *AdjustForTypeParameters(Signature *source, Signature *target);
351     void ThrowOverrideError(Signature *signature, Signature *overriddenSignature, const OverrideErrorCode &errorCode);
352     void CheckOverride(Signature *signature);
353     bool CheckOverride(Signature *signature, ETSObjectType *site);
354     std::tuple<bool, OverrideErrorCode> CheckOverride(Signature *signature, Signature *other);
355     bool IsMethodOverridesOther(Signature *target, Signature *source);
356     bool IsOverridableIn(Signature *signature);
357     [[nodiscard]] bool AreOverrideEquivalent(Signature *s1, Signature *s2);
358     [[nodiscard]] bool IsReturnTypeSubstitutable(Signature *s1, Signature *s2);
359     void CheckStaticHide(Signature *target, Signature *source);
360     void CheckThrowMarkers(Signature *source, Signature *target);
361     void ValidateSignatureAccessibility(ETSObjectType *callee, const ir::CallExpression *callExpr, Signature *signature,
362                                         const lexer::SourcePosition &pos, char const *errorMessage = nullptr);
363     void CreateLambdaObjectForLambdaReference(ir::ArrowFunctionExpression *lambda, ETSObjectType *functionalInterface);
364     ir::ClassProperty *CreateLambdaCapturedField(const varbinder::Variable *capturedVar, varbinder::ClassScope *scope,
365                                                  size_t &idx, const lexer::SourcePosition &pos);
366     ir::ClassProperty *CreateLambdaCapturedThis(varbinder::ClassScope *scope, size_t &idx,
367                                                 const lexer::SourcePosition &pos);
368     void CreateLambdaObjectForFunctionReference(ir::AstNode *refNode, Signature *signature,
369                                                 ETSObjectType *functionalInterface);
370     ir::AstNode *CreateLambdaImplicitField(varbinder::ClassScope *scope, const lexer::SourcePosition &pos);
371     ir::MethodDefinition *CreateLambdaImplicitCtor(const lexer::SourceRange &pos, bool isStaticReference);
372     ir::MethodDefinition *CreateLambdaImplicitCtor(ArenaVector<ir::AstNode *> &properties);
373     ir::MethodDefinition *CreateProxyMethodForLambda(ir::ClassDefinition *klass, ir::ArrowFunctionExpression *lambda,
374                                                      ArenaVector<ir::AstNode *> &captured, bool isStatic);
375     varbinder::FunctionParamScope *CreateProxyMethodParams(ir::ArrowFunctionExpression *lambda,
376                                                            ArenaVector<ir::Expression *> &proxyParams,
377                                                            ArenaVector<ir::AstNode *> &captured, bool isStatic);
378     void ReplaceIdentifierReferencesInProxyMethod(ir::AstNode *body, const ArenaVector<ir::Expression *> &proxyParams,
379                                                   const ArenaVector<ir::Expression *> &lambdaParams,
380                                                   ArenaVector<varbinder::Variable *> &captured);
381     void ReplaceIdentifierReferencesInProxyMethod(
382         ir::AstNode *node, const ArenaVector<ir::Expression *> &proxyParams,
383         std::unordered_map<varbinder::Variable *, size_t> &mergedTargetReferences);
384     void ReplaceIdentifierReferenceInProxyMethod(
385         ir::AstNode *node, const ArenaVector<ir::Expression *> &proxyParams,
386         std::unordered_map<varbinder::Variable *, size_t> &mergedTargetReferences);
387     ir::Statement *CreateLambdaCtorFieldInit(util::StringView name, varbinder::Variable *var);
388     varbinder::FunctionParamScope *CreateLambdaCtorImplicitParams(ArenaVector<ir::Expression *> &params,
389                                                                   ArenaVector<ir::AstNode *> &properties);
390     std::tuple<varbinder::FunctionParamScope *, varbinder::Variable *> CreateLambdaCtorImplicitParam(
391         ArenaVector<ir::Expression *> &params, const lexer::SourceRange &pos, bool isStaticReference);
392     ir::MethodDefinition *CreateLambdaInvokeProto();
393     void CreateLambdaFuncDecl(ir::MethodDefinition *func, varbinder::LocalScope *scope);
394     void ResolveProxyMethod(ir::MethodDefinition *proxyMethod, ir::ArrowFunctionExpression *lambda);
395     void ResolveLambdaObject(ir::ClassDefinition *lambdaObject, Signature *signature,
396                              ETSObjectType *functionalInterface, ir::AstNode *refNode);
397     void ResolveLambdaObject(ir::ClassDefinition *lambdaObject, ETSObjectType *functionalInterface,
398                              ir::ArrowFunctionExpression *lambda, ir::MethodDefinition *proxyMethod, bool saveThis);
399     void ResolveLambdaObjectCtor(ir::ClassDefinition *lambdaObject, bool isStaticReference);
400     void ResolveLambdaObjectCtor(ir::ClassDefinition *lambdaObject);
401     void ResolveLambdaObjectInvoke(ir::ClassDefinition *lambdaObject, Signature *signatureRef);
402     void ResolveLambdaObjectInvoke(ir::ClassDefinition *lambdaObject, ir::ArrowFunctionExpression *lambda,
403                                    ir::MethodDefinition *proxyMethod, bool isStatic);
404     ir::Statement *ResolveLambdaObjectInvokeFuncBody(ir::ClassDefinition *lambdaObject, Signature *signatureRef);
405     ir::Statement *ResolveLambdaObjectInvokeFuncBody(ir::ClassDefinition *lambdaObject,
406                                                      ir::MethodDefinition *proxyMethod, bool isStatic);
407     void CreateFunctionalInterfaceForFunctionType(ir::ETSFunctionType *funcType);
408     ir::MethodDefinition *CreateInvokeFunction(ir::ETSFunctionType *funcType);
409     void CheckCapturedVariables();
410     void CheckCapturedVariableInSubnodes(ir::AstNode *node, varbinder::Variable *var);
411     void CheckCapturedVariable(ir::AstNode *node, varbinder::Variable *var);
412     void BuildFunctionalInterfaceName(ir::ETSFunctionType *funcType);
413     void CreateAsyncProxyMethods(ir::ClassDefinition *classDef);
414     ir::MethodDefinition *CreateAsyncImplMethod(ir::MethodDefinition *asyncMethod, ir::ClassDefinition *classDef);
415     ir::MethodDefinition *CreateAsyncProxy(ir::MethodDefinition *asyncMethod, ir::ClassDefinition *classDef,
416                                            bool createDecl = true);
417     ir::MethodDefinition *CreateMethod(const util::StringView &name, ir::ModifierFlags modifiers,
418                                        ir::ScriptFunctionFlags flags, ArenaVector<ir::Expression *> &&params,
419                                        varbinder::FunctionParamScope *paramScope, ir::TypeNode *returnType,
420                                        ir::AstNode *body);
421     varbinder::FunctionParamScope *CopyParams(const ArenaVector<ir::Expression *> &params,
422                                               ArenaVector<ir::Expression *> &outParams);
423     void ReplaceScope(ir::AstNode *root, ir::AstNode *oldNode, varbinder::Scope *newScope);
424 
425     // Helpers
426     size_t ComputeProxyMethods(ir::ClassDefinition *klass);
427     ir::ModifierFlags GetFlagsForProxyLambda(bool isStatic);
428     ir::ScriptFunction *CreateProxyFunc(ir::ArrowFunctionExpression *lambda, ArenaVector<ir::AstNode *> &captured,
429                                         bool isStatic);
430     ir::AstNode *GetProxyMethodBody(ir::ArrowFunctionExpression *lambda, varbinder::FunctionScope *scope);
431     static std::string GetAsyncImplName(const util::StringView &name);
432     static std::string GetAsyncImplName(ir::MethodDefinition *asyncMethod);
433     std::vector<util::StringView> GetNameForSynteticObjectType(const util::StringView &source);
434     void SetPropertiesForModuleObject(checker::ETSObjectType *moduleObjType, const util::StringView &importPath);
435     void SetrModuleObjectTsType(ir::Identifier *local, checker::ETSObjectType *moduleObjType);
436     Type *GetReferencedTypeFromBase(Type *baseType, ir::Expression *name);
437     Type *GetReferencedTypeBase(ir::Expression *name);
438     Type *GetTypeFromInterfaceReference(varbinder::Variable *var);
439     Type *GetTypeFromTypeAliasReference(varbinder::Variable *var);
440     Type *GetTypeFromClassReference(varbinder::Variable *var);
441     void ValidateGenericTypeAliasForClonedNode(ir::TSTypeAliasDeclaration *typeAliasNode,
442                                                const ir::TSTypeParameterInstantiation *exactTypeParams);
443     Type *HandleTypeAlias(ir::Expression *name, const ir::TSTypeParameterInstantiation *typeParams);
444     Type *GetTypeFromEnumReference(varbinder::Variable *var);
445     Type *GetTypeFromTypeParameterReference(varbinder::LocalVariable *var, const lexer::SourcePosition &pos);
446     Type *GetNonConstantTypeFromPrimitiveType(Type *type);
447     bool IsNullLikeOrVoidExpression(const ir::Expression *expr) const;
448     bool IsConstantExpression(ir::Expression *expr, Type *type);
449     void ValidateUnaryOperatorOperand(varbinder::Variable *variable);
450     bool TestUnionType(Type *type, TypeFlag test);
451     bool CheckPossibilityPromotion(Type *left, Type *right, TypeFlag test);
452     std::tuple<Type *, bool> ApplyBinaryOperatorPromotion(Type *left, Type *right, TypeFlag test,
453                                                           bool doPromotion = true);
454     checker::Type *ApplyConditionalOperatorPromotion(checker::ETSChecker *checker, checker::Type *unboxedL,
455                                                      checker::Type *unboxedR);
456     Type *ApplyUnaryOperatorPromotion(Type *type, bool createConst = true, bool doPromotion = true,
457                                       bool isCondExpr = false);
458     Type *HandleBooleanLogicalOperators(Type *leftType, Type *rightType, lexer::TokenType tokenType);
459     Type *HandleBooleanLogicalOperatorsExtended(Type *leftType, Type *rightType, ir::BinaryExpression *expr);
460     checker::Type *CheckVariableDeclaration(ir::Identifier *ident, ir::TypeNode *typeAnnotation, ir::Expression *init,
461                                             ir::ModifierFlags flags);
462     void CheckTruthinessOfType(ir::Expression *expr);
463     Type *CreateNullishType(Type *otype, checker::TypeFlag nullishFlags, ArenaAllocator *allocator,
464                             TypeRelation *relation, GlobalTypesHolder *globalTypes);
465     void CheckNonNullishType(Type *type, lexer::SourcePosition lineInfo);
466     Type *CreateOptionalResultType(Type *type);
467     Type *GetNonNullishType(Type *type) const;
468     const Type *GetNonNullishType(const Type *type) const;
469     bool MayHaveNullValue(const Type *type) const;
470     bool MayHaveUndefinedValue(const Type *type) const;
471     bool MayHaveNulllikeValue(const Type *type) const;
472     void ConcatConstantString(util::UString &target, Type *type);
473     Type *HandleStringConcatenation(Type *leftType, Type *rightType);
474     Type *ResolveIdentifier(ir::Identifier *ident);
475     ETSFunctionType *FindFunctionInVectorGivenByName(util::StringView name, ArenaVector<ETSFunctionType *> &list);
476     void MergeComputedAbstracts(ArenaVector<ETSFunctionType *> &merged, ArenaVector<ETSFunctionType *> &current);
477     void MergeSignatures(ETSFunctionType *target, ETSFunctionType *source);
478     ir::AstNode *FindAncestorGivenByType(ir::AstNode *node, ir::AstNodeType type, const ir::AstNode *endNode = nullptr);
479     util::StringView GetContainingObjectNameFromSignature(Signature *signature);
480     bool IsFunctionContainsSignature(ETSFunctionType *funcType, Signature *signature);
481     void CheckFunctionContainsClashingSignature(const ETSFunctionType *funcType, Signature *signature);
482     bool IsTypeBuiltinType(const Type *type) const;
483     static bool IsReferenceType(const Type *type);
484     const ir::AstNode *FindJumpTarget(ir::AstNodeType nodeType, const ir::AstNode *node, const ir::Identifier *target);
485     void ValidatePropertyAccess(varbinder::Variable *var, ETSObjectType *obj, const lexer::SourcePosition &pos);
486     varbinder::VariableFlags GetAccessFlagFromNode(const ir::AstNode *node);
487     void CheckSwitchDiscriminant(ir::Expression *discriminant);
488     Type *ETSBuiltinTypeAsPrimitiveType(Type *objectType);
489     Type *ETSBuiltinTypeAsConditionalType(Type *objectType);
490     Type *PrimitiveTypeAsETSBuiltinType(Type *objectType);
491     void AddBoxingUnboxingFlagsToNode(ir::AstNode *node, Type *boxingUnboxingType);
492     ir::BoxingUnboxingFlags GetBoxingFlag(Type *boxingType);
493     ir::BoxingUnboxingFlags GetUnboxingFlag(Type const *unboxingType) const;
494     Type *MaybeBoxedType(const varbinder::Variable *var, ArenaAllocator *allocator) const;
MaybeBoxedType(const varbinder::Variable * var)495     Type *MaybeBoxedType(const varbinder::Variable *var)
496     {
497         return MaybeBoxedType(var, Allocator());
498     }
499     void CheckForSameSwitchCases(ArenaVector<ir::SwitchCaseStatement *> *cases);
500     std::string GetStringFromIdentifierValue(checker::Type *caseType) const;
501     bool CompareIdentifiersValuesAreDifferent(ir::Expression *compareValue, const std::string &caseValue);
502     void CheckIdentifierSwitchCase(ir::Expression *currentCase, ir::Expression *compareCase,
503                                    const lexer::SourcePosition &pos);
504     std::string GetStringFromLiteral(ir::Expression *caseTest) const;
505     varbinder::Variable *FindVariableInFunctionScope(util::StringView name);
506     std::pair<const varbinder::Variable *, const ETSObjectType *> FindVariableInClassOrEnclosing(
507         util::StringView name, const ETSObjectType *classType);
508     varbinder::Variable *FindVariableInGlobal(const ir::Identifier *identifier);
509     void ValidateResolvedIdentifier(ir::Identifier *ident, varbinder::Variable *resolved);
510     static bool IsVariableStatic(const varbinder::Variable *var);
511     static bool IsVariableGetterSetter(const varbinder::Variable *var);
512     bool IsSameDeclarationType(varbinder::LocalVariable *target, varbinder::LocalVariable *compare);
513     void SaveCapturedVariable(varbinder::Variable *var, const lexer::SourcePosition &pos);
514     void AddBoxingFlagToPrimitiveType(TypeRelation *relation, Type *target);
515     void AddUnboxingFlagToPrimitiveType(TypeRelation *relation, Type *source, Type *self);
516     void CheckUnboxedTypeWidenable(TypeRelation *relation, Type *target, Type *self);
517     void CheckUnboxedTypesAssignable(TypeRelation *relation, Type *source, Type *target);
518     void CheckBoxedSourceTypeAssignable(TypeRelation *relation, Type *source, Type *target);
519     void CheckUnboxedSourceTypeWithWideningAssignable(TypeRelation *relation, Type *source, Type *target);
520     void CheckValidGenericTypeParameter(Type *argType, const lexer::SourcePosition &pos);
521     void ValidateResolvedProperty(const varbinder::LocalVariable *property, const ETSObjectType *target,
522                                   const ir::Identifier *ident, PropertySearchFlags flags);
523     bool IsValidSetterLeftSide(const ir::MemberExpression *member);
524     bool CheckRethrowingParams(const ir::AstNode *ancestorFunction, const ir::AstNode *node);
525     void CheckThrowingStatements(ir::AstNode *node);
526     bool CheckThrowingPlacement(ir::AstNode *node, const ir::AstNode *ancestorFunction);
527     void CheckNumberOfTypeArguments(ETSObjectType *type, ir::TSTypeParameterInstantiation *typeArgs,
528                                     const lexer::SourcePosition &pos);
529     ir::BlockStatement *FindFinalizerOfTryStatement(ir::AstNode *startFrom, const ir::AstNode *p);
530     void CheckRethrowingFunction(ir::ScriptFunction *func);
531     ETSObjectType *GetRelevantArgumentedTypeFromChild(ETSObjectType *child, ETSObjectType *target);
532     util::StringView GetHashFromTypeArguments(const ArenaVector<Type *> &typeArgTypes);
533     util::StringView GetHashFromSubstitution(const Substitution *substitution);
534     ETSObjectType *GetOriginalBaseType(Type *object);
535     Type *GetTypeFromTypeAnnotation(ir::TypeNode *typeAnnotation);
536     void AddUndefinedParamsForDefaultParams(const Signature *signature,
537                                             ArenaVector<panda::es2panda::ir::Expression *> &arguments,
538                                             ETSChecker *checker);
539     void SetArrayPreferredTypeForNestedMemberExpressions(ir::MemberExpression *expr, Type *annotationType);
540     bool ExtensionETSFunctionType(checker::Type *type);
541     void ValidateTupleMinElementSize(ir::ArrayExpression *arrayExpr, ETSTupleType *tuple);
542     void ModifyPreferredType(ir::ArrayExpression *arrayExpr, Type *newPreferredType);
543     Type *SelectGlobalIntegerTypeForNumeric(Type *type);
544 
545     // Exception
546     ETSObjectType *CheckExceptionOrErrorType(checker::Type *type, lexer::SourcePosition pos);
547 
548     static Type *TryToInstantiate(Type *type, ArenaAllocator *allocator, TypeRelation *relation,
549                                   GlobalTypesHolder *globalTypes);
550     // Enum
551     [[nodiscard]] ir::Identifier *CreateEnumNamesArray(ETSEnumInterface const *enumType);
552     [[nodiscard]] ir::Identifier *CreateEnumValuesArray(ETSEnumType *enumType);
553     [[nodiscard]] ir::Identifier *CreateEnumStringValuesArray(ETSEnumInterface *enumType);
554     [[nodiscard]] ir::Identifier *CreateEnumItemsArray(ETSEnumInterface *enumType);
555     [[nodiscard]] ETSEnumType::Method CreateEnumFromIntMethod(ir::Identifier *namesArrayIdent,
556                                                               ETSEnumInterface *enumType);
557     [[nodiscard]] ETSEnumType::Method CreateEnumGetValueMethod(ir::Identifier *valuesArrayIdent, ETSEnumType *enumType);
558     [[nodiscard]] ETSEnumType::Method CreateEnumToStringMethod(ir::Identifier *stringValuesArrayIdent,
559                                                                ETSEnumInterface *enumType);
560     [[nodiscard]] ETSEnumType::Method CreateEnumGetNameMethod(ir::Identifier *namesArrayIdent,
561                                                               ETSEnumInterface *enumType);
562     [[nodiscard]] ETSEnumType::Method CreateEnumValueOfMethod(ir::Identifier *namesArrayIdent,
563                                                               ETSEnumInterface *enumType);
564     [[nodiscard]] ETSEnumType::Method CreateEnumValuesMethod(ir::Identifier *itemsArrayIdent,
565                                                              ETSEnumInterface *enumType);
566 
567     // Dynamic interop
568     template <typename T>
569     Signature *ResolveDynamicCallExpression(ir::Expression *callee, const ArenaVector<T *> &arguments, Language lang,
570                                             bool isConstruct);
571     void BuildDynamicCallClass(bool isConstruct);
572     void BuildDynamicNewClass(bool isConstruct);
573     void BuildDynamicImportClass();
574     void BuildLambdaObjectClass(ETSObjectType *functionalInterface, ir::TypeNode *retTypeAnnotation);
575     // Trailing lambda
576     void EnsureValidCurlyBrace(ir::CallExpression *callExpr);
577 
578     // Extension function
579     void HandleUpdatedCallExpressionNode(ir::CallExpression *callExpr);
580 
581     // Static invoke
582     void CheckInvokeMethodsLegitimacy(ETSObjectType *classType);
583     checker::Type *CheckArrayElements(ir::Identifier *ident, ir::ArrayExpression *init);
584     void ResolveReturnStatement(checker::Type *funcReturnType, checker::Type *argumentType,
585                                 ir::ScriptFunction *containingFunc, ir::ReturnStatement *st);
586 
Mutex()587     std::recursive_mutex *Mutex()
588     {
589         return &mtx_;
590     }
591 
592     template <typename T, typename... Args>
AllocNode(Args &&...args)593     T *AllocNode(Args &&...args)
594     {
595         auto *ret = Allocator()->New<T>(std::forward<Args>(args)...);
596         ret->Iterate([ret](auto *child) { child->SetParent(ret); });
597         return ret;
598     }
599 
600 private:
601     using ClassBuilder = std::function<void(varbinder::ClassScope *, ArenaVector<ir::AstNode *> *)>;
602     using ClassInitializerBuilder = std::function<void(varbinder::FunctionScope *, ArenaVector<ir::Statement *> *,
603                                                        ArenaVector<ir::Expression *> *)>;
604     using MethodBuilder = std::function<void(varbinder::FunctionScope *, ArenaVector<ir::Statement *> *,
605                                              ArenaVector<ir::Expression *> *, Type **)>;
606 
607     std::pair<const ir::Identifier *, ir::TypeNode *> GetTargetIdentifierAndType(ir::Identifier *ident);
608     void ThrowError(ir::Identifier *ident);
609     void CheckEtsFunctionType(ir::Identifier *ident, ir::Identifier const *id, ir::TypeNode const *annotation);
610     void NotResolvedError(ir::Identifier *ident);
611     void ValidateCallExpressionIdentifier(ir::Identifier *ident, Type *type);
612     void ValidateNewClassInstanceIdentifier(ir::Identifier *ident, varbinder::Variable *resolved);
613     void ValidateMemberIdentifier(ir::Identifier *ident, varbinder::Variable *resolved, Type *type);
614     void ValidatePropertyOrDeclaratorIdentifier(ir::Identifier *ident, varbinder::Variable *resolved);
615     void ValidateAssignmentIdentifier(ir::Identifier *ident, varbinder::Variable *resolved, Type *type);
616     bool ValidateBinaryExpressionIdentifier(ir::Identifier *ident, Type *type);
617     void ValidateGetterSetter(const ir::MemberExpression *memberExpr, const varbinder::LocalVariable *prop,
618                               PropertySearchFlags searchFlag);
619     void ValidateVarDeclaratorOrClassProperty(const ir::MemberExpression *memberExpr, varbinder::LocalVariable *prop);
620     std::tuple<bool, bool> IsResolvedAndValue(const ir::Expression *expr, Type *type) const;
621     PropertySearchFlags GetSearchFlags(const ir::MemberExpression *memberExpr, const varbinder::Variable *targetRef);
622     PropertySearchFlags GetInitialSearchFlags(const ir::MemberExpression *memberExpr);
623     const varbinder::Variable *GetTargetRef(const ir::MemberExpression *memberExpr);
624     void BuildClass(util::StringView name, const ClassBuilder &builder);
625     template <bool IS_STATIC>
626     std::conditional_t<IS_STATIC, ir::ClassStaticBlock *, ir::MethodDefinition *> CreateClassInitializer(
627         varbinder::ClassScope *classScope, const ClassInitializerBuilder &builder, ETSObjectType *type = nullptr);
628 
629     ir::ETSParameterExpression *AddParam(varbinder::FunctionParamScope *paramScope, util::StringView name,
630                                          checker::Type *type);
631 
632     template <bool IS_STATIC>
633     ir::MethodDefinition *CreateClassMethod(varbinder::ClassScope *classScope, std::string_view methodName,
634                                             panda::es2panda::ir::ModifierFlags modifierFlags,
635                                             const MethodBuilder &builder);
636 
637     template <typename T>
638     ir::ScriptFunction *CreateDynamicCallIntrinsic(ir::Expression *callee, const ArenaVector<T *> &arguments,
639                                                    Language lang);
640     ir::ClassStaticBlock *CreateDynamicCallClassInitializer(varbinder::ClassScope *classScope, Language lang,
641                                                             bool isConstruct);
642     ir::ClassStaticBlock *CreateDynamicModuleClassInitializer(varbinder::ClassScope *classScope,
643                                                               const std::vector<ir::ETSImportDeclaration *> &imports);
644     ir::MethodDefinition *CreateDynamicModuleClassInitMethod(varbinder::ClassScope *classScope);
645 
646     ir::MethodDefinition *CreateLambdaObjectClassInitializer(varbinder::ClassScope *classScope,
647                                                              ETSObjectType *functionalInterface);
648 
649     ir::MethodDefinition *CreateLambdaObjectClassInvokeMethod(varbinder::ClassScope *classScope,
650                                                               Signature *invokeSignature,
651                                                               ir::TypeNode *retTypeAnnotation);
652 
653     void EmitDynamicModuleClassInitCall();
654 
DynamicCallIntrinsics(bool isConstruct)655     DynamicCallIntrinsicsMap *DynamicCallIntrinsics(bool isConstruct)
656     {
657         return isConstruct ? &dynamicNewIntrinsics_ : &dynamicCallIntrinsics_;
658     }
659 
660     using Type2TypeMap = std::unordered_map<std::string_view, std::string_view>;
661     void CheckTypeParameterConstraint(ir::TSTypeParameter *param, Type2TypeMap &extends);
662 
663     void SetUpTypeParameterConstraint(ir::TSTypeParameter *param);
664     ETSObjectType *UpdateGlobalType(ETSObjectType *objType, util::StringView name);
665     ETSObjectType *UpdateBoxedGlobalType(ETSObjectType *objType, util::StringView name);
666     ETSObjectType *CreateETSObjectTypeCheckBuiltins(util::StringView name, ir::AstNode *declNode, ETSObjectFlags flags);
667     void CheckProgram(parser::Program *program, bool runAnalysis = false);
668 
669     template <typename UType>
670     UType HandleModulo(UType leftValue, UType rightValue);
671 
672     template <typename FloatOrIntegerType, typename IntegerType = FloatOrIntegerType>
673     Type *HandleBitWiseArithmetic(Type *leftValue, Type *rightValue, lexer::TokenType operationType);
674 
675     template <typename TargetType>
676     typename TargetType::UType GetOperand(Type *type);
677 
678     ETSObjectType *AsETSObjectType(Type *(GlobalTypesHolder::*typeFunctor)()) const;
679     Signature *GetMostSpecificSignature(ArenaVector<Signature *> &compatibleSignatures,
680                                         ArenaVector<Signature *> &proxySignatures,
681                                         const ArenaVector<ir::Expression *> &arguments,
682                                         std::vector<bool> &argTypeInferenceRequired, const lexer::SourcePosition &pos,
683                                         TypeRelationFlag resolveFlags);
684     std::pair<ArenaVector<Signature *>, ArenaVector<Signature *>> CollectSignatures(
685         ArenaVector<Signature *> &signatures, const ir::TSTypeParameterInstantiation *typeArguments,
686         const ArenaVector<ir::Expression *> &arguments, std::vector<bool> &argTypeInferenceRequired,
687         const lexer::SourcePosition &pos, TypeRelationFlag resolveFlags);
688     // Trailing lambda
689     void MoveTrailingBlockToEnclosingBlockStatement(ir::CallExpression *callExpr);
690     void TransformTraillingLambda(ir::CallExpression *callExpr);
691     ArenaVector<ir::Expression *> ExtendArgumentsWithFakeLamda(ir::CallExpression *callExpr);
692 
693     // Static invoke
694     bool TryTransformingToStaticInvoke(ir::Identifier *ident, const Type *resolvedType);
695 
696     ArrayMap arrayTypes_;
697     GlobalArraySignatureMap globalArraySignatures_;
698     PrimitiveWrappers primitiveWrappers_;
699     ComputedAbstracts cachedComputedAbstracts_;
700     DynamicCallIntrinsicsMap dynamicCallIntrinsics_;
701     DynamicCallIntrinsicsMap dynamicNewIntrinsics_;
702     DynamicLambdaObjectSignatureMap dynamicLambdaSignatureCache_;
703     std::recursive_mutex mtx_;
704 };
705 
706 }  // namespace panda::es2panda::checker
707 
708 #endif /* CHECKER_H */
709