13af6ab5fSopenharmony_ci/*
23af6ab5fSopenharmony_ci * Copyright (c) 2021-2024 Huawei Device Co., Ltd.
33af6ab5fSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
43af6ab5fSopenharmony_ci * you may not use this file except in compliance with the License.
53af6ab5fSopenharmony_ci * You may obtain a copy of the License at
63af6ab5fSopenharmony_ci *
73af6ab5fSopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0
83af6ab5fSopenharmony_ci *
93af6ab5fSopenharmony_ci * Unless required by applicable law or agreed to in writing, software
103af6ab5fSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
113af6ab5fSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
123af6ab5fSopenharmony_ci * See the License for the specific language governing permissions and
133af6ab5fSopenharmony_ci * limitations under the License.
143af6ab5fSopenharmony_ci */
153af6ab5fSopenharmony_ci
163af6ab5fSopenharmony_ci#ifndef ES2PANDA_CHECKER_ETS_CHECKER_H
173af6ab5fSopenharmony_ci#define ES2PANDA_CHECKER_ETS_CHECKER_H
183af6ab5fSopenharmony_ci
193af6ab5fSopenharmony_ci#include <mutex>
203af6ab5fSopenharmony_ci
213af6ab5fSopenharmony_ci#include "checker/checker.h"
223af6ab5fSopenharmony_ci
233af6ab5fSopenharmony_ci#include "checker/types/ets/types.h"
243af6ab5fSopenharmony_ci#include "checker/ets/primitiveWrappers.h"
253af6ab5fSopenharmony_ci#include "checker/resolveResult.h"
263af6ab5fSopenharmony_ci#include "util/helpers.h"
273af6ab5fSopenharmony_ci
283af6ab5fSopenharmony_cinamespace ark::es2panda::varbinder {
293af6ab5fSopenharmony_ciclass VarBinder;
303af6ab5fSopenharmony_ciclass Decl;
313af6ab5fSopenharmony_ciclass EnumVariable;
323af6ab5fSopenharmony_ciclass FunctionDecl;
333af6ab5fSopenharmony_ciclass LocalVariable;
343af6ab5fSopenharmony_ciclass Scope;
353af6ab5fSopenharmony_ciclass Variable;
363af6ab5fSopenharmony_ciclass ETSBinder;
373af6ab5fSopenharmony_ciclass RecordTable;
383af6ab5fSopenharmony_ciclass FunctionParamScope;
393af6ab5fSopenharmony_ci}  // namespace ark::es2panda::varbinder
403af6ab5fSopenharmony_ci
413af6ab5fSopenharmony_cinamespace ark::es2panda::evaluate {
423af6ab5fSopenharmony_ciclass ScopedDebugInfoPlugin;
433af6ab5fSopenharmony_ci}  // namespace ark::es2panda::evaluate
443af6ab5fSopenharmony_ci
453af6ab5fSopenharmony_cinamespace ark::es2panda::checker {
463af6ab5fSopenharmony_ci
473af6ab5fSopenharmony_cistruct Accessor {
483af6ab5fSopenharmony_ci    bool isGetter {false};
493af6ab5fSopenharmony_ci    bool isSetter {false};
503af6ab5fSopenharmony_ci    bool isExternal {false};
513af6ab5fSopenharmony_ci};
523af6ab5fSopenharmony_ci
533af6ab5fSopenharmony_ciusing ComputedAbstracts =
543af6ab5fSopenharmony_ci    ArenaUnorderedMap<ETSObjectType *, std::pair<ArenaVector<ETSFunctionType *>, std::unordered_set<ETSObjectType *>>>;
553af6ab5fSopenharmony_ciusing ArrayMap = ArenaUnorderedMap<Type *, ETSArrayType *>;
563af6ab5fSopenharmony_ciusing GlobalArraySignatureMap = ArenaUnorderedMap<ETSArrayType *, Signature *>;
573af6ab5fSopenharmony_ciusing DynamicCallIntrinsicsMap = ArenaUnorderedMap<Language, ArenaUnorderedMap<util::StringView, ir::ScriptFunction *>>;
583af6ab5fSopenharmony_ciusing DynamicClassIntrinsicsMap = ArenaUnorderedMap<Language, ir::ClassDeclaration *>;
593af6ab5fSopenharmony_ciusing DynamicLambdaObjectSignatureMap = ArenaUnorderedMap<std::string, Signature *>;
603af6ab5fSopenharmony_ciusing FunctionalInterfaceMap = ArenaUnorderedMap<util::StringView, ETSObjectType *>;
613af6ab5fSopenharmony_ciusing TypeMapping = ArenaUnorderedMap<Type const *, Type *>;
623af6ab5fSopenharmony_ciusing DynamicCallNamesMap = ArenaMap<const ArenaVector<util::StringView>, uint32_t>;
633af6ab5fSopenharmony_ciusing ConstraintCheckRecord = std::tuple<const ArenaVector<Type *> *, const Substitution *, lexer::SourcePosition>;
643af6ab5fSopenharmony_ci
653af6ab5fSopenharmony_ciclass ETSChecker final : public Checker {
663af6ab5fSopenharmony_cipublic:
673af6ab5fSopenharmony_ci    explicit ETSChecker()
683af6ab5fSopenharmony_ci        // NOLINTNEXTLINE(readability-redundant-member-init)
693af6ab5fSopenharmony_ci        : Checker(),
703af6ab5fSopenharmony_ci          arrayTypes_(Allocator()->Adapter()),
713af6ab5fSopenharmony_ci          pendingConstraintCheckRecords_(Allocator()->Adapter()),
723af6ab5fSopenharmony_ci          globalArraySignatures_(Allocator()->Adapter()),
733af6ab5fSopenharmony_ci          primitiveWrappers_(Allocator()),
743af6ab5fSopenharmony_ci          cachedComputedAbstracts_(Allocator()->Adapter()),
753af6ab5fSopenharmony_ci          dynamicIntrinsics_ {DynamicCallIntrinsicsMap {Allocator()->Adapter()},
763af6ab5fSopenharmony_ci                              DynamicCallIntrinsicsMap {Allocator()->Adapter()}},
773af6ab5fSopenharmony_ci          dynamicClasses_ {DynamicClassIntrinsicsMap(Allocator()->Adapter()),
783af6ab5fSopenharmony_ci                           DynamicClassIntrinsicsMap(Allocator()->Adapter())},
793af6ab5fSopenharmony_ci          dynamicLambdaSignatureCache_(Allocator()->Adapter()),
803af6ab5fSopenharmony_ci          functionalInterfaceCache_(Allocator()->Adapter()),
813af6ab5fSopenharmony_ci          apparentTypes_(Allocator()->Adapter()),
823af6ab5fSopenharmony_ci          dynamicCallNames_ {{DynamicCallNamesMap(Allocator()->Adapter()), DynamicCallNamesMap(Allocator()->Adapter())}}
833af6ab5fSopenharmony_ci    {
843af6ab5fSopenharmony_ci    }
853af6ab5fSopenharmony_ci
863af6ab5fSopenharmony_ci    ~ETSChecker() override = default;
873af6ab5fSopenharmony_ci
883af6ab5fSopenharmony_ci    NO_COPY_SEMANTIC(ETSChecker);
893af6ab5fSopenharmony_ci    NO_MOVE_SEMANTIC(ETSChecker);
903af6ab5fSopenharmony_ci
913af6ab5fSopenharmony_ci    [[nodiscard]] static inline TypeFlag ETSType(const Type *const type) noexcept
923af6ab5fSopenharmony_ci    {
933af6ab5fSopenharmony_ci        return static_cast<TypeFlag>(type->TypeFlags() & TypeFlag::ETS_TYPE);
943af6ab5fSopenharmony_ci    }
953af6ab5fSopenharmony_ci
963af6ab5fSopenharmony_ci    [[nodiscard]] static inline TypeFlag TypeKind(const Type *const type) noexcept
973af6ab5fSopenharmony_ci    {
983af6ab5fSopenharmony_ci        return static_cast<checker::TypeFlag>(type->TypeFlags() & checker::TypeFlag::ETS_TYPE);
993af6ab5fSopenharmony_ci    }
1003af6ab5fSopenharmony_ci
1013af6ab5fSopenharmony_ci    Type *GlobalByteType() const;
1023af6ab5fSopenharmony_ci    Type *GlobalShortType() const;
1033af6ab5fSopenharmony_ci    Type *GlobalIntType() const;
1043af6ab5fSopenharmony_ci    Type *GlobalLongType() const;
1053af6ab5fSopenharmony_ci    Type *GlobalFloatType() const;
1063af6ab5fSopenharmony_ci    Type *GlobalDoubleType() const;
1073af6ab5fSopenharmony_ci    Type *GlobalCharType() const;
1083af6ab5fSopenharmony_ci    Type *GlobalETSBooleanType() const;
1093af6ab5fSopenharmony_ci    Type *GlobalVoidType() const;
1103af6ab5fSopenharmony_ci    Type *GlobalETSNullType() const;
1113af6ab5fSopenharmony_ci    Type *GlobalETSUndefinedType() const;
1123af6ab5fSopenharmony_ci    Type *GlobalETSStringLiteralType() const;
1133af6ab5fSopenharmony_ci    Type *GlobalETSBigIntType() const;
1143af6ab5fSopenharmony_ci    Type *GlobalWildcardType() const;
1153af6ab5fSopenharmony_ci
1163af6ab5fSopenharmony_ci    ETSObjectType *GlobalETSObjectType() const;
1173af6ab5fSopenharmony_ci    ETSUnionType *GlobalETSNullishType() const;
1183af6ab5fSopenharmony_ci    ETSUnionType *GlobalETSNullishObjectType() const;
1193af6ab5fSopenharmony_ci    ETSObjectType *GlobalBuiltinETSStringType() const;
1203af6ab5fSopenharmony_ci    ETSObjectType *GlobalBuiltinETSBigIntType() const;
1213af6ab5fSopenharmony_ci    ETSObjectType *GlobalBuiltinTypeType() const;
1223af6ab5fSopenharmony_ci    ETSObjectType *GlobalBuiltinExceptionType() const;
1233af6ab5fSopenharmony_ci    ETSObjectType *GlobalBuiltinErrorType() const;
1243af6ab5fSopenharmony_ci    ETSObjectType *GlobalStringBuilderBuiltinType() const;
1253af6ab5fSopenharmony_ci    ETSObjectType *GlobalBuiltinPromiseType() const;
1263af6ab5fSopenharmony_ci    ETSObjectType *GlobalBuiltinJSRuntimeType() const;
1273af6ab5fSopenharmony_ci    ETSObjectType *GlobalBuiltinJSValueType() const;
1283af6ab5fSopenharmony_ci    ETSObjectType *GlobalBuiltinBoxType(Type *contents);
1293af6ab5fSopenharmony_ci
1303af6ab5fSopenharmony_ci    ETSObjectType *GlobalBuiltinFunctionType(size_t nargs, ir::ScriptFunctionFlags flags) const;
1313af6ab5fSopenharmony_ci    size_t GlobalBuiltinFunctionTypeVariadicThreshold() const;
1323af6ab5fSopenharmony_ci
1333af6ab5fSopenharmony_ci    ETSObjectType *GlobalBuiltinDynamicType(Language lang) const;
1343af6ab5fSopenharmony_ci
1353af6ab5fSopenharmony_ci    const checker::WrapperDesc &PrimitiveWrapper() const;
1363af6ab5fSopenharmony_ci
1373af6ab5fSopenharmony_ci    GlobalArraySignatureMap &GlobalArrayTypes();
1383af6ab5fSopenharmony_ci    const GlobalArraySignatureMap &GlobalArrayTypes() const;
1393af6ab5fSopenharmony_ci
1403af6ab5fSopenharmony_ci    Type *GlobalTypeError() const;
1413af6ab5fSopenharmony_ci
1423af6ab5fSopenharmony_ci    void InitializeBuiltins(varbinder::ETSBinder *varbinder);
1433af6ab5fSopenharmony_ci    void InitializeBuiltin(varbinder::Variable *var, const util::StringView &name);
1443af6ab5fSopenharmony_ci    bool StartChecker([[maybe_unused]] varbinder::VarBinder *varbinder, const CompilerOptions &options) override;
1453af6ab5fSopenharmony_ci    Type *CheckTypeCached(ir::Expression *expr) override;
1463af6ab5fSopenharmony_ci    void ResolveStructuredTypeMembers([[maybe_unused]] Type *type) override {}
1473af6ab5fSopenharmony_ci    Type *GetTypeOfVariable([[maybe_unused]] varbinder::Variable *var) override;
1483af6ab5fSopenharmony_ci    Type *GuaranteedTypeForUncheckedCast(Type *base, Type *substituted);
1493af6ab5fSopenharmony_ci    Type *GuaranteedTypeForUncheckedCallReturn(Signature *sig);
1503af6ab5fSopenharmony_ci    Type *GuaranteedTypeForUncheckedPropertyAccess(varbinder::Variable *prop);
1513af6ab5fSopenharmony_ci
1523af6ab5fSopenharmony_ci    [[nodiscard]] bool IsETSChecker() const noexcept override
1533af6ab5fSopenharmony_ci    {
1543af6ab5fSopenharmony_ci        return true;
1553af6ab5fSopenharmony_ci    }
1563af6ab5fSopenharmony_ci
1573af6ab5fSopenharmony_ci    // Object
1583af6ab5fSopenharmony_ci    ETSObjectType *BuildBasicClassProperties(ir::ClassDefinition *classDef);
1593af6ab5fSopenharmony_ci    ETSObjectType *BuildAnonymousClassProperties(ir::ClassDefinition *classDef, ETSObjectType *superType);
1603af6ab5fSopenharmony_ci    ETSObjectType *BuildBasicInterfaceProperties(ir::TSInterfaceDeclaration *interfaceDecl);
1613af6ab5fSopenharmony_ci    ETSObjectType *GetSuperType(ETSObjectType *type);
1623af6ab5fSopenharmony_ci    ArenaVector<ETSObjectType *> GetInterfaces(ETSObjectType *type);
1633af6ab5fSopenharmony_ci    void GetInterfacesOfClass(ETSObjectType *type);
1643af6ab5fSopenharmony_ci    void GetInterfacesOfInterface(ETSObjectType *type);
1653af6ab5fSopenharmony_ci    void ValidateImplementedInterface(ETSObjectType *type, Type *interface, std::unordered_set<Type *> *extendsSet,
1663af6ab5fSopenharmony_ci                                      const lexer::SourcePosition &pos);
1673af6ab5fSopenharmony_ci    void ResolveDeclaredMembersOfObject(const ETSObjectType *type);
1683af6ab5fSopenharmony_ci    std::optional<int32_t> GetTupleElementAccessValue(const Type *type, const lexer::SourcePosition &pos);
1693af6ab5fSopenharmony_ci    bool ValidateArrayIndex(ir::Expression *expr, bool relaxed = false);
1703af6ab5fSopenharmony_ci    bool ValidateTupleIndex(const ETSTupleType *tuple, ir::MemberExpression *expr);
1713af6ab5fSopenharmony_ci    ETSObjectType *CheckThisOrSuperAccess(ir::Expression *node, ETSObjectType *classType, std::string_view msg);
1723af6ab5fSopenharmony_ci    void CreateTypeForClassOrInterfaceTypeParameters(ETSObjectType *type);
1733af6ab5fSopenharmony_ci    ETSTypeParameter *SetUpParameterType(ir::TSTypeParameter *param);
1743af6ab5fSopenharmony_ci    void CheckIfOverrideIsValidInInterface(const ETSObjectType *classType, Signature *sig, ir::ScriptFunction *func);
1753af6ab5fSopenharmony_ci    void CheckFunctionRedeclarationInInterface(const ETSObjectType *classType,
1763af6ab5fSopenharmony_ci                                               ArenaVector<Signature *> &similarSignatures, ir::ScriptFunction *func);
1773af6ab5fSopenharmony_ci    void ValidateAbstractMethodsToBeImplemented(ArenaVector<ETSFunctionType *> &abstractsToBeImplemented,
1783af6ab5fSopenharmony_ci                                                ETSObjectType *classType,
1793af6ab5fSopenharmony_ci                                                const std::vector<Signature *> &implementedSignatures);
1803af6ab5fSopenharmony_ci    void ApplyModifiersAndRemoveImplementedAbstracts(ArenaVector<ETSFunctionType *>::iterator &it,
1813af6ab5fSopenharmony_ci                                                     ArenaVector<ETSFunctionType *> &abstractsToBeImplemented,
1823af6ab5fSopenharmony_ci                                                     ETSObjectType *classType, bool &functionOverridden,
1833af6ab5fSopenharmony_ci                                                     const Accessor &isGetSetExternal);
1843af6ab5fSopenharmony_ci    void ValidateAbstractSignature(ArenaVector<ETSFunctionType *>::iterator &it,
1853af6ab5fSopenharmony_ci                                   ArenaVector<ETSFunctionType *> &abstractsToBeImplemented,
1863af6ab5fSopenharmony_ci                                   const std::vector<Signature *> &implementedSignatures, bool &functionOverridden,
1873af6ab5fSopenharmony_ci                                   Accessor &isGetSetExternal);
1883af6ab5fSopenharmony_ci    void ValidateNonOverriddenFunction(ETSObjectType *classType, ArenaVector<ETSFunctionType *>::iterator &it,
1893af6ab5fSopenharmony_ci                                       ArenaVector<ETSFunctionType *> &abstractsToBeImplemented,
1903af6ab5fSopenharmony_ci                                       bool &functionOverridden, const Accessor &isGetSet);
1913af6ab5fSopenharmony_ci    void MaybeReportErrorsForOverridingValidation(ArenaVector<ETSFunctionType *> &abstractsToBeImplemented,
1923af6ab5fSopenharmony_ci                                                  ETSObjectType *classType, const lexer::SourcePosition &pos,
1933af6ab5fSopenharmony_ci                                                  bool reportError);
1943af6ab5fSopenharmony_ci    void ValidateOverriding(ETSObjectType *classType, const lexer::SourcePosition &pos);
1953af6ab5fSopenharmony_ci    void CheckInterfaceFunctions(ETSObjectType *classType);
1963af6ab5fSopenharmony_ci    void CollectImplementedMethodsFromInterfaces(ETSObjectType *classType,
1973af6ab5fSopenharmony_ci                                                 std::vector<Signature *> *implementedSignatures,
1983af6ab5fSopenharmony_ci                                                 const ArenaVector<ETSFunctionType *> &abstractsToBeImplemented);
1993af6ab5fSopenharmony_ci    void AddImplementedSignature(std::vector<Signature *> *implementedSignatures, varbinder::LocalVariable *function,
2003af6ab5fSopenharmony_ci                                 ETSFunctionType *it);
2013af6ab5fSopenharmony_ci    void CheckInnerClassMembers(const ETSObjectType *classType);
2023af6ab5fSopenharmony_ci    void CheckLocalClass(ir::ClassDefinition *classDef, CheckerStatus &checkerStatus);
2033af6ab5fSopenharmony_ci    void CheckClassDefinition(ir::ClassDefinition *classDef);
2043af6ab5fSopenharmony_ci    void CheckConstructors(ir::ClassDefinition *classDef, ETSObjectType *classType);
2053af6ab5fSopenharmony_ci    void FindAssignment(const ir::AstNode *node, const varbinder::LocalVariable *classVar, bool &initialized);
2063af6ab5fSopenharmony_ci    void FindAssignments(const ir::AstNode *node, const varbinder::LocalVariable *classVar, bool &initialized);
2073af6ab5fSopenharmony_ci    void CheckConstFields(const ETSObjectType *classType);
2083af6ab5fSopenharmony_ci    void CheckConstFieldInitialized(const ETSObjectType *classType, varbinder::LocalVariable *classVar);
2093af6ab5fSopenharmony_ci    void CheckConstFieldInitialized(const Signature *signature, varbinder::LocalVariable *classVar);
2103af6ab5fSopenharmony_ci    void ComputeAbstractsFromInterface(ETSObjectType *interfaceType);
2113af6ab5fSopenharmony_ci    ArenaVector<ETSFunctionType *> &GetAbstractsForClass(ETSObjectType *classType);
2123af6ab5fSopenharmony_ci    std::vector<Signature *> CollectAbstractSignaturesFromObject(const ETSObjectType *objType);
2133af6ab5fSopenharmony_ci    void CreateFunctionTypesFromAbstracts(const std::vector<Signature *> &abstracts,
2143af6ab5fSopenharmony_ci                                          ArenaVector<ETSFunctionType *> *target);
2153af6ab5fSopenharmony_ci    void CheckCyclicConstructorCall(Signature *signature);
2163af6ab5fSopenharmony_ci    std::vector<ResolveResult *> ResolveMemberReference(const ir::MemberExpression *memberExpr,
2173af6ab5fSopenharmony_ci                                                        const ETSObjectType *target);
2183af6ab5fSopenharmony_ci    varbinder::Variable *ResolveInstanceExtension(const ir::MemberExpression *memberExpr);
2193af6ab5fSopenharmony_ci    void CheckImplicitSuper(ETSObjectType *classType, Signature *ctorSig);
2203af6ab5fSopenharmony_ci    void CheckThisOrSuperCallInConstructor(ETSObjectType *classType, Signature *ctorSig);
2213af6ab5fSopenharmony_ci    void CheckExpressionsInConstructor(const ArenaVector<const ir::Expression *> &arguments);
2223af6ab5fSopenharmony_ci    ArenaVector<const ir::Expression *> CheckMemberOrCallOrObjectExpressionInConstructor(const ir::Expression *arg);
2233af6ab5fSopenharmony_ci    void CheckValidInheritance(ETSObjectType *classType, ir::ClassDefinition *classDef);
2243af6ab5fSopenharmony_ci    void CheckProperties(ETSObjectType *classType, ir::ClassDefinition *classDef, varbinder::LocalVariable *it,
2253af6ab5fSopenharmony_ci                         varbinder::LocalVariable *found, ETSObjectType *interfaceFound);
2263af6ab5fSopenharmony_ci    void TransformProperties(ETSObjectType *classType);
2273af6ab5fSopenharmony_ci    void CheckGetterSetterProperties(ETSObjectType *classType);
2283af6ab5fSopenharmony_ci    void AddElementsToModuleObject(ETSObjectType *moduleObj, const util::StringView &str);
2293af6ab5fSopenharmony_ci    void ComputeApparentType(Type *type)
2303af6ab5fSopenharmony_ci    {
2313af6ab5fSopenharmony_ci        [[maybe_unused]] auto x = GetApparentType(type);
2323af6ab5fSopenharmony_ci    }
2333af6ab5fSopenharmony_ci    [[nodiscard]] Type *GetApparentType(Type *type);
2343af6ab5fSopenharmony_ci    [[nodiscard]] Type const *GetApparentType(Type const *type) const;
2353af6ab5fSopenharmony_ci    ETSObjectType *GetClosestCommonAncestor(ETSObjectType *source, ETSObjectType *target);
2363af6ab5fSopenharmony_ci    bool HasETSFunctionType(ir::TypeNode *typeAnnotation);
2373af6ab5fSopenharmony_ci
2383af6ab5fSopenharmony_ci    // Type creation
2393af6ab5fSopenharmony_ci    ByteType *CreateByteType(int8_t value);
2403af6ab5fSopenharmony_ci    ETSBooleanType *CreateETSBooleanType(bool value);
2413af6ab5fSopenharmony_ci    DoubleType *CreateDoubleType(double value);
2423af6ab5fSopenharmony_ci    FloatType *CreateFloatType(float value);
2433af6ab5fSopenharmony_ci    IntType *CreateIntType(int32_t value);
2443af6ab5fSopenharmony_ci    LongType *CreateLongType(int64_t value);
2453af6ab5fSopenharmony_ci    ShortType *CreateShortType(int16_t value);
2463af6ab5fSopenharmony_ci    CharType *CreateCharType(char16_t value);
2473af6ab5fSopenharmony_ci    ETSBigIntType *CreateETSBigIntLiteralType(util::StringView value);
2483af6ab5fSopenharmony_ci    ETSStringType *CreateETSStringLiteralType(util::StringView value);
2493af6ab5fSopenharmony_ci    ETSArrayType *CreateETSArrayType(Type *elementType);
2503af6ab5fSopenharmony_ci    ETSIntEnumType *CreateEnumIntTypeFromEnumDeclaration(ir::TSEnumDeclaration const *const enumDecl);
2513af6ab5fSopenharmony_ci    ETSStringEnumType *CreateEnumStringTypeFromEnumDeclaration(ir::TSEnumDeclaration const *const enumDecl);
2523af6ab5fSopenharmony_ci
2533af6ab5fSopenharmony_ci    Type *CreateETSUnionType(Span<Type *const> constituentTypes);
2543af6ab5fSopenharmony_ci    template <size_t N>
2553af6ab5fSopenharmony_ci    Type *CreateETSUnionType(Type *const (&arr)[N])  // NOLINT(modernize-avoid-c-arrays)
2563af6ab5fSopenharmony_ci    {
2573af6ab5fSopenharmony_ci        return CreateETSUnionType(Span(arr));
2583af6ab5fSopenharmony_ci    }
2593af6ab5fSopenharmony_ci    Type *CreateETSUnionType(ArenaVector<Type *> &&constituentTypes)
2603af6ab5fSopenharmony_ci    {
2613af6ab5fSopenharmony_ci        return CreateETSUnionType(Span<Type *const>(constituentTypes));
2623af6ab5fSopenharmony_ci    }
2633af6ab5fSopenharmony_ci    ETSFunctionType *CreateETSFunctionType(Signature *signature);
2643af6ab5fSopenharmony_ci    ETSFunctionType *CreateETSFunctionType(Signature *signature, util::StringView name);
2653af6ab5fSopenharmony_ci    ETSFunctionType *CreateETSFunctionType(ir::ScriptFunction *func, Signature *signature, util::StringView name);
2663af6ab5fSopenharmony_ci    ETSFunctionType *CreateETSFunctionType(util::StringView name);
2673af6ab5fSopenharmony_ci    ETSFunctionType *CreateETSFunctionType(ArenaVector<Signature *> &signatures);
2683af6ab5fSopenharmony_ci    ETSFunctionType *CreateETSFunctionType(ir::ScriptFunction *func, ArenaVector<Signature *> &&signature,
2693af6ab5fSopenharmony_ci                                           util::StringView name);
2703af6ab5fSopenharmony_ci    ETSExtensionFuncHelperType *CreateETSExtensionFuncHelperType(ETSFunctionType *classMethodType,
2713af6ab5fSopenharmony_ci                                                                 ETSFunctionType *extensionFunctionType);
2723af6ab5fSopenharmony_ci    ETSObjectType *FunctionTypeToFunctionalInterfaceType(Signature *signature);
2733af6ab5fSopenharmony_ci    Type *ResolveFunctionalInterfaces(ArenaVector<Signature *> &signatures);
2743af6ab5fSopenharmony_ci    ETSTypeParameter *CreateTypeParameter();
2753af6ab5fSopenharmony_ci    ETSObjectType *CreateETSObjectType(util::StringView name, ir::AstNode *declNode, ETSObjectFlags flags);
2763af6ab5fSopenharmony_ci    std::tuple<util::StringView, SignatureInfo *> CreateBuiltinArraySignatureInfo(ETSArrayType *arrayType, size_t dim);
2773af6ab5fSopenharmony_ci    Signature *CreateBuiltinArraySignature(ETSArrayType *arrayType, size_t dim);
2783af6ab5fSopenharmony_ci    IntType *CreateIntTypeFromType(Type *type);
2793af6ab5fSopenharmony_ci    std::tuple<Language, bool> CheckForDynamicLang(ir::AstNode *declNode, util::StringView assemblerName);
2803af6ab5fSopenharmony_ci    ETSObjectType *CreateNewETSObjectType(util::StringView name, ir::AstNode *declNode, ETSObjectFlags flags);
2813af6ab5fSopenharmony_ci
2823af6ab5fSopenharmony_ci    Signature *CreateSignature(SignatureInfo *info, Type *returnType, ir::ScriptFunction *func);
2833af6ab5fSopenharmony_ci    Signature *CreateSignature(SignatureInfo *info, Type *returnType, util::StringView internalName);
2843af6ab5fSopenharmony_ci    SignatureInfo *CreateSignatureInfo();
2853af6ab5fSopenharmony_ci
2863af6ab5fSopenharmony_ci    // Arithmetic
2873af6ab5fSopenharmony_ci    Type *NegateNumericType(Type *type, ir::Expression *node);
2883af6ab5fSopenharmony_ci    Type *BitwiseNegateNumericType(Type *type, ir::Expression *node);
2893af6ab5fSopenharmony_ci    bool CheckBinaryOperatorForBigInt(Type *left, Type *right, lexer::TokenType op);
2903af6ab5fSopenharmony_ci    [[nodiscard]] bool CheckBinaryPlusMultDivOperandsForUnionType(const Type *leftType, const Type *rightType,
2913af6ab5fSopenharmony_ci                                                                  const ir::Expression *left,
2923af6ab5fSopenharmony_ci                                                                  const ir::Expression *right);
2933af6ab5fSopenharmony_ci    std::tuple<Type *, Type *> CheckBinaryOperator(ir::Expression *left, ir::Expression *right, ir::Expression *expr,
2943af6ab5fSopenharmony_ci                                                   lexer::TokenType operationType, lexer::SourcePosition pos,
2953af6ab5fSopenharmony_ci                                                   bool forcePromotion = false);
2963af6ab5fSopenharmony_ci    std::tuple<Type *, Type *> CheckArithmeticOperations(
2973af6ab5fSopenharmony_ci        ir::Expression *expr,
2983af6ab5fSopenharmony_ci        std::tuple<ir::Expression *, ir::Expression *, lexer::TokenType, lexer::SourcePosition> op, bool isEqualOp,
2993af6ab5fSopenharmony_ci        std::tuple<checker::Type *, checker::Type *, Type *, Type *> types);
3003af6ab5fSopenharmony_ci    checker::Type *CheckBinaryOperatorMulDivMod(
3013af6ab5fSopenharmony_ci        std::tuple<ir::Expression *, ir::Expression *, lexer::TokenType, lexer::SourcePosition> op, bool isEqualOp,
3023af6ab5fSopenharmony_ci        std::tuple<checker::Type *, checker::Type *, Type *, Type *> types);
3033af6ab5fSopenharmony_ci    checker::Type *CheckBinaryOperatorPlusForEnums(const checker::Type *const leftType,
3043af6ab5fSopenharmony_ci                                                   const checker::Type *const rightType);
3053af6ab5fSopenharmony_ci    checker::Type *CheckBinaryOperatorPlus(
3063af6ab5fSopenharmony_ci        std::tuple<ir::Expression *, ir::Expression *, lexer::TokenType, lexer::SourcePosition> op, bool isEqualOp,
3073af6ab5fSopenharmony_ci        std::tuple<checker::Type *, checker::Type *, Type *, Type *> types);
3083af6ab5fSopenharmony_ci    checker::Type *CheckBinaryOperatorShift(
3093af6ab5fSopenharmony_ci        std::tuple<ir::Expression *, ir::Expression *, lexer::TokenType, lexer::SourcePosition> op, bool isEqualOp,
3103af6ab5fSopenharmony_ci        std::tuple<checker::Type *, checker::Type *, Type *, Type *> types);
3113af6ab5fSopenharmony_ci    checker::Type *CheckBinaryOperatorBitwise(
3123af6ab5fSopenharmony_ci        std::tuple<ir::Expression *, ir::Expression *, lexer::TokenType, lexer::SourcePosition> op, bool isEqualOp,
3133af6ab5fSopenharmony_ci        std::tuple<checker::Type *, checker::Type *, Type *, Type *> types);
3143af6ab5fSopenharmony_ci    checker::Type *CheckBinaryOperatorLogical(ir::Expression *left, ir::Expression *right, ir::Expression *expr,
3153af6ab5fSopenharmony_ci                                              lexer::SourcePosition pos, checker::Type *leftType,
3163af6ab5fSopenharmony_ci                                              checker::Type *rightType, Type *unboxedL, Type *unboxedR);
3173af6ab5fSopenharmony_ci    std::tuple<Type *, Type *> CheckBinaryOperatorStrictEqual(ir::Expression *left, lexer::TokenType operationType,
3183af6ab5fSopenharmony_ci                                                              lexer::SourcePosition pos, checker::Type *leftType,
3193af6ab5fSopenharmony_ci                                                              checker::Type *rightType);
3203af6ab5fSopenharmony_ci    std::optional<std::tuple<Type *, Type *>> CheckBinaryOperatorEqualError(checker::Type *const leftType,
3213af6ab5fSopenharmony_ci                                                                            checker::Type *const rightType,
3223af6ab5fSopenharmony_ci                                                                            checker::Type *tsType,
3233af6ab5fSopenharmony_ci                                                                            lexer::SourcePosition pos);
3243af6ab5fSopenharmony_ci    std::tuple<Type *, Type *> CheckBinaryOperatorEqual(ir::Expression *left, ir::Expression *right,
3253af6ab5fSopenharmony_ci                                                        lexer::TokenType operationType, lexer::SourcePosition pos,
3263af6ab5fSopenharmony_ci                                                        checker::Type *leftType, checker::Type *rightType,
3273af6ab5fSopenharmony_ci                                                        Type *unboxedL, Type *unboxedR);
3283af6ab5fSopenharmony_ci    std::tuple<Type *, Type *> CheckBinaryOperatorEqualDynamic(ir::Expression *left, ir::Expression *right,
3293af6ab5fSopenharmony_ci                                                               lexer::SourcePosition pos);
3303af6ab5fSopenharmony_ci    std::tuple<Type *, Type *> CheckBinaryOperatorLessGreater(ir::Expression *left, ir::Expression *right,
3313af6ab5fSopenharmony_ci                                                              lexer::TokenType operationType, lexer::SourcePosition pos,
3323af6ab5fSopenharmony_ci                                                              bool isEqualOp, checker::Type *leftType,
3333af6ab5fSopenharmony_ci                                                              checker::Type *rightType, Type *unboxedL, Type *unboxedR);
3343af6ab5fSopenharmony_ci    std::tuple<Type *, Type *> CheckBinaryOperatorInstanceOf(lexer::SourcePosition pos, checker::Type *leftType,
3353af6ab5fSopenharmony_ci                                                             checker::Type *rightType);
3363af6ab5fSopenharmony_ci    checker::Type *CheckBinaryOperatorNullishCoalescing(ir::Expression *left, ir::Expression *right,
3373af6ab5fSopenharmony_ci                                                        lexer::SourcePosition pos);
3383af6ab5fSopenharmony_ci    bool AdjustNumberLiteralType(ir::NumberLiteral *literal, Type *literalType, Type *otherType);
3393af6ab5fSopenharmony_ci
3403af6ab5fSopenharmony_ci    Type *HandleArithmeticOperationOnTypes(Type *left, Type *right, lexer::TokenType operationType);
3413af6ab5fSopenharmony_ci    Type *HandleBitwiseOperationOnTypes(Type *left, Type *right, lexer::TokenType operationType);
3423af6ab5fSopenharmony_ci    void FlagExpressionWithUnboxing(Type *type, Type *unboxedType, ir::Expression *typeExpression);
3433af6ab5fSopenharmony_ci    template <typename ValueType>
3443af6ab5fSopenharmony_ci    Type *PerformArithmeticOperationOnTypes(Type *left, Type *right, lexer::TokenType operationType);
3453af6ab5fSopenharmony_ci
3463af6ab5fSopenharmony_ci    Type *HandleRelationOperationOnTypes(Type *left, Type *right, lexer::TokenType operationType);
3473af6ab5fSopenharmony_ci    template <typename TargetType>
3483af6ab5fSopenharmony_ci    Type *PerformRelationOperationOnTypes(Type *left, Type *right, lexer::TokenType operationType);
3493af6ab5fSopenharmony_ci
3503af6ab5fSopenharmony_ci    // Function
3513af6ab5fSopenharmony_ci    bool NeedTypeInference(const ir::ScriptFunction *lambda);
3523af6ab5fSopenharmony_ci    std::vector<bool> FindTypeInferenceArguments(const ArenaVector<ir::Expression *> &arguments);
3533af6ab5fSopenharmony_ci    void InferTypesForLambda(ir::ScriptFunction *lambda, ir::ETSFunctionType *calleeType,
3543af6ab5fSopenharmony_ci                             Signature *maybeSubstitutedFunctionSig = nullptr);
3553af6ab5fSopenharmony_ci    bool TypeInference(Signature *signature, const ArenaVector<ir::Expression *> &arguments,
3563af6ab5fSopenharmony_ci                       TypeRelationFlag flags = TypeRelationFlag::NONE);
3573af6ab5fSopenharmony_ci    bool CheckLambdaTypeAnnotation(ir::AstNode *typeAnnotation, ir::ArrowFunctionExpression *arrowFuncExpr,
3583af6ab5fSopenharmony_ci                                   Type *parameterType, TypeRelationFlag flags);
3593af6ab5fSopenharmony_ci    bool CheckLambdaInfer(ir::AstNode *typeAnnotation, ir::ArrowFunctionExpression *arrowFuncExpr,
3603af6ab5fSopenharmony_ci                          Type *const subParameterType);
3613af6ab5fSopenharmony_ci    bool CheckLambdaAssignable(ir::Expression *param, ir::ScriptFunction *lambda);
3623af6ab5fSopenharmony_ci    bool CheckLambdaAssignableUnion(ir::AstNode *typeAnn, ir::ScriptFunction *lambda);
3633af6ab5fSopenharmony_ci    bool IsCompatibleTypeArgument(ETSTypeParameter *typeParam, Type *typeArgument, const Substitution *substitution);
3643af6ab5fSopenharmony_ci    Substitution *NewSubstitution()
3653af6ab5fSopenharmony_ci    {
3663af6ab5fSopenharmony_ci        return Allocator()->New<Substitution>(Allocator()->Adapter());
3673af6ab5fSopenharmony_ci    }
3683af6ab5fSopenharmony_ci    Substitution *CopySubstitution(const Substitution *src)
3693af6ab5fSopenharmony_ci    {
3703af6ab5fSopenharmony_ci        return Allocator()->New<Substitution>(*src);
3713af6ab5fSopenharmony_ci    }
3723af6ab5fSopenharmony_ci    static void EmplaceSubstituted(Substitution *substitution, ETSTypeParameter *tparam, Type *typeArg);
3733af6ab5fSopenharmony_ci    [[nodiscard]] bool EnhanceSubstitutionForType(const ArenaVector<Type *> &typeParams, Type *paramType,
3743af6ab5fSopenharmony_ci                                                  Type *argumentType, Substitution *substitution);
3753af6ab5fSopenharmony_ci    [[nodiscard]] bool EnhanceSubstitutionForReadonly(const ArenaVector<Type *> &typeParams, ETSReadonlyType *paramType,
3763af6ab5fSopenharmony_ci                                                      Type *argumentType, Substitution *substitution);
3773af6ab5fSopenharmony_ci    [[nodiscard]] bool EnhanceSubstitutionForObject(const ArenaVector<Type *> &typeParams, ETSObjectType *paramType,
3783af6ab5fSopenharmony_ci                                                    Type *argumentType, Substitution *substitution);
3793af6ab5fSopenharmony_ci    [[nodiscard]] bool EnhanceSubstitutionForUnion(const ArenaVector<Type *> &typeParams, ETSUnionType *paramUn,
3803af6ab5fSopenharmony_ci                                                   Type *argumentType, Substitution *substitution);
3813af6ab5fSopenharmony_ci    [[nodiscard]] bool EnhanceSubstitutionForArray(const ArenaVector<Type *> &typeParams, ETSArrayType *paramType,
3823af6ab5fSopenharmony_ci                                                   Type *argumentType, Substitution *substitution);
3833af6ab5fSopenharmony_ci    [[nodiscard]] bool EnhanceSubstitutionForGenericType(const ArenaVector<Type *> &typeParams, const Type *argType,
3843af6ab5fSopenharmony_ci                                                         const Type *paramType, Substitution *substitution);
3853af6ab5fSopenharmony_ci    [[nodiscard]] static bool HasTypeArgsOfObject(Type *argType, Type *paramType);
3863af6ab5fSopenharmony_ci    [[nodiscard]] bool InsertTypeIntoSubstitution(const ArenaVector<Type *> &typeParams, const Type *typeParam,
3873af6ab5fSopenharmony_ci                                                  const size_t index, Substitution *substitution, Type *objectParam);
3883af6ab5fSopenharmony_ci    std::pair<ArenaVector<Type *>, bool> CreateUnconstrainedTypeParameters(
3893af6ab5fSopenharmony_ci        ir::TSTypeParameterDeclaration const *typeParams);
3903af6ab5fSopenharmony_ci    void AssignTypeParameterConstraints(ir::TSTypeParameterDeclaration const *typeParams);
3913af6ab5fSopenharmony_ci    Signature *ValidateParameterlessConstructor(Signature *signature, const lexer::SourcePosition &pos,
3923af6ab5fSopenharmony_ci                                                TypeRelationFlag flags);
3933af6ab5fSopenharmony_ci    Signature *CollectParameterlessConstructor(ArenaVector<Signature *> &signatures, const lexer::SourcePosition &pos,
3943af6ab5fSopenharmony_ci                                               TypeRelationFlag resolveFlags = TypeRelationFlag::NONE);
3953af6ab5fSopenharmony_ci    Signature *ValidateSignature(
3963af6ab5fSopenharmony_ci        std::tuple<Signature *, const ir::TSTypeParameterInstantiation *, TypeRelationFlag> info,
3973af6ab5fSopenharmony_ci        const ArenaVector<ir::Expression *> &arguments, const lexer::SourcePosition &pos,
3983af6ab5fSopenharmony_ci        const std::vector<bool> &argTypeInferenceRequired);
3993af6ab5fSopenharmony_ci    void MaybeSubstituteLambdaArgumentsInFunctionCall(ir::CallExpression *callExpr);
4003af6ab5fSopenharmony_ci    void MaybeSubstituteLambdaArgumentsInFunctionCallHelper(ir::CallExpression *callExpr, ir::Identifier *ident);
4013af6ab5fSopenharmony_ci    void MaybeSubstituteLambdaArguments(const ArenaVector<ir::Expression *> &params, ir::CallExpression *callExpr);
4023af6ab5fSopenharmony_ci    bool ValidateSignatureRequiredParams(Signature *substitutedSig, const ArenaVector<ir::Expression *> &arguments,
4033af6ab5fSopenharmony_ci                                         TypeRelationFlag flags, const std::vector<bool> &argTypeInferenceRequired,
4043af6ab5fSopenharmony_ci                                         bool reportError);
4053af6ab5fSopenharmony_ci    bool ValidateSignatureInvocationContext(Signature *substitutedSig, ir::Expression *argument, const Type *targetType,
4063af6ab5fSopenharmony_ci                                            std::size_t index, TypeRelationFlag flags);
4073af6ab5fSopenharmony_ci    bool CheckInvokable(Signature *substitutedSig, ir::Expression *argument, std::size_t index, TypeRelationFlag flags);
4083af6ab5fSopenharmony_ci    bool CheckOptionalLambdaFunction(ir::Expression *argument, Signature *substitutedSig, std::size_t index);
4093af6ab5fSopenharmony_ci    bool ValidateArgumentAsIdentifier(const ir::Identifier *identifier);
4103af6ab5fSopenharmony_ci    bool ValidateSignatureRestParams(Signature *substitutedSig, const ArenaVector<ir::Expression *> &arguments,
4113af6ab5fSopenharmony_ci                                     TypeRelationFlag flags, bool reportError);
4123af6ab5fSopenharmony_ci    Signature *ValidateSignatures(ArenaVector<Signature *> &signatures,
4133af6ab5fSopenharmony_ci                                  const ir::TSTypeParameterInstantiation *typeArguments,
4143af6ab5fSopenharmony_ci                                  const ArenaVector<ir::Expression *> &arguments, const lexer::SourcePosition &pos,
4153af6ab5fSopenharmony_ci                                  std::string_view signatureKind,
4163af6ab5fSopenharmony_ci                                  TypeRelationFlag resolveFlags = TypeRelationFlag::NONE);
4173af6ab5fSopenharmony_ci    Signature *FindMostSpecificSignature(const ArenaVector<Signature *> &signatures,
4183af6ab5fSopenharmony_ci                                         const ArenaMultiMap<size_t, Signature *> &bestSignaturesForParameter,
4193af6ab5fSopenharmony_ci                                         size_t paramCount);
4203af6ab5fSopenharmony_ci    void SearchAmongMostSpecificTypes(
4213af6ab5fSopenharmony_ci        Type *&mostSpecificType, Signature *&prevSig,
4223af6ab5fSopenharmony_ci        std::tuple<const lexer::SourcePosition &, size_t, size_t, size_t, Signature *> info, bool lookForClassType);
4233af6ab5fSopenharmony_ci    ArenaMultiMap<size_t, Signature *> GetSuitableSignaturesForParameter(
4243af6ab5fSopenharmony_ci        const std::vector<bool> &argTypeInferenceRequired, size_t paramCount, ArenaVector<Signature *> &signatures,
4253af6ab5fSopenharmony_ci        const lexer::SourcePosition &pos, size_t argumentsSize);
4263af6ab5fSopenharmony_ci    Signature *ChooseMostSpecificSignature(ArenaVector<Signature *> &signatures,
4273af6ab5fSopenharmony_ci                                           const std::vector<bool> &argTypeInferenceRequired,
4283af6ab5fSopenharmony_ci                                           const lexer::SourcePosition &pos, size_t argumentsSize = ULONG_MAX);
4293af6ab5fSopenharmony_ci    Signature *ResolveCallExpressionAndTrailingLambda(ArenaVector<Signature *> &signatures,
4303af6ab5fSopenharmony_ci                                                      ir::CallExpression *callExpr, const lexer::SourcePosition &pos,
4313af6ab5fSopenharmony_ci                                                      TypeRelationFlag reportFlag = TypeRelationFlag::NONE);
4323af6ab5fSopenharmony_ci    Signature *ResolveConstructExpression(ETSObjectType *type, const ArenaVector<ir::Expression *> &arguments,
4333af6ab5fSopenharmony_ci                                          const lexer::SourcePosition &pos);
4343af6ab5fSopenharmony_ci    void CheckObjectLiteralArguments(Signature *sig, ArenaVector<ir::Expression *> const &arguments);
4353af6ab5fSopenharmony_ci    Signature *ComposeSignature(ir::ScriptFunction *func, SignatureInfo *signatureInfo, Type *returnType,
4363af6ab5fSopenharmony_ci                                varbinder::Variable *nameVar);
4373af6ab5fSopenharmony_ci    Type *ComposeReturnType(ir::ScriptFunction *func);
4383af6ab5fSopenharmony_ci    SignatureInfo *ComposeSignatureInfo(ir::ScriptFunction *func);
4393af6ab5fSopenharmony_ci    ArenaVector<SignatureInfo *> ComposeSignatureInfosForArrowFunction(ir::ArrowFunctionExpression *arrowFuncExpr);
4403af6ab5fSopenharmony_ci    void SetParamForSignatureInfoOfArrowFunction(SignatureInfo *signatureInfo, ir::ETSParameterExpression *param);
4413af6ab5fSopenharmony_ci    void ValidateMainSignature(ir::ScriptFunction *func);
4423af6ab5fSopenharmony_ci    void BuildFunctionSignature(ir::ScriptFunction *func, bool isConstructSig = false);
4433af6ab5fSopenharmony_ci    checker::ETSFunctionType *BuildNamedFunctionType(ir::ScriptFunction *func);
4443af6ab5fSopenharmony_ci    checker::ETSFunctionType *BuildMethodSignature(ir::MethodDefinition *method);
4453af6ab5fSopenharmony_ci    Signature *CheckEveryAbstractSignatureIsOverridden(ETSFunctionType *target, ETSFunctionType *source);
4463af6ab5fSopenharmony_ci    static Signature *GetSignatureFromMethodDefinition(const ir::MethodDefinition *methodDef);
4473af6ab5fSopenharmony_ci    void CheckIdenticalOverloads(ETSFunctionType *func, ETSFunctionType *overload,
4483af6ab5fSopenharmony_ci                                 const ir::MethodDefinition *currentFunc);
4493af6ab5fSopenharmony_ci    static bool CmpAssemblerTypesWithRank(Signature const *const sig1, Signature const *const sig2) noexcept;
4503af6ab5fSopenharmony_ci    static bool HasSameAssemblySignature(Signature const *const sig1, Signature const *const sig2) noexcept;
4513af6ab5fSopenharmony_ci    static bool HasSameAssemblySignatures(ETSFunctionType const *const func1,
4523af6ab5fSopenharmony_ci                                          ETSFunctionType const *const func2) noexcept;
4533af6ab5fSopenharmony_ci
4543af6ab5fSopenharmony_ci    Signature *AdjustForTypeParameters(Signature *source, Signature *target);
4553af6ab5fSopenharmony_ci    void ReportOverrideError(Signature *signature, Signature *overriddenSignature, const OverrideErrorCode &errorCode);
4563af6ab5fSopenharmony_ci    void CheckOverride(Signature *signature);
4573af6ab5fSopenharmony_ci    bool CheckOverride(Signature *signature, ETSObjectType *site);
4583af6ab5fSopenharmony_ci    OverrideErrorCode CheckOverride(Signature *signature, Signature *other);
4593af6ab5fSopenharmony_ci    bool IsMethodOverridesOther(Signature *base, Signature *derived);
4603af6ab5fSopenharmony_ci    bool IsOverridableIn(Signature *signature);
4613af6ab5fSopenharmony_ci    [[nodiscard]] bool AreOverrideEquivalent(Signature *s1, Signature *s2);
4623af6ab5fSopenharmony_ci    [[nodiscard]] bool IsReturnTypeSubstitutable(Signature *s1, Signature *s2);
4633af6ab5fSopenharmony_ci    bool CheckThrowMarkers(Signature *source, Signature *target);
4643af6ab5fSopenharmony_ci    void ValidateSignatureAccessibility(ETSObjectType *callee, const ir::CallExpression *callExpr, Signature *signature,
4653af6ab5fSopenharmony_ci                                        const lexer::SourcePosition &pos, char const *errorMessage = nullptr);
4663af6ab5fSopenharmony_ci    void CheckCapturedVariables();
4673af6ab5fSopenharmony_ci    void CheckCapturedVariableInSubnodes(ir::AstNode *node, varbinder::Variable *var);
4683af6ab5fSopenharmony_ci    void CheckCapturedVariable(ir::AstNode *node, varbinder::Variable *var);
4693af6ab5fSopenharmony_ci    void CreateAsyncProxyMethods(ir::ClassDefinition *classDef);
4703af6ab5fSopenharmony_ci    ir::MethodDefinition *CreateAsyncImplMethod(ir::MethodDefinition *asyncMethod, ir::ClassDefinition *classDef);
4713af6ab5fSopenharmony_ci    ir::MethodDefinition *CreateAsyncProxy(ir::MethodDefinition *asyncMethod, ir::ClassDefinition *classDef,
4723af6ab5fSopenharmony_ci                                           bool createDecl = true);
4733af6ab5fSopenharmony_ci    ir::MethodDefinition *CreateMethod(const util::StringView &name, ir::ModifierFlags modifiers,
4743af6ab5fSopenharmony_ci                                       ir::ScriptFunctionFlags flags, ArenaVector<ir::Expression *> &&params,
4753af6ab5fSopenharmony_ci                                       varbinder::FunctionParamScope *paramScope, ir::TypeNode *returnType,
4763af6ab5fSopenharmony_ci                                       ir::AstNode *body);
4773af6ab5fSopenharmony_ci    varbinder::FunctionParamScope *CopyParams(const ArenaVector<ir::Expression *> &params,
4783af6ab5fSopenharmony_ci                                              ArenaVector<ir::Expression *> &outParams);
4793af6ab5fSopenharmony_ci    void ReplaceScope(ir::AstNode *root, ir::AstNode *oldNode, varbinder::Scope *newScope);
4803af6ab5fSopenharmony_ci
4813af6ab5fSopenharmony_ci    // Helpers
4823af6ab5fSopenharmony_ci    size_t ComputeProxyMethods(ir::ClassDefinition *klass);
4833af6ab5fSopenharmony_ci    ir::ModifierFlags GetFlagsForProxyLambda(bool isStatic);
4843af6ab5fSopenharmony_ci    ir::ScriptFunction *CreateProxyFunc(ir::ArrowFunctionExpression *lambda, ArenaVector<ir::AstNode *> &captured,
4853af6ab5fSopenharmony_ci                                        bool isStatic);
4863af6ab5fSopenharmony_ci    ir::AstNode *GetProxyMethodBody(ir::ArrowFunctionExpression *lambda, varbinder::FunctionScope *scope);
4873af6ab5fSopenharmony_ci    static std::string GetAsyncImplName(const util::StringView &name);
4883af6ab5fSopenharmony_ci    static std::string GetAsyncImplName(ir::MethodDefinition *asyncMethod);
4893af6ab5fSopenharmony_ci    static bool IsAsyncImplMethod(ir::MethodDefinition const *method);
4903af6ab5fSopenharmony_ci    std::vector<util::StringView> GetNameForSynteticObjectType(const util::StringView &source);
4913af6ab5fSopenharmony_ci    template <checker::PropertyType TYPE>
4923af6ab5fSopenharmony_ci    void BindingsModuleObjectAddProperty(checker::ETSObjectType *moduleObjType, ir::ETSImportDeclaration *importDecl,
4933af6ab5fSopenharmony_ci                                         const varbinder::Scope::VariableMap &bindings);
4943af6ab5fSopenharmony_ci    util::StringView FindPropNameForNamespaceImport(const util::StringView &originalName);
4953af6ab5fSopenharmony_ci    void SetPropertiesForModuleObject(checker::ETSObjectType *moduleObjType, const util::StringView &importPath,
4963af6ab5fSopenharmony_ci                                      ir::ETSImportDeclaration *importDecl = nullptr);
4973af6ab5fSopenharmony_ci    void SetrModuleObjectTsType(ir::Identifier *local, checker::ETSObjectType *moduleObjType);
4983af6ab5fSopenharmony_ci    Type *GetReferencedTypeFromBase(Type *baseType, ir::Expression *name);
4993af6ab5fSopenharmony_ci    Type *GetReferencedTypeBase(ir::Expression *name);
5003af6ab5fSopenharmony_ci    Type *GetTypeFromInterfaceReference(varbinder::Variable *var);
5013af6ab5fSopenharmony_ci    Type *GetTypeFromTypeAliasReference(varbinder::Variable *var);
5023af6ab5fSopenharmony_ci    Type *GetTypeFromClassReference(varbinder::Variable *var);
5033af6ab5fSopenharmony_ci    void ValidateGenericTypeAliasForClonedNode(ir::TSTypeAliasDeclaration *typeAliasNode,
5043af6ab5fSopenharmony_ci                                               const ir::TSTypeParameterInstantiation *exactTypeParams);
5053af6ab5fSopenharmony_ci    Type *HandleTypeAlias(ir::Expression *name, const ir::TSTypeParameterInstantiation *typeParams);
5063af6ab5fSopenharmony_ci    Type *GetTypeFromEnumReference(varbinder::Variable *var);
5073af6ab5fSopenharmony_ci    Type *GetTypeFromTypeParameterReference(varbinder::LocalVariable *var, const lexer::SourcePosition &pos);
5083af6ab5fSopenharmony_ci    Type *GetNonConstantType(Type *type);
5093af6ab5fSopenharmony_ci    bool IsNullLikeOrVoidExpression(const ir::Expression *expr) const;
5103af6ab5fSopenharmony_ci    bool IsConstantExpression(ir::Expression *expr, Type *type);
5113af6ab5fSopenharmony_ci    void ValidateUnaryOperatorOperand(varbinder::Variable *variable);
5123af6ab5fSopenharmony_ci    void InferAliasLambdaType(ir::TypeNode *localTypeAnnotation, ir::ArrowFunctionExpression *init);
5133af6ab5fSopenharmony_ci    bool TestUnionType(Type *type, TypeFlag test);
5143af6ab5fSopenharmony_ci    std::tuple<Type *, bool> ApplyBinaryOperatorPromotion(Type *left, Type *right, TypeFlag test,
5153af6ab5fSopenharmony_ci                                                          bool doPromotion = true);
5163af6ab5fSopenharmony_ci    checker::Type *ApplyConditionalOperatorPromotion(checker::ETSChecker *checker, checker::Type *unboxedL,
5173af6ab5fSopenharmony_ci                                                     checker::Type *unboxedR);
5183af6ab5fSopenharmony_ci    Type *ApplyUnaryOperatorPromotion(Type *type, bool createConst = true, bool doPromotion = true,
5193af6ab5fSopenharmony_ci                                      bool isCondExpr = false);
5203af6ab5fSopenharmony_ci    Type *HandleBooleanLogicalOperators(Type *leftType, Type *rightType, lexer::TokenType tokenType);
5213af6ab5fSopenharmony_ci    Type *HandleBooleanLogicalOperatorsExtended(Type *leftType, Type *rightType, ir::BinaryExpression *expr);
5223af6ab5fSopenharmony_ci
5233af6ab5fSopenharmony_ci    checker::Type *FixOptionalVariableType(varbinder::Variable *const bindingVar, ir::ModifierFlags flags,
5243af6ab5fSopenharmony_ci                                           ir::Expression *init);
5253af6ab5fSopenharmony_ci    void CheckEnumType(ir::Expression *init, checker::Type *initType, const util::StringView &varName);
5263af6ab5fSopenharmony_ci    checker::Type *CheckVariableDeclaration(ir::Identifier *ident, ir::TypeNode *typeAnnotation, ir::Expression *init,
5273af6ab5fSopenharmony_ci                                            ir::ModifierFlags flags);
5283af6ab5fSopenharmony_ci    void CheckAnnotationTypeForVariableDeclaration(checker::Type *annotationType, bool isUnionFunction,
5293af6ab5fSopenharmony_ci                                                   ir::Expression *init, checker::Type *initType);
5303af6ab5fSopenharmony_ci    void CheckTruthinessOfType(ir::Expression *expr);
5313af6ab5fSopenharmony_ci
5323af6ab5fSopenharmony_ci    bool CheckNonNullish(ir::Expression const *expr);
5333af6ab5fSopenharmony_ci    Type *GetNonNullishType(Type *type);
5343af6ab5fSopenharmony_ci    Type *RemoveNullType(Type *type);
5353af6ab5fSopenharmony_ci    Type *RemoveUndefinedType(Type *type);
5363af6ab5fSopenharmony_ci    std::pair<Type *, Type *> RemoveNullishTypes(Type *type);
5373af6ab5fSopenharmony_ci
5383af6ab5fSopenharmony_ci    void ConcatConstantString(util::UString &target, Type *type);
5393af6ab5fSopenharmony_ci    Type *HandleStringConcatenation(Type *leftType, Type *rightType);
5403af6ab5fSopenharmony_ci    Type *ResolveIdentifier(ir::Identifier *ident);
5413af6ab5fSopenharmony_ci    ETSFunctionType *FindFunctionInVectorGivenByName(util::StringView name, ArenaVector<ETSFunctionType *> &list);
5423af6ab5fSopenharmony_ci    void MergeComputedAbstracts(ArenaVector<ETSFunctionType *> &merged, ArenaVector<ETSFunctionType *> &current);
5433af6ab5fSopenharmony_ci    void MergeSignatures(ETSFunctionType *target, ETSFunctionType *source);
5443af6ab5fSopenharmony_ci    ir::AstNode *FindAncestorGivenByType(ir::AstNode *node, ir::AstNodeType type, const ir::AstNode *endNode = nullptr);
5453af6ab5fSopenharmony_ci    util::StringView GetContainingObjectNameFromSignature(Signature *signature);
5463af6ab5fSopenharmony_ci    bool IsFunctionContainsSignature(ETSFunctionType *funcType, Signature *signature);
5473af6ab5fSopenharmony_ci    bool CheckFunctionContainsClashingSignature(const ETSFunctionType *funcType, Signature *signature);
5483af6ab5fSopenharmony_ci    bool IsTypeBuiltinType(const Type *type) const;
5493af6ab5fSopenharmony_ci    static bool IsReferenceType(const Type *type)
5503af6ab5fSopenharmony_ci    {
5513af6ab5fSopenharmony_ci        return type->IsETSReferenceType();
5523af6ab5fSopenharmony_ci    }
5533af6ab5fSopenharmony_ci    std::optional<const ir::AstNode *> FindJumpTarget(ir::AstNode *node);
5543af6ab5fSopenharmony_ci    void ValidatePropertyAccess(varbinder::Variable *var, ETSObjectType *obj, const lexer::SourcePosition &pos);
5553af6ab5fSopenharmony_ci    varbinder::VariableFlags GetAccessFlagFromNode(const ir::AstNode *node);
5563af6ab5fSopenharmony_ci    Type *CheckSwitchDiscriminant(ir::Expression *discriminant);
5573af6ab5fSopenharmony_ci    Type *ETSBuiltinTypeAsPrimitiveType(Type *objectType);
5583af6ab5fSopenharmony_ci    Type *ETSBuiltinTypeAsConditionalType(Type *objectType);
5593af6ab5fSopenharmony_ci    Type *PrimitiveTypeAsETSBuiltinType(Type *objectType);
5603af6ab5fSopenharmony_ci    void AddBoxingUnboxingFlagsToNode(ir::AstNode *node, Type *boxingUnboxingType);
5613af6ab5fSopenharmony_ci    ir::BoxingUnboxingFlags GetBoxingFlag(Type *boxingType);
5623af6ab5fSopenharmony_ci    ir::BoxingUnboxingFlags GetUnboxingFlag(Type const *unboxingType) const;
5633af6ab5fSopenharmony_ci    Type *MaybeBoxExpression(ir::Expression *expr);
5643af6ab5fSopenharmony_ci    Type *MaybeUnboxExpression(ir::Expression *expr);
5653af6ab5fSopenharmony_ci    Type *MaybePromotedBuiltinType(Type *type) const;
5663af6ab5fSopenharmony_ci    Type const *MaybePromotedBuiltinType(Type const *type) const;
5673af6ab5fSopenharmony_ci    Type *MaybePrimitiveBuiltinType(Type *type) const;
5683af6ab5fSopenharmony_ci    void CheckForSameSwitchCases(ArenaVector<ir::SwitchCaseStatement *> const &cases);
5693af6ab5fSopenharmony_ci    std::string GetStringFromIdentifierValue(checker::Type *caseType) const;
5703af6ab5fSopenharmony_ci    bool CompareIdentifiersValuesAreDifferent(ir::Expression *compareValue, const std::string &caseValue);
5713af6ab5fSopenharmony_ci    void CheckIdentifierSwitchCase(ir::Expression *currentCase, ir::Expression *compareCase,
5723af6ab5fSopenharmony_ci                                   const lexer::SourcePosition &pos);
5733af6ab5fSopenharmony_ci    std::string GetStringFromLiteral(ir::Expression *caseTest) const;
5743af6ab5fSopenharmony_ci    varbinder::Variable *FindVariableInFunctionScope(util::StringView name,
5753af6ab5fSopenharmony_ci                                                     const varbinder::ResolveBindingOptions options);
5763af6ab5fSopenharmony_ci    std::pair<varbinder::Variable *, const ETSObjectType *> FindVariableInClassOrEnclosing(
5773af6ab5fSopenharmony_ci        util::StringView name, const ETSObjectType *classType);
5783af6ab5fSopenharmony_ci    varbinder::Variable *FindVariableInGlobal(const ir::Identifier *identifier,
5793af6ab5fSopenharmony_ci                                              const varbinder::ResolveBindingOptions options);
5803af6ab5fSopenharmony_ci    varbinder::Variable *ExtraCheckForResolvedError(ir::Identifier *ident);
5813af6ab5fSopenharmony_ci    void ValidateResolvedIdentifier(ir::Identifier *ident, varbinder::Variable *resolved);
5823af6ab5fSopenharmony_ci    static bool IsVariableStatic(const varbinder::Variable *var);
5833af6ab5fSopenharmony_ci    static bool IsVariableGetterSetter(const varbinder::Variable *var);
5843af6ab5fSopenharmony_ci    bool IsSameDeclarationType(varbinder::LocalVariable *target, varbinder::LocalVariable *compare);
5853af6ab5fSopenharmony_ci    void SaveCapturedVariable(varbinder::Variable *var, ir::Identifier *ident);
5863af6ab5fSopenharmony_ci    bool SaveCapturedVariableInLocalClass(varbinder::Variable *var, ir::Identifier *ident);
5873af6ab5fSopenharmony_ci    void AddBoxingFlagToPrimitiveType(TypeRelation *relation, Type *target);
5883af6ab5fSopenharmony_ci    void AddUnboxingFlagToPrimitiveType(TypeRelation *relation, Type *source, Type *self);
5893af6ab5fSopenharmony_ci    void CheckUnboxedTypeWidenable(TypeRelation *relation, Type *target, Type *self);
5903af6ab5fSopenharmony_ci    void CheckUnboxedTypesAssignable(TypeRelation *relation, Type *source, Type *target);
5913af6ab5fSopenharmony_ci    void CheckBoxedSourceTypeAssignable(TypeRelation *relation, Type *source, Type *target);
5923af6ab5fSopenharmony_ci    void CheckUnboxedSourceTypeWithWideningAssignable(TypeRelation *relation, Type *source, Type *target);
5933af6ab5fSopenharmony_ci    void CheckValidGenericTypeParameter(Type *argType, const lexer::SourcePosition &pos);
5943af6ab5fSopenharmony_ci    void ValidateResolvedProperty(varbinder::LocalVariable **property, const ETSObjectType *target,
5953af6ab5fSopenharmony_ci                                  const ir::Identifier *ident, PropertySearchFlags flags);
5963af6ab5fSopenharmony_ci    bool IsValidSetterLeftSide(const ir::MemberExpression *member);
5973af6ab5fSopenharmony_ci    bool CheckRethrowingParams(const ir::AstNode *ancestorFunction, const ir::AstNode *node);
5983af6ab5fSopenharmony_ci    void CheckThrowingStatements(ir::AstNode *node);
5993af6ab5fSopenharmony_ci    bool CheckThrowingPlacement(ir::AstNode *node, const ir::AstNode *ancestorFunction);
6003af6ab5fSopenharmony_ci    bool CheckNumberOfTypeArguments(ETSObjectType *type, ir::TSTypeParameterInstantiation *typeArgs,
6013af6ab5fSopenharmony_ci                                    const lexer::SourcePosition &pos);
6023af6ab5fSopenharmony_ci    ir::BlockStatement *FindFinalizerOfTryStatement(ir::AstNode *startFrom, const ir::AstNode *p);
6033af6ab5fSopenharmony_ci    void CheckExceptionClauseType(const std::vector<checker::ETSObjectType *> &exceptions, ir::CatchClause *catchClause,
6043af6ab5fSopenharmony_ci                                  checker::Type *clauseType);
6053af6ab5fSopenharmony_ci    void CheckRethrowingFunction(ir::ScriptFunction *func);
6063af6ab5fSopenharmony_ci    ETSObjectType *GetRelevantArgumentedTypeFromChild(ETSObjectType *child, ETSObjectType *target);
6073af6ab5fSopenharmony_ci    util::StringView GetHashFromTypeArguments(const ArenaVector<Type *> &typeArgTypes);
6083af6ab5fSopenharmony_ci    util::StringView GetHashFromSubstitution(const Substitution *substitution);
6093af6ab5fSopenharmony_ci    util::StringView GetHashFromFunctionType(ir::ETSFunctionType *type);
6103af6ab5fSopenharmony_ci    static ETSObjectType *GetOriginalBaseType(Type *object);
6113af6ab5fSopenharmony_ci    void SetArrayPreferredTypeForNestedMemberExpressions(ir::MemberExpression *expr, Type *annotationType);
6123af6ab5fSopenharmony_ci    bool ExtensionETSFunctionType(checker::Type *type);
6133af6ab5fSopenharmony_ci    bool ValidateTupleMinElementSize(ir::ArrayExpression *arrayExpr, ETSTupleType *tuple);
6143af6ab5fSopenharmony_ci    void ModifyPreferredType(ir::ArrayExpression *arrayExpr, Type *newPreferredType);
6153af6ab5fSopenharmony_ci    Type *SelectGlobalIntegerTypeForNumeric(Type *type);
6163af6ab5fSopenharmony_ci    Type *TryGettingFunctionTypeFromInvokeFunction(Type *type);
6173af6ab5fSopenharmony_ci    ir::ClassProperty *ClassPropToImplementationProp(ir::ClassProperty *classProp, varbinder::ClassScope *scope);
6183af6ab5fSopenharmony_ci    ir::Expression *GenerateImplicitInstantiateArg(varbinder::LocalVariable *instantiateMethod,
6193af6ab5fSopenharmony_ci                                                   const std::string &className);
6203af6ab5fSopenharmony_ci    void GenerateGetterSetterBody(ArenaVector<ir::Statement *> &stmts, ArenaVector<ir::Expression *> &params,
6213af6ab5fSopenharmony_ci                                  ir::ClassProperty *field, varbinder::FunctionParamScope *paramScope, bool isSetter);
6223af6ab5fSopenharmony_ci    static ir::MethodDefinition *GenerateDefaultGetterSetter(ir::ClassProperty *property, ir::ClassProperty *field,
6233af6ab5fSopenharmony_ci                                                             varbinder::ClassScope *scope, bool isSetter,
6243af6ab5fSopenharmony_ci                                                             ETSChecker *checker);
6253af6ab5fSopenharmony_ci    void GenerateGetterSetterPropertyAndMethod(ir::ClassProperty *originalProp, ETSObjectType *classType);
6263af6ab5fSopenharmony_ci    ETSObjectType *GetImportSpecifierObjectType(ir::ETSImportDeclaration *importDecl, ir::Identifier *ident);
6273af6ab5fSopenharmony_ci    void ImportNamespaceObjectTypeAddReExportType(ir::ETSImportDeclaration *importDecl,
6283af6ab5fSopenharmony_ci                                                  checker::ETSObjectType *lastObjectType, ir::Identifier *ident);
6293af6ab5fSopenharmony_ci    checker::ETSObjectType *CreateSyntheticType(util::StringView const &syntheticName,
6303af6ab5fSopenharmony_ci                                                checker::ETSObjectType *lastObjectType, ir::Identifier *id);
6313af6ab5fSopenharmony_ci    bool CheckValidUnionEqual(checker::Type *const leftType, checker::Type *const rightType);
6323af6ab5fSopenharmony_ci    bool CheckValidEqualReferenceType(checker::Type *const leftType, checker::Type *const rightType);
6333af6ab5fSopenharmony_ci    bool CheckVoidAnnotation(const ir::ETSPrimitiveType *typeAnnotation);
6343af6ab5fSopenharmony_ci
6353af6ab5fSopenharmony_ci    // Utility type handler functions
6363af6ab5fSopenharmony_ci    ir::TypeNode *GetUtilityTypeTypeParamNode(const ir::TSTypeParameterInstantiation *typeParams,
6373af6ab5fSopenharmony_ci                                              const std::string_view &utilityTypeName);
6383af6ab5fSopenharmony_ci    Type *HandleUtilityTypeParameterNode(const ir::TSTypeParameterInstantiation *typeParams,
6393af6ab5fSopenharmony_ci                                         const std::string_view &utilityType);
6403af6ab5fSopenharmony_ci    // Partial
6413af6ab5fSopenharmony_ci    Type *HandlePartialType(Type *typeToBePartial);
6423af6ab5fSopenharmony_ci    ir::ClassProperty *CreateNullishProperty(ir::ClassProperty *prop, ir::ClassDefinition *newClassDefinition);
6433af6ab5fSopenharmony_ci    ir::ClassDefinition *CreatePartialClassDeclaration(ir::ClassDefinition *newClassDefinition,
6443af6ab5fSopenharmony_ci                                                       const ir::ClassDefinition *classDef);
6453af6ab5fSopenharmony_ci    void CreateConstructorForPartialType(ir::ClassDefinition *partialClassDef, checker::ETSObjectType *partialType,
6463af6ab5fSopenharmony_ci                                         varbinder::RecordTable *recordTable);
6473af6ab5fSopenharmony_ci    ir::ClassDefinition *CreateClassPrototype(util::StringView name, parser::Program *classDeclProgram);
6483af6ab5fSopenharmony_ci    varbinder::Variable *SearchNamesInMultiplePrograms(const std::set<const parser::Program *> &programs,
6493af6ab5fSopenharmony_ci                                                       const std::set<util::StringView> &classNamesToFind);
6503af6ab5fSopenharmony_ci    util::StringView GetQualifiedClassName(const parser::Program *classDefProgram, util::StringView className);
6513af6ab5fSopenharmony_ci    Type *HandleUnionForPartialType(ETSUnionType *typeToBePartial);
6523af6ab5fSopenharmony_ci    Type *CreatePartialTypeClassDef(ir::ClassDefinition *partialClassDef, ir::ClassDefinition *classDef,
6533af6ab5fSopenharmony_ci                                    const Type *typeToBePartial, varbinder::RecordTable *recordTableToUse);
6543af6ab5fSopenharmony_ci    std::pair<ir::ScriptFunction *, ir::Identifier *> CreateScriptFunctionForConstructor(
6553af6ab5fSopenharmony_ci        varbinder::FunctionScope *scope);
6563af6ab5fSopenharmony_ci    ir::MethodDefinition *CreateNonStaticClassInitializer(varbinder::ClassScope *classScope,
6573af6ab5fSopenharmony_ci                                                          varbinder::RecordTable *recordTable);
6583af6ab5fSopenharmony_ci    // Readonly
6593af6ab5fSopenharmony_ci    Type *HandleReadonlyType(const ir::TSTypeParameterInstantiation *typeParams);
6603af6ab5fSopenharmony_ci    Type *GetReadonlyType(Type *type);
6613af6ab5fSopenharmony_ci    void MakePropertiesReadonly(ETSObjectType *classType);
6623af6ab5fSopenharmony_ci    // Required
6633af6ab5fSopenharmony_ci    Type *HandleRequiredType(Type *typeToBeRequired);
6643af6ab5fSopenharmony_ci    void MakePropertiesNonNullish(ETSObjectType *classType);
6653af6ab5fSopenharmony_ci    template <PropertyType PROP_TYPE>
6663af6ab5fSopenharmony_ci    void MakePropertyNonNullish(ETSObjectType *classType, varbinder::LocalVariable *prop);
6673af6ab5fSopenharmony_ci    void ValidateObjectLiteralForRequiredType(const ETSObjectType *requiredType,
6683af6ab5fSopenharmony_ci                                              const ir::ObjectExpression *initObjExpr);
6693af6ab5fSopenharmony_ci
6703af6ab5fSopenharmony_ci    // Smart cast support
6713af6ab5fSopenharmony_ci    [[nodiscard]] checker::Type *ResolveSmartType(checker::Type *sourceType, checker::Type *targetType);
6723af6ab5fSopenharmony_ci    [[nodiscard]] std::pair<Type *, Type *> CheckTestNullishCondition(Type *testedType, Type *actualType, bool strict);
6733af6ab5fSopenharmony_ci    [[nodiscard]] std::pair<Type *, Type *> CheckTestObjectCondition(ETSObjectType *testedType, Type *actualType,
6743af6ab5fSopenharmony_ci                                                                     bool strict);
6753af6ab5fSopenharmony_ci    [[nodiscard]] std::pair<Type *, Type *> CheckTestObjectCondition(ETSArrayType *testedType, Type *actualType);
6763af6ab5fSopenharmony_ci
6773af6ab5fSopenharmony_ci    void ApplySmartCast(varbinder::Variable const *variable, checker::Type *smartType) noexcept;
6783af6ab5fSopenharmony_ci
6793af6ab5fSopenharmony_ci    bool IsInLocalClass(const ir::AstNode *node) const;
6803af6ab5fSopenharmony_ci    // Exception
6813af6ab5fSopenharmony_ci    ETSObjectType *CheckExceptionOrErrorType(checker::Type *type, lexer::SourcePosition pos);
6823af6ab5fSopenharmony_ci
6833af6ab5fSopenharmony_ci    static Type *TryToInstantiate(Type *type, ArenaAllocator *allocator, TypeRelation *relation,
6843af6ab5fSopenharmony_ci                                  GlobalTypesHolder *globalTypes);
6853af6ab5fSopenharmony_ci
6863af6ab5fSopenharmony_ci    // Dynamic interop
6873af6ab5fSopenharmony_ci    template <typename T>
6883af6ab5fSopenharmony_ci    Signature *ResolveDynamicCallExpression(ir::Expression *callee, const ArenaVector<T *> &arguments, Language lang,
6893af6ab5fSopenharmony_ci                                            bool isConstruct);
6903af6ab5fSopenharmony_ci    ir::ClassProperty *CreateStaticReadonlyField(const char *name);
6913af6ab5fSopenharmony_ci    void BuildDynamicImportClass();
6923af6ab5fSopenharmony_ci    void BuildLambdaObjectClass(ETSObjectType *functionalInterface, ir::TypeNode *retTypeAnnotation);
6933af6ab5fSopenharmony_ci    // Trailing lambda
6943af6ab5fSopenharmony_ci    void EnsureValidCurlyBrace(ir::CallExpression *callExpr);
6953af6ab5fSopenharmony_ci
6963af6ab5fSopenharmony_ci    // Extension function
6973af6ab5fSopenharmony_ci    void HandleUpdatedCallExpressionNode(ir::CallExpression *callExpr);
6983af6ab5fSopenharmony_ci
6993af6ab5fSopenharmony_ci    // Static invoke
7003af6ab5fSopenharmony_ci    void CheckInvokeMethodsLegitimacy(ETSObjectType *classType);
7013af6ab5fSopenharmony_ci    checker::Type *CheckArrayElements(ir::ArrayExpression *init);
7023af6ab5fSopenharmony_ci    void ResolveReturnStatement(checker::Type *funcReturnType, checker::Type *argumentType,
7033af6ab5fSopenharmony_ci                                ir::ScriptFunction *containingFunc, ir::ReturnStatement *st);
7043af6ab5fSopenharmony_ci
7053af6ab5fSopenharmony_ci    auto *DynamicCallNames(bool isConstruct)
7063af6ab5fSopenharmony_ci    {
7073af6ab5fSopenharmony_ci        return &dynamicCallNames_[static_cast<uint32_t>(isConstruct)];
7083af6ab5fSopenharmony_ci    }
7093af6ab5fSopenharmony_ci
7103af6ab5fSopenharmony_ci    const auto *DynamicCallNames(bool isConstruct) const
7113af6ab5fSopenharmony_ci    {
7123af6ab5fSopenharmony_ci        return &dynamicCallNames_[static_cast<uint32_t>(isConstruct)];
7133af6ab5fSopenharmony_ci    }
7143af6ab5fSopenharmony_ci
7153af6ab5fSopenharmony_ci    std::recursive_mutex *Mutex()
7163af6ab5fSopenharmony_ci    {
7173af6ab5fSopenharmony_ci        return &mtx_;
7183af6ab5fSopenharmony_ci    }
7193af6ab5fSopenharmony_ci
7203af6ab5fSopenharmony_ci    template <typename T, typename... Args>
7213af6ab5fSopenharmony_ci    T *AllocNode(Args &&...args)
7223af6ab5fSopenharmony_ci    {
7233af6ab5fSopenharmony_ci        // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint)
7243af6ab5fSopenharmony_ci        return util::NodeAllocator::ForceSetParent<T>(Allocator(), std::forward<Args>(args)...);
7253af6ab5fSopenharmony_ci    }
7263af6ab5fSopenharmony_ci
7273af6ab5fSopenharmony_ci    ArenaVector<ConstraintCheckRecord> &PendingConstraintCheckRecords();
7283af6ab5fSopenharmony_ci    size_t &ConstraintCheckScopesCount();
7293af6ab5fSopenharmony_ci
7303af6ab5fSopenharmony_ci    ETSObjectType *GetCachedFunctionalInterface(ir::ETSFunctionType *type);
7313af6ab5fSopenharmony_ci    void CacheFunctionalInterface(ir::ETSFunctionType *type, ETSObjectType *ifaceType);
7323af6ab5fSopenharmony_ci    void CollectReturnStatements(ir::AstNode *parent);
7333af6ab5fSopenharmony_ci    ir::ETSParameterExpression *AddParam(util::StringView name, ir::TypeNode *type);
7343af6ab5fSopenharmony_ci
7353af6ab5fSopenharmony_ci    [[nodiscard]] ir::ScriptFunction *FindFunction(ir::TSEnumDeclaration const *const enumDecl,
7363af6ab5fSopenharmony_ci                                                   const std::string_view &name);
7373af6ab5fSopenharmony_ci
7383af6ab5fSopenharmony_ci    evaluate::ScopedDebugInfoPlugin *GetDebugInfoPlugin();
7393af6ab5fSopenharmony_ci    const evaluate::ScopedDebugInfoPlugin *GetDebugInfoPlugin() const;
7403af6ab5fSopenharmony_ci
7413af6ab5fSopenharmony_ci    void SetDebugInfoPlugin(evaluate::ScopedDebugInfoPlugin *debugInfo);
7423af6ab5fSopenharmony_ci
7433af6ab5fSopenharmony_ci    using ClassBuilder = std::function<void(ArenaVector<ir::AstNode *> *)>;
7443af6ab5fSopenharmony_ci    using ClassInitializerBuilder =
7453af6ab5fSopenharmony_ci        std::function<void(ArenaVector<ir::Statement *> *, ArenaVector<ir::Expression *> *)>;
7463af6ab5fSopenharmony_ci    using MethodBuilder = std::function<void(ArenaVector<ir::Statement *> *, ArenaVector<ir::Expression *> *, Type **)>;
7473af6ab5fSopenharmony_ci
7483af6ab5fSopenharmony_ci    ir::ClassStaticBlock *CreateClassStaticInitializer(const ClassInitializerBuilder &builder,
7493af6ab5fSopenharmony_ci                                                       ETSObjectType *type = nullptr);
7503af6ab5fSopenharmony_ci    ir::MethodDefinition *CreateClassInstanceInitializer(const ClassInitializerBuilder &builder,
7513af6ab5fSopenharmony_ci                                                         ETSObjectType *type = nullptr);
7523af6ab5fSopenharmony_ci    ir::MethodDefinition *CreateClassMethod(std::string_view name, ir::ScriptFunctionFlags funcFlags,
7533af6ab5fSopenharmony_ci                                            ir::ModifierFlags modifierFlags, const MethodBuilder &builder);
7543af6ab5fSopenharmony_ci    ir::ClassDeclaration *BuildClass(util::StringView name, const ClassBuilder &builder);
7553af6ab5fSopenharmony_ci
7563af6ab5fSopenharmony_ciprivate:
7573af6ab5fSopenharmony_ci    ETSEnumType::Method MakeMethod(ir::TSEnumDeclaration const *const enumDecl, const std::string_view &name,
7583af6ab5fSopenharmony_ci                                   bool buildPorxyParam, Type *returnType, bool buildProxy = true);
7593af6ab5fSopenharmony_ci
7603af6ab5fSopenharmony_ci    std::pair<const ir::Identifier *, ir::TypeNode *> GetTargetIdentifierAndType(ir::Identifier *ident);
7613af6ab5fSopenharmony_ci    void LogUnResolvedError(ir::Identifier *ident);
7623af6ab5fSopenharmony_ci    void LogOperatorCannotBeApplied(lexer::TokenType operationType, checker::Type *const leftType,
7633af6ab5fSopenharmony_ci                                    checker::Type *const rightType, lexer::SourcePosition pos);
7643af6ab5fSopenharmony_ci    void WrongContextErrorClassifyByType(ir::Identifier *ident, varbinder::Variable *resolved);
7653af6ab5fSopenharmony_ci    void CheckEtsFunctionType(ir::Identifier *ident, ir::Identifier const *id);
7663af6ab5fSopenharmony_ci    void NotResolvedError(ir::Identifier *const ident, const varbinder::Variable *classVar,
7673af6ab5fSopenharmony_ci                          const ETSObjectType *classType);
7683af6ab5fSopenharmony_ci    void ValidateCallExpressionIdentifier(ir::Identifier *const ident, varbinder::Variable *const resolved,
7693af6ab5fSopenharmony_ci                                          Type *const type);
7703af6ab5fSopenharmony_ci    void ValidateNewClassInstanceIdentifier(ir::Identifier *const ident, varbinder::Variable *const resolved);
7713af6ab5fSopenharmony_ci    void ValidateMemberIdentifier(ir::Identifier *const ident, varbinder::Variable *const resolved, Type *const type);
7723af6ab5fSopenharmony_ci    void ValidatePropertyOrDeclaratorIdentifier(ir::Identifier *const ident, varbinder::Variable *const resolved);
7733af6ab5fSopenharmony_ci    void ValidateAssignmentIdentifier(ir::Identifier *const ident, varbinder::Variable *const resolved,
7743af6ab5fSopenharmony_ci                                      Type *const type);
7753af6ab5fSopenharmony_ci    bool ValidateBinaryExpressionIdentifier(ir::Identifier *const ident, Type *const type);
7763af6ab5fSopenharmony_ci    void ValidateGetterSetter(const ir::MemberExpression *const memberExpr, const varbinder::LocalVariable *const prop,
7773af6ab5fSopenharmony_ci                              PropertySearchFlags searchFlag);
7783af6ab5fSopenharmony_ci    ir::ClassProperty *FindClassProperty(const ETSObjectType *objectType, const ETSFunctionType *propType);
7793af6ab5fSopenharmony_ci    bool IsInitializedProperty(const ir::ClassDefinition *classDefinition, const ir::ClassProperty *prop);
7803af6ab5fSopenharmony_ci    bool FindPropertyInAssignment(const ir::AstNode *it, const std::string &targetName);
7813af6ab5fSopenharmony_ci    void ValidateReadonlyProperty(const ir::MemberExpression *memberExpr, const ETSFunctionType *propType,
7823af6ab5fSopenharmony_ci                                  lexer::SourcePosition sourcePos);
7833af6ab5fSopenharmony_ci    void ValidateVarDeclaratorOrClassProperty(const ir::MemberExpression *memberExpr, varbinder::LocalVariable *prop);
7843af6ab5fSopenharmony_ci    void ResolveMemberReferenceValidate(varbinder::LocalVariable *prop, PropertySearchFlags searchFlag,
7853af6ab5fSopenharmony_ci                                        const ir::MemberExpression *const memberExpr);
7863af6ab5fSopenharmony_ci    std::tuple<bool, bool> IsResolvedAndValue(const ir::Expression *expr, Type *type) const;
7873af6ab5fSopenharmony_ci    PropertySearchFlags GetSearchFlags(const ir::MemberExpression *memberExpr, const varbinder::Variable *targetRef);
7883af6ab5fSopenharmony_ci    PropertySearchFlags GetInitialSearchFlags(const ir::MemberExpression *memberExpr);
7893af6ab5fSopenharmony_ci    const varbinder::Variable *GetTargetRef(const ir::MemberExpression *memberExpr);
7903af6ab5fSopenharmony_ci    Type *GetTypeOfSetterGetter([[maybe_unused]] varbinder::Variable *var);
7913af6ab5fSopenharmony_ci    void IterateInVariableContext([[maybe_unused]] varbinder::Variable *const var);
7923af6ab5fSopenharmony_ci    bool CheckInit(ir::Identifier *ident, ir::TypeNode *typeAnnotation, ir::Expression *init,
7933af6ab5fSopenharmony_ci                   checker::Type *annotationType, varbinder::Variable *const bindingVar);
7943af6ab5fSopenharmony_ci    void CheckItemCasesConstant(ArenaVector<ir::SwitchCaseStatement *> const &cases);
7953af6ab5fSopenharmony_ci    void CheckItemCasesDuplicate(ArenaVector<ir::SwitchCaseStatement *> const &cases);
7963af6ab5fSopenharmony_ci
7973af6ab5fSopenharmony_ci    template <typename EnumType>
7983af6ab5fSopenharmony_ci    EnumType *CreateEnumTypeFromEnumDeclaration(ir::TSEnumDeclaration const *const enumDecl);
7993af6ab5fSopenharmony_ci
8003af6ab5fSopenharmony_ci    std::pair<ir::ScriptFunction *, ir::Identifier *> CreateStaticScriptFunction(
8013af6ab5fSopenharmony_ci        ClassInitializerBuilder const &builder);
8023af6ab5fSopenharmony_ci    std::pair<ir::ScriptFunction *, ir::Identifier *> CreateScriptFunction(ClassInitializerBuilder const &builder);
8033af6ab5fSopenharmony_ci
8043af6ab5fSopenharmony_ci    template <typename T>
8053af6ab5fSopenharmony_ci    ir::MethodDefinition *CreateDynamicCallIntrinsic(ir::Expression *callee, const ArenaVector<T *> &arguments,
8063af6ab5fSopenharmony_ci                                                     Language lang);
8073af6ab5fSopenharmony_ci    ir::ClassStaticBlock *CreateDynamicCallClassInitializer(Language lang, bool isConstruct);
8083af6ab5fSopenharmony_ci    ir::ClassStaticBlock *CreateDynamicModuleClassInitializer(const std::vector<ir::ETSImportDeclaration *> &imports);
8093af6ab5fSopenharmony_ci    ir::MethodDefinition *CreateDynamicModuleClassInitMethod();
8103af6ab5fSopenharmony_ci
8113af6ab5fSopenharmony_ci    ir::MethodDefinition *CreateLambdaObjectClassInitializer(ETSObjectType *functionalInterface);
8123af6ab5fSopenharmony_ci
8133af6ab5fSopenharmony_ci    ir::MethodDefinition *CreateLambdaObjectClassInvokeMethod(Signature *invokeSignature,
8143af6ab5fSopenharmony_ci                                                              ir::TypeNode *retTypeAnnotation);
8153af6ab5fSopenharmony_ci
8163af6ab5fSopenharmony_ci    void ClassInitializerFromImport(ir::ETSImportDeclaration *import, ArenaVector<ir::Statement *> *statements);
8173af6ab5fSopenharmony_ci    void EmitDynamicModuleClassInitCall();
8183af6ab5fSopenharmony_ci    DynamicCallIntrinsicsMap *DynamicCallIntrinsics(bool isConstruct)
8193af6ab5fSopenharmony_ci    {
8203af6ab5fSopenharmony_ci        return &dynamicIntrinsics_[static_cast<size_t>(isConstruct)];
8213af6ab5fSopenharmony_ci    }
8223af6ab5fSopenharmony_ci
8233af6ab5fSopenharmony_ci    ir::ClassDeclaration *GetDynamicClass(Language lang, bool isConstruct);
8243af6ab5fSopenharmony_ci
8253af6ab5fSopenharmony_ci    using Type2TypeMap = std::unordered_map<varbinder::Variable *, varbinder::Variable *>;
8263af6ab5fSopenharmony_ci    using TypeSet = std::unordered_set<varbinder::Variable *>;
8273af6ab5fSopenharmony_ci    bool CheckTypeParameterConstraint(ir::TSTypeParameter *param, Type2TypeMap &extends);
8283af6ab5fSopenharmony_ci    bool CheckDefaultTypeParameter(const ir::TSTypeParameter *param, TypeSet &typeParameterDecls);
8293af6ab5fSopenharmony_ci
8303af6ab5fSopenharmony_ci    void SetUpTypeParameterConstraint(ir::TSTypeParameter *param);
8313af6ab5fSopenharmony_ci    ETSObjectType *UpdateGlobalType(ETSObjectType *objType, util::StringView name);
8323af6ab5fSopenharmony_ci    ETSObjectType *UpdateBoxedGlobalType(ETSObjectType *objType, util::StringView name);
8333af6ab5fSopenharmony_ci    ETSObjectType *CreateETSObjectTypeCheckBuiltins(util::StringView name, ir::AstNode *declNode, ETSObjectFlags flags);
8343af6ab5fSopenharmony_ci    void CheckProgram(parser::Program *program, bool runAnalysis = false);
8353af6ab5fSopenharmony_ci    void CheckWarnings(parser::Program *program, const CompilerOptions &options);
8363af6ab5fSopenharmony_ci
8373af6ab5fSopenharmony_ci    bool ComputeSuperType(ETSObjectType *type);
8383af6ab5fSopenharmony_ci
8393af6ab5fSopenharmony_ci    template <typename UType>
8403af6ab5fSopenharmony_ci    UType HandleModulo(UType leftValue, UType rightValue);
8413af6ab5fSopenharmony_ci
8423af6ab5fSopenharmony_ci    template <typename FloatOrIntegerType, typename IntegerType = FloatOrIntegerType>
8433af6ab5fSopenharmony_ci    Type *HandleBitWiseArithmetic(Type *leftValue, Type *rightValue, lexer::TokenType operationType);
8443af6ab5fSopenharmony_ci
8453af6ab5fSopenharmony_ci    template <typename TargetType>
8463af6ab5fSopenharmony_ci    typename TargetType::UType GetOperand(Type *type);
8473af6ab5fSopenharmony_ci
8483af6ab5fSopenharmony_ci    template <typename... Args>
8493af6ab5fSopenharmony_ci    ETSObjectType *AsETSObjectType(Type *(GlobalTypesHolder::*typeFunctor)(Args...), Args... args) const;
8503af6ab5fSopenharmony_ci    Signature *GetMostSpecificSignature(ArenaVector<Signature *> &compatibleSignatures,
8513af6ab5fSopenharmony_ci                                        const ArenaVector<ir::Expression *> &arguments,
8523af6ab5fSopenharmony_ci                                        const lexer::SourcePosition &pos, TypeRelationFlag resolveFlags);
8533af6ab5fSopenharmony_ci    ArenaVector<Signature *> CollectSignatures(ArenaVector<Signature *> &signatures,
8543af6ab5fSopenharmony_ci                                               const ir::TSTypeParameterInstantiation *typeArguments,
8553af6ab5fSopenharmony_ci                                               const ArenaVector<ir::Expression *> &arguments,
8563af6ab5fSopenharmony_ci                                               const lexer::SourcePosition &pos, TypeRelationFlag resolveFlags);
8573af6ab5fSopenharmony_ci    // Trailing lambda
8583af6ab5fSopenharmony_ci    void MoveTrailingBlockToEnclosingBlockStatement(ir::CallExpression *callExpr);
8593af6ab5fSopenharmony_ci    void TransformTraillingLambda(ir::CallExpression *callExpr);
8603af6ab5fSopenharmony_ci    ArenaVector<ir::Expression *> ExtendArgumentsWithFakeLamda(ir::CallExpression *callExpr);
8613af6ab5fSopenharmony_ci
8623af6ab5fSopenharmony_ci    // Static invoke
8633af6ab5fSopenharmony_ci    bool TryTransformingToStaticInvoke(ir::Identifier *ident, const Type *resolvedType);
8643af6ab5fSopenharmony_ci
8653af6ab5fSopenharmony_ci    ArrayMap arrayTypes_;
8663af6ab5fSopenharmony_ci    ArenaVector<ConstraintCheckRecord> pendingConstraintCheckRecords_;
8673af6ab5fSopenharmony_ci    size_t constraintCheckScopesCount_ {0};
8683af6ab5fSopenharmony_ci    GlobalArraySignatureMap globalArraySignatures_;
8693af6ab5fSopenharmony_ci    PrimitiveWrappers primitiveWrappers_;
8703af6ab5fSopenharmony_ci    ComputedAbstracts cachedComputedAbstracts_;
8713af6ab5fSopenharmony_ci    // NOTE(aleksisch): Extract dynamic from checker to separate class
8723af6ab5fSopenharmony_ci    std::array<DynamicCallIntrinsicsMap, 2U> dynamicIntrinsics_;
8733af6ab5fSopenharmony_ci    std::array<DynamicClassIntrinsicsMap, 2U> dynamicClasses_;
8743af6ab5fSopenharmony_ci    DynamicLambdaObjectSignatureMap dynamicLambdaSignatureCache_;
8753af6ab5fSopenharmony_ci    FunctionalInterfaceMap functionalInterfaceCache_;
8763af6ab5fSopenharmony_ci    TypeMapping apparentTypes_;
8773af6ab5fSopenharmony_ci    std::array<DynamicCallNamesMap, 2U> dynamicCallNames_;
8783af6ab5fSopenharmony_ci    std::recursive_mutex mtx_;
8793af6ab5fSopenharmony_ci    evaluate::ScopedDebugInfoPlugin *debugInfoPlugin_ {nullptr};
8803af6ab5fSopenharmony_ci};
8813af6ab5fSopenharmony_ci
8823af6ab5fSopenharmony_ci}  // namespace ark::es2panda::checker
8833af6ab5fSopenharmony_ci
8843af6ab5fSopenharmony_ci#endif /* CHECKER_H */
885