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