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_H
17#define ES2PANDA_IR_EXPRESSION_H
18
19#include "ir/astNode.h"
20#include "ir/typed.h"
21
22namespace ark::es2panda::ir {
23class Literal;
24class TypeNode;
25class AnnotatedExpression;
26
27class Expression : public TypedAstNode {
28public:
29    Expression() = delete;
30    ~Expression() override = default;
31
32    NO_COPY_OPERATOR(Expression);
33    NO_MOVE_SEMANTIC(Expression);
34
35    [[nodiscard]] bool IsGrouped() const noexcept
36    {
37        return grouped_;
38    }
39
40    void SetGrouped() noexcept
41    {
42        grouped_ = true;
43    }
44
45    [[nodiscard]] const Literal *AsLiteral() const
46    {
47        ASSERT(IsLiteral());
48        return reinterpret_cast<const Literal *>(this);
49    }
50
51    [[nodiscard]] Literal *AsLiteral()
52    {
53        ASSERT(IsLiteral());
54        return reinterpret_cast<Literal *>(this);
55    }
56
57    [[nodiscard]] virtual bool IsLiteral() const noexcept
58    {
59        return false;
60    }
61
62    [[nodiscard]] virtual bool IsTypeNode() const noexcept
63    {
64        return false;
65    }
66
67    [[nodiscard]] virtual bool IsAnnotatedExpression() const noexcept
68    {
69        return false;
70    }
71
72    [[nodiscard]] bool IsExpression() const noexcept override
73    {
74        return true;
75    }
76
77    [[nodiscard]] TypeNode *AsTypeNode()
78    {
79        ASSERT(IsTypeNode());
80        return reinterpret_cast<TypeNode *>(this);
81    }
82
83    [[nodiscard]] const TypeNode *AsTypeNode() const
84    {
85        ASSERT(IsTypeNode());
86        return reinterpret_cast<const TypeNode *>(this);
87    }
88
89    [[nodiscard]] AnnotatedExpression *AsAnnotatedExpression()
90    {
91        ASSERT(IsAnnotatedExpression());
92        return reinterpret_cast<AnnotatedExpression *>(this);
93    }
94
95    [[nodiscard]] const AnnotatedExpression *AsAnnotatedExpression() const
96    {
97        ASSERT(IsAnnotatedExpression());
98        return reinterpret_cast<const AnnotatedExpression *>(this);
99    }
100
101protected:
102    explicit Expression(AstNodeType const type) : TypedAstNode(type) {}
103    explicit Expression(AstNodeType const type, ModifierFlags const flags) : TypedAstNode(type, flags) {}
104
105    Expression(Expression const &other) : TypedAstNode(static_cast<TypedAstNode const &>(other))
106    {
107        grouped_ = other.grouped_;
108    }
109
110private:
111    bool grouped_ {};
112};
113
114class AnnotatedExpression : public Annotated<Expression> {
115public:
116    AnnotatedExpression() = delete;
117    ~AnnotatedExpression() override = default;
118
119    NO_COPY_SEMANTIC(AnnotatedExpression);
120    NO_MOVE_SEMANTIC(AnnotatedExpression);
121
122    [[nodiscard]] bool IsAnnotatedExpression() const noexcept override
123    {
124        return true;
125    }
126
127protected:
128    explicit AnnotatedExpression(AstNodeType const type, TypeNode *const typeAnnotation)
129        : Annotated<Expression>(type, typeAnnotation)
130    {
131    }
132    explicit AnnotatedExpression(AstNodeType const type) : Annotated<Expression>(type) {}
133
134    explicit AnnotatedExpression(AnnotatedExpression const &other, ArenaAllocator *allocator);
135};
136
137class MaybeOptionalExpression : public Expression {
138public:
139    MaybeOptionalExpression() = delete;
140    ~MaybeOptionalExpression() override = default;
141
142    NO_COPY_OPERATOR(MaybeOptionalExpression);
143    NO_MOVE_SEMANTIC(MaybeOptionalExpression);
144
145    [[nodiscard]] bool IsOptional() const noexcept
146    {
147        return optional_;
148    }
149
150    void ClearOptional() noexcept
151    {
152        optional_ = false;
153    }
154
155protected:
156    explicit MaybeOptionalExpression(AstNodeType type, bool optional) : Expression(type), optional_(optional) {}
157    explicit MaybeOptionalExpression(AstNodeType type, ModifierFlags flags, bool optional)
158        : Expression(type, flags), optional_(optional)
159    {
160    }
161
162    MaybeOptionalExpression(MaybeOptionalExpression const &other) : Expression(static_cast<Expression const &>(other))
163    {
164        optional_ = other.optional_;
165    }
166
167private:
168    bool optional_;
169};
170
171}  // namespace ark::es2panda::ir
172
173#endif /* ES2PANDA_IR_EXPRESSION_H */
174