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_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 "macros.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()124     explicit TSChecker() : Checker() {}
125 
GlobalNumberType()126     Type *GlobalNumberType()
127     {
128         return GetGlobalTypesHolder()->GlobalNumberType();
129     }
130 
GlobalAnyType()131     Type *GlobalAnyType()
132     {
133         return GetGlobalTypesHolder()->GlobalAnyType();
134     }
135 
GlobalStringType()136     Type *GlobalStringType()
137     {
138         return GetGlobalTypesHolder()->GlobalStringType();
139     }
140 
GlobalBooleanType()141     Type *GlobalBooleanType()
142     {
143         return GetGlobalTypesHolder()->GlobalBooleanType();
144     }
145 
GlobalVoidType()146     Type *GlobalVoidType()
147     {
148         return GetGlobalTypesHolder()->GlobalVoidType();
149     }
150 
GlobalNullType()151     Type *GlobalNullType()
152     {
153         return GetGlobalTypesHolder()->GlobalNullType();
154     }
155 
GlobalUndefinedType()156     Type *GlobalUndefinedType()
157     {
158         return GetGlobalTypesHolder()->GlobalUndefinedType();
159     }
160 
GlobalUnknownType()161     Type *GlobalUnknownType()
162     {
163         return GetGlobalTypesHolder()->GlobalUnknownType();
164     }
165 
GlobalNeverType()166     Type *GlobalNeverType()
167     {
168         return GetGlobalTypesHolder()->GlobalNeverType();
169     }
170 
GlobalNonPrimitiveType()171     Type *GlobalNonPrimitiveType()
172     {
173         return GetGlobalTypesHolder()->GlobalNonPrimitiveType();
174     }
175 
GlobalBigintType()176     Type *GlobalBigintType()
177     {
178         return GetGlobalTypesHolder()->GlobalBigintType();
179     }
180 
GlobalFalseType()181     Type *GlobalFalseType()
182     {
183         return GetGlobalTypesHolder()->GlobalFalseType();
184     }
185 
GlobalTrueType()186     Type *GlobalTrueType()
187     {
188         return GetGlobalTypesHolder()->GlobalTrueType();
189     }
190 
GlobalNumberOrBigintType()191     Type *GlobalNumberOrBigintType()
192     {
193         return GetGlobalTypesHolder()->GlobalNumberOrBigintType();
194     }
195 
GlobalStringOrNumberType()196     Type *GlobalStringOrNumberType()
197     {
198         return GetGlobalTypesHolder()->GlobalStringOrNumberType();
199     }
200 
GlobalZeroType()201     Type *GlobalZeroType()
202     {
203         return GetGlobalTypesHolder()->GlobalZeroType();
204     }
205 
GlobalEmptyStringType()206     Type *GlobalEmptyStringType()
207     {
208         return GetGlobalTypesHolder()->GlobalEmptyStringType();
209     }
210 
GlobalZeroBigintType()211     Type *GlobalZeroBigintType()
212     {
213         return GetGlobalTypesHolder()->GlobalZeroBigintType();
214     }
215 
GlobalPrimitiveType()216     Type *GlobalPrimitiveType()
217     {
218         return GetGlobalTypesHolder()->GlobalPrimitiveType();
219     }
220 
GlobalEmptyTupleType()221     Type *GlobalEmptyTupleType()
222     {
223         return GetGlobalTypesHolder()->GlobalEmptyTupleType();
224     }
225 
GlobalEmptyObjectType()226     Type *GlobalEmptyObjectType()
227     {
228         return GetGlobalTypesHolder()->GlobalEmptyObjectType();
229     }
230 
GlobalResolvingReturnType()231     Type *GlobalResolvingReturnType()
232     {
233         return GetGlobalTypesHolder()->GlobalResolvingReturnType();
234     }
235 
GlobalErrorType()236     Type *GlobalErrorType()
237     {
238         return GetGlobalTypesHolder()->GlobalErrorType();
239     }
240 
NumberLiteralMap()241     NumberLiteralPool &NumberLiteralMap()
242     {
243         return numberLiteralMap_;
244     }
245 
StringLiteralMap()246     StringLiteralPool &StringLiteralMap()
247     {
248         return stringLiteralMap_;
249     }
250 
BigintLiteralMap()251     StringLiteralPool &BigintLiteralMap()
252     {
253         return bigintLiteralMap_;
254     }
255 
256     bool StartChecker([[maybe_unused]] varbinder::VarBinder *varbinder, const CompilerOptions &options) override;
257     Type *CheckTypeCached(ir::Expression *expr) override;
258 
259     // Util
260     static bool InAssignment(ir::AstNode *node);
261     static bool IsAssignmentOperator(lexer::TokenType op);
262     static bool IsLiteralType(const Type *type);
263     static ir::AstNode *FindAncestorUntilGivenType(ir::AstNode *node, ir::AstNodeType stop);
264     static bool MaybeTypeOfKind(const Type *type, TypeFlag flags);
265     static bool MaybeTypeOfKind(const Type *type, ObjectType::ObjectTypeKind kind);
266     static bool IsConstantMemberAccess(ir::Expression *expr);
267     static bool IsStringLike(ir::Expression *expr);
268     static ir::MemberExpression *ResolveLeftMostMemberExpression(ir::MemberExpression *expr);
269 
270     // Helpers
271     void CheckTruthinessOfType(Type *type, lexer::SourcePosition lineInfo);
272     Type *CheckNonNullType(Type *type, lexer::SourcePosition lineInfo);
273     Type *GetBaseTypeOfLiteralType(Type *type);
274     void CheckReferenceExpression(ir::Expression *expr, const char *invalidReferenceMsg,
275                                   const char *invalidOptionalChainMsg);
276     void CheckTestingKnownTruthyCallableOrAwaitableType(ir::Expression *condExpr, Type *type, ir::AstNode *body);
277     Type *ExtractDefinitelyFalsyTypes(Type *type);
278     Type *RemoveDefinitelyFalsyTypes(Type *type);
279     TypeFlag GetFalsyFlags(Type *type);
280     bool IsVariableUsedInConditionBody(ir::AstNode *parent, varbinder::Variable *searchVar);
281     bool FindVariableInBinaryExpressionChain(ir::AstNode *parent, varbinder::Variable *searchVar);
282     bool IsVariableUsedInBinaryExpressionChain(ir::AstNode *parent, varbinder::Variable *searchVar);
283     [[noreturn]] void ThrowBinaryLikeError(lexer::TokenType op, Type *leftType, Type *rightType,
284                                            lexer::SourcePosition lineInfo);
285     [[noreturn]] void ThrowAssignmentError(Type *source, Type *target, lexer::SourcePosition lineInfo,
286                                            bool isAsSrcLeftType = false);
287     void ElaborateElementwise(Type *targetType, ir::Expression *sourceNode, const lexer::SourcePosition &pos);
288     void InferSimpleVariableDeclaratorType(ir::VariableDeclarator *declarator);
289     void GetTypeVar(varbinder::Decl *decl);
290     void GetTypeParam(varbinder::Variable *var, varbinder::Decl *decl);
291     void GetTypeEnum(varbinder::Variable *var, varbinder::Decl *decl);
292     Type *GetDeclTsType(varbinder::Variable *var, varbinder::Decl *decl);
293     Type *GetTypeOfVariable(varbinder::Variable *var) override;
294     Type *GetUnaryResultType(Type *operandType);
295     Type *GetTypeFromClassOrInterfaceReference(ir::TSTypeReference *node, varbinder::Variable *var);
296     Type *GetTypeFromTypeAliasReference(ir::TSTypeReference *node, varbinder::Variable *var);
297     Type *GetTypeReferenceType(ir::TSTypeReference *node, varbinder::Variable *var);
298 
299     // Type creation
300     Type *CreateNumberLiteralType(double value);
301     Type *CreateBigintLiteralType(const util::StringView &str, bool negative);
302     Type *CreateStringLiteralType(const util::StringView &str);
303     Type *CreateFunctionTypeWithSignature(Signature *callSignature);
304     Type *CreateConstructorTypeWithSignature(Signature *constructSignature);
305     Type *CreateTupleType(ObjectDescriptor *desc, ArenaVector<ElementFlags> &&elementFlags,
306                           const TupleTypeInfo &tupleTypeInfo);
307     Type *CreateTupleType(ObjectDescriptor *desc, ArenaVector<ElementFlags> &&elementFlags,
308                           const TupleTypeInfo &tupleTypeInfo, NamedTupleMemberPool &&namedMembers);
309     Type *CreateUnionType(std::initializer_list<Type *> constituentTypes);
310     Type *CreateUnionType(ArenaVector<Type *> &&constituentTypes);
311     Type *CreateUnionType(ArenaVector<Type *> &constituentTypes);
312     Type *CreateObjectTypeWithCallSignature(Signature *callSignature);
313     Type *CreateObjectTypeWithConstructSignature(Signature *constructSignature);
314 
315     // Object
316     void ResolvePropertiesOfObjectType(ObjectType *type, ir::AstNode *member,
317                                        ArenaVector<ir::TSSignatureDeclaration *> &signatureDeclarations,
318                                        ArenaVector<ir::TSIndexSignature *> &indexDeclarations, bool isInterface);
319     void ResolveSignaturesOfObjectType(ObjectType *type,
320                                        ArenaVector<ir::TSSignatureDeclaration *> &signatureDeclarations);
321     void ResolveIndexInfosOfObjectType(ObjectType *type, ArenaVector<ir::TSIndexSignature *> &indexDeclarations);
322     void ResolveDeclaredMembers(InterfaceType *type);
323     bool ValidateInterfaceMemberRedeclaration(ObjectType *type, varbinder::Variable *prop,
324                                               const lexer::SourcePosition &locInfo);
325     varbinder::Variable *GetPropertyOfType(Type *type, const util::StringView &name, bool getPartial = false,
326                                            varbinder::VariableFlags propagateFlags = varbinder::VariableFlags::NONE);
327     varbinder::Variable *GetPropertyOfUnionType(UnionType *type, const util::StringView &name, bool getPartial,
328                                                 varbinder::VariableFlags propagateFlags);
329     void CheckIndexConstraints(Type *type);
330     void ResolveUnionTypeMembers(UnionType *type);
331     void ResolveObjectTypeMembers(ObjectType *type);
332     void ResolveInterfaceOrClassTypeMembers(InterfaceType *type);
333     Type *CheckComputedPropertyName(ir::Expression *key);
334     Type *GetPropertyTypeForIndexType(Type *type, Type *indexType);
335     IndexInfo *GetApplicableIndexInfo(Type *type, Type *indexType);
336     ArenaVector<ObjectType *> GetBaseTypes(InterfaceType *type);
337     void ResolveStructuredTypeMembers(Type *type) override;
338 
339     // Function
340     Type *HandleFunctionReturn(ir::ScriptFunction *func);
341     void CheckFunctionParameterDeclarations(const ArenaVector<ir::Expression *> &params, SignatureInfo *signatureInfo);
342     std::tuple<varbinder::LocalVariable *, varbinder::LocalVariable *, bool> CheckFunctionParameter(
343         ir::Expression *param, SignatureInfo *signatureInfo);
344     std::tuple<varbinder::LocalVariable *, varbinder::LocalVariable *, bool> CheckFunctionIdentifierParameter(
345         ir::Identifier *param);
346     std::tuple<varbinder::LocalVariable *, varbinder::LocalVariable *, bool> CheckFunctionAssignmentPatternParameter(
347         ir::AssignmentExpression *param);
348     std::tuple<varbinder::LocalVariable *, varbinder::LocalVariable *, bool> CheckFunctionRestParameter(
349         ir::SpreadElement *param, SignatureInfo *signatureInfo);
350     std::tuple<varbinder::LocalVariable *, varbinder::LocalVariable *, bool> CheckFunctionArrayPatternParameter(
351         ir::ArrayExpression *param);
352     std::tuple<varbinder::LocalVariable *, varbinder::LocalVariable *, bool> CheckFunctionObjectPatternParameter(
353         ir::ObjectExpression *param);
354     void ValidateSubsequentNode(const ir::Statement *const subsequentNode, const ir::ScriptFunction *const func);
355     void CheckOverloadSignatureCompatibility(Signature *bodyCallSignature, Signature *signature);
356     void InferFunctionDeclarationType(const varbinder::FunctionDecl *decl, varbinder::Variable *funcVar);
357     void CollectTypesFromReturnStatements(ir::AstNode *parent, ArenaVector<Type *> *returnTypes);
358     void CheckAllCodePathsInNonVoidFunctionReturnOrThrow(ir::ScriptFunction *func, lexer::SourcePosition lineInfo,
359                                                          const char *errMsg);
360     void CreatePatternParameterName(ir::AstNode *node, std::stringstream &ss);
361     void HandlePropertyPatternParameterName(ir::Property *prop, std::stringstream &ss);
362     void ThrowReturnTypeCircularityError(ir::ScriptFunction *func);
363     ArgRange GetArgRange(const ArenaVector<Signature *> &signatures, ArenaVector<Signature *> *potentialSignatures,
364                          uint32_t callArgsSize, bool *haveSignatureWithRest);
365     bool CallMatchesSignature(const ArenaVector<ir::Expression *> &args, Signature *signature, bool throwError);
366     Type *ResolveCallOrNewExpression(const ArenaVector<Signature *> &signatures,
367                                      ArenaVector<ir::Expression *> arguments, const lexer::SourcePosition &errPos);
368     Type *CreateParameterTypeForArrayAssignmentPattern(ir::ArrayExpression *arrayPattern, Type *inferredType);
369     Type *CreateParameterTypeForObjectAssignmentPattern(ir::ObjectExpression *objectPattern, Type *inferredType);
370 
371     // Binary like expression
372     Type *CheckBinaryOperator(ExpressionTypeInfo *leftRightType, ir::Expression *leftExpr, ir::Expression *rightExpr,
373                               ir::AstNode *expr, lexer::TokenType op);
374     Type *CheckPlusOperator(ExpressionTypeInfo *leftRightType, ir::Expression *leftExpr, ir::Expression *rightExpr,
375                             ir::AstNode *expr, lexer::TokenType op);
376     Type *CheckCompareOperator(ExpressionTypeInfo *leftRightType, ir::Expression *leftExpr, ir::Expression *rightExpr,
377                                ir::AstNode *expr, lexer::TokenType op);
378     Type *CheckAndOperator(Type *leftType, Type *rightType, ir::Expression *leftExpr);
379     Type *CheckOrOperator(Type *leftType, Type *rightType, ir::Expression *leftExpr);
380     Type *CheckInstanceofExpression(Type *leftType, Type *rightType, ir::Expression *rightExpr, ir::AstNode *expr);
381     Type *CheckInExpression(Type *leftType, Type *rightType, ir::Expression *leftExpr, ir::Expression *rightExpr,
382                             ir::AstNode *expr);
383     void CheckAssignmentOperator(lexer::TokenType op, ir::Expression *leftExpr, Type *leftType, Type *valueType);
384 
385 private:
386     NumberLiteralPool numberLiteralMap_;
387     StringLiteralPool stringLiteralMap_;
388     StringLiteralPool bigintLiteralMap_;
389 
390     // Binary like expression
391     void CheckBooleanLikeType(Type *leftType, Type *rightType, ir::AstNode *expr, lexer::TokenType op);
392 
393     void CheckExtendsBases(ObjectType *&baseObj, InterfaceType *&type, varbinder::InterfaceDecl *&decl);
394 };
395 
396 }  // namespace ark::es2panda::checker
397 
398 #endif /* CHECKER_H */
399