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