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_ARRAY_EXPRESSION_H
17#define ES2PANDA_IR_EXPRESSION_ARRAY_EXPRESSION_H
18
19#include "ir/expression.h"
20#include "ir/validationInfo.h"
21#include "checker/types/ets/etsArrayType.h"
22
23namespace ark::es2panda::checker {
24class ETSAnalyzer;
25}  // namespace ark::es2panda::checker
26namespace ark::es2panda::compiler {
27class ETSCompiler;
28}  // namespace ark::es2panda::compiler
29namespace ark::es2panda::ir {
30class ArrayExpression : public AnnotatedExpression {
31private:
32    struct Tag {};
33
34public:
35    ArrayExpression() = delete;
36    ~ArrayExpression() override = default;
37
38    NO_COPY_SEMANTIC(ArrayExpression);
39    NO_MOVE_SEMANTIC(ArrayExpression);
40
41public:
42    explicit ArrayExpression(ArenaVector<Expression *> &&elements, ArenaAllocator *const allocator)
43        : ArrayExpression(AstNodeType::ARRAY_EXPRESSION, std::move(elements), allocator, false)
44    {
45    }
46
47    explicit ArrayExpression(AstNodeType nodeType, ArenaVector<Expression *> &&elements,
48                             ArenaAllocator *const allocator, bool const trailingComma)
49        : AnnotatedExpression(nodeType),
50          decorators_(allocator->Adapter()),
51          elements_(std::move(elements)),
52          trailingComma_(trailingComma)
53    {
54    }
55
56    explicit ArrayExpression(Tag tag, ArrayExpression const &other, ArenaAllocator *allocator);
57
58    // NOTE (vivienvoros): these friend relationships can be removed once there are getters for private fields
59    friend class checker::ETSAnalyzer;
60    friend class compiler::ETSCompiler;
61
62    [[nodiscard]] const ArenaVector<Expression *> &Elements() const noexcept
63    {
64        return elements_;
65    }
66
67    [[nodiscard]] ArenaVector<Expression *> &Elements() noexcept
68    {
69        return elements_;
70    }
71
72    void SetElements(ArenaVector<Expression *> &&elements) noexcept
73    {
74        elements_ = std::move(elements);
75    }
76
77    [[nodiscard]] bool IsDeclaration() const noexcept
78    {
79        return isDeclaration_;
80    }
81
82    [[nodiscard]] bool IsOptional() const noexcept
83    {
84        return optional_;
85    }
86
87    void SetDeclaration() noexcept
88    {
89        isDeclaration_ = true;
90    }
91
92    void SetOptional(bool optional) noexcept
93    {
94        optional_ = optional;
95    }
96
97    void SetPreferredType(checker::Type *preferredType) noexcept
98    {
99        preferredType_ = preferredType;
100    }
101
102    [[nodiscard]] checker::Type *GetPreferredType() noexcept
103    {
104        return preferredType_;
105    }
106
107    [[nodiscard]] checker::Type const *GetPreferredType() const noexcept
108    {
109        return preferredType_;
110    }
111
112    [[nodiscard]] const ArenaVector<Decorator *> &Decorators() const noexcept
113    {
114        return decorators_;
115    }
116
117    const ArenaVector<Decorator *> *DecoratorsPtr() const override
118    {
119        return &Decorators();
120    }
121
122    void AddDecorators([[maybe_unused]] ArenaVector<ir::Decorator *> &&decorators) override
123    {
124        decorators_ = std::move(decorators);
125    }
126
127    bool CanHaveDecorator([[maybe_unused]] bool inTs) const override
128    {
129        return true;
130    }
131
132    [[nodiscard]] ArrayExpression *Clone(ArenaAllocator *allocator, AstNode *parent) override;
133
134    [[nodiscard]] bool ConvertibleToArrayPattern();
135    [[nodiscard]] ValidationInfo ValidateExpression();
136    void TransformChildren(const NodeTransformer &cb, std::string_view transformationName) override;
137    void Iterate(const NodeTraverser &cb) const override;
138    void Dump(ir::AstDumper *dumper) const override;
139    void Dump(ir::SrcDumper *dumper) const override;
140    void Compile(compiler::PandaGen *pg) const override;
141    void Compile(compiler::ETSGen *etsg) const override;
142    checker::Type *Check(checker::TSChecker *checker) override;
143    checker::Type *Check(checker::ETSChecker *checker) override;
144    checker::Type *CheckPattern(checker::TSChecker *checker);
145    bool HandleNestedArrayExpression(checker::ETSChecker *checker, ArrayExpression *currentElement,
146                                     bool isPreferredTuple, std::size_t idx);
147
148    void Accept(ASTVisitorT *v) override
149    {
150        v->Accept(this);
151    }
152
153    void GetPrefferedTypeFromFuncParam(checker::ETSChecker *checker, Expression *param,
154                                       checker::TypeRelationFlag flags);
155
156private:
157    ArenaVector<Decorator *> decorators_;
158    ArenaVector<Expression *> elements_;
159    checker::Type *preferredType_ {};
160    bool isDeclaration_ {};
161    bool trailingComma_ {};
162    bool optional_ {};
163};
164}  // namespace ark::es2panda::ir
165
166#endif
167