• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**
2  * Copyright (c) 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 "generated/signatures.h"
20 #include "libpandabase/mem/mem.h"
21 #include "macros.h"
22 #include "mem/pool_manager.h"
23 #include "util/options.h"
24 #include "test/utils/asm_test.h"
25 
26 namespace ark::es2panda::compiler::test {
27 
28 class DeclareTest : public testing::Test {
29 public:
DeclareTest()30     DeclareTest()
31     {
32         mem::MemConfig::Initialize(0, 0, ark::es2panda::COMPILER_SIZE, 0, 0, 0);
33         PoolManager::Initialize(PoolType::MMAP);
34     }
~DeclareTest()35     ~DeclareTest() override
36     {
37         PoolManager::Finalize();
38         mem::MemConfig::Finalize();
39     }
40 
SetCurrentProgram(std::string_view src)41     void SetCurrentProgram(std::string_view src)
42     {
43         static constexpr std::string_view FILE_NAME = "ets_decl_test.ets";
44         std::array<char const *, 2> args = {"../../../../bin/es2panda",
45                                             "--ets-unnamed"};  // NOLINT(modernize-avoid-c-arrays)
46 
47         program_ = GetProgram({args.data(), args.size()}, FILE_NAME, src);
48         ASSERT_NE(program_.get(), nullptr);
49     }
50 
CheckRecordExternalFlag(std::string_view recordName)51     void CheckRecordExternalFlag(std::string_view recordName)
52     {
53         pandasm::Record *record = GetRecord(recordName, program_);
54         ASSERT_TRUE(record != nullptr) << "Record '" << recordName << "' not found";
55         ASSERT_TRUE(HasExternalFlag(record)) << "Record '" << record->name << "' doesn't have External flag";
56     }
57 
CheckFunctionExternalFlag(std::string_view functionName,bool isStatic=false)58     void CheckFunctionExternalFlag(std::string_view functionName, bool isStatic = false)
59     {
60         pandasm::Function *fn =
61             GetFunction(functionName, isStatic ? program_->functionStaticTable : program_->functionInstanceTable);
62         ASSERT_TRUE(fn != nullptr) << "Function '" << functionName << "' not found";
63         ASSERT_TRUE(HasExternalFlag(fn)) << "Function '" << fn->name << "' doesn't have External flag";
64     }
65 
CheckFunctionNoExternalFlag(std::string_view functionName,bool isStatic=false)66     void CheckFunctionNoExternalFlag(std::string_view functionName, bool isStatic = false)
67     {
68         pandasm::Function *fn =
69             GetFunction(functionName, isStatic ? program_->functionStaticTable : program_->functionInstanceTable);
70         ASSERT_TRUE(fn != nullptr) << "Function '" << functionName << "' not found";
71         ASSERT_FALSE(HasExternalFlag(fn)) << "Function '" << fn->name << "' has External flag";
72     }
73 
74 private:
HasExternalFlag(pandasm::Function * fn)75     bool HasExternalFlag(pandasm::Function *fn)
76     {
77         return (fn->metadata->GetAttribute("external"));
78     }
79 
HasExternalFlag(pandasm::Record * record)80     bool HasExternalFlag(pandasm::Record *record)
81     {
82         return (record->metadata->GetAttribute("external"));
83     }
84 
85     NO_COPY_SEMANTIC(DeclareTest);
86     NO_MOVE_SEMANTIC(DeclareTest);
87 
GetProgram(ark::Span<const char * const> args,std::string_view fileName,std::string_view src)88     static std::unique_ptr<pandasm::Program> GetProgram(ark::Span<const char *const> args, std::string_view fileName,
89                                                         std::string_view src)
90     {
91         auto de = util::DiagnosticEngine();
92         auto options = std::make_unique<es2panda::util::Options>(args[0], de);
93         if (!options->Parse(args)) {
94             return nullptr;
95         }
96 
97         Logger::ComponentMask mask {};
98         mask.set(Logger::Component::ES2PANDA);
99         Logger::InitializeStdLogging(options->LogLevel(), mask);
100 
101         es2panda::Compiler compiler(options->GetExtension(), options->GetThread());
102         es2panda::SourceFile input(fileName, src, options->IsModule());
103 
104         return std::unique_ptr<pandasm::Program>(compiler.Compile(input, *options, de));
105     }
106 
GetFunction(std::string_view functionName,const std::map<std::string,pandasm::Function> & table)107     pandasm::Function *GetFunction(std::string_view functionName, const std::map<std::string, pandasm::Function> &table)
108     {
109         auto it = table.find(functionName.data());
110         if (it == table.end()) {
111             return nullptr;
112         }
113         return const_cast<pandasm::Function *>(&it->second);
114     }
115 
GetRecord(std::string_view recordName,const std::unique_ptr<ark::pandasm::Program> & program)116     pandasm::Record *GetRecord(std::string_view recordName, const std::unique_ptr<ark::pandasm::Program> &program)
117     {
118         auto it = program->recordTable.find(recordName.data());
119         if (it == program->recordTable.end()) {
120             return nullptr;
121         }
122         return &it->second;
123     }
124 
125 private:
126     std::unique_ptr<pandasm::Program> program_ {};
127 };
128 
129 // === Function ===
TEST_F(DeclareTest,function_without_overloads_0)130 TEST_F(DeclareTest, function_without_overloads_0)
131 {
132     SetCurrentProgram(R"(
133         declare function foo(tmp: double): string
134     )");
135     CheckFunctionExternalFlag("ETSGLOBAL.foo:f64;std.core.String;", true);
136 }
137 
TEST_F(DeclareTest,function_with_overloads_0)138 TEST_F(DeclareTest, function_with_overloads_0)
139 {
140     SetCurrentProgram(R"(
141         declare function foo(tmp?: double): string
142     )");
143     CheckFunctionExternalFlag("ETSGLOBAL.foo:std.core.Double;std.core.String;", true);
144 }
145 
146 // === Method of class ===
TEST_F(DeclareTest,noImplclass_def_with_overload_0)147 TEST_F(DeclareTest, noImplclass_def_with_overload_0)
148 {
149     SetCurrentProgram(R"(
150         declare class my_class {
151             public foo(arg?: int): string
152         }
153     )");
154     CheckFunctionExternalFlag("my_class.foo:std.core.Int;std.core.String;");
155 }
156 
157 // === Constructor of class ===
TEST_F(DeclareTest,class_constructor_without_parameters_0)158 TEST_F(DeclareTest, class_constructor_without_parameters_0)
159 {
160     SetCurrentProgram(R"(
161         declare class A_class {
162             static x: double
163         }
164     )");
165     CheckFunctionExternalFlag("A_class.<ctor>:void;");
166 }
167 
TEST_F(DeclareTest,class_constructor_without_parameters_1)168 TEST_F(DeclareTest, class_constructor_without_parameters_1)
169 {
170     SetCurrentProgram(R"(
171         declare class A {
172             constructor();
173         }
174     )");
175     CheckFunctionExternalFlag("A.<ctor>:void;");
176 }
177 
TEST_F(DeclareTest,class_implicit_constructor_0)178 TEST_F(DeclareTest, class_implicit_constructor_0)
179 {
180     SetCurrentProgram(R"(
181         declare class A {
182         }
183     )");
184     CheckFunctionExternalFlag("A.<ctor>:void;");
185 }
186 
187 // === Method of interface ===
TEST_F(DeclareTest,noImplinterface_def_with_overload_0)188 TEST_F(DeclareTest, noImplinterface_def_with_overload_0)
189 {
190     SetCurrentProgram(R"(
191         declare interface my_inter {
192             foo(arg?: int): void
193         }
194     )");
195     CheckFunctionExternalFlag("my_inter.foo:std.core.Int;void;");
196 }
197 
TEST_F(DeclareTest,namespace_0)198 TEST_F(DeclareTest, namespace_0)
199 {
200     SetCurrentProgram(R"(
201         declare namespace A {
202         }
203     )");
204     CheckRecordExternalFlag("A");
205 }
206 
207 }  // namespace ark::es2panda::compiler::test
208