• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #include <cstring>
18 
19 #include "libabckit/include/c/abckit.h"
20 #include "helpers/helpers.h"
21 #include "helpers/helpers_runtime.h"
22 #include "libabckit/include/c/metadata_core.h"
23 #include "libabckit/include/c/extensions/arkts/metadata_arkts.h"
24 #include "ir_impl.h"
25 #include "libabckit/include/c/isa/isa_dynamic.h"
26 #include "metadata_inspect_impl.h"
27 #include "libabckit/include/c/statuses.h"
28 
29 namespace libabckit::test {
30 
31 static auto g_impl = AbckitGetApiImpl(ABCKIT_VERSION_RELEASE_1_0_0);
32 static auto g_implI = AbckitGetInspectApiImpl(ABCKIT_VERSION_RELEASE_1_0_0);
33 static auto g_implArkI = AbckitGetArktsInspectApiImpl(ABCKIT_VERSION_RELEASE_1_0_0);
34 static auto g_implM = AbckitGetModifyApiImpl(ABCKIT_VERSION_RELEASE_1_0_0);
35 static auto g_implArkM = AbckitGetArktsModifyApiImpl(ABCKIT_VERSION_RELEASE_1_0_0);
36 static auto g_implG = AbckitGetGraphApiImpl(ABCKIT_VERSION_RELEASE_1_0_0);
37 static auto g_dynG = AbckitGetIsaApiDynamicImpl(ABCKIT_VERSION_RELEASE_1_0_0);
38 
39 class LibAbcKitArkTSModifyApiModulesTest : public ::testing::Test {};
40 
41 constexpr auto MAIN_MODULE_NAME = "modules_dynamic_modify";
42 
43 // ========================================
44 // Helpers
45 // ========================================
46 
ModifyMetaDynModuleRemoveImport(AbckitFile * file,const std::string & name,bool shouldBeRemoved)47 static void ModifyMetaDynModuleRemoveImport(AbckitFile *file, const std::string &name, bool shouldBeRemoved)
48 {
49     helpers::ModuleByNameContext ctxFinder = {nullptr, MAIN_MODULE_NAME};
50     g_implI->fileEnumerateModules(file, &ctxFinder, helpers::ModuleByNameFinder);
51     ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
52     ASSERT_NE(ctxFinder.module, nullptr);
53     auto *module = ctxFinder.module;
54 
55     std::set<AbckitCoreImportDescriptor *> gotImports;
56     g_implI->moduleEnumerateImports(module, &gotImports, helpers::ModuleImportsCollector);
57     ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
58     ASSERT_EQ(gotImports.empty(), false);
59 
60     bool removed = false;
61     for (auto &gotImport : gotImports) {
62         auto impName = g_implI->importDescriptorGetAlias(gotImport);
63         auto strName = helpers::AbckitStringToString(impName);
64         if (strName == name) {
65             g_implArkM->moduleRemoveImport(g_implArkI->coreModuleToArktsModule(module),
66                                            g_implArkI->coreImportDescriptorToArktsImportDescriptor(gotImport));
67             ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
68             removed = true;
69             break;
70         }
71     }
72 
73     ASSERT_EQ(removed, shouldBeRemoved);
74 
75     std::set<AbckitCoreImportDescriptor *> gotImportsAfter;
76     g_implI->moduleEnumerateImports(module, &gotImportsAfter, helpers::ModuleImportsCollector);
77     ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
78     ASSERT_EQ(gotImportsAfter.empty(), false);
79 
80     for (auto &gotImportAfter : gotImportsAfter) {
81         auto impName = g_implI->importDescriptorGetAlias(gotImportAfter);
82         auto strName = helpers::AbckitStringToString(impName);
83         ASSERT_NE(strName, name);
84     }
85 }
86 
ModifyMetaDynModuleRemoveExport(AbckitFile * file,const std::string & exportName,bool shouldBeRemoved)87 static void ModifyMetaDynModuleRemoveExport(AbckitFile *file, const std::string &exportName, bool shouldBeRemoved)
88 {
89     helpers::ModuleByNameContext ctxFinder = {nullptr, MAIN_MODULE_NAME};
90     g_implI->fileEnumerateModules(file, &ctxFinder, helpers::ModuleByNameFinder);
91     ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
92     ASSERT_NE(ctxFinder.module, nullptr);
93     auto *module = ctxFinder.module;
94 
95     std::set<AbckitCoreExportDescriptor *> gotExports;
96     g_implI->moduleEnumerateExports(module, &gotExports, helpers::ModuleExportsCollector);
97     ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
98 
99     bool removed = false;
100     for (auto &gotExport : gotExports) {
101         auto expName = g_implI->exportDescriptorGetAlias(gotExport);
102         auto strName = helpers::AbckitStringToString(expName);
103         if (strName == exportName) {
104             g_implArkM->moduleRemoveExport(g_implArkI->coreModuleToArktsModule(module),
105                                            g_implArkI->coreExportDescriptorToArktsExportDescriptor(gotExport));
106             ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
107             removed = true;
108             break;
109         }
110     }
111 
112     ASSERT_EQ(removed, shouldBeRemoved);
113 
114     std::set<AbckitCoreExportDescriptor *> gotExportsAfter;
115     g_implI->moduleEnumerateExports(module, &gotExportsAfter, helpers::ModuleExportsCollector);
116     ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
117 
118     for (auto &gotExportAfter : gotExportsAfter) {
119         auto expName = g_implI->exportDescriptorGetAlias(gotExportAfter);
120         auto strName = helpers::AbckitStringToString(expName);
121         ASSERT_NE(strName, exportName);
122     }
123 }
124 
TransformIrDynModuleRemoveImport(AbckitGraph * graph,const std::string & name)125 static void TransformIrDynModuleRemoveImport(AbckitGraph *graph, const std::string &name)
126 {
127     AbckitInst *instWithName = helpers::FindFirstInst(
128         graph, ABCKIT_ISA_API_DYNAMIC_OPCODE_THROW_UNDEFINEDIFHOLEWITHNAME, [&](AbckitInst *inst) {
129             auto nameOffset = g_implG->iGetImmediate(inst, 0);
130             auto nameStr = graph->irInterface->GetStringIdByOffset(nameOffset);
131             return nameStr == name;
132         });
133 
134     ASSERT_NE(instWithName, nullptr);
135     auto ldExternalModuleVarInst = g_implG->iGetPrev(instWithName);
136     ASSERT_NE(ldExternalModuleVarInst, nullptr);
137     auto callArg0Inst = g_implG->iGetNext(instWithName);
138     ASSERT_NE(callArg0Inst, nullptr);
139 
140     g_implG->iRemove(instWithName);
141     g_implG->iRemove(ldExternalModuleVarInst);
142     g_implG->iRemove(callArg0Inst);
143 }
144 
TransformIrDynModuleRemoveNSImport(AbckitGraph * graph,const std::string & name)145 static void TransformIrDynModuleRemoveNSImport(AbckitGraph *graph, const std::string &name)
146 {
147     AbckitInst *ldObjByNameInst =
148         helpers::FindFirstInst(graph, ABCKIT_ISA_API_DYNAMIC_OPCODE_LDOBJBYNAME, [&](AbckitInst *inst) {
149             auto nameOffset = g_implG->iGetImmediate(inst, 1);
150             auto nameStr = graph->irInterface->GetStringIdByOffset(nameOffset);
151             return nameStr == name;
152         });
153 
154     ASSERT_NE(ldObjByNameInst, nullptr);
155     auto callThis0Inst = g_implG->iGetNext(ldObjByNameInst);
156     ASSERT_NE(callThis0Inst, nullptr);
157 
158     g_implG->iRemove(ldObjByNameInst);
159     g_implG->iRemove(callThis0Inst);
160 }
161 
TransformIrDynModuleRemoveExport(AbckitGraph * graph,const std::string & exportName)162 static void TransformIrDynModuleRemoveExport(AbckitGraph *graph, const std::string &exportName)
163 {
164     AbckitInst *instWithName = helpers::FindFirstInst(
165         graph, ABCKIT_ISA_API_DYNAMIC_OPCODE_THROW_UNDEFINEDIFHOLEWITHNAME, [&](AbckitInst *inst) {
166             auto nameOffset = g_implG->iGetImmediate(inst, 0);
167             auto nameStr = graph->irInterface->GetStringIdByOffset(nameOffset);
168             return nameStr == exportName;
169         });
170 
171     ASSERT_NE(instWithName, nullptr);
172     auto ldLocalModuleVarInst = g_implG->iGetPrev(instWithName);
173     ASSERT_NE(ldLocalModuleVarInst, nullptr);
174     auto callArg1Inst = g_implG->iGetNext(instWithName);
175     ASSERT_NE(callArg1Inst, nullptr);
176 
177     g_implG->iRemove(instWithName);
178     g_implG->iRemove(ldLocalModuleVarInst);
179     g_implG->iRemove(callArg1Inst);
180 
181     AbckitInst *stModuleVarInst =
182         helpers::FindFirstInst(graph, ABCKIT_ISA_API_DYNAMIC_OPCODE_STMODULEVAR, [&](AbckitInst *inst) {
183             return g_implG->iGetImmediate(inst, 0) == g_implG->iGetImmediate(ldLocalModuleVarInst, 0);
184         });
185 
186     ASSERT_NE(stModuleVarInst, nullptr);
187     g_implG->iRemove(stModuleVarInst);
188 }
189 
190 struct UserTransformerData {
191     std::string name;
192     std::string alias;
193     std::string moduleName;
194     bool isRegular = false;
195     AbckitDynamicExportKind kind = ABCKIT_DYNAMIC_EXPORT_KIND_LOCAL_EXPORT;
196 };
197 
AddImportFromDynamicModuleImpl(AbckitCoreModule * module,void * data)198 static void AddImportFromDynamicModuleImpl(AbckitCoreModule *module, void *data)
199 {
200     auto userTransformerData = reinterpret_cast<UserTransformerData *>(data);
201     AbckitFile *file = g_implI->moduleGetFile(module);
202 
203     helpers::ModuleByNameContext ctxFinder = {nullptr, (userTransformerData->moduleName).c_str()};
204     g_implI->fileEnumerateModules(file, &ctxFinder, helpers::ModuleByNameFinder);
205     ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
206     ASSERT_NE(ctxFinder.module, nullptr);
207 
208     AbckitArktsImportFromDynamicModuleCreateParams params {};
209     params.name = (userTransformerData->name).c_str();
210     params.alias = (userTransformerData->alias).c_str();
211 
212     auto newImport = g_implArkM->moduleAddImportFromArktsV1ToArktsV1(
213         g_implArkI->coreModuleToArktsModule(module), g_implArkI->coreModuleToArktsModule(ctxFinder.module), &params);
214     ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
215 
216     std::set<AbckitCoreImportDescriptor *> gotImports;
217     g_implI->moduleEnumerateImports(module, &gotImports, helpers::ModuleImportsCollector);
218 
219     bool existed = false;
220     for (auto &gotImport : gotImports) {
221         if (g_implArkI->coreImportDescriptorToArktsImportDescriptor(gotImport) != newImport) {
222             continue;
223         }
224         existed = true;
225 
226         auto impName = g_implI->importDescriptorGetName(gotImport);
227         auto strName = helpers::AbckitStringToString(impName);
228         auto impAlias = g_implI->importDescriptorGetAlias(gotImport);
229         auto strAlias = helpers::AbckitStringToString(impAlias);
230         ASSERT_EQ(userTransformerData->name, strName);
231         ASSERT_EQ(userTransformerData->alias, strAlias);
232         ASSERT_EQ(g_implI->importDescriptorGetImportedModule(gotImport), ctxFinder.module);
233         ASSERT_EQ(g_implI->importDescriptorGetImportingModule(gotImport), module);
234         ASSERT_EQ(gotImport->GetArkTSImpl()->payload.GetDynId().isRegularImport, userTransformerData->isRegular);
235     }
236 
237     ASSERT_EQ(existed, true);
238 }
239 
DynamicModuleAddExportImpl(AbckitCoreModule * module,void * data)240 static void DynamicModuleAddExportImpl(AbckitCoreModule *module, void *data)
241 {
242     auto userTransformerData = reinterpret_cast<UserTransformerData *>(data);
243     AbckitFile *file = g_implI->moduleGetFile(module);
244 
245     AbckitArktsDynamicModuleExportCreateParams params {};
246 
247     AbckitCoreModule *exported = nullptr;
248     if (!userTransformerData->moduleName.empty()) {
249         helpers::ModuleByNameContext ctxFinder = {nullptr, (userTransformerData->moduleName).c_str()};
250         g_implI->fileEnumerateModules(file, &ctxFinder, helpers::ModuleByNameFinder);
251         ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
252         ASSERT_NE(ctxFinder.module, nullptr);
253         exported = ctxFinder.module;
254     }
255     params.name = (userTransformerData->name).c_str();
256 
257     if (userTransformerData->alias.empty()) {
258         params.alias = nullptr;
259     } else {
260         params.alias = (userTransformerData->alias).c_str();
261     }
262 
263     auto newExport = g_implArkM->moduleAddExportFromArktsV1ToArktsV1(
264         g_implArkI->coreModuleToArktsModule(module), g_implArkI->coreModuleToArktsModule(exported), &params);
265     ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
266 
267     std::set<AbckitCoreExportDescriptor *> gotExports;
268     g_implI->moduleEnumerateExports(module, &gotExports, helpers::ModuleExportsCollector);
269 
270     bool existed = false;
271     for (auto &gotExport : gotExports) {
272         if (g_implArkI->coreExportDescriptorToArktsExportDescriptor(gotExport) != newExport) {
273             continue;
274         }
275         existed = true;
276 
277         auto expName = g_implI->exportDescriptorGetName(gotExport);
278         auto strName = helpers::AbckitStringToString(expName);
279         auto expAlias = g_implI->exportDescriptorGetAlias(gotExport);
280         auto strAlias = helpers::AbckitStringToString(expAlias);
281         ASSERT_EQ(userTransformerData->name, strName);
282         ASSERT_EQ(userTransformerData->alias, strAlias);
283         ASSERT_EQ(userTransformerData->kind, gotExport->GetArkTSImpl()->payload.GetDynamicPayload().kind);
284         if (userTransformerData->kind == AbckitDynamicExportKind::ABCKIT_DYNAMIC_EXPORT_KIND_LOCAL_EXPORT) {
285             ASSERT_EQ(g_implI->exportDescriptorGetExportedModule(gotExport), module);
286         } else {
287             ASSERT_EQ(g_implI->exportDescriptorGetExportedModule(gotExport), exported);
288         }
289         ASSERT_EQ(g_implI->exportDescriptorGetExportingModule(gotExport), module);
290     }
291 
292     ASSERT_EQ(existed, true);
293 }
294 
TransformIrAddImportedFunctionCall(AbckitGraph * graph,AbckitFile * file,const std::string & funcName)295 static void TransformIrAddImportedFunctionCall(AbckitGraph *graph, AbckitFile *file, const std::string &funcName)
296 {
297     auto abckitStrName = g_implM->createString(file, funcName.c_str(), funcName.size());
298     helpers::ModuleByNameContext ctxFinder = {nullptr, MAIN_MODULE_NAME};
299     g_implI->fileEnumerateModules(file, &ctxFinder, helpers::ModuleByNameFinder);
300     ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
301     ASSERT_NE(ctxFinder.module, nullptr);
302     helpers::ImportByAliasContext importFinder = {nullptr, funcName.c_str()};
303     g_implI->moduleEnumerateImports(ctxFinder.module, &importFinder, helpers::ImportByAliasFinder);
304     ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
305     ASSERT_NE(importFinder.id, nullptr);
306 
307     AbckitBasicBlock *mainBB = g_implG->bbGetSuccBlock(g_implG->gGetStartBasicBlock(graph), 0);
308     AbckitInst *lastInst = g_implG->bbGetLastInst(mainBB);
309     auto ldExternalModuleVarInst = g_dynG->iCreateLdexternalmodulevar(graph, importFinder.id);
310     ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
311     auto throwUndef = g_dynG->iCreateThrowUndefinedifholewithname(graph, ldExternalModuleVarInst, abckitStrName);
312     auto callInst = g_dynG->iCreateCallarg0(graph, ldExternalModuleVarInst);
313     g_implG->iInsertBefore(ldExternalModuleVarInst, lastInst);
314     g_implG->iInsertBefore(throwUndef, lastInst);
315     g_implG->iInsertBefore(callInst, lastInst);
316 }
317 
TransformIrAddImportedFunctionCallNS(AbckitGraph * graph,AbckitFile * file,const std::string & funcName,const std::string & moduleName)318 static void TransformIrAddImportedFunctionCallNS(AbckitGraph *graph, AbckitFile *file, const std::string &funcName,
319                                                  const std::string &moduleName)
320 {
321     auto abckitStrName = g_implM->createString(file, funcName.c_str(), funcName.size());
322     helpers::ModuleByNameContext ctxFinder = {nullptr, moduleName.c_str()};
323     g_implI->fileEnumerateModules(file, &ctxFinder, helpers::ModuleByNameFinder);
324     ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
325     ASSERT_NE(ctxFinder.module, nullptr);
326 
327     AbckitBasicBlock *mainBB = g_implG->bbGetSuccBlock(g_implG->gGetStartBasicBlock(graph), 0);
328     AbckitInst *lastInst = g_implG->bbGetLastInst(mainBB);
329     auto getModuleNamespaceInst = g_dynG->iCreateGetmodulenamespace(graph, ctxFinder.module);
330     ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
331     auto ldObjByNameInst = g_dynG->iCreateLdobjbyname(graph, getModuleNamespaceInst, abckitStrName);
332     auto callInst = g_dynG->iCreateCallthis0(graph, ldObjByNameInst, getModuleNamespaceInst);
333     g_implG->iInsertBefore(getModuleNamespaceInst, lastInst);
334     g_implG->iInsertBefore(ldObjByNameInst, lastInst);
335     g_implG->iInsertBefore(callInst, lastInst);
336 }
337 
TransformIrAddLocalExport(AbckitGraph * graph,AbckitFile * file,const std::string & varName,const std::string & moduleName)338 static void TransformIrAddLocalExport(AbckitGraph *graph, AbckitFile *file, const std::string &varName,
339                                       const std::string &moduleName)
340 {
341     AbckitBasicBlock *mainBB = g_implG->bbGetSuccBlock(g_implG->gGetStartBasicBlock(graph), 0);
342     AbckitInst *lastInst = g_implG->bbGetLastInst(mainBB);
343 
344     AbckitString *abckitStr = g_implM->createString(file, "print", strlen("print"));
345     auto tryLdGlobalByNameInst = g_dynG->iCreateTryldglobalbyname(graph, abckitStr);
346 
347     helpers::ModuleByNameContext ctxFinder = {nullptr, moduleName.c_str()};
348     g_implI->fileEnumerateModules(file, &ctxFinder, helpers::ModuleByNameFinder);
349     ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
350     ASSERT_NE(ctxFinder.module, nullptr);
351 
352     helpers::ExportByAliasContext exportFinder = {nullptr, varName.c_str()};
353     g_implI->moduleEnumerateExports(ctxFinder.module, &exportFinder, helpers::ExportByAliasFinder);
354     ASSERT_NE(exportFinder.ed, nullptr);
355 
356     auto constant = g_implG->gFindOrCreateConstantI32(graph, 5);
357     auto stModuleVarInst = g_dynG->iCreateStmodulevar(graph, constant, exportFinder.ed);
358     auto ldLocalModuleVarInst = g_dynG->iCreateLdlocalmodulevar(graph, exportFinder.ed);
359     AbckitString *varNameStr = g_implM->createString(file, varName.c_str(), varName.size());
360     auto throwUndef = g_dynG->iCreateThrowUndefinedifholewithname(graph, ldLocalModuleVarInst, varNameStr);
361     auto callInst = g_dynG->iCreateCallarg1(graph, tryLdGlobalByNameInst, ldLocalModuleVarInst);
362 
363     g_implG->iInsertBefore(stModuleVarInst, lastInst);
364     g_implG->iInsertBefore(tryLdGlobalByNameInst, lastInst);
365     g_implG->iInsertBefore(ldLocalModuleVarInst, lastInst);
366     g_implG->iInsertBefore(throwUndef, lastInst);
367     g_implG->iInsertBefore(callInst, lastInst);
368 }
369 
TransformIrAddIndirectExport(AbckitGraph * graph,AbckitFile * file,const std::string & varName,const std::string & moduleName)370 static void TransformIrAddIndirectExport(AbckitGraph *graph, AbckitFile *file, const std::string &varName,
371                                          const std::string &moduleName)
372 {
373     AbckitBasicBlock *mainBB = g_implG->bbGetSuccBlock(g_implG->gGetStartBasicBlock(graph), 0);
374     AbckitInst *lastInst = g_implG->bbGetLastInst(mainBB);
375 
376     AbckitString *abckitStr = g_implM->createString(file, "print", strlen("print"));
377     auto tryLdGlobalByNameInst = g_dynG->iCreateTryldglobalbyname(graph, abckitStr);
378 
379     helpers::ModuleByNameContext ctxFinder = {nullptr, moduleName.c_str()};
380     g_implI->fileEnumerateModules(file, &ctxFinder, helpers::ModuleByNameFinder);
381     ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
382     ASSERT_NE(ctxFinder.module, nullptr);
383 
384     helpers::ImportByAliasContext importFinder = {nullptr, varName.c_str()};
385     g_implI->moduleEnumerateImports(ctxFinder.module, &importFinder, helpers::ImportByAliasFinder);
386     ASSERT_NE(importFinder.id, nullptr);
387 
388     auto ldExternalModuleVarInst = g_dynG->iCreateLdexternalmodulevar(graph, importFinder.id);
389     AbckitString *varNameStr = g_implM->createString(file, varName.c_str(), varName.size());
390     auto throwUndef = g_dynG->iCreateThrowUndefinedifholewithname(graph, ldExternalModuleVarInst, varNameStr);
391     auto callInst = g_dynG->iCreateCallarg1(graph, tryLdGlobalByNameInst, ldExternalModuleVarInst);
392     g_implG->iInsertBefore(tryLdGlobalByNameInst, lastInst);
393     g_implG->iInsertBefore(ldExternalModuleVarInst, lastInst);
394     g_implG->iInsertBefore(throwUndef, lastInst);
395     g_implG->iInsertBefore(callInst, lastInst);
396 }
397 
TransformIrAddStarExport(AbckitGraph * graph,AbckitFile * file,const std::string & funcName,const std::string & moduleName)398 static void TransformIrAddStarExport(AbckitGraph *graph, AbckitFile *file, const std::string &funcName,
399                                      const std::string &moduleName)
400 {
401     AbckitBasicBlock *mainBB = g_implG->bbGetSuccBlock(g_implG->gGetStartBasicBlock(graph), 0);
402     AbckitInst *lastInst = g_implG->bbGetLastInst(mainBB);
403 
404     helpers::ModuleByNameContext ctxFinder = {nullptr, moduleName.c_str()};
405     g_implI->fileEnumerateModules(file, &ctxFinder, helpers::ModuleByNameFinder);
406     ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
407     ASSERT_NE(ctxFinder.module, nullptr);
408 
409     auto getModuleNamespaceInst = g_dynG->iCreateGetmodulenamespace(graph, ctxFinder.module);
410     AbckitString *funcNameStr = g_implM->createString(file, funcName.c_str(), funcName.size());
411     auto ldObjByNameInst = g_dynG->iCreateLdobjbyname(graph, getModuleNamespaceInst, funcNameStr);
412     auto callInst = g_dynG->iCreateCallthis0(graph, ldObjByNameInst, getModuleNamespaceInst);
413     g_implG->iInsertBefore(getModuleNamespaceInst, lastInst);
414     g_implG->iInsertBefore(ldObjByNameInst, lastInst);
415     g_implG->iInsertBefore(callInst, lastInst);
416 }
417 
TransformIrAddStarExportFunc(AbckitGraph * graph,AbckitFile * file,const std::string & exportName,const std::string & moduleName)418 static void TransformIrAddStarExportFunc(AbckitGraph *graph, AbckitFile *file, const std::string &exportName,
419                                          const std::string &moduleName)
420 {
421     AbckitBasicBlock *mainBB = g_implG->bbGetSuccBlock(g_implG->gGetStartBasicBlock(graph), 0);
422     AbckitInst *lastInst = g_implG->bbGetLastInst(mainBB);
423 
424     helpers::ModuleByNameContext ctxFinder = {nullptr, moduleName.c_str()};
425     g_implI->fileEnumerateModules(file, &ctxFinder, helpers::ModuleByNameFinder);
426     ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
427     ASSERT_NE(ctxFinder.module, nullptr);
428 
429     helpers::ModuleByNameContext ctxFinder2 = {nullptr, "modules/module4"};
430     g_implI->fileEnumerateModules(file, &ctxFinder2, helpers::ModuleByNameFinder);
431     ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
432     ASSERT_NE(ctxFinder2.module, nullptr);
433 
434     helpers::ExportByAliasContext exportFinder = {nullptr, exportName.c_str()};
435     g_implI->moduleEnumerateExports(ctxFinder2.module, &exportFinder, helpers::ExportByAliasFinder);
436     ASSERT_NE(exportFinder.ed, nullptr);
437 
438     auto getModuleNamespaceInst = g_dynG->iCreateGetmodulenamespace(graph, ctxFinder.module);           // module3
439     auto stModuleVarInst = g_dynG->iCreateStmodulevar(graph, getModuleNamespaceInst, exportFinder.ed);  // NewStarExport
440     g_implG->iInsertBefore(getModuleNamespaceInst, lastInst);
441     g_implG->iInsertBefore(stModuleVarInst, lastInst);
442 }
443 
TransformIrAddStarExportFunc2(AbckitGraph * graph,AbckitFile * file,const std::string & funcName,const std::string & moduleName)444 static void TransformIrAddStarExportFunc2(AbckitGraph *graph, AbckitFile *file, const std::string &funcName,
445                                           const std::string &moduleName)
446 {
447     AbckitBasicBlock *mainBB = g_implG->bbGetSuccBlock(g_implG->gGetStartBasicBlock(graph), 0);
448     AbckitInst *lastInst = g_implG->bbGetLastInst(mainBB);
449 
450     helpers::ModuleByNameContext ctxFinder = {nullptr, moduleName.c_str()};
451     g_implI->fileEnumerateModules(file, &ctxFinder, helpers::ModuleByNameFinder);
452     ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
453     ASSERT_NE(ctxFinder.module, nullptr);
454 
455     helpers::ImportByAliasContext importFinder = {nullptr, "NewStarExport"};
456     g_implI->moduleEnumerateImports(ctxFinder.module, &importFinder, helpers::ImportByAliasFinder);
457     ASSERT_NE(importFinder.id, nullptr);
458 
459     auto ldExternalModuleVarInst = g_dynG->iCreateLdexternalmodulevar(graph, importFinder.id);
460     auto exportStarName = g_implM->createString(file, "NewStarExport", strlen("NewStarExport"));
461     auto throwUndef = g_dynG->iCreateThrowUndefinedifholewithname(graph, ldExternalModuleVarInst, exportStarName);
462     auto funcNameStr = g_implM->createString(file, funcName.c_str(), funcName.size());
463     auto ldObjByNameInst = g_dynG->iCreateLdobjbyname(graph, ldExternalModuleVarInst, funcNameStr);
464     auto callInst = g_dynG->iCreateCallthis0(graph, ldObjByNameInst, ldExternalModuleVarInst);
465     g_implG->iInsertBefore(ldExternalModuleVarInst, lastInst);
466     g_implG->iInsertBefore(throwUndef, lastInst);
467     g_implG->iInsertBefore(ldObjByNameInst, lastInst);
468     g_implG->iInsertBefore(callInst, lastInst);
469 }
470 
471 // ========================================
472 // Modules Tests
473 // ========================================
474 
475 constexpr auto UNMODIFIED_EXPECTED_OUTPUT =
476     "regular import func1 from module1\nregular import func1 from module2\nregular default import func1 from "
477     "module3\nregular default import func2 from module2\nnamespace import func2 from module1\nnamespace import "
478     "func3 from module1\n1\n2\nnamespace import func3 from module2\nthe same func from module3\n";
479 
480 constexpr auto OUTPUT_PATH =
481     ABCKIT_ABC_DIR "ut/extensions/arkts/modify_api/modules/modules_dynamic_modify_modified.abc";
482 
483 constexpr auto INPUT_PATH = ABCKIT_ABC_DIR "ut/extensions/arkts/modify_api/modules/modules_dynamic_modify.abc";
484 
485 // Test: test-kind=api, api=ArktsModifyApiImpl::moduleRemoveImport, abc-kind=ArkTS1, category=positive, extension=c
TEST_F(LibAbcKitArkTSModifyApiModulesTest,DynamicModuleRemoveImport)486 TEST_F(LibAbcKitArkTSModifyApiModulesTest, DynamicModuleRemoveImport)
487 {
488     auto output = helpers::ExecuteDynamicAbc(INPUT_PATH, MAIN_MODULE_NAME);
489     auto expected = UNMODIFIED_EXPECTED_OUTPUT;
490     EXPECT_TRUE(helpers::Match(output, expected));
491 
492     helpers::TransformMethod(INPUT_PATH, OUTPUT_PATH, "modules_dynamic_modify.func_main_0",
493                              [](AbckitFile *file, AbckitCoreFunction *, AbckitGraph *graph) {
494                                  TransformIrDynModuleRemoveImport(graph, "regularImportFunc1FromModule1");
495                                  ModifyMetaDynModuleRemoveImport(file, "regularImportFunc1FromModule1", true);
496                              });
497 
498     output = helpers::ExecuteDynamicAbc(OUTPUT_PATH, MAIN_MODULE_NAME);
499     expected =
500         "regular import func1 from module2\nregular default import func1 from module3\nregular default import func2 "
501         "from module2\nnamespace import func2 from module1\nnamespace import func3 from module1\n1\n2\nnamespace "
502         "import func3 from module2\nthe same func from module3\n";
503     EXPECT_TRUE(helpers::Match(output, expected));
504 }
505 
506 // Test: test-kind=api, api=ArktsModifyApiImpl::moduleRemoveImport, abc-kind=ArkTS1, category=positive, extension=c
TEST_F(LibAbcKitArkTSModifyApiModulesTest,DynamicModuleRemoveNSImport)507 TEST_F(LibAbcKitArkTSModifyApiModulesTest, DynamicModuleRemoveNSImport)
508 {
509     auto output = helpers::ExecuteDynamicAbc(INPUT_PATH, MAIN_MODULE_NAME);
510     auto expected = UNMODIFIED_EXPECTED_OUTPUT;
511     EXPECT_TRUE(helpers::Match(output, expected));
512 
513     helpers::TransformMethod(INPUT_PATH, OUTPUT_PATH, "modules_dynamic_modify.func_main_0",
514                              [](AbckitFile *file, AbckitCoreFunction *, AbckitGraph *graph) {
515                                  TransformIrDynModuleRemoveNSImport(graph, "namespaceImportFunc2FromModule1");
516                                  TransformIrDynModuleRemoveNSImport(graph, "namespaceImportFunc3FromModule1");
517                                  ModifyMetaDynModuleRemoveImport(file, "NS1", true);
518                              });
519 
520     output = helpers::ExecuteDynamicAbc(OUTPUT_PATH, MAIN_MODULE_NAME);
521     expected =
522         "regular import func1 from module1\nregular import func1 from module2\nregular default import func1 from "
523         "module3\nregular default import func2 from module2\n1\n2\nnamespace import func3 from module2\nthe same func "
524         "from module3\n";
525     EXPECT_TRUE(helpers::Match(output, expected));
526 }
527 
528 // Test: test-kind=api, api=ArktsModifyApiImpl::moduleRemoveImport, abc-kind=ArkTS1, category=positive, extension=c
TEST_F(LibAbcKitArkTSModifyApiModulesTest,DynamicModuleRemoveImportAndModule)529 TEST_F(LibAbcKitArkTSModifyApiModulesTest, DynamicModuleRemoveImportAndModule)
530 {
531     auto output = helpers::ExecuteDynamicAbc(INPUT_PATH, MAIN_MODULE_NAME);
532     auto expected = UNMODIFIED_EXPECTED_OUTPUT;
533     EXPECT_TRUE(helpers::Match(output, expected));
534 
535     helpers::TransformMethod(INPUT_PATH, OUTPUT_PATH, "modules_dynamic_modify.func_main_0",
536                              [](AbckitFile *file, AbckitCoreFunction *, AbckitGraph *graph) {
537                                  TransformIrDynModuleRemoveImport(graph, "regularDefaultImportFunc1FromModule3");
538                                  ModifyMetaDynModuleRemoveImport(file, "regularDefaultImportFunc1FromModule3", true);
539                              });
540 
541     output = helpers::ExecuteDynamicAbc(OUTPUT_PATH, MAIN_MODULE_NAME);
542     expected =
543         "regular import func1 from module1\nregular import func1 from module2\nregular default import func2 from "
544         "module2\nnamespace import func2 from module1\nnamespace import func3 from module1\n1\n2\nnamespace import "
545         "func3 from module2\nthe same func from module3\n";
546     EXPECT_TRUE(helpers::Match(output, expected));
547 }
548 
549 // Test: test-kind=api, api=ArktsModifyApiImpl::moduleRemoveImport, abc-kind=ArkTS1, category=negative
TEST_F(LibAbcKitArkTSModifyApiModulesTest,DynamicModuleRemoveImportWithWrongName)550 TEST_F(LibAbcKitArkTSModifyApiModulesTest, DynamicModuleRemoveImportWithWrongName)
551 {
552     auto output = helpers::ExecuteDynamicAbc(INPUT_PATH, MAIN_MODULE_NAME);
553     auto expected = UNMODIFIED_EXPECTED_OUTPUT;
554     EXPECT_TRUE(helpers::Match(output, expected));
555 
556     helpers::TransformMethod(INPUT_PATH, OUTPUT_PATH, "modules_dynamic_modify.func_main_0",
557                              [](AbckitFile *file, AbckitCoreFunction *, AbckitGraph *) {
558                                  ModifyMetaDynModuleRemoveImport(file, "R", false);
559                              });
560 
561     output = helpers::ExecuteDynamicAbc(OUTPUT_PATH, MAIN_MODULE_NAME);
562     expected = UNMODIFIED_EXPECTED_OUTPUT;
563     EXPECT_TRUE(helpers::Match(output, expected));
564 }
565 
566 // Test: test-kind=api, api=ArktsModifyApiImpl::moduleRemoveImport, abc-kind=ArkTS1, category=negative
TEST_F(LibAbcKitArkTSModifyApiModulesTest,DynamicModuleRemoveWrongImport)567 TEST_F(LibAbcKitArkTSModifyApiModulesTest, DynamicModuleRemoveWrongImport)
568 {
569     auto output = helpers::ExecuteDynamicAbc(INPUT_PATH, MAIN_MODULE_NAME);
570     auto expected = UNMODIFIED_EXPECTED_OUTPUT;
571     EXPECT_TRUE(helpers::Match(output, expected));
572 
573     helpers::TransformMethod(
574         INPUT_PATH, OUTPUT_PATH, "modules_dynamic_modify.func_main_0",
575         [](AbckitFile *file, AbckitCoreFunction *method, AbckitGraph *) {
576             auto *newID = new AbckitCoreImportDescriptor();
577             auto newAID = std::make_unique<AbckitArktsImportDescriptor>();
578             newAID->core = newID;
579             newID->impl = std::move(newAID);
580             newID->importingModule = method->owningModule;
581             newID->importedModule = method->owningModule;  // just to make object newID valid
582             helpers::ModuleByNameContext ctxFinder = {nullptr, MAIN_MODULE_NAME};
583             g_implI->fileEnumerateModules(file, &ctxFinder, helpers::ModuleByNameFinder);
584             EXPECT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
585             EXPECT_NE(ctxFinder.module, nullptr);
586             auto *module = ctxFinder.module;
587             g_implArkM->moduleRemoveImport(g_implArkI->coreModuleToArktsModule(module),
588                                            g_implArkI->coreImportDescriptorToArktsImportDescriptor(newID));
589             EXPECT_EQ(g_impl->getLastError(), ABCKIT_STATUS_BAD_ARGUMENT);
590             g_implI->fileEnumerateModules(file, &ctxFinder, helpers::ModuleByNameFinder);  // just to clear last error
591             delete newID;
592         });
593 
594     output = helpers::ExecuteDynamicAbc(OUTPUT_PATH, MAIN_MODULE_NAME);
595     expected = UNMODIFIED_EXPECTED_OUTPUT;
596     EXPECT_TRUE(helpers::Match(output, expected));
597 }
598 
599 // Test: test-kind=api, api=ArktsModifyApiImpl::moduleRemoveImport, abc-kind=ArkTS1, category=negative, extension=c
TEST_F(LibAbcKitArkTSModifyApiModulesTest,DISABLED_DynamicModuleRemoveImport_WrongTargets)600 TEST_F(LibAbcKitArkTSModifyApiModulesTest, DISABLED_DynamicModuleRemoveImport_WrongTargets)
601 {
602     // Test is disabled
603     // importDescriptorGetAlias has no ArkTS_V2 support, aliases for imports are not implemented
604 
605     AbckitFile *file = nullptr;
606     helpers::AssertOpenAbc(INPUT_PATH, &file);
607 
608     helpers::ModuleByNameContext ctxFinder = {nullptr, MAIN_MODULE_NAME};
609     g_implI->fileEnumerateModules(file, &ctxFinder, helpers::ModuleByNameFinder);
610     ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
611     ASSERT_NE(ctxFinder.module, nullptr);
612     auto *module = ctxFinder.module;
613 
614     // Find import from module/module4 in module/module3
615     ctxFinder = {nullptr, "modules/module3"};
616     g_implI->fileEnumerateModules(file, &ctxFinder, helpers::ModuleByNameFinder);
617     ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
618     ASSERT_NE(ctxFinder.module, nullptr);
619     auto *module2 = ctxFinder.module;
620     // Set another module target
621     module2->target = ABCKIT_TARGET_ARK_TS_V2;
622 
623     std::set<AbckitCoreImportDescriptor *> gotImports;
624     g_implI->moduleEnumerateImports(module2, &gotImports, helpers::ModuleImportsCollector);
625     ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
626     ASSERT_EQ(gotImports.empty(), false);
627 
628     // Try to remove found import from main module
629     auto importName = "regularImportFunc1FromModule1";
630     for (auto &gotImport : gotImports) {
631         auto impName = g_implI->importDescriptorGetAlias(gotImport);
632         auto strName = helpers::AbckitStringToString(impName);
633         if (strName == importName) {
634             g_implArkM->moduleRemoveImport(g_implArkI->coreModuleToArktsModule(module),
635                                            g_implArkI->coreImportDescriptorToArktsImportDescriptor(gotImport));
636             ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_WRONG_TARGET);
637             break;
638         }
639     }
640 
641     g_impl->closeFile(file);
642 }
643 
644 // Test: test-kind=api, api=ArktsModifyApiImpl::moduleRemoveExport, abc-kind=ArkTS1, category=positive, extension=c
TEST_F(LibAbcKitArkTSModifyApiModulesTest,DynamicModuleRemoveExport)645 TEST_F(LibAbcKitArkTSModifyApiModulesTest, DynamicModuleRemoveExport)
646 {
647     auto output = helpers::ExecuteDynamicAbc(INPUT_PATH, MAIN_MODULE_NAME);
648     auto expected = UNMODIFIED_EXPECTED_OUTPUT;
649     EXPECT_TRUE(helpers::Match(output, expected));
650 
651     helpers::TransformMethod(INPUT_PATH, OUTPUT_PATH, "modules_dynamic_modify.func_main_0",
652                              [](AbckitFile *file, AbckitCoreFunction *, AbckitGraph *graph) {
653                                  TransformIrDynModuleRemoveExport(graph, "LocalExportConst");
654                                  ModifyMetaDynModuleRemoveExport(file, "LocalExportConst", true);
655                              });
656 
657     output = helpers::ExecuteDynamicAbc(OUTPUT_PATH, MAIN_MODULE_NAME);
658     expected =
659         "regular import func1 from module1\nregular import func1 from module2\nregular default import func1 from "
660         "module3\nregular default import func2 from module2\nnamespace import func2 from module1\nnamespace import "
661         "func3 from module1\n2\nnamespace import func3 from module2\nthe same func from module3\n";
662     EXPECT_TRUE(helpers::Match(output, expected));
663 }
664 
665 // Test: test-kind=api, api=ArktsModifyApiImpl::moduleRemoveExport, abc-kind=ArkTS1, category=negative
TEST_F(LibAbcKitArkTSModifyApiModulesTest,DynamicModuleRemoveExportWithWrongName)666 TEST_F(LibAbcKitArkTSModifyApiModulesTest, DynamicModuleRemoveExportWithWrongName)
667 {
668     auto output = helpers::ExecuteDynamicAbc(INPUT_PATH, MAIN_MODULE_NAME);
669     auto expected = UNMODIFIED_EXPECTED_OUTPUT;
670     EXPECT_TRUE(helpers::Match(output, expected));
671 
672     helpers::TransformMethod(INPUT_PATH, OUTPUT_PATH, "modules_dynamic_modify.func_main_0",
673                              [](AbckitFile *file, AbckitCoreFunction *, AbckitGraph *) {
674                                  ModifyMetaDynModuleRemoveExport(file, "R", false);
675                              });
676 
677     output = helpers::ExecuteDynamicAbc(OUTPUT_PATH, MAIN_MODULE_NAME);
678     expected = UNMODIFIED_EXPECTED_OUTPUT;
679     EXPECT_TRUE(helpers::Match(output, expected));
680 }
681 
682 // Test: test-kind=api, api=ArktsModifyApiImpl::moduleRemoveExport, abc-kind=ArkTS1, category=negative
TEST_F(LibAbcKitArkTSModifyApiModulesTest,DynamicModuleRemoveWrongExport)683 TEST_F(LibAbcKitArkTSModifyApiModulesTest, DynamicModuleRemoveWrongExport)
684 {
685     auto output = helpers::ExecuteDynamicAbc(INPUT_PATH, MAIN_MODULE_NAME);
686     auto expected = UNMODIFIED_EXPECTED_OUTPUT;
687     EXPECT_TRUE(helpers::Match(output, expected));
688 
689     helpers::TransformMethod(
690         INPUT_PATH, OUTPUT_PATH, "modules_dynamic_modify.func_main_0",
691         [](AbckitFile *file, AbckitCoreFunction *method, AbckitGraph *) {
692             auto *newED = new AbckitCoreExportDescriptor();
693             auto newAED = std::make_unique<AbckitArktsExportDescriptor>();
694             newAED->core = newED;
695             newED->impl = std::move(newAED);
696             newED->exportingModule = method->owningModule;
697             newED->exportedModule = method->owningModule;  // just to make object newED valid
698             helpers::ModuleByNameContext ctxFinder = {nullptr, MAIN_MODULE_NAME};
699             g_implI->fileEnumerateModules(file, &ctxFinder, helpers::ModuleByNameFinder);
700             EXPECT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
701             EXPECT_NE(ctxFinder.module, nullptr);
702             auto *module = ctxFinder.module;
703             g_implArkM->moduleRemoveExport(g_implArkI->coreModuleToArktsModule(module),
704                                            g_implArkI->coreExportDescriptorToArktsExportDescriptor(newED));
705             EXPECT_EQ(g_impl->getLastError(), ABCKIT_STATUS_BAD_ARGUMENT);
706             g_implI->fileEnumerateModules(file, &ctxFinder, helpers::ModuleByNameFinder);  // just to clear last error
707             delete newED;
708         });
709 
710     output = helpers::ExecuteDynamicAbc(OUTPUT_PATH, MAIN_MODULE_NAME);
711     expected = UNMODIFIED_EXPECTED_OUTPUT;
712     EXPECT_TRUE(helpers::Match(output, expected));
713 }
714 
715 // Test: test-kind=api, api=ArktsModifyApiImpl::moduleRemoveExport, abc-kind=ArkTS1, category=negative
TEST_F(LibAbcKitArkTSModifyApiModulesTest,DISABLED_DynamicModuleRemoveExport_WrongTargets)716 TEST_F(LibAbcKitArkTSModifyApiModulesTest, DISABLED_DynamicModuleRemoveExport_WrongTargets)
717 {
718     // Test is disabled
719     // exportDescriptorGetAlias has no ArkTS_V2 support, aliases for exports are not implemented
720 
721     AbckitFile *file = nullptr;
722     helpers::AssertOpenAbc(INPUT_PATH, &file);
723 
724     helpers::ModuleByNameContext ctxFinder = {nullptr, MAIN_MODULE_NAME};
725     g_implI->fileEnumerateModules(file, &ctxFinder, helpers::ModuleByNameFinder);
726     ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
727     ASSERT_NE(ctxFinder.module, nullptr);
728     auto *module = ctxFinder.module;
729 
730     // Find export in module/module3
731     ctxFinder = {nullptr, "modules/module3"};
732     g_implI->fileEnumerateModules(file, &ctxFinder, helpers::ModuleByNameFinder);
733     ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
734     ASSERT_NE(ctxFinder.module, nullptr);
735     auto *module2 = ctxFinder.module;
736     // Set another module target
737     module2->target = ABCKIT_TARGET_ARK_TS_V2;
738 
739     std::set<AbckitCoreExportDescriptor *> gotExports;
740     g_implI->moduleEnumerateExports(module2, &gotExports, helpers::ModuleExportsCollector);
741     ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
742     ASSERT_EQ(gotExports.empty(), false);
743 
744     auto exportName = "regularDefaultImportFunc1FromModule3";
745     for (auto &gotExport : gotExports) {
746         auto expName = g_implI->exportDescriptorGetAlias(gotExport);
747         auto strName = helpers::AbckitStringToString(expName);
748         if (strName == exportName) {
749             g_implArkM->moduleRemoveExport(g_implArkI->coreModuleToArktsModule(module),
750                                            g_implArkI->coreExportDescriptorToArktsExportDescriptor(gotExport));
751             ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_WRONG_TARGET);
752             break;
753         }
754     }
755 
756     g_impl->closeFile(file);
757 }
758 
759 // Test: test-kind=api, api=ArktsModifyApiImpl::moduleAddImportFromArktsV1ToArktsV1, abc-kind=ArkTS1,
760 // category=positive
TEST_F(LibAbcKitArkTSModifyApiModulesTest,ModuleAddImportFromDynamicModule_RegularImport)761 TEST_F(LibAbcKitArkTSModifyApiModulesTest, ModuleAddImportFromDynamicModule_RegularImport)
762 {
763     AbckitFile *file = nullptr;
764     helpers::AssertOpenAbc(INPUT_PATH, &file);
765 
766     helpers::ModuleByNameContext ctxFinder = {nullptr, MAIN_MODULE_NAME};
767     g_implI->fileEnumerateModules(file, &ctxFinder, helpers::ModuleByNameFinder);
768     ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
769     ASSERT_NE(ctxFinder.module, nullptr);
770     auto module = ctxFinder.module;
771     UserTransformerData utd;
772     utd.name = "newImportedFunc";
773     utd.alias = "newImportedFunc";
774     utd.moduleName = "modules/module3";
775     utd.isRegular = true;
776     AddImportFromDynamicModuleImpl(module, &utd);
777     ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
778 
779     g_impl->writeAbc(file, OUTPUT_PATH, strlen(OUTPUT_PATH));
780     ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
781     g_impl->closeFile(file);
782     ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
783 
784     auto output = helpers::ExecuteDynamicAbc(OUTPUT_PATH, MAIN_MODULE_NAME);
785     auto expected = UNMODIFIED_EXPECTED_OUTPUT;
786     EXPECT_TRUE(helpers::Match(output, expected));
787 
788     helpers::TransformMethod(
789         OUTPUT_PATH, OUTPUT_PATH, "modules_dynamic_modify.func_main_0",
790         [](AbckitFile *, AbckitCoreFunction *method, AbckitGraph *graph) {
791             TransformIrAddImportedFunctionCall(graph, g_implI->functionGetFile(method), "newImportedFunc");
792         },
793         []([[maybe_unused]] AbckitGraph *graph) {});
794 
795     output = helpers::ExecuteDynamicAbc(OUTPUT_PATH, MAIN_MODULE_NAME);
796     expected =
797         "regular import func1 from module1\nregular import func1 from module2\nregular default import func1 from "
798         "module3\nregular default import func2 from module2\nnamespace import func2 from module1\nnamespace import "
799         "func3 from module1\n1\n2\nnamespace import func3 from module2\nthe same func from module3\nnew imported func "
800         "from module3\n";
801     EXPECT_TRUE(helpers::Match(output, expected));
802 }
803 
804 // Test: test-kind=api, api=ArktsModifyApiImpl::moduleAddImportFromArktsV1ToArktsV1, abc-kind=ArkTS1,
805 // category=positive
TEST_F(LibAbcKitArkTSModifyApiModulesTest,ModuleAddImportFromDynamicModule_RegularImport2)806 TEST_F(LibAbcKitArkTSModifyApiModulesTest, ModuleAddImportFromDynamicModule_RegularImport2)
807 {
808     AbckitFile *file = nullptr;
809     helpers::AssertOpenAbc(INPUT_PATH, &file);
810 
811     helpers::ModuleByNameContext ctxFinder = {nullptr, MAIN_MODULE_NAME};
812     g_implI->fileEnumerateModules(file, &ctxFinder, helpers::ModuleByNameFinder);
813     ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
814     ASSERT_NE(ctxFinder.module, nullptr);
815     auto module = ctxFinder.module;
816     UserTransformerData utd;
817     utd.name = "newImportedFunc";
818     utd.alias = "NewImportedFuncAlias";
819     utd.moduleName = "modules/module3";
820     utd.isRegular = true;
821     AddImportFromDynamicModuleImpl(module, &utd);
822     ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
823 
824     g_impl->writeAbc(file, OUTPUT_PATH, strlen(OUTPUT_PATH));
825     ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
826     g_impl->closeFile(file);
827     ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
828 
829     auto output = helpers::ExecuteDynamicAbc(OUTPUT_PATH, MAIN_MODULE_NAME);
830     auto expected = UNMODIFIED_EXPECTED_OUTPUT;
831     EXPECT_TRUE(helpers::Match(output, expected));
832 
833     helpers::TransformMethod(
834         OUTPUT_PATH, OUTPUT_PATH, "modules_dynamic_modify.func_main_0",
835         [](AbckitFile *, AbckitCoreFunction *method, AbckitGraph *graph) {
836             TransformIrAddImportedFunctionCall(graph, g_implI->functionGetFile(method), "NewImportedFuncAlias");
837         },
838         []([[maybe_unused]] AbckitGraph *graph) {});
839 
840     output = helpers::ExecuteDynamicAbc(OUTPUT_PATH, MAIN_MODULE_NAME);
841     expected =
842         "regular import func1 from module1\nregular import func1 from module2\nregular default import func1 from "
843         "module3\nregular default import func2 from module2\nnamespace import func2 from module1\nnamespace import "
844         "func3 from module1\n1\n2\nnamespace import func3 from module2\nthe same func from module3\nnew imported func "
845         "from module3\n";
846     EXPECT_TRUE(helpers::Match(output, expected));
847 }
848 
849 // Test: test-kind=api, api=ArktsModifyApiImpl::moduleAddImportFromArktsV1ToArktsV1, abc-kind=ArkTS1,
850 // category=positive
TEST_F(LibAbcKitArkTSModifyApiModulesTest,ModuleAddImportFromDynamicModule_RegularImport3)851 TEST_F(LibAbcKitArkTSModifyApiModulesTest, ModuleAddImportFromDynamicModule_RegularImport3)
852 {
853     auto output = helpers::ExecuteDynamicAbc(INPUT_PATH, MAIN_MODULE_NAME);
854     auto expected = UNMODIFIED_EXPECTED_OUTPUT;
855     EXPECT_TRUE(helpers::Match(output, expected));
856     AbckitFile *file = nullptr;
857 
858     helpers::AssertOpenAbc(INPUT_PATH, &file);
859 
860     helpers::ModuleByNameContext ctxFinder = {nullptr, MAIN_MODULE_NAME};
861     g_implI->fileEnumerateModules(file, &ctxFinder, helpers::ModuleByNameFinder);
862     ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
863     ASSERT_NE(ctxFinder.module, nullptr);
864     auto module = ctxFinder.module;
865     UserTransformerData utd;
866     utd.name = "newImportedFuncFromModule4";
867     utd.alias = "NewImportedFuncAlias";
868     utd.moduleName = "modules/module4";
869     utd.isRegular = true;
870     AddImportFromDynamicModuleImpl(module, &utd);
871     ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
872 
873     g_impl->writeAbc(file, OUTPUT_PATH, strlen(OUTPUT_PATH));
874     ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
875     g_impl->closeFile(file);
876     ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
877 
878     output = helpers::ExecuteDynamicAbc(OUTPUT_PATH, MAIN_MODULE_NAME);
879     expected = UNMODIFIED_EXPECTED_OUTPUT;
880     EXPECT_TRUE(helpers::Match(output, expected));
881 
882     helpers::TransformMethod(
883         OUTPUT_PATH, OUTPUT_PATH, "modules_dynamic_modify.func_main_0",
884         [](AbckitFile *, AbckitCoreFunction *method, AbckitGraph *graph) {
885             TransformIrAddImportedFunctionCall(graph, g_implI->functionGetFile(method), "NewImportedFuncAlias");
886         },
887         []([[maybe_unused]] AbckitGraph *graph) {});
888 
889     output = helpers::ExecuteDynamicAbc(OUTPUT_PATH, MAIN_MODULE_NAME);
890     expected =
891         "regular import func1 from module1\nregular import func1 from module2\nregular default import func1 from "
892         "module3\nregular default import func2 from module2\nnamespace import func2 from module1\nnamespace import "
893         "func3 from module1\n1\n2\nnamespace import func3 from module2\nthe same func from module3\nnew imported func "
894         "from module4\n";
895     EXPECT_TRUE(helpers::Match(output, expected));
896 }
897 
898 // Test: test-kind=api, api=ArktsModifyApiImpl::moduleAddImportFromArktsV1ToArktsV1, abc-kind=ArkTS1,
899 // category=positive
TEST_F(LibAbcKitArkTSModifyApiModulesTest,ModuleAddImportFromDynamicModule_RegularImport4)900 TEST_F(LibAbcKitArkTSModifyApiModulesTest, ModuleAddImportFromDynamicModule_RegularImport4)
901 {
902     auto output = helpers::ExecuteDynamicAbc(INPUT_PATH, MAIN_MODULE_NAME);
903     auto expected = UNMODIFIED_EXPECTED_OUTPUT;
904     EXPECT_TRUE(helpers::Match(output, expected));
905     AbckitFile *file = nullptr;
906 
907     helpers::AssertOpenAbc(INPUT_PATH, &file);
908 
909     helpers::ModuleByNameContext ctxFinder = {nullptr, MAIN_MODULE_NAME};
910     g_implI->fileEnumerateModules(file, &ctxFinder, helpers::ModuleByNameFinder);
911     ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
912     ASSERT_NE(ctxFinder.module, nullptr);
913     auto module = ctxFinder.module;
914     UserTransformerData utd;
915     utd.name = "default";
916     utd.alias = "newImportedDefaultFuncFromModule4";
917     utd.moduleName = "modules/module4";
918     utd.isRegular = true;
919     AddImportFromDynamicModuleImpl(module, &utd);
920     ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
921 
922     g_impl->writeAbc(file, OUTPUT_PATH, strlen(OUTPUT_PATH));
923     ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
924     g_impl->closeFile(file);
925     ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
926 
927     output = helpers::ExecuteDynamicAbc(OUTPUT_PATH, MAIN_MODULE_NAME);
928     expected = UNMODIFIED_EXPECTED_OUTPUT;
929     EXPECT_TRUE(helpers::Match(output, expected));
930 
931     helpers::TransformMethod(
932         OUTPUT_PATH, OUTPUT_PATH, "modules_dynamic_modify.func_main_0",
933         [](AbckitFile *, AbckitCoreFunction *method, AbckitGraph *graph) {
934             TransformIrAddImportedFunctionCall(graph, g_implI->functionGetFile(method),
935                                                "newImportedDefaultFuncFromModule4");
936         },
937         []([[maybe_unused]] AbckitGraph *graph) {});
938 
939     output = helpers::ExecuteDynamicAbc(OUTPUT_PATH, MAIN_MODULE_NAME);
940     expected =
941         "regular import func1 from module1\nregular import func1 from module2\nregular default import func1 from "
942         "module3\nregular default import func2 from module2\nnamespace import func2 from module1\nnamespace import "
943         "func3 from module1\n1\n2\nnamespace import func3 from module2\nthe same func from module3\nnew imported "
944         "default func from module4\n";
945     EXPECT_TRUE(helpers::Match(output, expected));
946 }
947 
948 // Test: test-kind=api, api=ArktsModifyApiImpl::moduleAddImportFromArktsV1ToArktsV1, abc-kind=ArkTS1,
949 // category=positive
TEST_F(LibAbcKitArkTSModifyApiModulesTest,ModuleAddImportFromDynamicModule_NamespaceImport)950 TEST_F(LibAbcKitArkTSModifyApiModulesTest, ModuleAddImportFromDynamicModule_NamespaceImport)
951 {
952     auto output = helpers::ExecuteDynamicAbc(INPUT_PATH, MAIN_MODULE_NAME);
953     auto expected = UNMODIFIED_EXPECTED_OUTPUT;
954     EXPECT_TRUE(helpers::Match(output, expected));
955     AbckitFile *file = nullptr;
956 
957     helpers::AssertOpenAbc(INPUT_PATH, &file);
958 
959     helpers::ModuleByNameContext ctxFinder = {nullptr, MAIN_MODULE_NAME};
960     g_implI->fileEnumerateModules(file, &ctxFinder, helpers::ModuleByNameFinder);
961     ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
962     ASSERT_NE(ctxFinder.module, nullptr);
963     auto module = ctxFinder.module;
964     UserTransformerData utd;
965     utd.name = "*";
966     utd.alias = "NewImport";
967     utd.moduleName = "modules/module3";
968     utd.isRegular = false;
969     AddImportFromDynamicModuleImpl(module, &utd);
970     ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
971 
972     g_impl->writeAbc(file, OUTPUT_PATH, strlen(OUTPUT_PATH));
973     ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
974     g_impl->closeFile(file);
975     ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
976 
977     output = helpers::ExecuteDynamicAbc(OUTPUT_PATH, MAIN_MODULE_NAME);
978     expected = UNMODIFIED_EXPECTED_OUTPUT;
979     EXPECT_TRUE(helpers::Match(output, expected));
980 
981     helpers::TransformMethod(
982         OUTPUT_PATH, OUTPUT_PATH, "modules_dynamic_modify.func_main_0",
983         [](AbckitFile *, AbckitCoreFunction *method, AbckitGraph *graph) {
984             TransformIrAddImportedFunctionCallNS(graph, g_implI->functionGetFile(method), "newImportedFunc",
985                                                  "modules/module3");
986         },
987         []([[maybe_unused]] AbckitGraph *graph) {});
988 
989     output = helpers::ExecuteDynamicAbc(OUTPUT_PATH, MAIN_MODULE_NAME);
990     expected =
991         "regular import func1 from module1\nregular import func1 from module2\nregular default import func1 from "
992         "module3\nregular default import func2 from module2\nnamespace import func2 from module1\nnamespace import "
993         "func3 from module1\n1\n2\nnamespace import func3 from module2\nthe same func from module3\nnew imported func "
994         "from module3\n";
995     EXPECT_TRUE(helpers::Match(output, expected));
996 }
997 
998 // Test: test-kind=api, api=ArktsModifyApiImpl::moduleAddImportFromArktsV1ToArktsV1, abc-kind=ArkTS1,
999 // category=positive
TEST_F(LibAbcKitArkTSModifyApiModulesTest,ModuleAddImportFromDynamicModule_NamespaceImport2)1000 TEST_F(LibAbcKitArkTSModifyApiModulesTest, ModuleAddImportFromDynamicModule_NamespaceImport2)
1001 {
1002     auto output = helpers::ExecuteDynamicAbc(INPUT_PATH, MAIN_MODULE_NAME);
1003     auto expected = UNMODIFIED_EXPECTED_OUTPUT;
1004     EXPECT_TRUE(helpers::Match(output, expected));
1005     AbckitFile *file = nullptr;
1006 
1007     helpers::AssertOpenAbc(INPUT_PATH, &file);
1008 
1009     helpers::ModuleByNameContext ctxFinder = {nullptr, MAIN_MODULE_NAME};
1010     g_implI->fileEnumerateModules(file, &ctxFinder, helpers::ModuleByNameFinder);
1011     ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
1012     ASSERT_NE(ctxFinder.module, nullptr);
1013     auto module = ctxFinder.module;
1014     UserTransformerData utd = {"*", "NewImport", "modules/module4", false};
1015     AddImportFromDynamicModuleImpl(module, &utd);
1016     ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
1017 
1018     g_impl->writeAbc(file, OUTPUT_PATH, strlen(OUTPUT_PATH));
1019     ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
1020     g_impl->closeFile(file);
1021     ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
1022 
1023     output = helpers::ExecuteDynamicAbc(OUTPUT_PATH, MAIN_MODULE_NAME);
1024     expected = UNMODIFIED_EXPECTED_OUTPUT;
1025     EXPECT_TRUE(helpers::Match(output, expected));
1026 
1027     helpers::TransformMethod(
1028         OUTPUT_PATH, OUTPUT_PATH, "modules_dynamic_modify.func_main_0",
1029         [](AbckitFile *, AbckitCoreFunction *method, AbckitGraph *graph) {
1030             TransformIrAddImportedFunctionCallNS(graph, g_implI->functionGetFile(method), "newImportedFuncFromModule4",
1031                                                  "modules/module4");
1032         },
1033         []([[maybe_unused]] AbckitGraph *graph) {});
1034 
1035     output = helpers::ExecuteDynamicAbc(OUTPUT_PATH, MAIN_MODULE_NAME);
1036     expected =
1037         "regular import func1 from module1\nregular import func1 from module2\nregular default import func1 from "
1038         "module3\nregular default import func2 from module2\nnamespace import func2 from module1\nnamespace import "
1039         "func3 from module1\n1\n2\nnamespace import func3 from module2\nthe same func from module3\nnew imported func "
1040         "from module4\n";
1041     EXPECT_TRUE(helpers::Match(output, expected));
1042 }
1043 
1044 // Test: test-kind=api, api=ArktsModifyApiImpl::moduleAddImportFromArktsV1ToArktsV1, abc-kind=ArkTS1,
1045 // category=negative
TEST_F(LibAbcKitArkTSModifyApiModulesTest,ModuleAddImportFromDynamicModule_WrongTargets)1046 TEST_F(LibAbcKitArkTSModifyApiModulesTest, ModuleAddImportFromDynamicModule_WrongTargets)
1047 {
1048     AbckitFile *file = nullptr;
1049     helpers::AssertOpenAbc(INPUT_PATH, &file);
1050 
1051     helpers::ModuleByNameContext ctxFinder = {nullptr, MAIN_MODULE_NAME};
1052     g_implI->fileEnumerateModules(file, &ctxFinder, helpers::ModuleByNameFinder);
1053     ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
1054     ASSERT_NE(ctxFinder.module, nullptr);
1055     auto *module = ctxFinder.module;
1056 
1057     helpers::ModuleByNameContext ctxFinder2 = {nullptr, "modules/module4"};
1058     g_implI->fileEnumerateModules(file, &ctxFinder2, helpers::ModuleByNameFinder);
1059     ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
1060     ASSERT_NE(ctxFinder2.module, nullptr);
1061     auto *importedModule = ctxFinder2.module;
1062 
1063     AbckitArktsImportFromDynamicModuleCreateParams params {};
1064     params.name = "*";
1065     params.alias = "NewImport";
1066 
1067     importedModule->target = ABCKIT_TARGET_ARK_TS_V2;
1068 
1069     g_implArkM->moduleAddImportFromArktsV1ToArktsV1(g_implArkI->coreModuleToArktsModule(module),
1070                                                     g_implArkI->coreModuleToArktsModule(importedModule), &params);
1071     ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_WRONG_TARGET);
1072 
1073     g_impl->closeFile(file);
1074 }
1075 
1076 // Test: test-kind=api, api=ArktsModifyApiImpl::moduleAddExportFromArktsV1ToArktsV1, abc-kind=ArkTS1,
1077 // category=positive
TEST_F(LibAbcKitArkTSModifyApiModulesTest,DynamicModuleAddExport_LocalExport)1078 TEST_F(LibAbcKitArkTSModifyApiModulesTest, DynamicModuleAddExport_LocalExport)
1079 {
1080     AbckitFile *file = nullptr;
1081     helpers::AssertOpenAbc(INPUT_PATH, &file);
1082 
1083     helpers::ModuleByNameContext ctxFinder = {nullptr, MAIN_MODULE_NAME};
1084     g_implI->fileEnumerateModules(file, &ctxFinder, helpers::ModuleByNameFinder);
1085     ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
1086     ASSERT_NE(ctxFinder.module, nullptr);
1087     auto module = ctxFinder.module;
1088     UserTransformerData utd;
1089     utd.name = "NewExportedVar";
1090     utd.alias = "NewExportedVar";
1091     utd.kind = AbckitDynamicExportKind::ABCKIT_DYNAMIC_EXPORT_KIND_LOCAL_EXPORT;
1092     utd.moduleName = MAIN_MODULE_NAME;
1093     DynamicModuleAddExportImpl(module, &utd);
1094     ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
1095 
1096     g_impl->writeAbc(file, OUTPUT_PATH, strlen(OUTPUT_PATH));
1097     ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
1098     g_impl->closeFile(file);
1099     ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
1100 
1101     auto output = helpers::ExecuteDynamicAbc(OUTPUT_PATH, MAIN_MODULE_NAME);
1102     auto expected = UNMODIFIED_EXPECTED_OUTPUT;
1103     EXPECT_TRUE(helpers::Match(output, expected));
1104 
1105     helpers::TransformMethod(
1106         OUTPUT_PATH, OUTPUT_PATH, "modules_dynamic_modify.func_main_0",
1107         [&utd](AbckitFile *, AbckitCoreFunction *method, AbckitGraph *graph) {
1108             TransformIrAddLocalExport(graph, g_implI->functionGetFile(method), utd.alias, MAIN_MODULE_NAME);
1109         },
1110         []([[maybe_unused]] AbckitGraph *graph) {});
1111 
1112     output = helpers::ExecuteDynamicAbc(OUTPUT_PATH, MAIN_MODULE_NAME);
1113     expected =
1114         "regular import func1 from module1\nregular import func1 from module2\nregular default import func1 from "
1115         "module3\nregular default import func2 from module2\nnamespace import func2 from module1\nnamespace import "
1116         "func3 from module1\n1\n2\nnamespace import func3 from module2\nthe same func from module3\n5\n";
1117     EXPECT_TRUE(helpers::Match(output, expected));
1118 }
1119 
1120 // Test: test-kind=api, api=ArktsModifyApiImpl::moduleAddExportFromArktsV1ToArktsV1, abc-kind=ArkTS1,
1121 // category=positive
TEST_F(LibAbcKitArkTSModifyApiModulesTest,DynamicModuleAddExport_LocalExport2)1122 TEST_F(LibAbcKitArkTSModifyApiModulesTest, DynamicModuleAddExport_LocalExport2)
1123 {
1124     AbckitFile *file = nullptr;
1125     helpers::AssertOpenAbc(INPUT_PATH, &file);
1126 
1127     helpers::ModuleByNameContext ctxFinder = {nullptr, MAIN_MODULE_NAME};
1128     g_implI->fileEnumerateModules(file, &ctxFinder, helpers::ModuleByNameFinder);
1129     ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
1130     ASSERT_NE(ctxFinder.module, nullptr);
1131     auto module = ctxFinder.module;
1132     UserTransformerData utd;
1133     utd.name = "NewExportedVar";
1134     utd.alias = "NewExportedVarAlias";
1135     utd.kind = AbckitDynamicExportKind::ABCKIT_DYNAMIC_EXPORT_KIND_LOCAL_EXPORT;
1136     utd.moduleName = MAIN_MODULE_NAME;
1137     DynamicModuleAddExportImpl(module, &utd);
1138     ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
1139 
1140     g_impl->writeAbc(file, OUTPUT_PATH, strlen(OUTPUT_PATH));
1141     ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
1142     g_impl->closeFile(file);
1143     ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
1144 
1145     auto output = helpers::ExecuteDynamicAbc(OUTPUT_PATH, MAIN_MODULE_NAME);
1146     auto expected = UNMODIFIED_EXPECTED_OUTPUT;
1147     EXPECT_TRUE(helpers::Match(output, expected));
1148 
1149     helpers::TransformMethod(
1150         OUTPUT_PATH, OUTPUT_PATH, "modules_dynamic_modify.func_main_0",
1151         [&utd](AbckitFile *, AbckitCoreFunction *method, AbckitGraph *graph) {
1152             TransformIrAddLocalExport(graph, g_implI->functionGetFile(method), utd.alias, MAIN_MODULE_NAME);
1153         },
1154         []([[maybe_unused]] AbckitGraph *graph) {});
1155 
1156     output = helpers::ExecuteDynamicAbc(OUTPUT_PATH, MAIN_MODULE_NAME);
1157     expected =
1158         "regular import func1 from module1\nregular import func1 from module2\nregular default import func1 from "
1159         "module3\nregular default import func2 from module2\nnamespace import func2 from module1\nnamespace import "
1160         "func3 from module1\n1\n2\nnamespace import func3 from module2\nthe same func from module3\n5\n";
1161     EXPECT_TRUE(helpers::Match(output, expected));
1162 }
1163 
1164 // Test: test-kind=api, api=ArktsModifyApiImpl::moduleAddExportFromArktsV1ToArktsV1, abc-kind=ArkTS1,
1165 // category=positive
TEST_F(LibAbcKitArkTSModifyApiModulesTest,DynamicModuleAddExport_LocalExport3)1166 TEST_F(LibAbcKitArkTSModifyApiModulesTest, DynamicModuleAddExport_LocalExport3)
1167 {
1168     AbckitFile *file = nullptr;
1169     helpers::AssertOpenAbc(INPUT_PATH, &file);
1170 
1171     helpers::ModuleByNameContext ctxFinder = {nullptr, MAIN_MODULE_NAME};
1172     g_implI->fileEnumerateModules(file, &ctxFinder, helpers::ModuleByNameFinder);
1173     ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
1174     ASSERT_NE(ctxFinder.module, nullptr);
1175     auto module = ctxFinder.module;
1176     UserTransformerData utd;
1177     utd.name = "default";
1178     utd.alias = "NewExportedVarDefault";
1179     utd.kind = AbckitDynamicExportKind::ABCKIT_DYNAMIC_EXPORT_KIND_LOCAL_EXPORT;
1180     utd.moduleName = MAIN_MODULE_NAME;
1181     DynamicModuleAddExportImpl(module, &utd);
1182     ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
1183 
1184     g_impl->writeAbc(file, OUTPUT_PATH, strlen(OUTPUT_PATH));
1185     ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
1186     g_impl->closeFile(file);
1187     ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
1188 
1189     auto output = helpers::ExecuteDynamicAbc(OUTPUT_PATH, MAIN_MODULE_NAME);
1190     auto expected = UNMODIFIED_EXPECTED_OUTPUT;
1191     EXPECT_TRUE(helpers::Match(output, expected));
1192 
1193     helpers::TransformMethod(
1194         OUTPUT_PATH, OUTPUT_PATH, "modules_dynamic_modify.func_main_0",
1195         [&utd](AbckitFile *, AbckitCoreFunction *method, AbckitGraph *graph) {
1196             TransformIrAddLocalExport(graph, g_implI->functionGetFile(method), utd.alias, MAIN_MODULE_NAME);
1197         },
1198         []([[maybe_unused]] AbckitGraph *graph) {});
1199 
1200     output = helpers::ExecuteDynamicAbc(OUTPUT_PATH, MAIN_MODULE_NAME);
1201     expected =
1202         "regular import func1 from module1\nregular import func1 from module2\nregular default import func1 from "
1203         "module3\nregular default import func2 from module2\nnamespace import func2 from module1\nnamespace import "
1204         "func3 from module1\n1\n2\nnamespace import func3 from module2\nthe same func from module3\n5\n";
1205     EXPECT_TRUE(helpers::Match(output, expected));
1206 }
1207 
1208 // Test: test-kind=api, api=ArktsModifyApiImpl::moduleAddExportFromArktsV1ToArktsV1, abc-kind=ArkTS1,
1209 // category=positive
TEST_F(LibAbcKitArkTSModifyApiModulesTest,DynamicModuleAddExport_IndirectExport)1210 TEST_F(LibAbcKitArkTSModifyApiModulesTest, DynamicModuleAddExport_IndirectExport)
1211 {
1212     AbckitFile *file = nullptr;
1213     helpers::AssertOpenAbc(INPUT_PATH, &file);
1214 
1215     helpers::ModuleByNameContext ctxFinder = {nullptr, "modules/module2"};
1216     g_implI->fileEnumerateModules(file, &ctxFinder, helpers::ModuleByNameFinder);
1217     ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
1218     ASSERT_NE(ctxFinder.module, nullptr);
1219     auto module = ctxFinder.module;
1220     UserTransformerData utd;
1221     utd.name = "NewLocalExportLet";
1222     utd.alias = "NewLocalExportLet";
1223     utd.moduleName = "modules/module1";
1224     utd.kind = AbckitDynamicExportKind::ABCKIT_DYNAMIC_EXPORT_KIND_INDIRECT_EXPORT;
1225     DynamicModuleAddExportImpl(module, &utd);
1226     ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
1227 
1228     UserTransformerData utd2;
1229     utd2.name = utd.name;
1230     utd2.alias = utd.alias;
1231     utd2.moduleName = "modules/module2";
1232     utd2.isRegular = true;
1233     ctxFinder = {nullptr, MAIN_MODULE_NAME};
1234     g_implI->fileEnumerateModules(file, &ctxFinder, helpers::ModuleByNameFinder);
1235     ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
1236     ASSERT_NE(ctxFinder.module, nullptr);
1237     AddImportFromDynamicModuleImpl(ctxFinder.module, &utd2);
1238     ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
1239 
1240     g_impl->writeAbc(file, OUTPUT_PATH, strlen(OUTPUT_PATH));
1241     ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
1242     g_impl->closeFile(file);
1243     ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
1244 
1245     auto output = helpers::ExecuteDynamicAbc(OUTPUT_PATH, MAIN_MODULE_NAME);
1246     auto expected = UNMODIFIED_EXPECTED_OUTPUT;
1247     EXPECT_TRUE(helpers::Match(output, expected));
1248 
1249     helpers::TransformMethod(
1250         OUTPUT_PATH, OUTPUT_PATH, "modules_dynamic_modify.func_main_0",
1251         [&utd2](AbckitFile *, AbckitCoreFunction *method, AbckitGraph *graph) {
1252             TransformIrAddIndirectExport(graph, g_implI->functionGetFile(method), utd2.alias, MAIN_MODULE_NAME);
1253         },
1254         []([[maybe_unused]] AbckitGraph *graph) {});
1255 
1256     output = helpers::ExecuteDynamicAbc(OUTPUT_PATH, MAIN_MODULE_NAME);
1257     expected =
1258         "regular import func1 from module1\nregular import func1 from module2\nregular default import func1 from "
1259         "module3\nregular default import func2 from module2\nnamespace import func2 from module1\nnamespace import "
1260         "func3 from module1\n1\n2\nnamespace import func3 from module2\nthe same func from module3\n3\n";
1261     EXPECT_TRUE(helpers::Match(output, expected));
1262 }
1263 
1264 // Test: test-kind=api, api=ArktsModifyApiImpl::moduleAddExportFromArktsV1ToArktsV1, abc-kind=ArkTS1,
1265 // category=positive
TEST_F(LibAbcKitArkTSModifyApiModulesTest,DynamicModuleAddExport_IndirectExport2)1266 TEST_F(LibAbcKitArkTSModifyApiModulesTest, DynamicModuleAddExport_IndirectExport2)
1267 {
1268     AbckitFile *file = nullptr;
1269     helpers::AssertOpenAbc(INPUT_PATH, &file);
1270 
1271     helpers::ModuleByNameContext ctxFinder = {nullptr, "modules/module2"};
1272     g_implI->fileEnumerateModules(file, &ctxFinder, helpers::ModuleByNameFinder);
1273     ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
1274     ASSERT_NE(ctxFinder.module, nullptr);
1275     auto module = ctxFinder.module;
1276     UserTransformerData utd;
1277     utd.name = "NewLocalExportVar";
1278     utd.alias = "NewLocalExportVarAlias";
1279     utd.moduleName = "modules/module4";
1280     utd.kind = AbckitDynamicExportKind::ABCKIT_DYNAMIC_EXPORT_KIND_INDIRECT_EXPORT;
1281     DynamicModuleAddExportImpl(module, &utd);
1282     ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
1283 
1284     UserTransformerData utd2 = {utd.alias, "NewLocalExportVarFromModule4", "modules/module2", true};
1285     ctxFinder = {nullptr, MAIN_MODULE_NAME};
1286     g_implI->fileEnumerateModules(file, &ctxFinder, helpers::ModuleByNameFinder);
1287     ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
1288     ASSERT_NE(ctxFinder.module, nullptr);
1289     AddImportFromDynamicModuleImpl(ctxFinder.module, &utd2);
1290     ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
1291 
1292     g_impl->writeAbc(file, OUTPUT_PATH, strlen(OUTPUT_PATH));
1293     ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
1294     g_impl->closeFile(file);
1295     ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
1296 
1297     auto output = helpers::ExecuteDynamicAbc(OUTPUT_PATH, MAIN_MODULE_NAME);
1298     auto expected = UNMODIFIED_EXPECTED_OUTPUT;
1299     EXPECT_TRUE(helpers::Match(output, expected));
1300 
1301     helpers::TransformMethod(
1302         OUTPUT_PATH, OUTPUT_PATH, "modules_dynamic_modify.func_main_0",
1303         [&utd2](AbckitFile *, AbckitCoreFunction *method, AbckitGraph *graph) {
1304             TransformIrAddIndirectExport(graph, g_implI->functionGetFile(method), utd2.alias, MAIN_MODULE_NAME);
1305         },
1306         []([[maybe_unused]] AbckitGraph *graph) {});
1307 
1308     output = helpers::ExecuteDynamicAbc(OUTPUT_PATH, MAIN_MODULE_NAME);
1309     expected =
1310         "regular import func1 from module1\nregular import func1 from module2\nregular default import func1 from "
1311         "module3\nregular default import func2 from module2\nnamespace import func2 from module1\nnamespace import "
1312         "func3 from module1\n1\n2\nnamespace import func3 from module2\nthe same func from module3\n6\n";
1313     EXPECT_TRUE(helpers::Match(output, expected));
1314 }
1315 
1316 // Test: test-kind=api, api=ArktsModifyApiImpl::moduleAddExportFromArktsV1ToArktsV1, abc-kind=ArkTS1,
1317 // category=positive
TEST_F(LibAbcKitArkTSModifyApiModulesTest,DynamicModuleAddExport_StarExport)1318 TEST_F(LibAbcKitArkTSModifyApiModulesTest, DynamicModuleAddExport_StarExport)
1319 {
1320     AbckitFile *file = nullptr;
1321     helpers::AssertOpenAbc(INPUT_PATH, &file);
1322 
1323     helpers::ModuleByNameContext ctxFinder = {nullptr, "modules/module4"};
1324     g_implI->fileEnumerateModules(file, &ctxFinder, helpers::ModuleByNameFinder);
1325     ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
1326     ASSERT_NE(ctxFinder.module, nullptr);
1327     auto module = ctxFinder.module;
1328     UserTransformerData utd = {"*", "", "modules/module3", false,
1329                                AbckitDynamicExportKind::ABCKIT_DYNAMIC_EXPORT_KIND_STAR_EXPORT};
1330     DynamicModuleAddExportImpl(module, &utd);
1331     ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
1332 
1333     ctxFinder = {nullptr, MAIN_MODULE_NAME};
1334     g_implI->fileEnumerateModules(file, &ctxFinder, helpers::ModuleByNameFinder);
1335     ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
1336     ASSERT_NE(ctxFinder.module, nullptr);
1337     module = ctxFinder.module;
1338     UserTransformerData utd2 = {"*", "NS4", "modules/module4", false};
1339     AddImportFromDynamicModuleImpl(module, &utd2);
1340     ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
1341 
1342     g_impl->writeAbc(file, OUTPUT_PATH, strlen(OUTPUT_PATH));
1343     ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
1344     g_impl->closeFile(file);
1345     ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
1346 
1347     auto output = helpers::ExecuteDynamicAbc(OUTPUT_PATH, MAIN_MODULE_NAME);
1348     auto expected = UNMODIFIED_EXPECTED_OUTPUT;
1349     EXPECT_TRUE(helpers::Match(output, expected));
1350 
1351     helpers::TransformMethod(
1352         OUTPUT_PATH, OUTPUT_PATH, "modules_dynamic_modify.func_main_0",
1353         [&utd2](AbckitFile *, AbckitCoreFunction *method, AbckitGraph *graph) {
1354             TransformIrAddStarExport(graph, g_implI->functionGetFile(method), "newExportedFunc", utd2.moduleName);
1355         },
1356         []([[maybe_unused]] AbckitGraph *graph) {});
1357 
1358     output = helpers::ExecuteDynamicAbc(OUTPUT_PATH, MAIN_MODULE_NAME);
1359     expected =
1360         "regular import func1 from module1\nregular import func1 from module2\nregular default import func1 from "
1361         "module3\nregular default import func2 from module2\nnamespace import func2 from module1\nnamespace import "
1362         "func3 from module1\n1\n2\nnamespace import func3 from module2\nthe same func from module3\nnew exported func "
1363         "from module3\n";
1364     EXPECT_TRUE(helpers::Match(output, expected));
1365 }
1366 
1367 // Test: test-kind=api, api=ArktsModifyApiImpl::moduleAddExportFromArktsV1ToArktsV1, abc-kind=ArkTS1,
1368 // category=positive
TEST_F(LibAbcKitArkTSModifyApiModulesTest,DynamicModuleAddExport_StarExport2)1369 TEST_F(LibAbcKitArkTSModifyApiModulesTest, DynamicModuleAddExport_StarExport2)
1370 {
1371     AbckitFile *file = nullptr;
1372     helpers::AssertOpenAbc(INPUT_PATH, &file);
1373 
1374     helpers::ModuleByNameContext ctxFinder = {nullptr, "modules/module3"};
1375     g_implI->fileEnumerateModules(file, &ctxFinder, helpers::ModuleByNameFinder);
1376     ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
1377     ASSERT_NE(ctxFinder.module, nullptr);
1378     auto module = ctxFinder.module;
1379     UserTransformerData utd;
1380     utd.name = "*";
1381     utd.moduleName = "modules/module4";
1382     utd.kind = AbckitDynamicExportKind::ABCKIT_DYNAMIC_EXPORT_KIND_STAR_EXPORT;
1383     DynamicModuleAddExportImpl(module, &utd);
1384     ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
1385 
1386     g_impl->writeAbc(file, OUTPUT_PATH, strlen(OUTPUT_PATH));
1387     ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
1388     g_impl->closeFile(file);
1389     ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
1390 
1391     auto output = helpers::ExecuteDynamicAbc(OUTPUT_PATH, MAIN_MODULE_NAME);
1392     auto expected = UNMODIFIED_EXPECTED_OUTPUT;
1393     EXPECT_TRUE(helpers::Match(output, expected));
1394 
1395     helpers::TransformMethod(
1396         OUTPUT_PATH, OUTPUT_PATH, "modules_dynamic_modify.func_main_0",
1397         [](AbckitFile *, AbckitCoreFunction *method, AbckitGraph *graph) {
1398             TransformIrAddStarExport(graph, g_implI->functionGetFile(method), "newExportedFuncFromModule4",
1399                                      "modules/module3");
1400         },
1401         []([[maybe_unused]] AbckitGraph *graph) {});
1402 
1403     output = helpers::ExecuteDynamicAbc(OUTPUT_PATH, MAIN_MODULE_NAME);
1404     expected =
1405         "regular import func1 from module1\nregular import func1 from module2\nregular default import func1 from "
1406         "module3\nregular default import func2 from module2\nnamespace import func2 from module1\nnamespace import "
1407         "func3 from module1\n1\n2\nnamespace import func3 from module2\nthe same func from module3\nnew exported func "
1408         "from module4\n";
1409     EXPECT_TRUE(helpers::Match(output, expected));
1410 }
1411 
1412 // Test: test-kind=api, api=ArktsModifyApiImpl::moduleAddExportFromArktsV1ToArktsV1, abc-kind=ArkTS1,
1413 // category=positive
TEST_F(LibAbcKitArkTSModifyApiModulesTest,DynamicModuleAddExport_StarExport3)1414 TEST_F(LibAbcKitArkTSModifyApiModulesTest, DynamicModuleAddExport_StarExport3)
1415 {
1416     AbckitFile *file = nullptr;
1417     helpers::AssertOpenAbc(INPUT_PATH, &file);
1418 
1419     helpers::ModuleByNameContext ctxFinder = {nullptr, "modules/module4"};
1420     g_implI->fileEnumerateModules(file, &ctxFinder, helpers::ModuleByNameFinder);
1421     ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
1422     ASSERT_NE(ctxFinder.module, nullptr);
1423     UserTransformerData utd = {"*", "NewStarExport", "modules/module3", false,
1424                                AbckitDynamicExportKind::ABCKIT_DYNAMIC_EXPORT_KIND_STAR_EXPORT};
1425     DynamicModuleAddExportImpl(ctxFinder.module, &utd);
1426     ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
1427 
1428     ctxFinder = {nullptr, MAIN_MODULE_NAME};
1429     g_implI->fileEnumerateModules(file, &ctxFinder, helpers::ModuleByNameFinder);
1430     ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
1431     ASSERT_NE(ctxFinder.module, nullptr);
1432     UserTransformerData utd2 = {"NewStarExport", "NewStarExport", "modules/module4", true};
1433     AddImportFromDynamicModuleImpl(ctxFinder.module, &utd2);
1434     ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
1435 
1436     g_impl->writeAbc(file, OUTPUT_PATH, strlen(OUTPUT_PATH));
1437     ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
1438     g_impl->closeFile(file);
1439     ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
1440 
1441     auto output = helpers::ExecuteDynamicAbc(OUTPUT_PATH, MAIN_MODULE_NAME);
1442     auto expected = UNMODIFIED_EXPECTED_OUTPUT;
1443     EXPECT_TRUE(helpers::Match(output, expected));
1444 
1445     helpers::TransformMethod(
1446         OUTPUT_PATH, OUTPUT_PATH, "modules/module4.func_main_0",
1447         [&utd2, &utd](AbckitFile *, AbckitCoreFunction *method, AbckitGraph *graph) {
1448             TransformIrAddStarExportFunc(graph, g_implI->functionGetFile(method), utd2.alias, utd.moduleName);
1449         },
1450         []([[maybe_unused]] AbckitGraph *graph) {});
1451 
1452     helpers::TransformMethod(
1453         OUTPUT_PATH, OUTPUT_PATH, "modules_dynamic_modify.func_main_0",
1454         [](AbckitFile *, AbckitCoreFunction *method, AbckitGraph *graph) {
1455             TransformIrAddStarExportFunc2(graph, g_implI->functionGetFile(method), "newExportedFunc", MAIN_MODULE_NAME);
1456         },
1457         []([[maybe_unused]] AbckitGraph *graph) {});
1458 
1459     output = helpers::ExecuteDynamicAbc(OUTPUT_PATH, MAIN_MODULE_NAME);
1460     expected =
1461         "regular import func1 from module1\nregular import func1 from module2\nregular default import func1 from "
1462         "module3\nregular default import func2 from module2\nnamespace import func2 from module1\nnamespace import "
1463         "func3 from module1\n1\n2\nnamespace import func3 from module2\nthe same func from module3\nnew exported func "
1464         "from module3\n";
1465     EXPECT_TRUE(helpers::Match(output, expected));
1466 }
1467 
1468 // Test: test-kind=api, api=ArktsModifyApiImpl::moduleAddExportFromArktsV1ToArktsV1, abc-kind=ArkTS1,
1469 // category=negative, extension=c
TEST_F(LibAbcKitArkTSModifyApiModulesTest,DynamicModuleAddExport_WrongTargets)1470 TEST_F(LibAbcKitArkTSModifyApiModulesTest, DynamicModuleAddExport_WrongTargets)
1471 {
1472     AbckitFile *file = nullptr;
1473     helpers::AssertOpenAbc(INPUT_PATH, &file);
1474 
1475     helpers::ModuleByNameContext ctxFinder = {nullptr, "modules/module2"};
1476     g_implI->fileEnumerateModules(file, &ctxFinder, helpers::ModuleByNameFinder);
1477     ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
1478     ASSERT_NE(ctxFinder.module, nullptr);
1479     auto *module = ctxFinder.module;
1480 
1481     helpers::ModuleByNameContext ctxFinder2 = {nullptr, "modules/module1"};
1482     g_implI->fileEnumerateModules(file, &ctxFinder2, helpers::ModuleByNameFinder);
1483     ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
1484     ASSERT_NE(ctxFinder2.module, nullptr);
1485     auto *exportedModule = ctxFinder2.module;
1486 
1487     AbckitArktsDynamicModuleExportCreateParams params {};
1488     params.name = "NewLocalExportLet";
1489     params.alias = "NewLocalExportLet";
1490 
1491     exportedModule->target = ABCKIT_TARGET_ARK_TS_V2;
1492 
1493     g_implArkM->moduleAddExportFromArktsV1ToArktsV1(g_implArkI->coreModuleToArktsModule(module),
1494                                                     g_implArkI->coreModuleToArktsModule(exportedModule), &params);
1495     ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_WRONG_TARGET);
1496 
1497     g_impl->closeFile(file);
1498 }
1499 
1500 // Test: test-kind=api, api=ArktsModifyApiImpl::fileAddExternalModuleArktsV1, abc-kind=ArkTS1, category=positive,
1501 // extension=c
TEST_F(LibAbcKitArkTSModifyApiModulesTest,fileAddExternalModuleArktsV1)1502 TEST_F(LibAbcKitArkTSModifyApiModulesTest, fileAddExternalModuleArktsV1)
1503 {
1504     AbckitFile *file = nullptr;
1505     helpers::AssertOpenAbc(INPUT_PATH, &file);
1506 
1507     AbckitArktsV1ExternalModuleCreateParams params {};
1508     params.name = "ExternalModule";
1509     AbckitArktsModule *arkTsModule = g_implArkM->fileAddExternalModuleArktsV1(file, &params);
1510     ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
1511     ASSERT_NE(arkTsModule, nullptr);
1512 
1513     AbckitCoreModule *coreModule = g_implArkI->arktsModuleToCoreModule(arkTsModule);
1514     ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
1515     ASSERT_NE(coreModule, nullptr);
1516 
1517     helpers::ModuleByNameContext ctxFinder = {nullptr, params.name};
1518     g_implI->fileEnumerateModules(file, &ctxFinder, helpers::ModuleByNameFinder);
1519     ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
1520     ASSERT_NE(ctxFinder.module, nullptr);
1521     ASSERT_EQ(g_implI->moduleIsExternal(ctxFinder.module), true);
1522 
1523     g_impl->writeAbc(file, OUTPUT_PATH, strlen(OUTPUT_PATH));
1524     ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
1525     g_impl->closeFile(file);
1526     ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
1527 
1528     auto output = helpers::ExecuteDynamicAbc(OUTPUT_PATH, MAIN_MODULE_NAME);
1529     auto expected = UNMODIFIED_EXPECTED_OUTPUT;
1530     EXPECT_TRUE(helpers::Match(output, expected));
1531 }
1532 
1533 }  // namespace libabckit::test
1534