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 
22 namespace ark::es2panda::ir {
23 class Literal;
24 class TypeNode;
25 class AnnotatedExpression;
26 
27 class Expression : public TypedAstNode {
28 public:
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 
AsLiteral() const45     [[nodiscard]] const Literal *AsLiteral() const
46     {
47         ASSERT(IsLiteral());
48         return reinterpret_cast<const Literal *>(this);
49     }
50 
AsLiteral()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 
AsTypeNode()77     [[nodiscard]] TypeNode *AsTypeNode()
78     {
79         ASSERT(IsTypeNode());
80         return reinterpret_cast<TypeNode *>(this);
81     }
82 
AsTypeNode() const83     [[nodiscard]] const TypeNode *AsTypeNode() const
84     {
85         ASSERT(IsTypeNode());
86         return reinterpret_cast<const TypeNode *>(this);
87     }
88 
AsAnnotatedExpression()89     [[nodiscard]] AnnotatedExpression *AsAnnotatedExpression()
90     {
91         ASSERT(IsAnnotatedExpression());
92         return reinterpret_cast<AnnotatedExpression *>(this);
93     }
94 
AsAnnotatedExpression() const95     [[nodiscard]] const AnnotatedExpression *AsAnnotatedExpression() const
96     {
97         ASSERT(IsAnnotatedExpression());
98         return reinterpret_cast<const AnnotatedExpression *>(this);
99     }
100 
101 protected:
Expression(AstNodeType const type)102     explicit Expression(AstNodeType const type) : TypedAstNode(type) {}
Expression(AstNodeType const type, ModifierFlags const flags)103     explicit Expression(AstNodeType const type, ModifierFlags const flags) : TypedAstNode(type, flags) {}
104 
Expression(Expression const &other)105     Expression(Expression const &other) : TypedAstNode(static_cast<TypedAstNode const &>(other))
106     {
107         grouped_ = other.grouped_;
108     }
109 
110 private:
111     bool grouped_ {};
112 };
113 
114 class AnnotatedExpression : public Annotated<Expression> {
115 public:
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 
127 protected:
AnnotatedExpression(AstNodeType const type, TypeNode *const typeAnnotation)128     explicit AnnotatedExpression(AstNodeType const type, TypeNode *const typeAnnotation)
129         : Annotated<Expression>(type, typeAnnotation)
130     {
131     }
AnnotatedExpression(AstNodeType const type)132     explicit AnnotatedExpression(AstNodeType const type) : Annotated<Expression>(type) {}
133 
134     explicit AnnotatedExpression(AnnotatedExpression const &other, ArenaAllocator *allocator);
135 };
136 
137 class MaybeOptionalExpression : public Expression {
138 public:
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 
155 protected:
MaybeOptionalExpression(AstNodeType type, bool optional)156     explicit MaybeOptionalExpression(AstNodeType type, bool optional) : Expression(type), optional_(optional) {}
MaybeOptionalExpression(AstNodeType type, ModifierFlags flags, bool optional)157     explicit MaybeOptionalExpression(AstNodeType type, ModifierFlags flags, bool optional)
158         : Expression(type, flags), optional_(optional)
159     {
160     }
161 
MaybeOptionalExpression(MaybeOptionalExpression const &other)162     MaybeOptionalExpression(MaybeOptionalExpression const &other) : Expression(static_cast<Expression const &>(other))
163     {
164         optional_ = other.optional_;
165     }
166 
167 private:
168     bool optional_;
169 };
170 
171 }  // namespace ark::es2panda::ir
172 
173 #endif /* ES2PANDA_IR_EXPRESSION_H */
174