• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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