• 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 #ifndef ECMASCRIPT_MODULE_MODULE_PATH_HELPER_H
16 #define ECMASCRIPT_MODULE_MODULE_PATH_HELPER_H
17 
18 #include "ecmascript/base/path_helper.h"
19 
20 #include "ecmascript/compiler/aot_file/aot_file_manager.h"
21 #include "ecmascript/base/string_helper.h"
22 #include "ecmascript/ecma_macros.h"
23 #include "ecmascript/ecma_string.h"
24 #include "ecmascript/ecma_vm.h"
25 #include "ecmascript/global_env.h"
26 #include "ecmascript/js_tagged_value-inl.h"
27 #include "ecmascript/jspandafile/js_pandafile.h"
28 /*
29  * Intra-application cross hap:
30  * baseFileName = 'data/storage/el1/bundle/moduleName/ets/modules.abc';
31  * cross-application:
32  * baseFileName = 'data/storage/el1/bundle/bundleName/moduleName/moduleName/ets/modules.abc';
33  * recordName = bundleName/moduleName/xxx(entry)/xxx(ets)/xxx(pages)/xxx  specific abc file
34  *
35  * ohmUrl: It's an index information that can uniquely identify module files.
36  * Current ohmUrl has the following five different prefixs:
37  * 1. @bundle:... Identify OpenHarmony modules.
38  *    {project_path}\entry\src\main\ets\pages\Index --> @bundle:bundleName/moduleName/ets/pages/Index
39  *    @namespace: needs to add when import local har or ohosTest import entry file.
40  *    {project_path}\namespace\src\main\ets\pages\Index --> @bundle:bundleName/moduleName@namespace/ets/pages/Index
41  *
42  * 2. @package:... Identify open source third party modules.
43  *    {project_path}\node_modules.ohpm\pkgName\oh_modules\pkgName\xxx\xxx
44  *    --> @package:pkg_modules/.ohpm/pkgName/pkg_modules/pkgName/xxx/xxx
45  *
46  * 3. @app:... Identify c++ modules in application.
47  *    libxxx.so --> @app:bundleName/moduleName/xxx
48  *
49  * 4. @native:... Identify system builtin modules.
50  *    system.app --> @native:system.app
51  *
52  * 5. @ohos:... Identify ohos builtin modules.
53  *    @ohos:hilog --> @ohos:hilog
54  */
55 
56 namespace panda::ecmascript {
57 using PathHelper = base::PathHelper;
58 using StringHelper = base::StringHelper;
59 
60 class ModulePathHelper {
61 public:
62     static constexpr char EXT_NAME_ABC[] = ".abc";
63     static constexpr char EXT_NAME_ETS[] = ".ets";
64     static constexpr char EXT_NAME_TS[] = ".ts";
65     static constexpr char EXT_NAME_JS[] = ".js";
66     static constexpr char EXT_NAME_JSON[] = ".json";
67     static constexpr char EXT_NAME_Z_SO[] = ".z.so";
68     static constexpr char EXT_NAME_D_TS[] = ".d.ts";
69     static constexpr char EXT_NAME_MJS[] = ".mjs";
70     static constexpr char EXT_NAME_HQF[] = ".hqf";
71     static constexpr char PREFIX_NORMALIZED[] = "@normalized:";
72     static constexpr char PREFIX_NORMALIZED_SO[] = "@normalized:Y";
73     static constexpr char PREFIX_NORMALIZED_NOT_SO[] = "@normalized:N";
74     static constexpr char PREFIX_BUNDLE[] = "@bundle:";
75     static constexpr char PREFIX_MODULE[] = "@module:";
76     static constexpr char PREFIX_PACKAGE[] = "@package:";
77     static constexpr char PREFIX_ETS[] = "ets/";
78     static constexpr char PREFIX_LIB[] = "lib";
79     static constexpr char REQUIRE_NAITVE_MODULE_PREFIX[] = "@native:";
80     static constexpr char REQUIRE_NAPI_OHOS_PREFIX[] = "@ohos:";
81     static constexpr char REQUIRE_NAPI_APP_PREFIX[] = "@app:";
82     static constexpr char RAW_ARKUIX_PREFIX[] = "@arkui-x.";
83     static constexpr char NPM_PATH_SEGMENT[] = "node_modules";
84     static constexpr char PACKAGE_PATH_SEGMENT[] = "pkg_modules";
85     static constexpr char PACKAGE_ENTRY_FILE[] = "/index";
86     static constexpr char BUNDLE_INSTALL_PATH[] = "/data/storage/el1/bundle/";
87     static constexpr char MERGE_ABC_ETS_MODULES[] = "/ets/modules.abc";
88     static constexpr char ABC[] = ".abc";
89     static constexpr char MODULE_DEFAULE_ETS[] = "/ets/";
90     static constexpr char BUNDLE_SUB_INSTALL_PATH[] = "/data/storage/el1/";
91     static constexpr char PREVIEW_OF_ACROSS_HAP_FLAG[] = "[preview]";
92     static constexpr char PREVIER_TEST_DIR[] = ".test";
93     static constexpr char PHYCICAL_FILE_PATH[] = "/src/main";
94     static constexpr char VMA_NAME_ARKTS_CODE[] = "ArkTS Code";
95     static constexpr char ENTRY_MAIN_FUNCTION[] = "_GLOBAL::func_main_0";
96     static constexpr char TRUE_FLAG[] = "true";
97 
98     static constexpr size_t MAX_PACKAGE_LEVEL = 1;
99     static constexpr size_t SEGMENTS_LIMIT_TWO = 2;
100     static constexpr size_t EXT_NAME_ABC_LEN = 4;
101     static constexpr size_t EXT_NAME_ETS_LEN = 4;
102     static constexpr size_t EXT_NAME_TS_LEN = 3;
103     static constexpr size_t EXT_NAME_JS_LEN = 3;
104     static constexpr size_t EXT_NAME_JSON_LEN = 5;
105     static constexpr size_t PREFIX_BUNDLE_LEN = 8;
106     static constexpr size_t PREFIX_MODULE_LEN = 8;
107     static constexpr size_t PREFIX_PACKAGE_LEN = 9;
108     static constexpr size_t NATIVE_PREFIX_SIZE = 8;
109     static constexpr size_t OHOS_PREFIX_SIZE = 6;
110     static constexpr size_t APP_PREFIX_SIZE = 5;
111     static constexpr size_t BUNDLE_INSTALL_PATH_LEN = 25;
112     static constexpr size_t PHYCICAL_FILE_PATH_LEN = 10;
113     static constexpr size_t NORMALIZED_OHMURL_ARGS_NUM = 5;
114     static constexpr size_t NORMALIZED_MODULE_NAME_INDEX = 1;
115     static constexpr size_t NORMALIZED_BUNDLE_NAME_INDEX = 2;
116     static constexpr size_t NORMALIZED_IMPORT_PATH_INDEX = 3;
117     static constexpr size_t NORMALIZED_VERSION_INDEX = 4;
118     static constexpr size_t CURRENT_DIREATORY_TAG_LEN = 2;
119     static constexpr size_t SO_PREFIX_LEN = 3;
120     static constexpr size_t SO_SUFFIX_LEN = 3;
121 
122     static constexpr size_t PKGINFO_PACKAGE_NAME_INDEX = 1;
123     static constexpr size_t PKGINFO_BUDNLE_NAME_INDEX = 3;
124     static constexpr size_t PKGINFO_MODULE_NAME_INDEX = 5;
125     static constexpr size_t PKGINFO_VERSION_INDEX = 7;
126     static constexpr size_t PKGINFO_ENTRY_PATH_INDEX = 9;
127     static constexpr size_t PKGINFO_IS_SO_INDEX = 11;
128 
129     static CString PUBLIC_API ConcatFileNameWithMerge(JSThread *thread, const JSPandaFile *jsPandaFile,
130                                                       CString &baseFileName, CString recordName, CString requestName);
131     static void ParseAbcPathAndOhmUrl(EcmaVM *vm, const CString &inputFileName, CString &outBaseFileName,
132                                       CString &outEntryPoint);
133     static CString ConcatUnifiedOhmUrl(const CString &bundleName, const CString &pkgname, const CString &entryPath,
134                                        const CString &path, const CString &version);
135     static CString ConcatUnifiedOhmUrl(const CString &bundleName, const CString &normalizedpath,
136         const CString &version);
137     static CString ConcatPreviewTestUnifiedOhmUrl(const CString &bundleName, const CString &pkgname,
138         const CString &path, const CString &version);
139     static CString ConcatHspFileNameCrossBundle(const CString &bundleName, const CString &moduleName);
140     static CString ConcatHspFileName(const CString &moduleName);
141     static CString TransformToNormalizedOhmUrl(EcmaVM *vm, const CString &inputFileName, const CString &baseFileName,
142         const CString &oldEntryPoint);
143     static CString ParseUrl(EcmaVM *vm, const CString &recordName);
144     static CString ParsePrefixBundle(JSThread *thread, const JSPandaFile *jsPandaFile,
145         [[maybe_unused]] CString &baseFileName, CString moduleRequestName, [[maybe_unused]] CString recordName);
146     static CString ParseNormalizedOhmUrl(JSThread *thread, CString &baseFileName, const CString &recordName,
147                                          CString requestName);
148     static CString MakeNewRecord(JSThread *thread, const JSPandaFile *jsPandaFile, CString &baseFileName,
149                                  const CString &recordName, const CString &requestName);
150     static CString FindOhpmEntryPoint(const JSPandaFile *jsPandaFile, const CString &ohpmPath,
151                                       const CString &requestName);
152     static CString FindPackageInTopLevelWithNamespace(const JSPandaFile *jsPandaFile, const CString &requestName,
153                                                       const CString &recordName);
154     static CString ParseOhpmPackage(const JSPandaFile *jsPandaFile, const CString &recordName,
155                                     const CString &requestName);
156     static CString ParseThirdPartyPackage(const JSPandaFile *jsPandaFile, const CString &recordName,
157                                           const CString &requestName, const CString &packagePath);
158     static CString ParseThirdPartyPackage(const JSPandaFile *jsPandaFile, const CString &recordName,
159                                           const CString &requestName);
160     static void ResolveCurrentPath(CString &dirPath, CString &fileName, const JSPandaFile *jsPandaFile);
161     static CString FindNpmEntryPoint(const JSPandaFile *jsPandaFile, const CString &packageEntryPoint);
162     static CString FindPackageInTopLevel(const JSPandaFile *jsPandaFile, const CString &requestName,
163                                          const CString &packagePath);
164     static bool IsImportFile(const CString &moduleRequestName);
165     static CString RemoveSuffix(const CString &requestName);
166     static bool NeedTranstale(const CString &requestName);
167     static bool NeedTranslateToNormalized(const CString &requestName);
168     static void TranstaleExpressionInput(const JSPandaFile *jsPandaFile, CString &requestPath);
169     static CString GetModuleNameWithBaseFile(const CString &baseFileName);
170     static CString TranslateExpressionInputWithEts(JSThread *thread, const JSPandaFile *jsPandaFile,
171                                                    CString &baseFileName, const CString &requestName);
172     static void ParseCrossModuleFile(const JSPandaFile *jsPandaFile, CString &requestPath);
173     static CString ReformatPath(CString requestName);
174     static CString TranslateExpressionToNormalized(JSThread *thread, const JSPandaFile *jsPandaFile,
175                                                    [[maybe_unused]] CString &baseFileName, const CString &recordName,
176                                                    CString &requestPath);
177     static CVector<CString> GetPkgContextInfoListElements(EcmaVM *vm, CString &moduleName,
178                                                           CString &packageName);
179     static CString TranslateNapiFileRequestPath(JSThread *thread, const CString &modulePath,
180                                                 const CString &requestName);
181     static CVector<CString> SplitNormalizedOhmurl(const CString &ohmurl);
182     static CString ConcatImportFileNormalizedOhmurl(const CString &recordPath, const CString &requestName,
183                                                     const CString &version = "");
184     static CString ConcatNativeSoNormalizedOhmurl(const CString &moduleName, const CString &bundleName,
185                                                   const CString &pkgName, const CString &version);
186     static CString ConcatNotSoNormalizedOhmurl(const CString &moduleName, const CString &bundleName,
187                                                const CString &pkgName, const CString &entryPath,
188                                                const CString &version);
189     static CString ConcatMergeFileNameToNormalized(JSThread *thread, const JSPandaFile *jsPandaFile,
190                                                    CString &baseFileName, const CString &recordName,
191                                                    CString requestName);
192     static CVector<CString> SplitNormalizedRecordName(const CString &recordName);
193     static CString ConcatImportFileNormalizedOhmurlWithRecordName(JSThread *thread, const JSPandaFile *jsPandaFile,
194                                                                   CString &baseFileName, const CString &recordName,
195                                                                   const CString &requestName);
196     static void ConcatOtherNormalizedOhmurl(EcmaVM *vm, const JSPandaFile *jsPandaFile,
197                                             [[maybe_unused]] CString &baseFileName, CString &requestPath);
198     static CString ConcatNormalizedOhmurlWithData(CVector<CString> &data, CString &pkgName, CString &entryPath);
199     static CString GetBundleNameWithRecordName(EcmaVM *vm, const CString &recordName);
200     static CString Utf8ConvertToString(JSTaggedValue str);
201 
202     static CString ParseFileNameToVMAName(const CString &filename);
203     static CString ConcatOtherNormalizedOhmurlWithFilePath(EcmaVM *vm, size_t filePathPos, CString &moduleName,
204                                                            const CString &requestPath);
205     /*
206      * Before: /data/storage/el1/bundle/moduleName/ets/modules.abc
207      * After:  bundle/moduleName
208      */
ParseHapPath(const CString & baseFileName)209     inline static std::string ParseHapPath(const CString &baseFileName)
210     {
211         CString bundleSubInstallName(BUNDLE_SUB_INSTALL_PATH);
212         size_t startStrLen = bundleSubInstallName.length();
213         if (baseFileName.length() > startStrLen && baseFileName.compare(0, startStrLen, bundleSubInstallName) == 0) {
214             CString hapPath = baseFileName.substr(startStrLen);
215             size_t pos = hapPath.find(MERGE_ABC_ETS_MODULES);
216             if (pos != CString::npos) {
217                 return hapPath.substr(0, pos).c_str();
218             }
219         }
220         return std::string();
221     }
222 
223     /*
224      * Before: xxx
225      * After:  xxx || xxx/index
226      */
ConfirmLoadingIndexOrNot(const JSPandaFile * jsPandaFile,const CString & packageEntryPoint)227     inline static CString ConfirmLoadingIndexOrNot(const JSPandaFile *jsPandaFile, const CString &packageEntryPoint)
228     {
229         CString entryPoint = packageEntryPoint;
230         if (jsPandaFile->HasRecord(entryPoint)) {
231             return entryPoint;
232         }
233         // Possible import directory
234         entryPoint += PACKAGE_ENTRY_FILE;
235         entryPoint = PathHelper::NormalizePath(entryPoint);
236         if (jsPandaFile->HasRecord(entryPoint)) {
237             return entryPoint;
238         }
239         return CString();
240     }
241 
IsNativeModuleRequest(const CString & requestName)242     inline static bool IsNativeModuleRequest(const CString &requestName)
243     {
244         if (requestName[0] != PathHelper::NAME_SPACE_TAG) {
245             return false;
246         }
247         if (StringHelper::StringStartWith(requestName, ModulePathHelper::REQUIRE_NAPI_OHOS_PREFIX) ||
248             StringHelper::StringStartWith(requestName, ModulePathHelper::REQUIRE_NAPI_APP_PREFIX) ||
249             StringHelper::StringStartWith(requestName, ModulePathHelper::REQUIRE_NAITVE_MODULE_PREFIX)) {
250             return true;
251         }
252         return false;
253     }
254 
255     /*
256      * Before: bundleName/moduleName/ets/xxx/xxx
257      * After:  moduleName
258      */
GetModuleName(const CString recordName)259     inline static CString GetModuleName(const CString recordName)
260     {
261         size_t pos1 = recordName.find(PathHelper::SLASH_TAG);
262         if (pos1 != CString::npos) {
263             pos1++;
264             size_t pos2 = recordName.find(PathHelper::SLASH_TAG, pos1);
265             if (pos2 != CString::npos) {
266                 CString moduleName = recordName.substr(pos1, pos2 - pos1);
267                 PathHelper::DeleteNamespace(moduleName);
268                 return moduleName;
269             }
270         }
271         return CString();
272     }
273 
274     /*
275      * Before: &moduleName/src/xxx
276      * After:  moduleName
277      */
GetModuleNameWithNormalizedName(const CString recordName)278     inline static CString GetModuleNameWithNormalizedName(const CString recordName)
279     {
280         size_t pos1 = recordName.find(PathHelper::NORMALIZED_OHMURL_TAG);
281         if (pos1 != CString::npos) {
282             pos1++;
283             size_t pos2 = recordName.find(PathHelper::SLASH_TAG, pos1);
284             if (pos2 != CString::npos) {
285                 CString moduleName = recordName.substr(pos1, pos2 - pos1);
286                 return moduleName;
287             }
288         }
289         return CString();
290     }
291 
292     /*
293      * Before: bundleName/moduleName
294      * After:  moduleName
295      */
GetModuleNameWithPath(const CString modulePath)296     inline static CString GetModuleNameWithPath(const CString modulePath)
297     {
298         size_t pos1 = modulePath.find(PathHelper::SLASH_TAG);
299         if (pos1 != CString::npos) {
300             pos1++;
301             return modulePath.substr(pos1, modulePath.size() - pos1 + 1);
302         }
303         return CString();
304     }
305     /*
306      * Before: @xxx.
307      * After:  @xxx:
308      */
ChangeTag(CString & path)309     inline static bool ChangeTag(CString &path)
310     {
311         if (path[0] == PathHelper::NAME_SPACE_TAG) {
312             size_t pos = path.find(PathHelper::POINT_TAG);
313             if (pos != CString::npos) {
314                 path.replace(pos, 1, PathHelper::COLON_TAG); // 1: length
315                 return true;
316             }
317         }
318         return false;
319     }
320 
321     /*
322      * Before: moduleName
323      * After:  data/storage/el1/bundle/moduleName/ets/modules.abc
324      */
ConcatPandaFilePath(const CString & moduleName)325     inline static CString ConcatPandaFilePath(const CString &moduleName)
326     {
327         if (moduleName.size() == 0) {
328             return CString();
329         }
330         return BUNDLE_INSTALL_PATH + moduleName + MERGE_ABC_ETS_MODULES;
331     }
332 
GetBundleNameFromNormalized(const EcmaVM * vm,const CString & moduleName)333     inline static CString GetBundleNameFromNormalized(const EcmaVM *vm, const CString &moduleName)
334     {
335         CVector<CString> res = SplitNormalizedOhmurl(moduleName);
336         if (res.size() != NORMALIZED_OHMURL_ARGS_NUM) {
337             LOG_FULL(ERROR) << "GetBundleNameFromNormalized Invalid normalized ohmurl";
338             return "";
339         }
340         CString bundleName = res[NORMALIZED_BUNDLE_NAME_INDEX];
341         if (bundleName.size() == 0) {
342             return vm->GetBundleName();
343         }
344         return bundleName;
345     }
346 
GetNormalizedPathFromOhmUrl(const CString & moduleName)347     inline static CString GetNormalizedPathFromOhmUrl(const CString &moduleName)
348     {
349         CVector<CString> res = SplitNormalizedOhmurl(moduleName);
350         if (res.size() != NORMALIZED_OHMURL_ARGS_NUM) {
351             LOG_FULL(ERROR) << "GetNormalizedPathFromOhmUrl Invalid normalized ohmurl";
352             return "";
353         }
354         CString soName = res[NORMALIZED_IMPORT_PATH_INDEX];
355         // Delete the prefix "lib" and suffix ".so".
356         soName = soName.substr(SO_PREFIX_LEN, soName.size() - SO_PREFIX_LEN - SO_SUFFIX_LEN);
357         return soName;
358     }
359 
360     /*
361      * Before: /data/storage/el1/xxx/xxx/xxx/xxx.abc
362      */
ValidateAbcPath(const CString & baseFileName)363     inline static bool ValidateAbcPath(const CString &baseFileName)
364     {
365         CString bundleSubInstallName(BUNDLE_SUB_INSTALL_PATH);
366         size_t startStrLen = bundleSubInstallName.length();
367         if (baseFileName.length() > startStrLen && baseFileName.compare(0, startStrLen, bundleSubInstallName) == 0) {
368             if (baseFileName.rfind(ABC) != CString::npos) {
369                 return true;
370             }
371         }
372         return false;
373     }
374 };
375 } // namespace panda::ecmascript
376 #endif // ECMASCRIPT_MODULE_MODULE_PATH_HELPER_H