• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2025 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_TS_CHECKER_H
17 #define ES2PANDA_CHECKER_TS_CHECKER_H
18 
19 #include "checker/checker.h"
20 #include "varbinder/enumMemberResult.h"
21 #include "checker/types/globalTypesHolder.h"
22 #include "checker/types/ts/types.h"
23 #include "util/enumbitops.h"
24 #include "util/ustring.h"
25 #include "util/es2pandaMacros.h"
26 
27 #include <cstdint>
28 #include <initializer_list>
29 #include <unordered_map>
30 #include <unordered_set>
31 
32 namespace ark::es2panda::varbinder {
33 class VarBinder;
34 class Decl;
35 class EnumVariable;
36 class FunctionDecl;
37 class LocalVariable;
38 class Scope;
39 class Variable;
40 }  // namespace ark::es2panda::varbinder
41 
42 namespace ark::es2panda::ir {
43 class AstNode;
44 class SpreadElement;
45 class AssignmentExpression;
46 class Property;
47 class Expression;
48 class ScriptFunction;
49 class UnaryExpression;
50 class BinaryExpression;
51 class Identifier;
52 class MemberExpression;
53 class TSEnumDeclaration;
54 class TSInterfaceDeclaration;
55 class ObjectExpression;
56 class TSArrayType;
57 class TSUnionType;
58 class TSFunctionType;
59 class TSConstructorType;
60 class TSTypeLiteral;
61 class TSTypeReference;
62 class TSQualifiedName;
63 class TSIndexedAccessType;
64 class TSInterfaceHeritage;
65 class TSTypeQuery;
66 class TSTupleType;
67 class ArrayExpression;
68 class Statement;
69 class TSTypeParameterDeclaration;
70 class TSTypeParameterInstantiation;
71 class BlockStatement;
72 class VariableDeclaration;
73 class IfStatement;
74 class DoWhileStatement;
75 class WhileStatement;
76 class ForUpdateStatement;
77 class ForInStatement;
78 class ForOfStatement;
79 class ReturnStatement;
80 class SwitchStatement;
81 class LabelledStatement;
82 class ThrowStatement;
83 class TryStatement;
84 class TSTypeAliasDeclaration;
85 class TSAsExpression;
86 class ThisExpression;
87 class TypeofExpression;
88 class NewExpression;
89 class FunctionExpression;
90 class AwaitExpression;
91 class UpdateExpression;
92 class ConditionalExpression;
93 class YieldExpression;
94 class ArrowFunctionExpression;
95 class TemplateLiteral;
96 class TaggedTemplateExpression;
97 class TSIndexSignature;
98 class TSSignatureDeclaration;
99 class TSPropertySignature;
100 class TSMethodSignature;
101 class ChainExpression;
102 class VariableDeclarator;
103 
104 enum class AstNodeType;
105 }  // namespace ark::es2panda::ir
106 
107 namespace ark::es2panda::checker {
108 
109 struct ExpressionTypeInfo {
110     Type *leftType;
111     Type *rightType;
112 };
113 
114 struct TupleTypeInfo {
115     ElementFlags combinedFlags;
116     uint32_t minLength;
117     uint32_t fixedLength;
118     bool readonly;
119 };
120 
121 class TSChecker : public Checker {
122 public:
123     // NOLINTNEXTLINE(readability-redundant-member-init)
TSChecker(util::DiagnosticEngine & diagnosticEngine,ArenaAllocator * programAllocator)124     explicit TSChecker(util::DiagnosticEngine &diagnosticEngine, [[maybe_unused]] ArenaAllocator *programAllocator)
125         : Checker(diagnosticEngine)
126     {
127     }
128 
GlobalNumberType()129     Type *GlobalNumberType()
130     {
131         return GetGlobalTypesHolder()->GlobalNumberType();
132     }
133 
GlobalAnyType()134     Type *GlobalAnyType()
135     {
136         return GetGlobalTypesHolder()->GlobalAnyType();
137     }
138 
GlobalStringType()139     Type *GlobalStringType()
140     {
141         return GetGlobalTypesHolder()->GlobalStringType();
142     }
143 
GlobalBooleanType()144     Type *GlobalBooleanType()
145     {
146         return GetGlobalTypesHolder()->GlobalBooleanType();
147     }
148 
GlobalVoidType()149     Type *GlobalVoidType()
150     {
151         return GetGlobalTypesHolder()->GlobalVoidType();
152     }
153 
GlobalNullType()154     Type *GlobalNullType()
155     {
156         return GetGlobalTypesHolder()->GlobalNullType();
157     }
158 
GlobalUndefinedType()159     Type *GlobalUndefinedType()
160     {
161         return GetGlobalTypesHolder()->GlobalUndefinedType();
162     }
163 
GlobalUnknownType()164     Type *GlobalUnknownType()
165     {
166         return GetGlobalTypesHolder()->GlobalUnknownType();
167     }
168 
GlobalNeverType()169     Type *GlobalNeverType()
170     {
171         return GetGlobalTypesHolder()->GlobalNeverType();
172     }
173 
GlobalNonPrimitiveType()174     Type *GlobalNonPrimitiveType()
175     {
176         return GetGlobalTypesHolder()->GlobalNonPrimitiveType();
177     }
178 
GlobalBigintType()179     Type *GlobalBigintType()
180     {
181         return GetGlobalTypesHolder()->GlobalBigintType();
182     }
183 
GlobalFalseType()184     Type *GlobalFalseType()
185     {
186         return GetGlobalTypesHolder()->GlobalFalseType();
187     }
188 
GlobalTrueType()189     Type *GlobalTrueType()
190     {
191         return GetGlobalTypesHolder()->GlobalTrueType();
192     }
193 
GlobalNumberOrBigintType()194     Type *GlobalNumberOrBigintType()
195     {
196         return GetGlobalTypesHolder()->GlobalNumberOrBigintType();
197     }
198 
GlobalStringOrNumberType()199     Type *GlobalStringOrNumberType()
200     {
201         return GetGlobalTypesHolder()->GlobalStringOrNumberType();
202     }
203 
GlobalZeroType()204     Type *GlobalZeroType()
205     {
206         return GetGlobalTypesHolder()->GlobalZeroType();
207     }
208 
GlobalEmptyStringType()209     Type *GlobalEmptyStringType()
210     {
211         return GetGlobalTypesHolder()->GlobalEmptyStringType();
212     }
213 
GlobalZeroBigintType()214     Type *GlobalZeroBigintType()
215     {
216         return GetGlobalTypesHolder()->GlobalZeroBigintType();
217     }
218 
GlobalPrimitiveType()219     Type *GlobalPrimitiveType()
220     {
221         return GetGlobalTypesHolder()->GlobalPrimitiveType();
222     }
223 
GlobalEmptyTupleType()224     Type *GlobalEmptyTupleType()
225     {
226         return GetGlobalTypesHolder()->GlobalEmptyTupleType();
227     }
228 
GlobalEmptyObjectType()229     Type *GlobalEmptyObjectType()
230     {
231         return GetGlobalTypesHolder()->GlobalEmptyObjectType();
232     }
233 
GlobalResolvingReturnType()234     Type *GlobalResolvingReturnType()
235     {
236         return GetGlobalTypesHolder()->GlobalResolvingReturnType();
237     }
238 
GlobalErrorType()239     Type *GlobalErrorType()
240     {
241         return GetGlobalTypesHolder()->GlobalErrorType();
242     }
243 
NumberLiteralMap()244     NumberLiteralPool &NumberLiteralMap()
245     {
246         return numberLiteralMap_;
247     }
248 
StringLiteralMap()249     StringLiteralPool &StringLiteralMap()
250     {
251         return stringLiteralMap_;
252     }
253 
BigintLiteralMap()254     StringLiteralPool &BigintLiteralMap()
255     {
256         return bigintLiteralMap_;
257     }
258 
259     bool StartChecker([[maybe_unused]] varbinder::VarBinder *varbinder, const util::Options &options) override;
260     Type *CheckTypeCached(ir::Expression *expr) override;
261 
262     // Util
263     static bool InAssignment(ir::AstNode *node);
264     static bool IsAssignmentOperator(lexer::TokenType op);
265     static bool IsLiteralType(const Type *type);
266     static ir::AstNode *FindAncestorUntilGivenType(ir::AstNode *node, ir::AstNodeType stop);
267     static bool MaybeTypeOfKind(const Type *type, TypeFlag flags);
268     static bool MaybeTypeOfKind(const Type *type, ObjectType::ObjectTypeKind kind);
269     static bool IsConstantMemberAccess(ir::Expression *expr);
270     static bool IsStringLike(ir::Expression *expr);
271     static ir::MemberExpression *ResolveLeftMostMemberExpression(ir::MemberExpression *expr);
272 
273     // Helpers
274     void CheckTruthinessOfType(Type *type, lexer::SourcePosition lineInfo);
275     Type *CheckNonNullType(Type *type, lexer::SourcePosition lineInfo);
276     Type *GetBaseTypeOfLiteralType(Type *type);
277     void CheckReferenceExpression(ir::Expression *expr, const char *invalidReferenceMsg,
278                                   const char *invalidOptionalChainMsg);
279     void CheckTestingKnownTruthyCallableOrAwaitableType(ir::Expression *condExpr, Type *type, ir::AstNode *body);
280     Type *ExtractDefinitelyFalsyTypes(Type *type);
281     Type *RemoveDefinitelyFalsyTypes(Type *type);
282     TypeFlag GetFalsyFlags(Type *type);
283     bool IsVariableUsedInConditionBody(ir::AstNode *parent, varbinder::Variable *searchVar);
284     bool FindVariableInBinaryExpressionChain(ir::AstNode *parent, varbinder::Variable *searchVar);
285     bool IsVariableUsedInBinaryExpressionChain(ir::AstNode *parent, varbinder::Variable *searchVar);
286     [[noreturn]] void ThrowTypeError(std::string_view message, const lexer::SourcePosition &pos);
287     [[noreturn]] void ThrowTypeError(const util::DiagnosticMessageParams &list, const lexer::SourcePosition &pos);
288     [[noreturn]] void ThrowBinaryLikeError(lexer::TokenType op, Type *leftType, Type *rightType,
289                                            lexer::SourcePosition lineInfo);
290     [[noreturn]] void ThrowAssignmentError(Type *source, Type *target, lexer::SourcePosition lineInfo,
291                                            bool isAsSrcLeftType = false);
292     void ElaborateElementwise(Type *targetType, ir::Expression *sourceNode, const lexer::SourcePosition &pos);
293     void InferSimpleVariableDeclaratorType(ir::VariableDeclarator *declarator);
294     void GetTypeVar(varbinder::Decl *decl);
295     void GetTypeParam(varbinder::Variable *var, varbinder::Decl *decl);
296     void GetTypeEnum(varbinder::Variable *var, varbinder::Decl *decl);
297     Type *GetDeclTsType(varbinder::Variable *var, varbinder::Decl *decl);
298     Type *GetTypeOfVariable(varbinder::Variable *var) override;
299     Type *GetUnaryResultType(Type *operandType);
300     Type *GetTypeFromClassOrInterfaceReference(ir::TSTypeReference *node, varbinder::Variable *var);
301     Type *GetTypeFromTypeAliasReference(ir::TSTypeReference *node, varbinder::Variable *var);
302     Type *GetTypeReferenceType(ir::TSTypeReference *node, varbinder::Variable *var);
303 
304     // Type creation
305     Type *CreateNumberLiteralType(double value);
306     Type *CreateBigintLiteralType(const util::StringView &str, bool negative);
307     Type *CreateStringLiteralType(const util::StringView &str);
308     Type *CreateFunctionTypeWithSignature(Signature *callSignature);
309     Type *CreateConstructorTypeWithSignature(Signature *constructSignature);
310     Type *CreateTupleType(ObjectDescriptor *desc, ArenaVector<ElementFlags> &&elementFlags,
311                           const TupleTypeInfo &tupleTypeInfo);
312     Type *CreateTupleType(ObjectDescriptor *desc, ArenaVector<ElementFlags> &&elementFlags,
313                           const TupleTypeInfo &tupleTypeInfo, NamedTupleMemberPool &&namedMembers);
314     Type *CreateUnionType(std::initializer_list<Type *> constituentTypes);
315     Type *CreateUnionType(ArenaVector<Type *> &&constituentTypes);
316     Type *CreateUnionType(ArenaVector<Type *> &constituentTypes);
317     Type *CreateObjectTypeWithCallSignature(Signature *callSignature);
318     Type *CreateObjectTypeWithConstructSignature(Signature *constructSignature);
319 
320     // Object
321     void ResolvePropertiesOfObjectType(ObjectType *type, ir::AstNode *member,
322                                        ArenaVector<ir::TSSignatureDeclaration *> &signatureDeclarations,
323                                        ArenaVector<ir::TSIndexSignature *> &indexDeclarations, bool isInterface);
324     void ResolveSignaturesOfObjectType(ObjectType *type,
325                                        ArenaVector<ir::TSSignatureDeclaration *> &signatureDeclarations);
326     void ResolveIndexInfosOfObjectType(ObjectType *type, ArenaVector<ir::TSIndexSignature *> &indexDeclarations);
327     void ResolveDeclaredMembers(InterfaceType *type);
328     bool ValidateInterfaceMemberRedeclaration(ObjectType *type, varbinder::Variable *prop,
329                                               const lexer::SourcePosition &locInfo);
330     varbinder::Variable *GetPropertyOfType(Type *type, const util::StringView &name, bool getPartial = false,
331                                            varbinder::VariableFlags propagateFlags = varbinder::VariableFlags::NONE);
332     varbinder::Variable *GetPropertyOfUnionType(UnionType *type, const util::StringView &name, bool getPartial,
333                                                 varbinder::VariableFlags propagateFlags);
334     void CheckIndexConstraints(Type *type);
335     void ResolveUnionTypeMembers(UnionType *type);
336     void ResolveObjectTypeMembers(ObjectType *type);
337     void ResolveInterfaceOrClassTypeMembers(InterfaceType *type);
338     Type *CheckComputedPropertyName(ir::Expression *key);
339     Type *GetPropertyTypeForIndexType(Type *type, Type *indexType);
340     IndexInfo *GetApplicableIndexInfo(Type *type, Type *indexType);
341     ArenaVector<ObjectType *> GetBaseTypes(InterfaceType *type);
342     void ResolveStructuredTypeMembers(Type *type) override;
343 
344     // Function
345     Type *HandleFunctionReturn(ir::ScriptFunction *func);
346     void CheckFunctionParameterDeclarations(const ArenaVector<ir::Expression *> &params, SignatureInfo *signatureInfo);
347     std::tuple<varbinder::LocalVariable *, varbinder::LocalVariable *, bool> CheckFunctionParameter(
348         ir::Expression *param, SignatureInfo *signatureInfo);
349     std::tuple<varbinder::LocalVariable *, varbinder::LocalVariable *, bool> CheckFunctionIdentifierParameter(
350         ir::Identifier *param);
351     std::tuple<varbinder::LocalVariable *, varbinder::LocalVariable *, bool> CheckFunctionAssignmentPatternParameter(
352         ir::AssignmentExpression *param);
353     std::tuple<varbinder::LocalVariable *, varbinder::LocalVariable *, bool> CheckFunctionRestParameter(
354         ir::SpreadElement *param, SignatureInfo *signatureInfo);
355     std::tuple<varbinder::LocalVariable *, varbinder::LocalVariable *, bool> CheckFunctionArrayPatternParameter(
356         ir::ArrayExpression *param);
357     std::tuple<varbinder::LocalVariable *, varbinder::LocalVariable *, bool> CheckFunctionObjectPatternParameter(
358         ir::ObjectExpression *param);
359     void ValidateSubsequentNode(const ir::Statement *const subsequentNode, const ir::ScriptFunction *const func);
360     void CheckOverloadSignatureCompatibility(Signature *bodyCallSignature, Signature *signature);
361     void InferFunctionDeclarationType(const varbinder::FunctionDecl *decl, varbinder::Variable *funcVar);
362     void CollectTypesFromReturnStatements(ir::AstNode *parent, ArenaVector<Type *> *returnTypes);
363     void CheckAllCodePathsInNonVoidFunctionReturnOrThrow(ir::ScriptFunction *func, lexer::SourcePosition lineInfo,
364                                                          const char *errMsg);
365     void CreatePatternParameterName(ir::AstNode *node, std::stringstream &ss);
366     void HandlePropertyPatternParameterName(ir::Property *prop, std::stringstream &ss);
367     void ThrowReturnTypeCircularityError(ir::ScriptFunction *func);
368     ArgRange GetArgRange(const ArenaVector<Signature *> &signatures, ArenaVector<Signature *> *potentialSignatures,
369                          uint32_t callArgsSize, bool *haveSignatureWithRest);
370     bool CallMatchesSignature(const ArenaVector<ir::Expression *> &args, Signature *signature, bool throwError);
371     Type *ResolveCallOrNewExpression(const ArenaVector<Signature *> &signatures,
372                                      ArenaVector<ir::Expression *> arguments, const lexer::SourcePosition &errPos);
373     Type *CreateParameterTypeForArrayAssignmentPattern(ir::ArrayExpression *arrayPattern, Type *inferredType);
374     Type *CreateParameterTypeForObjectAssignmentPattern(ir::ObjectExpression *objectPattern, Type *inferredType);
375 
376     // Binary like expression
377     Type *CheckBinaryOperator(ExpressionTypeInfo *leftRightType, ir::Expression *leftExpr, ir::Expression *rightExpr,
378                               ir::AstNode *expr, lexer::TokenType op);
379     Type *CheckPlusOperator(ExpressionTypeInfo *leftRightType, ir::Expression *leftExpr, ir::Expression *rightExpr,
380                             ir::AstNode *expr, lexer::TokenType op);
381     Type *CheckCompareOperator(ExpressionTypeInfo *leftRightType, ir::Expression *leftExpr, ir::Expression *rightExpr,
382                                ir::AstNode *expr, lexer::TokenType op);
383     Type *CheckAndOperator(Type *leftType, Type *rightType, ir::Expression *leftExpr);
384     Type *CheckOrOperator(Type *leftType, Type *rightType, ir::Expression *leftExpr);
385     Type *CheckInstanceofExpression(Type *leftType, Type *rightType, ir::Expression *rightExpr, ir::AstNode *expr);
386     Type *CheckInExpression(Type *leftType, Type *rightType, ir::Expression *leftExpr, ir::Expression *rightExpr,
387                             ir::AstNode *expr);
388     void CheckAssignmentOperator(lexer::TokenType op, ir::Expression *leftExpr, Type *leftType, Type *valueType);
389 
390 private:
391     NumberLiteralPool numberLiteralMap_;
392     StringLiteralPool stringLiteralMap_;
393     StringLiteralPool bigintLiteralMap_;
394 
395     // Binary like expression
396     void CheckBooleanLikeType(Type *leftType, Type *rightType, ir::AstNode *expr, lexer::TokenType op);
397 
398     void CheckExtendsBases(ObjectType *&baseObj, InterfaceType *&type, varbinder::InterfaceDecl *&decl);
399 };
400 
401 }  // namespace ark::es2panda::checker
402 
403 #endif /* CHECKER_H */
404