1 /**
2 * Copyright (c) 2024 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 "util/options.h"
25
26 namespace ark::es2panda::compiler::test {
27
28 class DeclareTest : public testing::Test {
29 public:
DeclareTest()30 DeclareTest()
31 {
32 const auto compilerSize = 268435456;
33
34 mem::MemConfig::Initialize(0, 0, compilerSize, 0, 0, 0);
35 PoolManager::Initialize(PoolType::MMAP);
36 }
~DeclareTest()37 ~DeclareTest() override
38 {
39 PoolManager::Finalize();
40 mem::MemConfig::Finalize();
41 }
42
SetCurrentProgram(std::string_view src)43 void SetCurrentProgram(std::string_view src)
44 {
45 int argc = 1;
46 const char *argv = "../../../../bin/es2panda"; // NOLINT(modernize-avoid-c-arrays)
47 static constexpr std::string_view FILE_NAME = "ets_decl_test.sts";
48
49 program_ = GetProgram(argc, &argv, FILE_NAME, src);
50 ASSERT_NE(program_.get(), nullptr);
51 }
52
CheckExternalFlag(std::string_view functionName)53 void CheckExternalFlag(std::string_view functionName)
54 {
55 pandasm::Function *fn = GetFunction(functionName);
56 ASSERT_TRUE(fn != nullptr) << "Function '" << functionName << "' not found";
57 ASSERT_TRUE(HasExternalFlag(fn)) << "Function '" << fn->name << "' doesn't have External flag";
58 }
59
CheckNoExternalFlag(std::string_view functionName)60 void CheckNoExternalFlag(std::string_view functionName)
61 {
62 pandasm::Function *fn = GetFunction(functionName);
63 ASSERT_TRUE(fn != nullptr) << "Function '" << functionName << "' not found";
64 ASSERT_FALSE(HasExternalFlag(fn)) << "Function '" << fn->name << "' has External flag";
65 }
66
67 private:
HasExternalFlag(pandasm::Function * fn)68 bool HasExternalFlag(pandasm::Function *fn)
69 {
70 return (fn->metadata->GetAttribute("external"));
71 }
72
73 NO_COPY_SEMANTIC(DeclareTest);
74 NO_MOVE_SEMANTIC(DeclareTest);
75
GetProgram(int argc,const char ** argv,std::string_view fileName,std::string_view src)76 static std::unique_ptr<pandasm::Program> GetProgram(int argc, const char **argv, std::string_view fileName,
77 std::string_view src)
78 {
79 auto options = std::make_unique<es2panda::util::Options>();
80 if (!options->Parse(argc, argv)) {
81 std::cerr << options->ErrorMsg() << std::endl;
82 return nullptr;
83 }
84
85 Logger::ComponentMask mask {};
86 mask.set(Logger::Component::ES2PANDA);
87 Logger::InitializeStdLogging(Logger::LevelFromString(options->LogLevel()), mask);
88
89 es2panda::Compiler compiler(options->Extension(), options->ThreadCount());
90 es2panda::SourceFile input(fileName, src, options->ParseModule());
91
92 return std::unique_ptr<pandasm::Program>(compiler.Compile(input, *options));
93 }
94
GetFunction(std::string_view functionName)95 pandasm::Function *GetFunction(std::string_view functionName)
96 {
97 auto it = program_->functionTable.find(functionName.data());
98 if (it == program_->functionTable.end()) {
99 return nullptr;
100 }
101 return &it->second;
102 }
103
104 private:
105 std::unique_ptr<pandasm::Program> program_ {};
106 };
107
108 // === Function ===
TEST_F(DeclareTest,function_without_overloads_0)109 TEST_F(DeclareTest, function_without_overloads_0)
110 {
111 SetCurrentProgram(R"(
112 declare function foo(tmp: double): string
113 )");
114 CheckExternalFlag("ETSGLOBAL.foo:f64;std.core.String;");
115 }
116
TEST_F(DeclareTest,function_with_overloads_0)117 TEST_F(DeclareTest, function_with_overloads_0)
118 {
119 SetCurrentProgram(R"(
120 declare function foo(tmp?: double): string
121 )");
122 CheckExternalFlag("ETSGLOBAL.foo:std.core.Object;std.core.String;");
123 CheckExternalFlag("ETSGLOBAL.foo:std.core.String;");
124 }
125
126 // === Method of class ===
TEST_F(DeclareTest,noImplclass_def_with_overload_0)127 TEST_F(DeclareTest, noImplclass_def_with_overload_0)
128 {
129 SetCurrentProgram(R"(
130 declare class my_class {
131 public foo(arg?: int): string
132 }
133 )");
134 CheckExternalFlag("my_class.foo:std.core.Object;std.core.String;");
135 CheckExternalFlag("my_class.foo:std.core.String;");
136 }
137
138 // === Constructor of class ===
TEST_F(DeclareTest,class_constructor_without_parameters_0)139 TEST_F(DeclareTest, class_constructor_without_parameters_0)
140 {
141 SetCurrentProgram(R"(
142 declare class A_class {
143 static x: double
144 }
145 )");
146 CheckExternalFlag("A_class.<ctor>:void;");
147 }
148
TEST_F(DeclareTest,class_constructor_without_parameters_1)149 TEST_F(DeclareTest, class_constructor_without_parameters_1)
150 {
151 SetCurrentProgram(R"(
152 declare class A {
153 constructor();
154 }
155 )");
156 CheckExternalFlag("A.<ctor>:void;");
157 }
158
TEST_F(DeclareTest,class_implicit_constructor_0)159 TEST_F(DeclareTest, class_implicit_constructor_0)
160 {
161 SetCurrentProgram(R"(
162 declare class A {
163 }
164 )");
165 CheckExternalFlag("A.<ctor>:void;");
166 }
167
168 // === Method of interface ===
TEST_F(DeclareTest,noImplinterface_def_with_overload_0)169 TEST_F(DeclareTest, noImplinterface_def_with_overload_0)
170 {
171 SetCurrentProgram(R"(
172 declare interface my_inter {
173 foo(arg?: int): void
174 }
175 )");
176 CheckExternalFlag("my_inter.foo:std.core.Object;void;");
177 CheckExternalFlag("my_inter.foo:void;");
178 }
179
180 } // namespace ark::es2panda::compiler::test
181