• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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_ETSANALYZER_H
17 #define ES2PANDA_CHECKER_ETSANALYZER_H
18 
19 #include "checker/SemanticAnalyzer.h"
20 #include "checker/ETSchecker.h"
21 #include "ETSAnalyzerHelpers.h"
22 
23 namespace ark::es2panda::checker {
24 
25 class ETSAnalyzer final : public SemanticAnalyzer {
26 public:
ETSAnalyzer(Checker * checker)27     explicit ETSAnalyzer(Checker *checker) : SemanticAnalyzer(checker) {};
28 // CC-OFFNXT(G.PRE.02,G.PRE.09) name part
29 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
30 #define DECLARE_ETSANALYZER_CHECK_METHOD(_, nodeType) checker::Type *Check(ir::nodeType *node) const override;
31     AST_NODE_MAPPING(DECLARE_ETSANALYZER_CHECK_METHOD)
32 #undef DECLARE_ETSANALYZER_CHECK_METHOD
33 
34 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
35 #define DECLARE_ETSANALYZER_CHECK_METHOD(_, __, nodeType, ___) \
36     virtual checker::Type *Check(ir::nodeType *node) const override;  // CC-OFF(G.PRE.02,G.PRE.09) name part
37     AST_NODE_REINTERPRET_MAPPING(DECLARE_ETSANALYZER_CHECK_METHOD)
38 #undef DECLARE_ETSANALYZER_CHECK_METHOD
39     checker::Type *PreferredType(ir::ObjectExpression *expr) const;
40     checker::Type *CheckDynamic(ir::ObjectExpression *expr) const;
41     checker::Type *GetPreferredType(ir::ArrayExpression *expr) const;
42     void GetUnionPreferredType(ir::ArrayExpression *expr) const;
43     void CheckObjectExprProps(const ir::ObjectExpression *expr, checker::PropertySearchFlags searchFlags) const;
44     std::tuple<Type *, ir::Expression *> CheckAssignmentExprOperatorType(ir::AssignmentExpression *expr,
45                                                                          Type *leftType) const;
46 
47 private:
48     ETSChecker *GetETSChecker() const;
49     void CheckInstantatedClass(ir::ETSNewClassInstanceExpression *expr, ETSObjectType *&calleeObj) const;
50     void CheckMethodModifiers(ir::MethodDefinition *node) const;
51     checker::Signature *ResolveSignature(ETSChecker *checker, ir::CallExpression *expr, checker::Type *calleeType,
52                                          bool isFunctionalInterface, bool isUnionTypeWithFunctionalInterface) const;
53     checker::Type *GetReturnType(ir::CallExpression *expr, checker::Type *calleeType) const;
54     checker::Type *GetFunctionReturnType(ir::ReturnStatement *st, ir::ScriptFunction *containingFunc) const;
55     checker::Type *GetCallExpressionReturnType(ir::CallExpression *expr, checker::Type *calleeType) const;
56     checker::Type *UnwrapPromiseType(checker::Type *type) const;
57     checker::Type *GetSmartType(ir::AssignmentExpression *expr, checker::Type *leftType,
58                                 checker::Type *rightType) const;
59     bool CheckInferredFunctionReturnType(ir::ReturnStatement *st, ir::ScriptFunction *containingFunc,
60                                          checker::Type *&funcReturnType, ir::TypeNode *returnTypeAnnotation,
61                                          ETSChecker *checker) const;
62     void CheckClassProperty(ETSChecker *checker, ir::ScriptFunction *scriptFunc) const;
GetCalleeType(ETSChecker * checker,ir::ETSNewClassInstanceExpression * expr)63     checker::Type *GetCalleeType(ETSChecker *checker, ir::ETSNewClassInstanceExpression *expr) const
64     {
65         checker::Type *calleeType = expr->GetTypeRef()->Check(checker);
66         if (calleeType->IsTypeError()) {
67             expr->GetTypeRef()->SetTsType(checker->GlobalTypeError());
68             return checker->GlobalTypeError();
69         }
70 
71         if (!calleeType->IsETSObjectType()) {
72             checker->LogTypeError("This expression is not constructible.", expr->Start());
73             expr->GetTypeRef()->SetTsType(checker->GlobalTypeError());
74             return checker->GlobalTypeError();
75         }
76 
77         return calleeType;
78     }
79 
80     checker::Type *CheckEnumMemberExpression(ETSEnumType *const baseType, ir::MemberExpression *const expr) const;
81 
CheckVoidTypeExpression(ETSChecker * checker,const ir::Expression * expr)82     void CheckVoidTypeExpression(ETSChecker *checker, const ir::Expression *expr) const
83     {
84         // Existing void expression inconsistency,refer to #17762
85         if (expr->TsType() == nullptr || !expr->TsType()->IsETSVoidType() || expr->Parent() == nullptr) {
86             return;
87         }
88         auto parent = expr->Parent();
89         while (parent->IsConditionalExpression()) {
90             parent = parent->Parent();
91             if (parent == nullptr) {
92                 return;
93             }
94         }
95         bool acceptVoid = parent->IsExpressionStatement() || parent->IsReturnStatement() ||
96                           parent->IsETSLaunchExpression() || parent->IsCallExpression();
97         if (!acceptVoid) {
98             checker->LogTypeError({"Cannot use type 'void' as value. "}, expr->Start());
99         }
100     }
101 };
102 
103 }  // namespace ark::es2panda::checker
104 
105 #endif  // ES2PANDA_CHECKER_ETSANALYZER_H
106