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 <mutex> 20 21 #include "checker/checker.h" 22 23 #include "checker/types/ets/types.h" 24 #include "checker/ets/primitiveWrappers.h" 25 #include "checker/resolveResult.h" 26 #include "util/helpers.h" 27 28 namespace ark::es2panda::varbinder { 29 class VarBinder; 30 class Decl; 31 class EnumVariable; 32 class FunctionDecl; 33 class LocalVariable; 34 class Scope; 35 class Variable; 36 class ETSBinder; 37 class RecordTable; 38 class FunctionParamScope; 39 } // namespace ark::es2panda::varbinder 40 41 namespace ark::es2panda::evaluate { 42 class ScopedDebugInfoPlugin; 43 } // namespace ark::es2panda::evaluate 44 45 namespace ark::es2panda::checker { 46 47 struct Accessor { 48 bool isGetter {false}; 49 bool isSetter {false}; 50 bool isExternal {false}; 51 }; 52 53 using ComputedAbstracts = 54 ArenaUnorderedMap<ETSObjectType *, std::pair<ArenaVector<ETSFunctionType *>, std::unordered_set<ETSObjectType *>>>; 55 using ArrayMap = ArenaUnorderedMap<Type *, ETSArrayType *>; 56 using GlobalArraySignatureMap = ArenaUnorderedMap<ETSArrayType *, Signature *>; 57 using DynamicCallIntrinsicsMap = ArenaUnorderedMap<Language, ArenaUnorderedMap<util::StringView, ir::ScriptFunction *>>; 58 using DynamicClassIntrinsicsMap = ArenaUnorderedMap<Language, ir::ClassDeclaration *>; 59 using DynamicLambdaObjectSignatureMap = ArenaUnorderedMap<std::string, Signature *>; 60 using FunctionalInterfaceMap = ArenaUnorderedMap<util::StringView, ETSObjectType *>; 61 using TypeMapping = ArenaUnorderedMap<Type const *, Type *>; 62 using DynamicCallNamesMap = ArenaMap<const ArenaVector<util::StringView>, uint32_t>; 63 using ConstraintCheckRecord = std::tuple<const ArenaVector<Type *> *, const Substitution *, lexer::SourcePosition>; 64 65 class ETSChecker final : public Checker { 66 public: ETSChecker()67 explicit ETSChecker() 68 // NOLINTNEXTLINE(readability-redundant-member-init) 69 : Checker(), 70 arrayTypes_(Allocator()->Adapter()), 71 pendingConstraintCheckRecords_(Allocator()->Adapter()), 72 globalArraySignatures_(Allocator()->Adapter()), 73 primitiveWrappers_(Allocator()), 74 cachedComputedAbstracts_(Allocator()->Adapter()), 75 dynamicIntrinsics_ {DynamicCallIntrinsicsMap {Allocator()->Adapter()}, 76 DynamicCallIntrinsicsMap {Allocator()->Adapter()}}, 77 dynamicClasses_ {DynamicClassIntrinsicsMap(Allocator()->Adapter()), 78 DynamicClassIntrinsicsMap(Allocator()->Adapter())}, 79 dynamicLambdaSignatureCache_(Allocator()->Adapter()), 80 functionalInterfaceCache_(Allocator()->Adapter()), 81 apparentTypes_(Allocator()->Adapter()), 82 dynamicCallNames_ {{DynamicCallNamesMap(Allocator()->Adapter()), DynamicCallNamesMap(Allocator()->Adapter())}} 83 { 84 } 85 86 ~ETSChecker() override = default; 87 88 NO_COPY_SEMANTIC(ETSChecker); 89 NO_MOVE_SEMANTIC(ETSChecker); 90 91 [[nodiscard]] static inline TypeFlag ETSType(const Type *const type) noexcept 92 { 93 return static_cast<TypeFlag>(type->TypeFlags() & TypeFlag::ETS_TYPE); 94 } 95 96 [[nodiscard]] static inline TypeFlag TypeKind(const Type *const type) noexcept 97 { 98 return static_cast<checker::TypeFlag>(type->TypeFlags() & checker::TypeFlag::ETS_TYPE); 99 } 100 101 Type *GlobalByteType() const; 102 Type *GlobalShortType() const; 103 Type *GlobalIntType() const; 104 Type *GlobalLongType() const; 105 Type *GlobalFloatType() const; 106 Type *GlobalDoubleType() const; 107 Type *GlobalCharType() const; 108 Type *GlobalETSBooleanType() const; 109 Type *GlobalVoidType() const; 110 Type *GlobalETSNullType() const; 111 Type *GlobalETSUndefinedType() const; 112 Type *GlobalETSStringLiteralType() const; 113 Type *GlobalETSBigIntType() const; 114 Type *GlobalWildcardType() const; 115 116 ETSObjectType *GlobalETSObjectType() const; 117 ETSUnionType *GlobalETSNullishType() const; 118 ETSUnionType *GlobalETSNullishObjectType() const; 119 ETSObjectType *GlobalBuiltinETSStringType() const; 120 ETSObjectType *GlobalBuiltinETSBigIntType() const; 121 ETSObjectType *GlobalBuiltinTypeType() const; 122 ETSObjectType *GlobalBuiltinExceptionType() const; 123 ETSObjectType *GlobalBuiltinErrorType() const; 124 ETSObjectType *GlobalStringBuilderBuiltinType() const; 125 ETSObjectType *GlobalBuiltinPromiseType() const; 126 ETSObjectType *GlobalBuiltinJSRuntimeType() const; 127 ETSObjectType *GlobalBuiltinJSValueType() const; 128 ETSObjectType *GlobalBuiltinBoxType(Type *contents); 129 130 ETSObjectType *GlobalBuiltinFunctionType(size_t nargs, ir::ScriptFunctionFlags flags) const; 131 size_t GlobalBuiltinFunctionTypeVariadicThreshold() const; 132 133 ETSObjectType *GlobalBuiltinDynamicType(Language lang) const; 134 135 const checker::WrapperDesc &PrimitiveWrapper() const; 136 137 GlobalArraySignatureMap &GlobalArrayTypes(); 138 const GlobalArraySignatureMap &GlobalArrayTypes() const; 139 140 Type *GlobalTypeError() const; 141 142 void InitializeBuiltins(varbinder::ETSBinder *varbinder); 143 void InitializeBuiltin(varbinder::Variable *var, const util::StringView &name); 144 bool StartChecker([[maybe_unused]] varbinder::VarBinder *varbinder, const CompilerOptions &options) override; 145 Type *CheckTypeCached(ir::Expression *expr) override; 146 void ResolveStructuredTypeMembers([[maybe_unused]] Type *type) override {} 147 Type *GetTypeOfVariable([[maybe_unused]] varbinder::Variable *var) override; 148 Type *GuaranteedTypeForUncheckedCast(Type *base, Type *substituted); 149 Type *GuaranteedTypeForUncheckedCallReturn(Signature *sig); 150 Type *GuaranteedTypeForUncheckedPropertyAccess(varbinder::Variable *prop); 151 152 [[nodiscard]] bool IsETSChecker() const noexcept override 153 { 154 return true; 155 } 156 157 // Object 158 ETSObjectType *BuildBasicClassProperties(ir::ClassDefinition *classDef); 159 ETSObjectType *BuildAnonymousClassProperties(ir::ClassDefinition *classDef, ETSObjectType *superType); 160 ETSObjectType *BuildBasicInterfaceProperties(ir::TSInterfaceDeclaration *interfaceDecl); 161 ETSObjectType *GetSuperType(ETSObjectType *type); 162 ArenaVector<ETSObjectType *> GetInterfaces(ETSObjectType *type); 163 void GetInterfacesOfClass(ETSObjectType *type); 164 void GetInterfacesOfInterface(ETSObjectType *type); 165 void ValidateImplementedInterface(ETSObjectType *type, Type *interface, std::unordered_set<Type *> *extendsSet, 166 const lexer::SourcePosition &pos); 167 void ResolveDeclaredMembersOfObject(const ETSObjectType *type); 168 std::optional<int32_t> GetTupleElementAccessValue(const Type *type, const lexer::SourcePosition &pos); 169 bool ValidateArrayIndex(ir::Expression *expr, bool relaxed = false); 170 bool ValidateTupleIndex(const ETSTupleType *tuple, ir::MemberExpression *expr); 171 ETSObjectType *CheckThisOrSuperAccess(ir::Expression *node, ETSObjectType *classType, std::string_view msg); 172 void CreateTypeForClassOrInterfaceTypeParameters(ETSObjectType *type); 173 ETSTypeParameter *SetUpParameterType(ir::TSTypeParameter *param); 174 void CheckIfOverrideIsValidInInterface(const ETSObjectType *classType, Signature *sig, ir::ScriptFunction *func); 175 void CheckFunctionRedeclarationInInterface(const ETSObjectType *classType, 176 ArenaVector<Signature *> &similarSignatures, ir::ScriptFunction *func); 177 void ValidateAbstractMethodsToBeImplemented(ArenaVector<ETSFunctionType *> &abstractsToBeImplemented, 178 ETSObjectType *classType, 179 const std::vector<Signature *> &implementedSignatures); 180 void ApplyModifiersAndRemoveImplementedAbstracts(ArenaVector<ETSFunctionType *>::iterator &it, 181 ArenaVector<ETSFunctionType *> &abstractsToBeImplemented, 182 ETSObjectType *classType, bool &functionOverridden, 183 const Accessor &isGetSetExternal); 184 void ValidateAbstractSignature(ArenaVector<ETSFunctionType *>::iterator &it, 185 ArenaVector<ETSFunctionType *> &abstractsToBeImplemented, 186 const std::vector<Signature *> &implementedSignatures, bool &functionOverridden, 187 Accessor &isGetSetExternal); 188 void ValidateNonOverriddenFunction(ETSObjectType *classType, ArenaVector<ETSFunctionType *>::iterator &it, 189 ArenaVector<ETSFunctionType *> &abstractsToBeImplemented, 190 bool &functionOverridden, const Accessor &isGetSet); 191 void MaybeReportErrorsForOverridingValidation(ArenaVector<ETSFunctionType *> &abstractsToBeImplemented, 192 ETSObjectType *classType, const lexer::SourcePosition &pos, 193 bool reportError); 194 void ValidateOverriding(ETSObjectType *classType, const lexer::SourcePosition &pos); 195 void CheckInterfaceFunctions(ETSObjectType *classType); 196 void CollectImplementedMethodsFromInterfaces(ETSObjectType *classType, 197 std::vector<Signature *> *implementedSignatures, 198 const ArenaVector<ETSFunctionType *> &abstractsToBeImplemented); 199 void AddImplementedSignature(std::vector<Signature *> *implementedSignatures, varbinder::LocalVariable *function, 200 ETSFunctionType *it); 201 void CheckInnerClassMembers(const ETSObjectType *classType); 202 void CheckLocalClass(ir::ClassDefinition *classDef, CheckerStatus &checkerStatus); 203 void CheckClassDefinition(ir::ClassDefinition *classDef); 204 void CheckConstructors(ir::ClassDefinition *classDef, ETSObjectType *classType); 205 void FindAssignment(const ir::AstNode *node, const varbinder::LocalVariable *classVar, bool &initialized); 206 void FindAssignments(const ir::AstNode *node, const varbinder::LocalVariable *classVar, bool &initialized); 207 void CheckConstFields(const ETSObjectType *classType); 208 void CheckConstFieldInitialized(const ETSObjectType *classType, varbinder::LocalVariable *classVar); 209 void CheckConstFieldInitialized(const Signature *signature, varbinder::LocalVariable *classVar); 210 void ComputeAbstractsFromInterface(ETSObjectType *interfaceType); 211 ArenaVector<ETSFunctionType *> &GetAbstractsForClass(ETSObjectType *classType); 212 std::vector<Signature *> CollectAbstractSignaturesFromObject(const ETSObjectType *objType); 213 void CreateFunctionTypesFromAbstracts(const std::vector<Signature *> &abstracts, 214 ArenaVector<ETSFunctionType *> *target); 215 void CheckCyclicConstructorCall(Signature *signature); 216 std::vector<ResolveResult *> ResolveMemberReference(const ir::MemberExpression *memberExpr, 217 const ETSObjectType *target); 218 varbinder::Variable *ResolveInstanceExtension(const ir::MemberExpression *memberExpr); 219 void CheckImplicitSuper(ETSObjectType *classType, Signature *ctorSig); 220 void CheckThisOrSuperCallInConstructor(ETSObjectType *classType, Signature *ctorSig); 221 void CheckExpressionsInConstructor(const ArenaVector<const ir::Expression *> &arguments); 222 ArenaVector<const ir::Expression *> CheckMemberOrCallOrObjectExpressionInConstructor(const ir::Expression *arg); 223 void CheckValidInheritance(ETSObjectType *classType, ir::ClassDefinition *classDef); 224 void CheckProperties(ETSObjectType *classType, ir::ClassDefinition *classDef, varbinder::LocalVariable *it, 225 varbinder::LocalVariable *found, ETSObjectType *interfaceFound); 226 void TransformProperties(ETSObjectType *classType); 227 void CheckGetterSetterProperties(ETSObjectType *classType); 228 void AddElementsToModuleObject(ETSObjectType *moduleObj, const util::StringView &str); ComputeApparentType(Type *type)229 void ComputeApparentType(Type *type) 230 { 231 [[maybe_unused]] auto x = GetApparentType(type); 232 } 233 [[nodiscard]] Type *GetApparentType(Type *type); 234 [[nodiscard]] Type const *GetApparentType(Type const *type) const; 235 ETSObjectType *GetClosestCommonAncestor(ETSObjectType *source, ETSObjectType *target); 236 bool HasETSFunctionType(ir::TypeNode *typeAnnotation); 237 238 // Type creation 239 ByteType *CreateByteType(int8_t value); 240 ETSBooleanType *CreateETSBooleanType(bool value); 241 DoubleType *CreateDoubleType(double value); 242 FloatType *CreateFloatType(float value); 243 IntType *CreateIntType(int32_t value); 244 LongType *CreateLongType(int64_t value); 245 ShortType *CreateShortType(int16_t value); 246 CharType *CreateCharType(char16_t value); 247 ETSBigIntType *CreateETSBigIntLiteralType(util::StringView value); 248 ETSStringType *CreateETSStringLiteralType(util::StringView value); 249 ETSArrayType *CreateETSArrayType(Type *elementType); 250 ETSIntEnumType *CreateEnumIntTypeFromEnumDeclaration(ir::TSEnumDeclaration const *const enumDecl); 251 ETSStringEnumType *CreateEnumStringTypeFromEnumDeclaration(ir::TSEnumDeclaration const *const enumDecl); 252 253 Type *CreateETSUnionType(Span<Type *const> constituentTypes); 254 template <size_t N> CreateETSUnionType(Type *const (&arr)[N])255 Type *CreateETSUnionType(Type *const (&arr)[N]) // NOLINT(modernize-avoid-c-arrays) 256 { 257 return CreateETSUnionType(Span(arr)); 258 } CreateETSUnionType(ArenaVector<Type *> &&constituentTypes)259 Type *CreateETSUnionType(ArenaVector<Type *> &&constituentTypes) 260 { 261 return CreateETSUnionType(Span<Type *const>(constituentTypes)); 262 } 263 ETSFunctionType *CreateETSFunctionType(Signature *signature); 264 ETSFunctionType *CreateETSFunctionType(Signature *signature, util::StringView name); 265 ETSFunctionType *CreateETSFunctionType(ir::ScriptFunction *func, Signature *signature, util::StringView name); 266 ETSFunctionType *CreateETSFunctionType(util::StringView name); 267 ETSFunctionType *CreateETSFunctionType(ArenaVector<Signature *> &signatures); 268 ETSFunctionType *CreateETSFunctionType(ir::ScriptFunction *func, ArenaVector<Signature *> &&signature, 269 util::StringView name); 270 ETSExtensionFuncHelperType *CreateETSExtensionFuncHelperType(ETSFunctionType *classMethodType, 271 ETSFunctionType *extensionFunctionType); 272 ETSObjectType *FunctionTypeToFunctionalInterfaceType(Signature *signature); 273 Type *ResolveFunctionalInterfaces(ArenaVector<Signature *> &signatures); 274 ETSTypeParameter *CreateTypeParameter(); 275 ETSObjectType *CreateETSObjectType(util::StringView name, ir::AstNode *declNode, ETSObjectFlags flags); 276 std::tuple<util::StringView, SignatureInfo *> CreateBuiltinArraySignatureInfo(ETSArrayType *arrayType, size_t dim); 277 Signature *CreateBuiltinArraySignature(ETSArrayType *arrayType, size_t dim); 278 IntType *CreateIntTypeFromType(Type *type); 279 std::tuple<Language, bool> CheckForDynamicLang(ir::AstNode *declNode, util::StringView assemblerName); 280 ETSObjectType *CreateNewETSObjectType(util::StringView name, ir::AstNode *declNode, ETSObjectFlags flags); 281 282 Signature *CreateSignature(SignatureInfo *info, Type *returnType, ir::ScriptFunction *func); 283 Signature *CreateSignature(SignatureInfo *info, Type *returnType, util::StringView internalName); 284 SignatureInfo *CreateSignatureInfo(); 285 286 // Arithmetic 287 Type *NegateNumericType(Type *type, ir::Expression *node); 288 Type *BitwiseNegateNumericType(Type *type, ir::Expression *node); 289 bool CheckBinaryOperatorForBigInt(Type *left, Type *right, lexer::TokenType op); 290 [[nodiscard]] bool CheckBinaryPlusMultDivOperandsForUnionType(const Type *leftType, const Type *rightType, 291 const ir::Expression *left, 292 const ir::Expression *right); 293 std::tuple<Type *, Type *> CheckBinaryOperator(ir::Expression *left, ir::Expression *right, ir::Expression *expr, 294 lexer::TokenType operationType, lexer::SourcePosition pos, 295 bool forcePromotion = false); 296 std::tuple<Type *, Type *> CheckArithmeticOperations( 297 ir::Expression *expr, 298 std::tuple<ir::Expression *, ir::Expression *, lexer::TokenType, lexer::SourcePosition> op, bool isEqualOp, 299 std::tuple<checker::Type *, checker::Type *, Type *, Type *> types); 300 checker::Type *CheckBinaryOperatorMulDivMod( 301 std::tuple<ir::Expression *, ir::Expression *, lexer::TokenType, lexer::SourcePosition> op, bool isEqualOp, 302 std::tuple<checker::Type *, checker::Type *, Type *, Type *> types); 303 checker::Type *CheckBinaryOperatorPlusForEnums(const checker::Type *const leftType, 304 const checker::Type *const rightType); 305 checker::Type *CheckBinaryOperatorPlus( 306 std::tuple<ir::Expression *, ir::Expression *, lexer::TokenType, lexer::SourcePosition> op, bool isEqualOp, 307 std::tuple<checker::Type *, checker::Type *, Type *, Type *> types); 308 checker::Type *CheckBinaryOperatorShift( 309 std::tuple<ir::Expression *, ir::Expression *, lexer::TokenType, lexer::SourcePosition> op, bool isEqualOp, 310 std::tuple<checker::Type *, checker::Type *, Type *, Type *> types); 311 checker::Type *CheckBinaryOperatorBitwise( 312 std::tuple<ir::Expression *, ir::Expression *, lexer::TokenType, lexer::SourcePosition> op, bool isEqualOp, 313 std::tuple<checker::Type *, checker::Type *, Type *, Type *> types); 314 checker::Type *CheckBinaryOperatorLogical(ir::Expression *left, ir::Expression *right, ir::Expression *expr, 315 lexer::SourcePosition pos, checker::Type *leftType, 316 checker::Type *rightType, Type *unboxedL, Type *unboxedR); 317 std::tuple<Type *, Type *> CheckBinaryOperatorStrictEqual(ir::Expression *left, lexer::TokenType operationType, 318 lexer::SourcePosition pos, checker::Type *leftType, 319 checker::Type *rightType); 320 std::optional<std::tuple<Type *, Type *>> CheckBinaryOperatorEqualError(checker::Type *const leftType, 321 checker::Type *const rightType, 322 checker::Type *tsType, 323 lexer::SourcePosition pos); 324 std::tuple<Type *, Type *> CheckBinaryOperatorEqual(ir::Expression *left, ir::Expression *right, 325 lexer::TokenType operationType, lexer::SourcePosition pos, 326 checker::Type *leftType, checker::Type *rightType, 327 Type *unboxedL, Type *unboxedR); 328 std::tuple<Type *, Type *> CheckBinaryOperatorEqualDynamic(ir::Expression *left, ir::Expression *right, 329 lexer::SourcePosition pos); 330 std::tuple<Type *, Type *> CheckBinaryOperatorLessGreater(ir::Expression *left, ir::Expression *right, 331 lexer::TokenType operationType, lexer::SourcePosition pos, 332 bool isEqualOp, checker::Type *leftType, 333 checker::Type *rightType, Type *unboxedL, Type *unboxedR); 334 std::tuple<Type *, Type *> CheckBinaryOperatorInstanceOf(lexer::SourcePosition pos, checker::Type *leftType, 335 checker::Type *rightType); 336 checker::Type *CheckBinaryOperatorNullishCoalescing(ir::Expression *left, ir::Expression *right, 337 lexer::SourcePosition pos); 338 bool AdjustNumberLiteralType(ir::NumberLiteral *literal, Type *literalType, Type *otherType); 339 340 Type *HandleArithmeticOperationOnTypes(Type *left, Type *right, lexer::TokenType operationType); 341 Type *HandleBitwiseOperationOnTypes(Type *left, Type *right, lexer::TokenType operationType); 342 void FlagExpressionWithUnboxing(Type *type, Type *unboxedType, ir::Expression *typeExpression); 343 template <typename ValueType> 344 Type *PerformArithmeticOperationOnTypes(Type *left, Type *right, lexer::TokenType operationType); 345 346 Type *HandleRelationOperationOnTypes(Type *left, Type *right, lexer::TokenType operationType); 347 template <typename TargetType> 348 Type *PerformRelationOperationOnTypes(Type *left, Type *right, lexer::TokenType operationType); 349 350 // Function 351 bool NeedTypeInference(const ir::ScriptFunction *lambda); 352 std::vector<bool> FindTypeInferenceArguments(const ArenaVector<ir::Expression *> &arguments); 353 void InferTypesForLambda(ir::ScriptFunction *lambda, ir::ETSFunctionType *calleeType, 354 Signature *maybeSubstitutedFunctionSig = nullptr); 355 bool TypeInference(Signature *signature, const ArenaVector<ir::Expression *> &arguments, 356 TypeRelationFlag flags = TypeRelationFlag::NONE); 357 bool CheckLambdaTypeAnnotation(ir::AstNode *typeAnnotation, ir::ArrowFunctionExpression *arrowFuncExpr, 358 Type *parameterType, TypeRelationFlag flags); 359 bool CheckLambdaInfer(ir::AstNode *typeAnnotation, ir::ArrowFunctionExpression *arrowFuncExpr, 360 Type *const subParameterType); 361 bool CheckLambdaAssignable(ir::Expression *param, ir::ScriptFunction *lambda); 362 bool CheckLambdaAssignableUnion(ir::AstNode *typeAnn, ir::ScriptFunction *lambda); 363 bool IsCompatibleTypeArgument(ETSTypeParameter *typeParam, Type *typeArgument, const Substitution *substitution); NewSubstitution()364 Substitution *NewSubstitution() 365 { 366 return Allocator()->New<Substitution>(Allocator()->Adapter()); 367 } CopySubstitution(const Substitution *src)368 Substitution *CopySubstitution(const Substitution *src) 369 { 370 return Allocator()->New<Substitution>(*src); 371 } 372 static void EmplaceSubstituted(Substitution *substitution, ETSTypeParameter *tparam, Type *typeArg); 373 [[nodiscard]] bool EnhanceSubstitutionForType(const ArenaVector<Type *> &typeParams, Type *paramType, 374 Type *argumentType, Substitution *substitution); 375 [[nodiscard]] bool EnhanceSubstitutionForReadonly(const ArenaVector<Type *> &typeParams, ETSReadonlyType *paramType, 376 Type *argumentType, Substitution *substitution); 377 [[nodiscard]] bool EnhanceSubstitutionForObject(const ArenaVector<Type *> &typeParams, ETSObjectType *paramType, 378 Type *argumentType, Substitution *substitution); 379 [[nodiscard]] bool EnhanceSubstitutionForUnion(const ArenaVector<Type *> &typeParams, ETSUnionType *paramUn, 380 Type *argumentType, Substitution *substitution); 381 [[nodiscard]] bool EnhanceSubstitutionForArray(const ArenaVector<Type *> &typeParams, ETSArrayType *paramType, 382 Type *argumentType, Substitution *substitution); 383 [[nodiscard]] bool EnhanceSubstitutionForGenericType(const ArenaVector<Type *> &typeParams, const Type *argType, 384 const Type *paramType, Substitution *substitution); 385 [[nodiscard]] static bool HasTypeArgsOfObject(Type *argType, Type *paramType); 386 [[nodiscard]] bool InsertTypeIntoSubstitution(const ArenaVector<Type *> &typeParams, const Type *typeParam, 387 const size_t index, Substitution *substitution, Type *objectParam); 388 std::pair<ArenaVector<Type *>, bool> CreateUnconstrainedTypeParameters( 389 ir::TSTypeParameterDeclaration const *typeParams); 390 void AssignTypeParameterConstraints(ir::TSTypeParameterDeclaration const *typeParams); 391 Signature *ValidateParameterlessConstructor(Signature *signature, const lexer::SourcePosition &pos, 392 TypeRelationFlag flags); 393 Signature *CollectParameterlessConstructor(ArenaVector<Signature *> &signatures, const lexer::SourcePosition &pos, 394 TypeRelationFlag resolveFlags = TypeRelationFlag::NONE); 395 Signature *ValidateSignature( 396 std::tuple<Signature *, const ir::TSTypeParameterInstantiation *, TypeRelationFlag> info, 397 const ArenaVector<ir::Expression *> &arguments, const lexer::SourcePosition &pos, 398 const std::vector<bool> &argTypeInferenceRequired); 399 void MaybeSubstituteLambdaArgumentsInFunctionCall(ir::CallExpression *callExpr); 400 void MaybeSubstituteLambdaArgumentsInFunctionCallHelper(ir::CallExpression *callExpr, ir::Identifier *ident); 401 void MaybeSubstituteLambdaArguments(const ArenaVector<ir::Expression *> ¶ms, ir::CallExpression *callExpr); 402 bool ValidateSignatureRequiredParams(Signature *substitutedSig, const ArenaVector<ir::Expression *> &arguments, 403 TypeRelationFlag flags, const std::vector<bool> &argTypeInferenceRequired, 404 bool reportError); 405 bool ValidateSignatureInvocationContext(Signature *substitutedSig, ir::Expression *argument, const Type *targetType, 406 std::size_t index, TypeRelationFlag flags); 407 bool CheckInvokable(Signature *substitutedSig, ir::Expression *argument, std::size_t index, TypeRelationFlag flags); 408 bool CheckOptionalLambdaFunction(ir::Expression *argument, Signature *substitutedSig, std::size_t index); 409 bool ValidateArgumentAsIdentifier(const ir::Identifier *identifier); 410 bool ValidateSignatureRestParams(Signature *substitutedSig, const ArenaVector<ir::Expression *> &arguments, 411 TypeRelationFlag flags, bool reportError); 412 Signature *ValidateSignatures(ArenaVector<Signature *> &signatures, 413 const ir::TSTypeParameterInstantiation *typeArguments, 414 const ArenaVector<ir::Expression *> &arguments, const lexer::SourcePosition &pos, 415 std::string_view signatureKind, 416 TypeRelationFlag resolveFlags = TypeRelationFlag::NONE); 417 Signature *FindMostSpecificSignature(const ArenaVector<Signature *> &signatures, 418 const ArenaMultiMap<size_t, Signature *> &bestSignaturesForParameter, 419 size_t paramCount); 420 void SearchAmongMostSpecificTypes( 421 Type *&mostSpecificType, Signature *&prevSig, 422 std::tuple<const lexer::SourcePosition &, size_t, size_t, size_t, Signature *> info, bool lookForClassType); 423 ArenaMultiMap<size_t, Signature *> GetSuitableSignaturesForParameter( 424 const std::vector<bool> &argTypeInferenceRequired, size_t paramCount, ArenaVector<Signature *> &signatures, 425 const lexer::SourcePosition &pos, size_t argumentsSize); 426 Signature *ChooseMostSpecificSignature(ArenaVector<Signature *> &signatures, 427 const std::vector<bool> &argTypeInferenceRequired, 428 const lexer::SourcePosition &pos, size_t argumentsSize = ULONG_MAX); 429 Signature *ResolveCallExpressionAndTrailingLambda(ArenaVector<Signature *> &signatures, 430 ir::CallExpression *callExpr, const lexer::SourcePosition &pos, 431 TypeRelationFlag reportFlag = TypeRelationFlag::NONE); 432 Signature *ResolveConstructExpression(ETSObjectType *type, const ArenaVector<ir::Expression *> &arguments, 433 const lexer::SourcePosition &pos); 434 void CheckObjectLiteralArguments(Signature *sig, ArenaVector<ir::Expression *> const &arguments); 435 Signature *ComposeSignature(ir::ScriptFunction *func, SignatureInfo *signatureInfo, Type *returnType, 436 varbinder::Variable *nameVar); 437 Type *ComposeReturnType(ir::ScriptFunction *func); 438 SignatureInfo *ComposeSignatureInfo(ir::ScriptFunction *func); 439 ArenaVector<SignatureInfo *> ComposeSignatureInfosForArrowFunction(ir::ArrowFunctionExpression *arrowFuncExpr); 440 void SetParamForSignatureInfoOfArrowFunction(SignatureInfo *signatureInfo, ir::ETSParameterExpression *param); 441 void ValidateMainSignature(ir::ScriptFunction *func); 442 void BuildFunctionSignature(ir::ScriptFunction *func, bool isConstructSig = false); 443 checker::ETSFunctionType *BuildNamedFunctionType(ir::ScriptFunction *func); 444 checker::ETSFunctionType *BuildMethodSignature(ir::MethodDefinition *method); 445 Signature *CheckEveryAbstractSignatureIsOverridden(ETSFunctionType *target, ETSFunctionType *source); 446 static Signature *GetSignatureFromMethodDefinition(const ir::MethodDefinition *methodDef); 447 void CheckIdenticalOverloads(ETSFunctionType *func, ETSFunctionType *overload, 448 const ir::MethodDefinition *currentFunc); 449 static bool CmpAssemblerTypesWithRank(Signature const *const sig1, Signature const *const sig2) noexcept; 450 static bool HasSameAssemblySignature(Signature const *const sig1, Signature const *const sig2) noexcept; 451 static bool HasSameAssemblySignatures(ETSFunctionType const *const func1, 452 ETSFunctionType const *const func2) noexcept; 453 454 Signature *AdjustForTypeParameters(Signature *source, Signature *target); 455 void ReportOverrideError(Signature *signature, Signature *overriddenSignature, const OverrideErrorCode &errorCode); 456 void CheckOverride(Signature *signature); 457 bool CheckOverride(Signature *signature, ETSObjectType *site); 458 OverrideErrorCode CheckOverride(Signature *signature, Signature *other); 459 bool IsMethodOverridesOther(Signature *base, Signature *derived); 460 bool IsOverridableIn(Signature *signature); 461 [[nodiscard]] bool AreOverrideEquivalent(Signature *s1, Signature *s2); 462 [[nodiscard]] bool IsReturnTypeSubstitutable(Signature *s1, Signature *s2); 463 bool CheckThrowMarkers(Signature *source, Signature *target); 464 void ValidateSignatureAccessibility(ETSObjectType *callee, const ir::CallExpression *callExpr, Signature *signature, 465 const lexer::SourcePosition &pos, char const *errorMessage = nullptr); 466 void CheckCapturedVariables(); 467 void CheckCapturedVariableInSubnodes(ir::AstNode *node, varbinder::Variable *var); 468 void CheckCapturedVariable(ir::AstNode *node, varbinder::Variable *var); 469 void CreateAsyncProxyMethods(ir::ClassDefinition *classDef); 470 ir::MethodDefinition *CreateAsyncImplMethod(ir::MethodDefinition *asyncMethod, ir::ClassDefinition *classDef); 471 ir::MethodDefinition *CreateAsyncProxy(ir::MethodDefinition *asyncMethod, ir::ClassDefinition *classDef, 472 bool createDecl = true); 473 ir::MethodDefinition *CreateMethod(const util::StringView &name, ir::ModifierFlags modifiers, 474 ir::ScriptFunctionFlags flags, ArenaVector<ir::Expression *> &¶ms, 475 varbinder::FunctionParamScope *paramScope, ir::TypeNode *returnType, 476 ir::AstNode *body); 477 varbinder::FunctionParamScope *CopyParams(const ArenaVector<ir::Expression *> ¶ms, 478 ArenaVector<ir::Expression *> &outParams); 479 void ReplaceScope(ir::AstNode *root, ir::AstNode *oldNode, varbinder::Scope *newScope); 480 481 // Helpers 482 size_t ComputeProxyMethods(ir::ClassDefinition *klass); 483 ir::ModifierFlags GetFlagsForProxyLambda(bool isStatic); 484 ir::ScriptFunction *CreateProxyFunc(ir::ArrowFunctionExpression *lambda, ArenaVector<ir::AstNode *> &captured, 485 bool isStatic); 486 ir::AstNode *GetProxyMethodBody(ir::ArrowFunctionExpression *lambda, varbinder::FunctionScope *scope); 487 static std::string GetAsyncImplName(const util::StringView &name); 488 static std::string GetAsyncImplName(ir::MethodDefinition *asyncMethod); 489 static bool IsAsyncImplMethod(ir::MethodDefinition const *method); 490 std::vector<util::StringView> GetNameForSynteticObjectType(const util::StringView &source); 491 template <checker::PropertyType TYPE> 492 void BindingsModuleObjectAddProperty(checker::ETSObjectType *moduleObjType, ir::ETSImportDeclaration *importDecl, 493 const varbinder::Scope::VariableMap &bindings); 494 util::StringView FindPropNameForNamespaceImport(const util::StringView &originalName); 495 void SetPropertiesForModuleObject(checker::ETSObjectType *moduleObjType, const util::StringView &importPath, 496 ir::ETSImportDeclaration *importDecl = nullptr); 497 void SetrModuleObjectTsType(ir::Identifier *local, checker::ETSObjectType *moduleObjType); 498 Type *GetReferencedTypeFromBase(Type *baseType, ir::Expression *name); 499 Type *GetReferencedTypeBase(ir::Expression *name); 500 Type *GetTypeFromInterfaceReference(varbinder::Variable *var); 501 Type *GetTypeFromTypeAliasReference(varbinder::Variable *var); 502 Type *GetTypeFromClassReference(varbinder::Variable *var); 503 void ValidateGenericTypeAliasForClonedNode(ir::TSTypeAliasDeclaration *typeAliasNode, 504 const ir::TSTypeParameterInstantiation *exactTypeParams); 505 Type *HandleTypeAlias(ir::Expression *name, const ir::TSTypeParameterInstantiation *typeParams); 506 Type *GetTypeFromEnumReference(varbinder::Variable *var); 507 Type *GetTypeFromTypeParameterReference(varbinder::LocalVariable *var, const lexer::SourcePosition &pos); 508 Type *GetNonConstantType(Type *type); 509 bool IsNullLikeOrVoidExpression(const ir::Expression *expr) const; 510 bool IsConstantExpression(ir::Expression *expr, Type *type); 511 void ValidateUnaryOperatorOperand(varbinder::Variable *variable); 512 void InferAliasLambdaType(ir::TypeNode *localTypeAnnotation, ir::ArrowFunctionExpression *init); 513 bool TestUnionType(Type *type, TypeFlag test); 514 std::tuple<Type *, bool> ApplyBinaryOperatorPromotion(Type *left, Type *right, TypeFlag test, 515 bool doPromotion = true); 516 checker::Type *ApplyConditionalOperatorPromotion(checker::ETSChecker *checker, checker::Type *unboxedL, 517 checker::Type *unboxedR); 518 Type *ApplyUnaryOperatorPromotion(Type *type, bool createConst = true, bool doPromotion = true, 519 bool isCondExpr = false); 520 Type *HandleBooleanLogicalOperators(Type *leftType, Type *rightType, lexer::TokenType tokenType); 521 Type *HandleBooleanLogicalOperatorsExtended(Type *leftType, Type *rightType, ir::BinaryExpression *expr); 522 523 checker::Type *FixOptionalVariableType(varbinder::Variable *const bindingVar, ir::ModifierFlags flags, 524 ir::Expression *init); 525 void CheckEnumType(ir::Expression *init, checker::Type *initType, const util::StringView &varName); 526 checker::Type *CheckVariableDeclaration(ir::Identifier *ident, ir::TypeNode *typeAnnotation, ir::Expression *init, 527 ir::ModifierFlags flags); 528 void CheckAnnotationTypeForVariableDeclaration(checker::Type *annotationType, bool isUnionFunction, 529 ir::Expression *init, checker::Type *initType); 530 void CheckTruthinessOfType(ir::Expression *expr); 531 532 bool CheckNonNullish(ir::Expression const *expr); 533 Type *GetNonNullishType(Type *type); 534 Type *RemoveNullType(Type *type); 535 Type *RemoveUndefinedType(Type *type); 536 std::pair<Type *, Type *> RemoveNullishTypes(Type *type); 537 538 void ConcatConstantString(util::UString &target, Type *type); 539 Type *HandleStringConcatenation(Type *leftType, Type *rightType); 540 Type *ResolveIdentifier(ir::Identifier *ident); 541 ETSFunctionType *FindFunctionInVectorGivenByName(util::StringView name, ArenaVector<ETSFunctionType *> &list); 542 void MergeComputedAbstracts(ArenaVector<ETSFunctionType *> &merged, ArenaVector<ETSFunctionType *> ¤t); 543 void MergeSignatures(ETSFunctionType *target, ETSFunctionType *source); 544 ir::AstNode *FindAncestorGivenByType(ir::AstNode *node, ir::AstNodeType type, const ir::AstNode *endNode = nullptr); 545 util::StringView GetContainingObjectNameFromSignature(Signature *signature); 546 bool IsFunctionContainsSignature(ETSFunctionType *funcType, Signature *signature); 547 bool CheckFunctionContainsClashingSignature(const ETSFunctionType *funcType, Signature *signature); 548 bool IsTypeBuiltinType(const Type *type) const; IsReferenceType(const Type *type)549 static bool IsReferenceType(const Type *type) 550 { 551 return type->IsETSReferenceType(); 552 } 553 std::optional<const ir::AstNode *> FindJumpTarget(ir::AstNode *node); 554 void ValidatePropertyAccess(varbinder::Variable *var, ETSObjectType *obj, const lexer::SourcePosition &pos); 555 varbinder::VariableFlags GetAccessFlagFromNode(const ir::AstNode *node); 556 Type *CheckSwitchDiscriminant(ir::Expression *discriminant); 557 Type *ETSBuiltinTypeAsPrimitiveType(Type *objectType); 558 Type *ETSBuiltinTypeAsConditionalType(Type *objectType); 559 Type *PrimitiveTypeAsETSBuiltinType(Type *objectType); 560 void AddBoxingUnboxingFlagsToNode(ir::AstNode *node, Type *boxingUnboxingType); 561 ir::BoxingUnboxingFlags GetBoxingFlag(Type *boxingType); 562 ir::BoxingUnboxingFlags GetUnboxingFlag(Type const *unboxingType) const; 563 Type *MaybeBoxExpression(ir::Expression *expr); 564 Type *MaybeUnboxExpression(ir::Expression *expr); 565 Type *MaybePromotedBuiltinType(Type *type) const; 566 Type const *MaybePromotedBuiltinType(Type const *type) const; 567 Type *MaybePrimitiveBuiltinType(Type *type) const; 568 void CheckForSameSwitchCases(ArenaVector<ir::SwitchCaseStatement *> const &cases); 569 std::string GetStringFromIdentifierValue(checker::Type *caseType) const; 570 bool CompareIdentifiersValuesAreDifferent(ir::Expression *compareValue, const std::string &caseValue); 571 void CheckIdentifierSwitchCase(ir::Expression *currentCase, ir::Expression *compareCase, 572 const lexer::SourcePosition &pos); 573 std::string GetStringFromLiteral(ir::Expression *caseTest) const; 574 varbinder::Variable *FindVariableInFunctionScope(util::StringView name, 575 const varbinder::ResolveBindingOptions options); 576 std::pair<varbinder::Variable *, const ETSObjectType *> FindVariableInClassOrEnclosing( 577 util::StringView name, const ETSObjectType *classType); 578 varbinder::Variable *FindVariableInGlobal(const ir::Identifier *identifier, 579 const varbinder::ResolveBindingOptions options); 580 varbinder::Variable *ExtraCheckForResolvedError(ir::Identifier *ident); 581 void ValidateResolvedIdentifier(ir::Identifier *ident, varbinder::Variable *resolved); 582 static bool IsVariableStatic(const varbinder::Variable *var); 583 static bool IsVariableGetterSetter(const varbinder::Variable *var); 584 bool IsSameDeclarationType(varbinder::LocalVariable *target, varbinder::LocalVariable *compare); 585 void SaveCapturedVariable(varbinder::Variable *var, ir::Identifier *ident); 586 bool SaveCapturedVariableInLocalClass(varbinder::Variable *var, ir::Identifier *ident); 587 void AddBoxingFlagToPrimitiveType(TypeRelation *relation, Type *target); 588 void AddUnboxingFlagToPrimitiveType(TypeRelation *relation, Type *source, Type *self); 589 void CheckUnboxedTypeWidenable(TypeRelation *relation, Type *target, Type *self); 590 void CheckUnboxedTypesAssignable(TypeRelation *relation, Type *source, Type *target); 591 void CheckBoxedSourceTypeAssignable(TypeRelation *relation, Type *source, Type *target); 592 void CheckUnboxedSourceTypeWithWideningAssignable(TypeRelation *relation, Type *source, Type *target); 593 void CheckValidGenericTypeParameter(Type *argType, const lexer::SourcePosition &pos); 594 void ValidateResolvedProperty(varbinder::LocalVariable **property, const ETSObjectType *target, 595 const ir::Identifier *ident, PropertySearchFlags flags); 596 bool IsValidSetterLeftSide(const ir::MemberExpression *member); 597 bool CheckRethrowingParams(const ir::AstNode *ancestorFunction, const ir::AstNode *node); 598 void CheckThrowingStatements(ir::AstNode *node); 599 bool CheckThrowingPlacement(ir::AstNode *node, const ir::AstNode *ancestorFunction); 600 bool CheckNumberOfTypeArguments(ETSObjectType *type, ir::TSTypeParameterInstantiation *typeArgs, 601 const lexer::SourcePosition &pos); 602 ir::BlockStatement *FindFinalizerOfTryStatement(ir::AstNode *startFrom, const ir::AstNode *p); 603 void CheckExceptionClauseType(const std::vector<checker::ETSObjectType *> &exceptions, ir::CatchClause *catchClause, 604 checker::Type *clauseType); 605 void CheckRethrowingFunction(ir::ScriptFunction *func); 606 ETSObjectType *GetRelevantArgumentedTypeFromChild(ETSObjectType *child, ETSObjectType *target); 607 util::StringView GetHashFromTypeArguments(const ArenaVector<Type *> &typeArgTypes); 608 util::StringView GetHashFromSubstitution(const Substitution *substitution); 609 util::StringView GetHashFromFunctionType(ir::ETSFunctionType *type); 610 static ETSObjectType *GetOriginalBaseType(Type *object); 611 void SetArrayPreferredTypeForNestedMemberExpressions(ir::MemberExpression *expr, Type *annotationType); 612 bool ExtensionETSFunctionType(checker::Type *type); 613 bool ValidateTupleMinElementSize(ir::ArrayExpression *arrayExpr, ETSTupleType *tuple); 614 void ModifyPreferredType(ir::ArrayExpression *arrayExpr, Type *newPreferredType); 615 Type *SelectGlobalIntegerTypeForNumeric(Type *type); 616 Type *TryGettingFunctionTypeFromInvokeFunction(Type *type); 617 ir::ClassProperty *ClassPropToImplementationProp(ir::ClassProperty *classProp, varbinder::ClassScope *scope); 618 ir::Expression *GenerateImplicitInstantiateArg(varbinder::LocalVariable *instantiateMethod, 619 const std::string &className); 620 void GenerateGetterSetterBody(ArenaVector<ir::Statement *> &stmts, ArenaVector<ir::Expression *> ¶ms, 621 ir::ClassProperty *field, varbinder::FunctionParamScope *paramScope, bool isSetter); 622 static ir::MethodDefinition *GenerateDefaultGetterSetter(ir::ClassProperty *property, ir::ClassProperty *field, 623 varbinder::ClassScope *scope, bool isSetter, 624 ETSChecker *checker); 625 void GenerateGetterSetterPropertyAndMethod(ir::ClassProperty *originalProp, ETSObjectType *classType); 626 ETSObjectType *GetImportSpecifierObjectType(ir::ETSImportDeclaration *importDecl, ir::Identifier *ident); 627 void ImportNamespaceObjectTypeAddReExportType(ir::ETSImportDeclaration *importDecl, 628 checker::ETSObjectType *lastObjectType, ir::Identifier *ident); 629 checker::ETSObjectType *CreateSyntheticType(util::StringView const &syntheticName, 630 checker::ETSObjectType *lastObjectType, ir::Identifier *id); 631 bool CheckValidUnionEqual(checker::Type *const leftType, checker::Type *const rightType); 632 bool CheckValidEqualReferenceType(checker::Type *const leftType, checker::Type *const rightType); 633 bool CheckVoidAnnotation(const ir::ETSPrimitiveType *typeAnnotation); 634 635 // Utility type handler functions 636 ir::TypeNode *GetUtilityTypeTypeParamNode(const ir::TSTypeParameterInstantiation *typeParams, 637 const std::string_view &utilityTypeName); 638 Type *HandleUtilityTypeParameterNode(const ir::TSTypeParameterInstantiation *typeParams, 639 const std::string_view &utilityType); 640 // Partial 641 Type *HandlePartialType(Type *typeToBePartial); 642 ir::ClassProperty *CreateNullishProperty(ir::ClassProperty *prop, ir::ClassDefinition *newClassDefinition); 643 ir::ClassDefinition *CreatePartialClassDeclaration(ir::ClassDefinition *newClassDefinition, 644 const ir::ClassDefinition *classDef); 645 void CreateConstructorForPartialType(ir::ClassDefinition *partialClassDef, checker::ETSObjectType *partialType, 646 varbinder::RecordTable *recordTable); 647 ir::ClassDefinition *CreateClassPrototype(util::StringView name, parser::Program *classDeclProgram); 648 varbinder::Variable *SearchNamesInMultiplePrograms(const std::set<const parser::Program *> &programs, 649 const std::set<util::StringView> &classNamesToFind); 650 util::StringView GetQualifiedClassName(const parser::Program *classDefProgram, util::StringView className); 651 Type *HandleUnionForPartialType(ETSUnionType *typeToBePartial); 652 Type *CreatePartialTypeClassDef(ir::ClassDefinition *partialClassDef, ir::ClassDefinition *classDef, 653 const Type *typeToBePartial, varbinder::RecordTable *recordTableToUse); 654 std::pair<ir::ScriptFunction *, ir::Identifier *> CreateScriptFunctionForConstructor( 655 varbinder::FunctionScope *scope); 656 ir::MethodDefinition *CreateNonStaticClassInitializer(varbinder::ClassScope *classScope, 657 varbinder::RecordTable *recordTable); 658 // Readonly 659 Type *HandleReadonlyType(const ir::TSTypeParameterInstantiation *typeParams); 660 Type *GetReadonlyType(Type *type); 661 void MakePropertiesReadonly(ETSObjectType *classType); 662 // Required 663 Type *HandleRequiredType(Type *typeToBeRequired); 664 void MakePropertiesNonNullish(ETSObjectType *classType); 665 template <PropertyType PROP_TYPE> 666 void MakePropertyNonNullish(ETSObjectType *classType, varbinder::LocalVariable *prop); 667 void ValidateObjectLiteralForRequiredType(const ETSObjectType *requiredType, 668 const ir::ObjectExpression *initObjExpr); 669 670 // Smart cast support 671 [[nodiscard]] checker::Type *ResolveSmartType(checker::Type *sourceType, checker::Type *targetType); 672 [[nodiscard]] std::pair<Type *, Type *> CheckTestNullishCondition(Type *testedType, Type *actualType, bool strict); 673 [[nodiscard]] std::pair<Type *, Type *> CheckTestObjectCondition(ETSObjectType *testedType, Type *actualType, 674 bool strict); 675 [[nodiscard]] std::pair<Type *, Type *> CheckTestObjectCondition(ETSArrayType *testedType, Type *actualType); 676 677 void ApplySmartCast(varbinder::Variable const *variable, checker::Type *smartType) noexcept; 678 679 bool IsInLocalClass(const ir::AstNode *node) const; 680 // Exception 681 ETSObjectType *CheckExceptionOrErrorType(checker::Type *type, lexer::SourcePosition pos); 682 683 static Type *TryToInstantiate(Type *type, ArenaAllocator *allocator, TypeRelation *relation, 684 GlobalTypesHolder *globalTypes); 685 686 // Dynamic interop 687 template <typename T> 688 Signature *ResolveDynamicCallExpression(ir::Expression *callee, const ArenaVector<T *> &arguments, Language lang, 689 bool isConstruct); 690 ir::ClassProperty *CreateStaticReadonlyField(const char *name); 691 void BuildDynamicImportClass(); 692 void BuildLambdaObjectClass(ETSObjectType *functionalInterface, ir::TypeNode *retTypeAnnotation); 693 // Trailing lambda 694 void EnsureValidCurlyBrace(ir::CallExpression *callExpr); 695 696 // Extension function 697 void HandleUpdatedCallExpressionNode(ir::CallExpression *callExpr); 698 699 // Static invoke 700 void CheckInvokeMethodsLegitimacy(ETSObjectType *classType); 701 checker::Type *CheckArrayElements(ir::ArrayExpression *init); 702 void ResolveReturnStatement(checker::Type *funcReturnType, checker::Type *argumentType, 703 ir::ScriptFunction *containingFunc, ir::ReturnStatement *st); 704 DynamicCallNames(bool isConstruct)705 auto *DynamicCallNames(bool isConstruct) 706 { 707 return &dynamicCallNames_[static_cast<uint32_t>(isConstruct)]; 708 } 709 DynamicCallNames(bool isConstruct) const710 const auto *DynamicCallNames(bool isConstruct) const 711 { 712 return &dynamicCallNames_[static_cast<uint32_t>(isConstruct)]; 713 } 714 Mutex()715 std::recursive_mutex *Mutex() 716 { 717 return &mtx_; 718 } 719 720 template <typename T, typename... Args> AllocNode(Args &&....args)721 T *AllocNode(Args &&...args) 722 { 723 // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) 724 return util::NodeAllocator::ForceSetParent<T>(Allocator(), std::forward<Args>(args)...); 725 } 726 727 ArenaVector<ConstraintCheckRecord> &PendingConstraintCheckRecords(); 728 size_t &ConstraintCheckScopesCount(); 729 730 ETSObjectType *GetCachedFunctionalInterface(ir::ETSFunctionType *type); 731 void CacheFunctionalInterface(ir::ETSFunctionType *type, ETSObjectType *ifaceType); 732 void CollectReturnStatements(ir::AstNode *parent); 733 ir::ETSParameterExpression *AddParam(util::StringView name, ir::TypeNode *type); 734 735 [[nodiscard]] ir::ScriptFunction *FindFunction(ir::TSEnumDeclaration const *const enumDecl, 736 const std::string_view &name); 737 738 evaluate::ScopedDebugInfoPlugin *GetDebugInfoPlugin(); 739 const evaluate::ScopedDebugInfoPlugin *GetDebugInfoPlugin() const; 740 741 void SetDebugInfoPlugin(evaluate::ScopedDebugInfoPlugin *debugInfo); 742 743 using ClassBuilder = std::function<void(ArenaVector<ir::AstNode *> *)>; 744 using ClassInitializerBuilder = 745 std::function<void(ArenaVector<ir::Statement *> *, ArenaVector<ir::Expression *> *)>; 746 using MethodBuilder = std::function<void(ArenaVector<ir::Statement *> *, ArenaVector<ir::Expression *> *, Type **)>; 747 748 ir::ClassStaticBlock *CreateClassStaticInitializer(const ClassInitializerBuilder &builder, 749 ETSObjectType *type = nullptr); 750 ir::MethodDefinition *CreateClassInstanceInitializer(const ClassInitializerBuilder &builder, 751 ETSObjectType *type = nullptr); 752 ir::MethodDefinition *CreateClassMethod(std::string_view name, ir::ScriptFunctionFlags funcFlags, 753 ir::ModifierFlags modifierFlags, const MethodBuilder &builder); 754 ir::ClassDeclaration *BuildClass(util::StringView name, const ClassBuilder &builder); 755 756 private: 757 ETSEnumType::Method MakeMethod(ir::TSEnumDeclaration const *const enumDecl, const std::string_view &name, 758 bool buildPorxyParam, Type *returnType, bool buildProxy = true); 759 760 std::pair<const ir::Identifier *, ir::TypeNode *> GetTargetIdentifierAndType(ir::Identifier *ident); 761 void LogUnResolvedError(ir::Identifier *ident); 762 void LogOperatorCannotBeApplied(lexer::TokenType operationType, checker::Type *const leftType, 763 checker::Type *const rightType, lexer::SourcePosition pos); 764 void WrongContextErrorClassifyByType(ir::Identifier *ident, varbinder::Variable *resolved); 765 void CheckEtsFunctionType(ir::Identifier *ident, ir::Identifier const *id); 766 void NotResolvedError(ir::Identifier *const ident, const varbinder::Variable *classVar, 767 const ETSObjectType *classType); 768 void ValidateCallExpressionIdentifier(ir::Identifier *const ident, varbinder::Variable *const resolved, 769 Type *const type); 770 void ValidateNewClassInstanceIdentifier(ir::Identifier *const ident, varbinder::Variable *const resolved); 771 void ValidateMemberIdentifier(ir::Identifier *const ident, varbinder::Variable *const resolved, Type *const type); 772 void ValidatePropertyOrDeclaratorIdentifier(ir::Identifier *const ident, varbinder::Variable *const resolved); 773 void ValidateAssignmentIdentifier(ir::Identifier *const ident, varbinder::Variable *const resolved, 774 Type *const type); 775 bool ValidateBinaryExpressionIdentifier(ir::Identifier *const ident, Type *const type); 776 void ValidateGetterSetter(const ir::MemberExpression *const memberExpr, const varbinder::LocalVariable *const prop, 777 PropertySearchFlags searchFlag); 778 ir::ClassProperty *FindClassProperty(const ETSObjectType *objectType, const ETSFunctionType *propType); 779 bool IsInitializedProperty(const ir::ClassDefinition *classDefinition, const ir::ClassProperty *prop); 780 bool FindPropertyInAssignment(const ir::AstNode *it, const std::string &targetName); 781 void ValidateReadonlyProperty(const ir::MemberExpression *memberExpr, const ETSFunctionType *propType, 782 lexer::SourcePosition sourcePos); 783 void ValidateVarDeclaratorOrClassProperty(const ir::MemberExpression *memberExpr, varbinder::LocalVariable *prop); 784 void ResolveMemberReferenceValidate(varbinder::LocalVariable *prop, PropertySearchFlags searchFlag, 785 const ir::MemberExpression *const memberExpr); 786 std::tuple<bool, bool> IsResolvedAndValue(const ir::Expression *expr, Type *type) const; 787 PropertySearchFlags GetSearchFlags(const ir::MemberExpression *memberExpr, const varbinder::Variable *targetRef); 788 PropertySearchFlags GetInitialSearchFlags(const ir::MemberExpression *memberExpr); 789 const varbinder::Variable *GetTargetRef(const ir::MemberExpression *memberExpr); 790 Type *GetTypeOfSetterGetter([[maybe_unused]] varbinder::Variable *var); 791 void IterateInVariableContext([[maybe_unused]] varbinder::Variable *const var); 792 bool CheckInit(ir::Identifier *ident, ir::TypeNode *typeAnnotation, ir::Expression *init, 793 checker::Type *annotationType, varbinder::Variable *const bindingVar); 794 void CheckItemCasesConstant(ArenaVector<ir::SwitchCaseStatement *> const &cases); 795 void CheckItemCasesDuplicate(ArenaVector<ir::SwitchCaseStatement *> const &cases); 796 797 template <typename EnumType> 798 EnumType *CreateEnumTypeFromEnumDeclaration(ir::TSEnumDeclaration const *const enumDecl); 799 800 std::pair<ir::ScriptFunction *, ir::Identifier *> CreateStaticScriptFunction( 801 ClassInitializerBuilder const &builder); 802 std::pair<ir::ScriptFunction *, ir::Identifier *> CreateScriptFunction(ClassInitializerBuilder const &builder); 803 804 template <typename T> 805 ir::MethodDefinition *CreateDynamicCallIntrinsic(ir::Expression *callee, const ArenaVector<T *> &arguments, 806 Language lang); 807 ir::ClassStaticBlock *CreateDynamicCallClassInitializer(Language lang, bool isConstruct); 808 ir::ClassStaticBlock *CreateDynamicModuleClassInitializer(const std::vector<ir::ETSImportDeclaration *> &imports); 809 ir::MethodDefinition *CreateDynamicModuleClassInitMethod(); 810 811 ir::MethodDefinition *CreateLambdaObjectClassInitializer(ETSObjectType *functionalInterface); 812 813 ir::MethodDefinition *CreateLambdaObjectClassInvokeMethod(Signature *invokeSignature, 814 ir::TypeNode *retTypeAnnotation); 815 816 void ClassInitializerFromImport(ir::ETSImportDeclaration *import, ArenaVector<ir::Statement *> *statements); 817 void EmitDynamicModuleClassInitCall(); DynamicCallIntrinsics(bool isConstruct)818 DynamicCallIntrinsicsMap *DynamicCallIntrinsics(bool isConstruct) 819 { 820 return &dynamicIntrinsics_[static_cast<size_t>(isConstruct)]; 821 } 822 823 ir::ClassDeclaration *GetDynamicClass(Language lang, bool isConstruct); 824 825 using Type2TypeMap = std::unordered_map<varbinder::Variable *, varbinder::Variable *>; 826 using TypeSet = std::unordered_set<varbinder::Variable *>; 827 bool CheckTypeParameterConstraint(ir::TSTypeParameter *param, Type2TypeMap &extends); 828 bool CheckDefaultTypeParameter(const ir::TSTypeParameter *param, TypeSet &typeParameterDecls); 829 830 void SetUpTypeParameterConstraint(ir::TSTypeParameter *param); 831 ETSObjectType *UpdateGlobalType(ETSObjectType *objType, util::StringView name); 832 ETSObjectType *UpdateBoxedGlobalType(ETSObjectType *objType, util::StringView name); 833 ETSObjectType *CreateETSObjectTypeCheckBuiltins(util::StringView name, ir::AstNode *declNode, ETSObjectFlags flags); 834 void CheckProgram(parser::Program *program, bool runAnalysis = false); 835 void CheckWarnings(parser::Program *program, const CompilerOptions &options); 836 837 bool ComputeSuperType(ETSObjectType *type); 838 839 template <typename UType> 840 UType HandleModulo(UType leftValue, UType rightValue); 841 842 template <typename FloatOrIntegerType, typename IntegerType = FloatOrIntegerType> 843 Type *HandleBitWiseArithmetic(Type *leftValue, Type *rightValue, lexer::TokenType operationType); 844 845 template <typename TargetType> 846 typename TargetType::UType GetOperand(Type *type); 847 848 template <typename... Args> 849 ETSObjectType *AsETSObjectType(Type *(GlobalTypesHolder::*typeFunctor)(Args...), Args... args) const; 850 Signature *GetMostSpecificSignature(ArenaVector<Signature *> &compatibleSignatures, 851 const ArenaVector<ir::Expression *> &arguments, 852 const lexer::SourcePosition &pos, TypeRelationFlag resolveFlags); 853 ArenaVector<Signature *> CollectSignatures(ArenaVector<Signature *> &signatures, 854 const ir::TSTypeParameterInstantiation *typeArguments, 855 const ArenaVector<ir::Expression *> &arguments, 856 const lexer::SourcePosition &pos, TypeRelationFlag resolveFlags); 857 // Trailing lambda 858 void MoveTrailingBlockToEnclosingBlockStatement(ir::CallExpression *callExpr); 859 void TransformTraillingLambda(ir::CallExpression *callExpr); 860 ArenaVector<ir::Expression *> ExtendArgumentsWithFakeLamda(ir::CallExpression *callExpr); 861 862 // Static invoke 863 bool TryTransformingToStaticInvoke(ir::Identifier *ident, const Type *resolvedType); 864 865 ArrayMap arrayTypes_; 866 ArenaVector<ConstraintCheckRecord> pendingConstraintCheckRecords_; 867 size_t constraintCheckScopesCount_ {0}; 868 GlobalArraySignatureMap globalArraySignatures_; 869 PrimitiveWrappers primitiveWrappers_; 870 ComputedAbstracts cachedComputedAbstracts_; 871 // NOTE(aleksisch): Extract dynamic from checker to separate class 872 std::array<DynamicCallIntrinsicsMap, 2U> dynamicIntrinsics_; 873 std::array<DynamicClassIntrinsicsMap, 2U> dynamicClasses_; 874 DynamicLambdaObjectSignatureMap dynamicLambdaSignatureCache_; 875 FunctionalInterfaceMap functionalInterfaceCache_; 876 TypeMapping apparentTypes_; 877 std::array<DynamicCallNamesMap, 2U> dynamicCallNames_; 878 std::recursive_mutex mtx_; 879 evaluate::ScopedDebugInfoPlugin *debugInfoPlugin_ {nullptr}; 880 }; 881 882 } // namespace ark::es2panda::checker 883 884 #endif /* CHECKER_H */ 885