/** * Copyright (c) 2024-2025 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "lowering_test.h" #include "compiler/lowering/ets/constantExpressionLowering.h" namespace ark::es2panda { template static bool CheckNumberLiteral(const ir::AstNode *node) { if (node->IsNumberLiteral()) { auto numNode = node->AsNumberLiteral()->Number(); if (numNode.CanGetValue()) { return numNode.GetValue() == EXPECT_VAL; } } return false; } TEST_F(LoweringTest, TestConstantExpressionConcatExtendedBoolean1) { char const *text = R"( @interface MyAnno { a : int c : int d : int } @MyAnno({a = null ? 1 : 0, c = "a" ? 5 : 4, d = 12 ? 7 : 6}) function main() {} )"; int const expectA = 0; int const expectC = 5; int const expectD = 7; CONTEXT(ES2PANDA_STATE_CHECKED, text) { const auto *const ast = GetAst(); ASSERT_FALSE(ast->IsAnyChild([](ir::AstNode *const node) { return node->IsBinaryExpression() || node->IsUnaryExpression() || node->IsConditionalExpression(); })); ASSERT_TRUE( ast->IsAnyChild([](ir::AstNode *const node) { return CheckNumberLiteral(node); })); ASSERT_TRUE( ast->IsAnyChild([](ir::AstNode *const node) { return CheckNumberLiteral(node); })); ASSERT_TRUE( ast->IsAnyChild([](ir::AstNode *const node) { return CheckNumberLiteral(node); })); } } TEST_F(LoweringTest, TestConstantExpressionConcatExtendedBoolean2) { char const *text = R"( @interface MyAnno { a : int c : int d : int } @MyAnno({a = undefined ? 1 : 0, c = "" ? 5 : 4, d = 0 ? 7 : 6}) function main() {} )"; int const expectA = 0; int const expectC = 4; int const expectD = 6; CONTEXT(ES2PANDA_STATE_CHECKED, text) { const auto *const ast = GetAst(); ASSERT_FALSE(ast->IsAnyChild([](ir::AstNode *const node) { return node->IsBinaryExpression() || node->IsUnaryExpression() || node->IsConditionalExpression(); })); ASSERT_TRUE( ast->IsAnyChild([](ir::AstNode *const node) { return CheckNumberLiteral(node); })); ASSERT_TRUE( ast->IsAnyChild([](ir::AstNode *const node) { return CheckNumberLiteral(node); })); ASSERT_TRUE( ast->IsAnyChild([](ir::AstNode *const node) { return CheckNumberLiteral(node); })); } } TEST_F(LoweringTest, TestConstantExpressionConcatExtendedBoolean4) { char const *text = R"( @interface MyAnno { a : boolean b : int = "aaa" ? 1 : 2 } @MyAnno({a = ((("aa" >= "aa") && ("ab" < "aa")) || ("aa" != "bb")) && "aa!" == "aa!"}) function main() {} )"; bool const expectA = true; int const expectB = 1; CONTEXT(ES2PANDA_STATE_CHECKED, text) { const auto *const ast = GetAst(); ASSERT_FALSE(ast->IsAnyChild([](ir::AstNode *const node) { return node->IsBinaryExpression() || node->IsUnaryExpression() || node->IsConditionalExpression(); })); ASSERT_TRUE(ast->IsAnyChild([](ir::AstNode *const node) { return node->IsBooleanLiteral() && node->AsBooleanLiteral()->Value() == expectA; })); ASSERT_TRUE( ast->IsAnyChild([](ir::AstNode *const node) { return CheckNumberLiteral(node); })); } } TEST_F(LoweringTest, TestConstantExpressionConcatExtendedBoolean3) { char const *text = R"( @interface MyAnno { a : int b : int } @MyAnno({a = !null ? 10 : 20, b= "test" && !undefined ? 1 : 2}) function main() {} )"; int const expectA = 10; int const expectB = 1; CONTEXT(ES2PANDA_STATE_CHECKED, text) { const auto *const ast = GetAst(); ASSERT_FALSE(ast->IsAnyChild([](ir::AstNode *const node) { return node->IsBinaryExpression() || node->IsUnaryExpression() || node->IsConditionalExpression(); })); ASSERT_TRUE( ast->IsAnyChild([](ir::AstNode *const node) { return CheckNumberLiteral(node); })); ASSERT_TRUE( ast->IsAnyChild([](ir::AstNode *const node) { return CheckNumberLiteral(node); })); } } TEST_F(LoweringTest, TestConstantExpressionConcat) { char const *text = R"( @interface MyAnno { a : int b : long c : boolean d : int } @MyAnno({a = 1 + -1, b = 1554.4 ^ 10, c = 12 >= 10, d = 15 != 10 ? 1+4 : 5+1}) function main() {} )"; int const expectA = 0; int64_t const expectB = 1560; bool const expectC = true; int const expectD = 5; CONTEXT(ES2PANDA_STATE_CHECKED, text) { const auto *const ast = GetAst(); ASSERT_FALSE(ast->IsAnyChild([](ir::AstNode *const node) { return node->IsBinaryExpression() || node->IsUnaryExpression() || node->IsConditionalExpression(); })); ASSERT_TRUE( ast->IsAnyChild([](ir::AstNode *const node) { return CheckNumberLiteral(node); })); ASSERT_TRUE( ast->IsAnyChild([](ir::AstNode *const node) { return CheckNumberLiteral(node); })); ASSERT_TRUE(ast->IsAnyChild([](ir::AstNode *const node) { return node->IsBooleanLiteral() && node->AsBooleanLiteral()->Value() == expectC; })); ASSERT_TRUE( ast->IsAnyChild([](ir::AstNode *const node) { return CheckNumberLiteral(node); })); } } TEST_F(LoweringTest, TestConstantExpressionConcatNumeric1) { char const *text = R"( @interface MyAnno { a : int = 1+1 } @MyAnno() function main() {} )"; int32_t const expectA = 2; CONTEXT(ES2PANDA_STATE_CHECKED, text) { const auto *const ast = GetAst(); ASSERT_FALSE(ast->IsAnyChild([](ir::AstNode *const node) { return node->IsBinaryExpression() || node->IsUnaryExpression() || node->IsConditionalExpression(); })); ASSERT_TRUE( ast->IsAnyChild([](ir::AstNode *const node) { return CheckNumberLiteral(node); })); } } TEST_F(LoweringTest, TestConstantExpressionConcatBoolean) { char const *text = R"( @interface MyAnno { a : boolean } @MyAnno({a = ((20<=10) || true) ? !false && (10==10) && (30 != 10): false}) function main() {} )"; bool const expectA = true; CONTEXT(ES2PANDA_STATE_CHECKED, text) { const auto *const ast = GetAst(); ASSERT_FALSE(ast->IsAnyChild([](ir::AstNode *const node) { return node->IsBinaryExpression() || node->IsUnaryExpression() || node->IsConditionalExpression(); })); ASSERT_TRUE(ast->IsAnyChild([](ir::AstNode *const node) { return node->IsBooleanLiteral() && node->AsBooleanLiteral()->Value() == expectA; })); } } TEST_F(LoweringTest, TestConstantExpressionConcatNumeric) { char const *text = R"( @interface MyAnno { a : long } @MyAnno({a = ((((1 + -1 + 10) * 123 / 5) ^ (~10.2) << 1) >> 2.6 >>> 33 & 141 | 12) % 53}) function main() {} )"; int64_t const expectA = 35; CONTEXT(ES2PANDA_STATE_CHECKED, text) { const auto *const ast = GetAst(); ASSERT_FALSE(ast->IsAnyChild([](ir::AstNode *const node) { return node->IsBinaryExpression() || node->IsUnaryExpression() || node->IsConditionalExpression(); })); ASSERT_TRUE( ast->IsAnyChild([](ir::AstNode *const node) { return CheckNumberLiteral(node); })); } } } // namespace ark::es2panda