• 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 <gtest/gtest.h>
17 
18 #include "assembler/assembly-program.h"
19 #include "es2panda.h"
20 #include "generated/signatures.h"
21 #include "libpandabase/mem/mem.h"
22 #include "macros.h"
23 #include "mem/pool_manager.h"
24 #include "test/utils/asm_test.h"
25 
26 namespace ark::es2panda::compiler::test {
27 
28 class RestParameterTest : public ::test::utils::AsmTest {
29 public:
30     RestParameterTest() = default;
31 
32     ~RestParameterTest() override = default;
33 
CheckRestParameterFlag(std::string_view functionName,bool isStatic)34     void CheckRestParameterFlag(std::string_view functionName, bool isStatic)
35     {
36         pandasm::Function *fn =
37             GetFunction(functionName, isStatic ? program_->functionStaticTable : program_->functionInstanceTable);
38         ASSERT_TRUE(fn != nullptr) << "Function '" << functionName << "' not found";
39         ASSERT_TRUE(HasRestParameterFlag(fn)) << "Function '" << fn->name << "' doesn't have ACC_VARARGS flag";
40     }
41 
CheckNoRestParameterFlag(std::string_view functionName,bool isStatic)42     void CheckNoRestParameterFlag(std::string_view functionName, bool isStatic)
43     {
44         pandasm::Function *fn =
45             GetFunction(functionName, isStatic ? program_->functionStaticTable : program_->functionInstanceTable);
46         ASSERT_TRUE(fn != nullptr) << "Function '" << functionName << "' not found";
47         ASSERT_FALSE(HasRestParameterFlag(fn)) << "Function '" << fn->name << "' has ACC_VARARGS flag";
48     }
49 
50 private:
HasRestParameterFlag(pandasm::Function * fn)51     bool HasRestParameterFlag(pandasm::Function *fn)
52     {
53         return (fn->metadata->GetAccessFlags() & ACC_VARARGS) != 0;
54     }
55 
56     NO_COPY_SEMANTIC(RestParameterTest);
57     NO_MOVE_SEMANTIC(RestParameterTest);
58 };
59 
60 // === Function ===
TEST_F(RestParameterTest,function_without_rest_parameters_0)61 TEST_F(RestParameterTest, function_without_rest_parameters_0)
62 {
63     SetCurrentProgram(R"(
64         function fn(): void {
65         }
66     )");
67     CheckNoRestParameterFlag("dummy.ETSGLOBAL.fn:void;", true);
68 }
69 
TEST_F(RestParameterTest,function_without_rest_parameters_1)70 TEST_F(RestParameterTest, function_without_rest_parameters_1)
71 {
72     SetCurrentProgram(R"(
73         function fn(args: FixedArray<int>): void {
74         }
75     )");
76     CheckNoRestParameterFlag("dummy.ETSGLOBAL.fn:i32[];void;", true);
77 }
78 
TEST_F(RestParameterTest,function_without_rest_parameters_2)79 TEST_F(RestParameterTest, function_without_rest_parameters_2)
80 {
81     SetCurrentProgram(R"(
82         function fn(arg0: int, args: FixedArray<String>): void {
83         }
84     )");
85     CheckNoRestParameterFlag("dummy.ETSGLOBAL.fn:i32;std.core.String[];void;", true);
86 }
87 
TEST_F(RestParameterTest,function_with_rest_parameter_0)88 TEST_F(RestParameterTest, function_with_rest_parameter_0)
89 {
90     SetCurrentProgram(R"(
91         function fn(...args: FixedArray<String>): void {
92         }
93     )");
94     CheckRestParameterFlag("dummy.ETSGLOBAL.fn:std.core.String[];void;", true);
95 }
96 
TEST_F(RestParameterTest,function_with_rest_parameter_1)97 TEST_F(RestParameterTest, function_with_rest_parameter_1)
98 {
99     SetCurrentProgram(R"(
100         function fn(o: Object, ...args: FixedArray<int>): void {
101         }
102     )");
103     CheckRestParameterFlag("dummy.ETSGLOBAL.fn:std.core.Object;i32[];void;", true);
104 }
105 
106 // === Method of class ===
TEST_F(RestParameterTest,class_method_without_rest_parameters_0)107 TEST_F(RestParameterTest, class_method_without_rest_parameters_0)
108 {
109     SetCurrentProgram(R"(
110         class A {
111             fn() {};
112         }
113     )");
114     CheckNoRestParameterFlag("dummy.A.fn:void;", false);
115 }
116 
TEST_F(RestParameterTest,class_method_without_rest_parameters_1)117 TEST_F(RestParameterTest, class_method_without_rest_parameters_1)
118 {
119     SetCurrentProgram(R"(
120         class A {
121             fn(arg0: int) {};
122         }
123     )");
124     CheckNoRestParameterFlag("dummy.A.fn:i32;void;", false);
125 }
126 
TEST_F(RestParameterTest,class_method_with_rest_parameters_0)127 TEST_F(RestParameterTest, class_method_with_rest_parameters_0)
128 {
129     SetCurrentProgram(R"(
130         class A {
131             fn(...args: FixedArray<int>) {};
132         }
133     )");
134     CheckRestParameterFlag("dummy.A.fn:i32[];void;", false);
135 }
136 
137 // === Static method of class ===
TEST_F(RestParameterTest,static_class_method_without_rest_parameters_0)138 TEST_F(RestParameterTest, static_class_method_without_rest_parameters_0)
139 {
140     SetCurrentProgram(R"(
141         class A {
142             static fn() {};
143         }
144     )");
145     CheckNoRestParameterFlag("dummy.A.fn:void;", true);
146 }
147 
TEST_F(RestParameterTest,static_class_method_without_rest_parameters_1)148 TEST_F(RestParameterTest, static_class_method_without_rest_parameters_1)
149 {
150     SetCurrentProgram(R"(
151         class A {
152             static fn(arg0: int) {};
153         }
154     )");
155     CheckNoRestParameterFlag("dummy.A.fn:i32;void;", true);
156 }
157 
TEST_F(RestParameterTest,static_class_method_with_rest_parameters_0)158 TEST_F(RestParameterTest, static_class_method_with_rest_parameters_0)
159 {
160     SetCurrentProgram(R"(
161         class A {
162             static fn(...args: FixedArray<int>) {};
163         }
164     )");
165     CheckRestParameterFlag("dummy.A.fn:i32[];void;", true);
166 }
167 
TEST_F(RestParameterTest,static_class_method_with_rest_parameters_1)168 TEST_F(RestParameterTest, static_class_method_with_rest_parameters_1)
169 {
170     SetCurrentProgram(R"(
171         class A {
172             static fn(a: FixedArray<String>, ...args: FixedArray<int>) {};
173         }
174     )");
175     CheckRestParameterFlag("dummy.A.fn:std.core.String[];i32[];void;", true);
176 }
177 
178 // === Constructor of class ===
TEST_F(RestParameterTest,class_constructor_without_rest_parameters_0)179 TEST_F(RestParameterTest, class_constructor_without_rest_parameters_0)
180 {
181     SetCurrentProgram(R"(
182         class A {
183             constructor() {};
184         }
185     )");
186     CheckNoRestParameterFlag("dummy.A.<ctor>:void;", false);
187 }
188 
TEST_F(RestParameterTest,class_constructor_without_rest_parameters_1)189 TEST_F(RestParameterTest, class_constructor_without_rest_parameters_1)
190 {
191     SetCurrentProgram(R"(
192         class A {
193             constructor(args: FixedArray<String>) {};
194         }
195     )");
196     CheckNoRestParameterFlag("dummy.A.<ctor>:std.core.String[];void;", false);
197 }
198 
TEST_F(RestParameterTest,class_constructor_with_rest_parameters_0)199 TEST_F(RestParameterTest, class_constructor_with_rest_parameters_0)
200 {
201     SetCurrentProgram(R"(
202         class A {
203             constructor(...args: FixedArray<int>) {};
204         }
205     )");
206     CheckRestParameterFlag("dummy.A.<ctor>:i32[];void;", false);
207 }
208 
TEST_F(RestParameterTest,class_constructor_with_rest_parameters_1)209 TEST_F(RestParameterTest, class_constructor_with_rest_parameters_1)
210 {
211     SetCurrentProgram(R"(
212         class A {
213             constructor(v0: long, ...args: FixedArray<String>) {};
214         }
215     )");
216     CheckRestParameterFlag("dummy.A.<ctor>:i64;std.core.String[];void;", false);
217 }
218 
219 // === Method of interface ===
TEST_F(RestParameterTest,interface_without_rest_parameters_0)220 TEST_F(RestParameterTest, interface_without_rest_parameters_0)
221 {
222     SetCurrentProgram(R"(
223         interface A {
224             fn() {};
225         }
226     )");
227     CheckNoRestParameterFlag("dummy.A.fn:void;", false);
228 }
229 
TEST_F(RestParameterTest,interface_without_rest_parameters_1)230 TEST_F(RestParameterTest, interface_without_rest_parameters_1)
231 {
232     SetCurrentProgram(R"(
233         interface A {
234             fn(args: FixedArray<String>) {};
235         }
236     )");
237     CheckNoRestParameterFlag("dummy.A.fn:std.core.String[];void;", false);
238 }
239 
TEST_F(RestParameterTest,interface_with_rest_parameters_0)240 TEST_F(RestParameterTest, interface_with_rest_parameters_0)
241 {
242     SetCurrentProgram(R"(
243         interface A {
244             fn(...args: FixedArray<Object>) {};
245         }
246     )");
247     CheckRestParameterFlag("dummy.A.fn:std.core.Object[];void;", false);
248 }
249 
TEST_F(RestParameterTest,interface_with_rest_parameters_1)250 TEST_F(RestParameterTest, interface_with_rest_parameters_1)
251 {
252     SetCurrentProgram(R"(
253         interface A {
254             fn(o: Object, ...args: FixedArray<String>) {};
255         }
256     )");
257     CheckRestParameterFlag("dummy.A.fn:std.core.Object;std.core.String[];void;", false);
258 }
259 
260 // === Lambda method ===
TEST_F(RestParameterTest,lambda_without_rest_parameters_0)261 TEST_F(RestParameterTest, lambda_without_rest_parameters_0)
262 {
263     SetCurrentProgram(R"(
264         let fn: ()=>int = (): int => {
265             return 1;
266         }
267     )");
268     CheckNoRestParameterFlag("dummy.ETSGLOBAL.lambda$invoke$0:i32;", true);
269 }
270 
TEST_F(RestParameterTest,lambda_without_rest_parameters_1)271 TEST_F(RestParameterTest, lambda_without_rest_parameters_1)
272 {
273     SetCurrentProgram(R"(
274         let fn: (args: FixedArray<long>)=>int = (args: FixedArray<long>): int => {
275             return 1;
276         }
277     )");
278     CheckNoRestParameterFlag("dummy.ETSGLOBAL.lambda$invoke$0:i64[];i32;", true);
279 }
280 
281 // === Abstract method of abstract class ===
TEST_F(RestParameterTest,abstract_function_without_rest_parameter_0)282 TEST_F(RestParameterTest, abstract_function_without_rest_parameter_0)
283 {
284     SetCurrentProgram(R"(
285         abstract class A {
286             abstract fn(): void
287         }
288     )");
289     CheckNoRestParameterFlag("dummy.A.fn:void;", false);
290 }
291 
TEST_F(RestParameterTest,abstract_function_without_rest_parameter_1)292 TEST_F(RestParameterTest, abstract_function_without_rest_parameter_1)
293 {
294     SetCurrentProgram(R"(
295         abstract class A {
296             abstract fn(args: FixedArray<String>): void
297         }
298     )");
299     CheckNoRestParameterFlag("dummy.A.fn:std.core.String[];void;", false);
300 }
301 
TEST_F(RestParameterTest,abstract_function_with_rest_parameter_0)302 TEST_F(RestParameterTest, abstract_function_with_rest_parameter_0)
303 {
304     SetCurrentProgram(R"(
305         abstract class A {
306             abstract fn(...args: FixedArray<String>): void
307         }
308     )");
309     CheckRestParameterFlag("dummy.A.fn:std.core.String[];void;", false);
310 }
311 
TEST_F(RestParameterTest,abstract_function_with_rest_parameter_1)312 TEST_F(RestParameterTest, abstract_function_with_rest_parameter_1)
313 {
314     SetCurrentProgram(R"(
315         abstract class A {
316             abstract fn(v: int, ...args: FixedArray<String>): void
317         }
318     )");
319     CheckRestParameterFlag("dummy.A.fn:i32;std.core.String[];void;", false);
320 }
321 
322 // === External methods ===
TEST_F(RestParameterTest,external_function_with_rest_parameter_0)323 TEST_F(RestParameterTest, external_function_with_rest_parameter_0)
324 {
325     SetCurrentProgram("");
326     CheckRestParameterFlag("std.core.LambdaValue.invoke:escompat.Array;std.core.Object;", false);
327 }
328 
TEST_F(RestParameterTest,external_function_with_rest_parameter_1)329 TEST_F(RestParameterTest, external_function_with_rest_parameter_1)
330 {
331     SetCurrentProgram("");
332     CheckRestParameterFlag("escompat.Math.max:escompat.Array;f64;", true);
333 }
334 
335 }  // namespace ark::es2panda::compiler::test
336