1/**
2 * Copyright (c) 2021 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_PARSER_INCLUDE_AST_METHOD_DEFINITION_H
17#define ES2PANDA_PARSER_INCLUDE_AST_METHOD_DEFINITION_H
18
19#include <ir/statement.h>
20#include <ir/expression.h>
21
22namespace panda::es2panda::compiler {
23class PandaGen;
24}  // namespace panda::es2panda::compiler
25
26namespace panda::es2panda::checker {
27class Checker;
28class Type;
29}  // namespace panda::es2panda::checker
30
31namespace panda::es2panda::ir {
32
33class FunctionExpression;
34
35enum class MethodDefinitionKind { CONSTRUCTOR, METHOD, GET, SET };
36
37struct ParamDecorators {
38    size_t paramIndex;
39    ArenaVector<Decorator *> decorators;
40};
41
42class MethodDefinition : public Statement {
43public:
44    explicit MethodDefinition(MethodDefinitionKind kind, Expression *key, FunctionExpression *value,
45                              ModifierFlags modifiers, ArenaAllocator *allocator, ArenaVector<Decorator *> &&decorators,
46                              ArenaVector<Annotation *> &&annotations, ArenaVector<ParamDecorators> &&paramDecorators,
47                              bool isComputed)
48        : Statement(AstNodeType::METHOD_DEFINITION),
49          kind_(kind),
50          key_(key),
51          value_(value),
52          modifiers_(modifiers),
53          overloads_(allocator->Adapter()),
54          decorators_(std::move(decorators)),
55          annotations_(std::move(annotations)),
56          paramDecorators_(std::move(paramDecorators)),
57          isComputed_(isComputed)
58    {
59    }
60
61    MethodDefinitionKind Kind() const
62    {
63        return kind_;
64    }
65
66    ModifierFlags Modifiers() const
67    {
68        return modifiers_;
69    }
70
71    const Expression *Key() const
72    {
73        return key_;
74    }
75
76    Expression *Key()
77    {
78        return key_;
79    }
80
81    void SetKey(Expression *key)
82    {
83        key_ = key;
84    }
85
86    const FunctionExpression *Value() const
87    {
88        return value_;
89    }
90
91    bool Computed() const
92    {
93        return isComputed_;
94    }
95
96    bool IsAbstract() const
97    {
98        return (modifiers_ & ModifierFlags::ABSTRACT) != 0;
99    }
100
101    bool IsStatic() const
102    {
103        return (modifiers_ & ModifierFlags::STATIC) != 0;
104    }
105
106    bool IsAccessor() const
107    {
108        return (kind_ == MethodDefinitionKind::GET) || (kind_ == MethodDefinitionKind::SET);
109    }
110
111    bool IsOptional() const
112    {
113        return (modifiers_ & ModifierFlags::OPTIONAL) != 0;
114    }
115
116    bool IsPrivate() const
117    {
118        return key_->IsPrivateIdentifier();
119    }
120
121    const ArenaVector<MethodDefinition *> &Overloads() const
122    {
123        return overloads_;
124    }
125
126    const ArenaVector<Decorator *> &Decorators() const
127    {
128        return decorators_;
129    }
130
131    const ArenaVector<Annotation *> &Annotations() const
132    {
133        return annotations_;
134    }
135
136    void SetAnnotations(ArenaVector<Annotation *> &&annotations)
137    {
138        annotations_ = std::move(annotations);
139    }
140
141    const ArenaVector<ParamDecorators> &GetParamDecorators() const
142    {
143        return paramDecorators_;
144    }
145
146    bool HasParamDecorators() const
147    {
148        return !paramDecorators_.empty();
149    }
150
151    bool HasDecorators() const
152    {
153        return !decorators_.empty();
154    }
155
156    void SetOverloads(ArenaVector<MethodDefinition *> &&overloads)
157    {
158        overloads_ = std::move(overloads);
159    }
160
161    void AddOverload(MethodDefinition *overload)
162    {
163        overloads_.push_back(overload);
164    }
165
166    void SetKeyReg(compiler::VReg keyReg)
167    {
168        keyReg_ = keyReg;
169    }
170
171    compiler::VReg KeyReg() const
172    {
173        return keyReg_;
174    }
175
176    const ScriptFunction *Function() const;
177
178    ScriptFunction *Function();
179
180    void Iterate(const NodeTraverser &cb) const override;
181    void Dump(ir::AstDumper *dumper) const override;
182    void Compile([[maybe_unused]] compiler::PandaGen *pg) const override;
183    checker::Type *Check([[maybe_unused]] checker::Checker *checker) const override;
184    void UpdateSelf(const NodeUpdater &cb, [[maybe_unused]] binder::Binder *binder) override;
185
186private:
187    MethodDefinitionKind kind_;
188    Expression *key_;
189    compiler::VReg keyReg_ {0};
190    FunctionExpression *value_;
191    ModifierFlags modifiers_;
192    ArenaVector<MethodDefinition *> overloads_;
193    ArenaVector<Decorator *> decorators_;
194    ArenaVector<Annotation *> annotations_;
195    ArenaVector<ParamDecorators> paramDecorators_;
196    bool isComputed_;
197};
198
199}  // namespace panda::es2panda::ir
200
201#endif
202