1 /**
2 * Copyright (c) 2024-2025 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 #include "lowering_test.h"
17 #include "compiler/lowering/ets/constantExpressionLowering.h"
18
19 namespace ark::es2panda {
20
21 template <typename T, T EXPECT_VAL>
CheckNumberLiteral(const ir::AstNode * node)22 static bool CheckNumberLiteral(const ir::AstNode *node)
23 {
24 if (node->IsNumberLiteral()) {
25 auto numNode = node->AsNumberLiteral()->Number();
26 if (numNode.CanGetValue<T>()) {
27 return numNode.GetValue<T>() == EXPECT_VAL;
28 }
29 }
30 return false;
31 }
32
TEST_F(LoweringTest,TestConstantExpressionConcatExtendedBoolean1)33 TEST_F(LoweringTest, TestConstantExpressionConcatExtendedBoolean1)
34 {
35 char const *text = R"(
36 @interface MyAnno {
37 a : int
38 c : int
39 d : int
40 }
41 @MyAnno({a = null ? 1 : 0, c = "a" ? 5 : 4, d = 12 ? 7 : 6})
42 function main() {}
43 )";
44
45 int const expectA = 0;
46 int const expectC = 5;
47 int const expectD = 7;
48 CONTEXT(ES2PANDA_STATE_CHECKED, text)
49 {
50 const auto *const ast = GetAst();
51 ASSERT_FALSE(ast->IsAnyChild([](ir::AstNode *const node) {
52 return node->IsBinaryExpression() || node->IsUnaryExpression() || node->IsConditionalExpression();
53 }));
54
55 ASSERT_TRUE(
56 ast->IsAnyChild([](ir::AstNode *const node) { return CheckNumberLiteral<int32_t, expectA>(node); }));
57
58 ASSERT_TRUE(
59 ast->IsAnyChild([](ir::AstNode *const node) { return CheckNumberLiteral<int32_t, expectC>(node); }));
60
61 ASSERT_TRUE(
62 ast->IsAnyChild([](ir::AstNode *const node) { return CheckNumberLiteral<int32_t, expectD>(node); }));
63 }
64 }
65
TEST_F(LoweringTest,TestConstantExpressionConcatExtendedBoolean2)66 TEST_F(LoweringTest, TestConstantExpressionConcatExtendedBoolean2)
67 {
68 char const *text = R"(
69 @interface MyAnno {
70 a : int
71 c : int
72 d : int
73 }
74 @MyAnno({a = undefined ? 1 : 0, c = "" ? 5 : 4, d = 0 ? 7 : 6})
75 function main() {}
76 )";
77
78 int const expectA = 0;
79 int const expectC = 4;
80 int const expectD = 6;
81 CONTEXT(ES2PANDA_STATE_CHECKED, text)
82 {
83 const auto *const ast = GetAst();
84 ASSERT_FALSE(ast->IsAnyChild([](ir::AstNode *const node) {
85 return node->IsBinaryExpression() || node->IsUnaryExpression() || node->IsConditionalExpression();
86 }));
87
88 ASSERT_TRUE(
89 ast->IsAnyChild([](ir::AstNode *const node) { return CheckNumberLiteral<int32_t, expectA>(node); }));
90
91 ASSERT_TRUE(
92 ast->IsAnyChild([](ir::AstNode *const node) { return CheckNumberLiteral<int32_t, expectC>(node); }));
93
94 ASSERT_TRUE(
95 ast->IsAnyChild([](ir::AstNode *const node) { return CheckNumberLiteral<int32_t, expectD>(node); }));
96 }
97 }
98
TEST_F(LoweringTest,TestConstantExpressionConcatExtendedBoolean4)99 TEST_F(LoweringTest, TestConstantExpressionConcatExtendedBoolean4)
100 {
101 char const *text = R"(
102 @interface MyAnno {
103 a : boolean
104 b : int = "aaa" ? 1 : 2
105 }
106 @MyAnno({a = ((("aa" >= "aa") && ("ab" < "aa")) || ("aa" != "bb")) && "aa!" == "aa!"})
107 function main() {}
108 )";
109
110 bool const expectA = true;
111 int const expectB = 1;
112 CONTEXT(ES2PANDA_STATE_CHECKED, text)
113 {
114 const auto *const ast = GetAst();
115
116 ASSERT_FALSE(ast->IsAnyChild([](ir::AstNode *const node) {
117 return node->IsBinaryExpression() || node->IsUnaryExpression() || node->IsConditionalExpression();
118 }));
119
120 ASSERT_TRUE(ast->IsAnyChild([](ir::AstNode *const node) {
121 return node->IsBooleanLiteral() && node->AsBooleanLiteral()->Value() == expectA;
122 }));
123
124 ASSERT_TRUE(
125 ast->IsAnyChild([](ir::AstNode *const node) { return CheckNumberLiteral<int32_t, expectB>(node); }));
126 }
127 }
128
TEST_F(LoweringTest,TestConstantExpressionConcatExtendedBoolean3)129 TEST_F(LoweringTest, TestConstantExpressionConcatExtendedBoolean3)
130 {
131 char const *text = R"(
132 @interface MyAnno {
133 a : int
134 b : int
135 }
136 @MyAnno({a = !null ? 10 : 20, b= "test" && !undefined ? 1 : 2})
137 function main() {}
138 )";
139
140 int const expectA = 10;
141 int const expectB = 1;
142 CONTEXT(ES2PANDA_STATE_CHECKED, text)
143 {
144 const auto *const ast = GetAst();
145
146 ASSERT_FALSE(ast->IsAnyChild([](ir::AstNode *const node) {
147 return node->IsBinaryExpression() || node->IsUnaryExpression() || node->IsConditionalExpression();
148 }));
149
150 ASSERT_TRUE(
151 ast->IsAnyChild([](ir::AstNode *const node) { return CheckNumberLiteral<int32_t, expectA>(node); }));
152
153 ASSERT_TRUE(
154 ast->IsAnyChild([](ir::AstNode *const node) { return CheckNumberLiteral<int32_t, expectB>(node); }));
155 }
156 }
TEST_F(LoweringTest,TestConstantExpressionConcat)157 TEST_F(LoweringTest, TestConstantExpressionConcat)
158 {
159 char const *text = R"(
160 @interface MyAnno {
161 a : int
162 b : long
163 c : boolean
164 d : int
165 }
166 @MyAnno({a = 1 + -1, b = 1554.4 ^ 10, c = 12 >= 10, d = 15 != 10 ? 1+4 : 5+1})
167 function main() {}
168 )";
169 int const expectA = 0;
170 int64_t const expectB = 1560;
171 bool const expectC = true;
172 int const expectD = 5;
173
174 CONTEXT(ES2PANDA_STATE_CHECKED, text)
175 {
176 const auto *const ast = GetAst();
177
178 ASSERT_FALSE(ast->IsAnyChild([](ir::AstNode *const node) {
179 return node->IsBinaryExpression() || node->IsUnaryExpression() || node->IsConditionalExpression();
180 }));
181
182 ASSERT_TRUE(
183 ast->IsAnyChild([](ir::AstNode *const node) { return CheckNumberLiteral<int32_t, expectA>(node); }));
184
185 ASSERT_TRUE(
186 ast->IsAnyChild([](ir::AstNode *const node) { return CheckNumberLiteral<int64_t, expectB>(node); }));
187
188 ASSERT_TRUE(ast->IsAnyChild([](ir::AstNode *const node) {
189 return node->IsBooleanLiteral() && node->AsBooleanLiteral()->Value() == expectC;
190 }));
191
192 ASSERT_TRUE(
193 ast->IsAnyChild([](ir::AstNode *const node) { return CheckNumberLiteral<int32_t, expectD>(node); }));
194 }
195 }
196
TEST_F(LoweringTest,TestConstantExpressionConcatNumeric1)197 TEST_F(LoweringTest, TestConstantExpressionConcatNumeric1)
198 {
199 char const *text = R"(
200 @interface MyAnno {
201 a : int = 1+1
202 }
203 @MyAnno()
204 function main() {}
205 )";
206
207 int32_t const expectA = 2;
208 CONTEXT(ES2PANDA_STATE_CHECKED, text)
209 {
210 const auto *const ast = GetAst();
211
212 ASSERT_FALSE(ast->IsAnyChild([](ir::AstNode *const node) {
213 return node->IsBinaryExpression() || node->IsUnaryExpression() || node->IsConditionalExpression();
214 }));
215
216 ASSERT_TRUE(
217 ast->IsAnyChild([](ir::AstNode *const node) { return CheckNumberLiteral<int32_t, expectA>(node); }));
218 }
219 }
220
TEST_F(LoweringTest,TestConstantExpressionConcatBoolean)221 TEST_F(LoweringTest, TestConstantExpressionConcatBoolean)
222 {
223 char const *text = R"(
224 @interface MyAnno {
225 a : boolean
226 }
227 @MyAnno({a = ((20<=10) || true) ? !false && (10==10) && (30 != 10): false})
228 function main() {}
229 )";
230
231 bool const expectA = true;
232 CONTEXT(ES2PANDA_STATE_CHECKED, text)
233 {
234 const auto *const ast = GetAst();
235
236 ASSERT_FALSE(ast->IsAnyChild([](ir::AstNode *const node) {
237 return node->IsBinaryExpression() || node->IsUnaryExpression() || node->IsConditionalExpression();
238 }));
239
240 ASSERT_TRUE(ast->IsAnyChild([](ir::AstNode *const node) {
241 return node->IsBooleanLiteral() && node->AsBooleanLiteral()->Value() == expectA;
242 }));
243 }
244 }
245
TEST_F(LoweringTest,TestConstantExpressionConcatNumeric)246 TEST_F(LoweringTest, TestConstantExpressionConcatNumeric)
247 {
248 char const *text = R"(
249 @interface MyAnno {
250 a : long
251 }
252 @MyAnno({a = ((((1 + -1 + 10) * 123 / 5) ^ (~10.2) << 1) >> 2.6 >>> 33 & 141 | 12) % 53})
253 function main() {}
254 )";
255
256 int64_t const expectA = 35;
257 CONTEXT(ES2PANDA_STATE_CHECKED, text)
258 {
259 const auto *const ast = GetAst();
260 ASSERT_FALSE(ast->IsAnyChild([](ir::AstNode *const node) {
261 return node->IsBinaryExpression() || node->IsUnaryExpression() || node->IsConditionalExpression();
262 }));
263
264 ASSERT_TRUE(
265 ast->IsAnyChild([](ir::AstNode *const node) { return CheckNumberLiteral<int64_t, expectA>(node); }));
266 }
267 }
268 } // namespace ark::es2panda
269