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