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_IR_EXPRESSION_CALL_EXPRESSION_H
17 #define ES2PANDA_IR_EXPRESSION_CALL_EXPRESSION_H
18 
19 #include "varbinder/variable.h"
20 #include "ir/expression.h"
21 
22 namespace ark::es2panda::checker {
23 class ETSAnalyzer;
24 class TSAnalyzer;
25 class Signature;
26 }  // namespace ark::es2panda::checker
27 
28 namespace ark::es2panda::compiler {
29 class JSCompiler;
30 class ETSCompiler;
31 }  // namespace ark::es2panda::compiler
32 
33 namespace ark::es2panda::ir {
34 class TSTypeParameterInstantiation;
35 
36 class CallExpression : public MaybeOptionalExpression {
37 public:
38     CallExpression() = delete;
39     ~CallExpression() override = default;
40 
41     NO_COPY_SEMANTIC(CallExpression);
42     NO_MOVE_SEMANTIC(CallExpression);
43 
CallExpression(Expression *const callee, ArenaVector<Expression *> &&arguments, TSTypeParameterInstantiation *const typeParams, bool const optional, bool const trailingComma = false)44     explicit CallExpression(Expression *const callee, ArenaVector<Expression *> &&arguments,
45                             TSTypeParameterInstantiation *const typeParams, bool const optional,
46                             bool const trailingComma = false)
47         : MaybeOptionalExpression(AstNodeType::CALL_EXPRESSION, optional),
48           callee_(callee),
49           arguments_(std::move(arguments)),
50           typeParams_(typeParams),
51           trailingComma_(trailingComma)
52     {
53     }
54 
55     explicit CallExpression(CallExpression const &other, ArenaAllocator *allocator);
56 
57     // NOTE (csabahurton): these friend relationships can be removed once there are getters for private fields
58     friend class checker::TSAnalyzer;
59     friend class checker::ETSAnalyzer;
60     friend class compiler::JSCompiler;
61     friend class compiler::ETSCompiler;
62 
Callee() const63     const Expression *Callee() const
64     {
65         return callee_;
66     }
67 
68     [[nodiscard]] Expression *Callee() noexcept
69     {
70         return callee_;
71     }
72 
73     void SetCallee(Expression *callee) noexcept
74     {
75         callee_ = callee;
76         callee_->SetParent(this);
77     }
78 
79     [[nodiscard]] const TSTypeParameterInstantiation *TypeParams() const noexcept
80     {
81         return typeParams_;
82     }
83 
84     [[nodiscard]] TSTypeParameterInstantiation *TypeParams() noexcept
85     {
86         return typeParams_;
87     }
88 
89     [[nodiscard]] const ArenaVector<Expression *> &Arguments() const noexcept
90     {
91         return arguments_;
92     }
93 
94     [[nodiscard]] ArenaVector<Expression *> &Arguments() noexcept
95     {
96         return arguments_;
97     }
98 
99     [[nodiscard]] bool HasTrailingComma() const noexcept
100     {
101         return trailingComma_;
102     }
103 
104     [[nodiscard]] checker::Signature *Signature() noexcept
105     {
106         return signature_;
107     }
108 
109     [[nodiscard]] checker::Signature *Signature() const noexcept
110     {
111         return signature_;
112     }
113 
114     void SetSignature(checker::Signature *const signature) noexcept
115     {
116         signature_ = signature;
117     }
118 
119     void SetTypeParams(TSTypeParameterInstantiation *typeParams) noexcept;
120 
121     [[nodiscard]] checker::Type *UncheckedType() const noexcept
122     {
123         return uncheckedType_;
124     }
125 
126     void SetUncheckedType(checker::Type *type) noexcept
127     {
128         uncheckedType_ = type;
129     }
130 
131     void SetTrailingBlock(ir::BlockStatement *const block) noexcept;
132 
133     [[nodiscard]] ir::BlockStatement *TrailingBlock() const noexcept
134     {
135         return trailingBlock_;
136     }
137 
138     void SetIsTrailingBlockInNewLine(bool const isNewLine) noexcept
139     {
140         isTrailingBlockInNewLine_ = isNewLine;
141     }
142 
143     [[nodiscard]] bool IsTrailingBlockInNewLine() const noexcept
144     {
145         return isTrailingBlockInNewLine_;
146     }
147 
148     [[nodiscard]] CallExpression *Clone(ArenaAllocator *allocator, AstNode *parent) override;
149 
150     void TransformChildren(const NodeTransformer &cb, std::string_view transformationName) override;
151     void Iterate(const NodeTraverser &cb) const override;
152 
153     void Dump(ir::AstDumper *dumper) const override;
154     void Dump(ir::SrcDumper *dumper) const override;
155     void Compile(compiler::PandaGen *pg) const override;
156     void Compile(compiler::ETSGen *etsg) const override;
157     checker::Type *Check(checker::TSChecker *checker) override;
158     checker::Type *Check(checker::ETSChecker *checker) override;
159 
160     void Accept(ASTVisitorT *v) override
161     {
162         v->Accept(this);
163     }
164 
165 protected:
166     // NOLINTBEGIN(misc-non-private-member-variables-in-classes)
167     Expression *callee_;
168     ArenaVector<Expression *> arguments_;
169     TSTypeParameterInstantiation *typeParams_;
170     checker::Signature *signature_ {};
171     bool trailingComma_;
172     // for trailing lambda feature in ets
173     ir::BlockStatement *trailingBlock_ {};
174     bool isTrailingBlockInNewLine_ {false};
175     checker::Type *uncheckedType_ {};
176     // NOLINTEND(misc-non-private-member-variables-in-classes)
177 
178 private:
179     bool IsETSConstructorCall() const;
180     checker::Type *InitAnonymousLambdaCallee(checker::ETSChecker *checker, Expression *callee,
181                                              checker::Type *calleeType);
182 };
183 }  // namespace ark::es2panda::ir
184 
185 #endif
186