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/topLevelStmts/topLevelStmts.h"
18
19 namespace ark::es2panda {
20
TEST_F(LoweringTest,TestTopLevelStmtsSyntheticModuleGlobalClass)21 TEST_F(LoweringTest, TestTopLevelStmtsSyntheticModuleGlobalClass)
22 {
23 char const *text = R"(
24 function foo() { } // foo is a member of *module* class
25 )";
26
27 CONTEXT(ES2PANDA_STATE_LOWERED, text)
28 {
29 const auto *const ast = GetAst();
30 [[maybe_unused]] auto *classDef = ast->FindChild([](ir::AstNode *child) {
31 return child->IsClassDefinition() &&
32 (child->AsClassDefinition()->InternalName().Mutf8() == "dummy.ETSGLOBAL");
33 });
34 ASSERT(classDef != nullptr);
35 ASSERT(classDef->AsClassDefinition()->IsGlobalInitialized());
36 }
37 }
38
TEST_F(LoweringTest,TestTopLevelStmtsSyntheticModuleClass)39 TEST_F(LoweringTest, TestTopLevelStmtsSyntheticModuleClass)
40 {
41 char const *text = R"(
42 namespace X {
43 export function bar() { } // bar is a member of another *module* class
44 }
45 )";
46
47 CONTEXT(ES2PANDA_STATE_LOWERED, text)
48 {
49 const auto *const ast = GetAst();
50 [[maybe_unused]] auto *classDef = ast->FindChild([](ir::AstNode *child) {
51 return child->IsClassDefinition() && (child->AsClassDefinition()->InternalName().Mutf8() == "dummy.X");
52 });
53 ASSERT(classDef != nullptr);
54 ASSERT(classDef->AsClassDefinition()->IsNamespaceTransformed());
55 }
56 }
57
TEST_F(LoweringTest,TestTopLevelStmtsExportedClass)58 TEST_F(LoweringTest, TestTopLevelStmtsExportedClass)
59 {
60 char const *text = R"(
61 export class A {}
62 class B {}
63 )";
64
65 CONTEXT(ES2PANDA_STATE_LOWERED, text)
66 {
67 const auto *const ast = GetAst();
68 auto *classDef = ast->FindChild([](ir::AstNode *child) {
69 return child->IsClassDefinition() && child->AsClassDefinition()->IsGlobalInitialized();
70 });
71 ASSERT_NE(classDef, nullptr);
72
73 const auto &exportedClasses = classDef->AsClassDefinition()->ExportedClasses();
74 ASSERT_EQ(exportedClasses.size(), 1);
75 ASSERT_TRUE(exportedClasses[0]->IsExported());
76 ASSERT_EQ(exportedClasses[0]->Definition()->InternalName().Mutf8(), "dummy.A");
77 }
78 }
79
TEST_F(LoweringTest,TestTopLevelStmtsExportedNamespace)80 TEST_F(LoweringTest, TestTopLevelStmtsExportedNamespace)
81 {
82 char const *text = R"(
83 export namespace A {}
84 namespace B {}
85 )";
86
87 CONTEXT(ES2PANDA_STATE_LOWERED, text)
88 {
89 const auto *const ast = GetAst();
90 auto *classDef = ast->FindChild([](ir::AstNode *child) {
91 return child->IsClassDefinition() && child->AsClassDefinition()->IsGlobalInitialized();
92 });
93 ASSERT_NE(classDef, nullptr);
94
95 const auto &exportedClasses = classDef->AsClassDefinition()->ExportedClasses();
96 ASSERT_EQ(exportedClasses.size(), 1);
97 ASSERT_TRUE(exportedClasses[0]->IsExported());
98 ASSERT_EQ(exportedClasses[0]->Definition()->InternalName().Mutf8(), "dummy.A");
99 }
100 }
101
TEST_F(LoweringTest,TestTopLevelStmtsExportedNamespaceNested)102 TEST_F(LoweringTest, TestTopLevelStmtsExportedNamespaceNested)
103 {
104 char const *text = R"(
105 export namespace A {
106 export namespace B {}
107 namespace C {}
108 export class D {}
109 class E {}
110 }
111 )";
112
113 CONTEXT(ES2PANDA_STATE_LOWERED, text)
114 {
115 const auto *const ast = GetAst();
116 auto *classDef = ast->FindChild([](ir::AstNode *child) {
117 return child->IsClassDefinition() && child->AsClassDefinition()->IsNamespaceTransformed();
118 });
119 ASSERT(classDef != nullptr);
120
121 const auto &exportedClasses = classDef->AsClassDefinition()->ExportedClasses();
122 constexpr uint32_t EXPORTED_CLASSES_NUM = 2;
123 ASSERT_EQ(exportedClasses.size(), EXPORTED_CLASSES_NUM);
124 ASSERT_TRUE(exportedClasses[0]->IsExported());
125 ASSERT_TRUE(exportedClasses[1]->IsExported());
126 ASSERT_EQ(exportedClasses[0]->Definition()->InternalName().Mutf8(), "dummy.A.B");
127 ASSERT_EQ(exportedClasses[1]->Definition()->InternalName().Mutf8(), "dummy.A.D");
128 }
129 }
130
TEST_F(LoweringTest,TestTopLevelStmtsExportedEnum)131 TEST_F(LoweringTest, TestTopLevelStmtsExportedEnum)
132 {
133 char const *text = R"(
134 export let a = 10;
135 export enum Color {
136 Red = 1
137 }
138 )";
139
140 CONTEXT(ES2PANDA_STATE_LOWERED, text)
141 {
142 const auto *const ast = GetAst();
143 auto *classDef = ast->FindChild([](ir::AstNode *child) {
144 return child->IsClassDefinition() && child->AsClassDefinition()->IsGlobalInitialized();
145 });
146 ASSERT(classDef != nullptr);
147
148 const auto &exportedClasses = classDef->AsClassDefinition()->ExportedClasses();
149 constexpr uint32_t EXPORTED_CLASSES_NUM = 2;
150 ASSERT_EQ(exportedClasses.size(), EXPORTED_CLASSES_NUM);
151 ASSERT_TRUE(exportedClasses[1]->IsExported());
152 ASSERT_EQ(exportedClasses[0]->Definition()->InternalName().Mutf8(), "dummy.ETSGLOBAL");
153 ASSERT_EQ(exportedClasses[1]->Definition()->InternalName().Mutf8(), "dummy.Color");
154 }
155 }
156
157 } // namespace ark::es2panda
158