• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023 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 PREFIX_BUNDLE[] = "@bundle:";
68     static constexpr char PREFIX_MODULE[] = "@module:";
69     static constexpr char PREFIX_PACKAGE[] = "@package:";
70     static constexpr char PREFIX_ETS[] = "ets/";
71     static constexpr char REQUIRE_NAITVE_MODULE_PREFIX[] = "@native:";
72     static constexpr char REQUIRE_NAPI_OHOS_PREFIX[] = "@ohos:";
73     static constexpr char REQUIRE_NAPI_APP_PREFIX[] = "@app:";
74     static constexpr char RAW_ARKUIX_PREFIX[] = "@arkui-x.";
75     static constexpr char NPM_PATH_SEGMENT[] = "node_modules";
76     static constexpr char PACKAGE_PATH_SEGMENT[] = "pkg_modules";
77     static constexpr char PACKAGE_ENTRY_FILE[] = "/index";
78     static constexpr char BUNDLE_INSTALL_PATH[] = "/data/storage/el1/bundle/";
79     static constexpr char MERGE_ABC_ETS_MODULES[] = "/ets/modules.abc";
80     static constexpr char MODULE_DEFAULE_ETS[] = "/ets/";
81     static constexpr char BUNDLE_SUB_INSTALL_PATH[] = "/data/storage/el1/";
82     static constexpr char PREVIEW_OF_ACROSS_HAP_FLAG[] = "[preview]";
83     static constexpr char PREVIER_TEST_DIR[] = ".test";
84 
85     static constexpr size_t MAX_PACKAGE_LEVEL = 1;
86     static constexpr size_t SEGMENTS_LIMIT_TWO = 2;
87     static constexpr size_t EXT_NAME_ABC_LEN = 4;
88     static constexpr size_t EXT_NAME_ETS_LEN = 4;
89     static constexpr size_t EXT_NAME_TS_LEN = 3;
90     static constexpr size_t EXT_NAME_JS_LEN = 3;
91     static constexpr size_t EXT_NAME_JSON_LEN = 5;
92     static constexpr size_t PREFIX_BUNDLE_LEN = 8;
93     static constexpr size_t PREFIX_MODULE_LEN = 8;
94     static constexpr size_t PREFIX_PACKAGE_LEN = 9;
95     static constexpr size_t NATIVE_PREFIX_SIZE = 8;
96     static constexpr size_t OHOS_PREFIX_SIZE = 6;
97     static constexpr size_t APP_PREFIX_SIZE = 5;
98     static constexpr size_t BUNDLE_INSTALL_PATH_LEN = 25;
99 
100     static CString ConcatFileNameWithMerge(JSThread *thread, const JSPandaFile *jsPandaFile,
101                                            CString &baseFileName, CString recordName, CString requestName);
102     static void ParseOhmUrl(EcmaVM *vm, const CString &inputFileName,
103                             CString &outBaseFileName, CString &outEntryPoint);
104     static CString ParseUrl(EcmaVM *vm, const CString &recordName);
105     static CString ParsePrefixBundle(JSThread *thread, const JSPandaFile *jsPandaFile,
106         [[maybe_unused]] CString &baseFileName, CString moduleRequestName, [[maybe_unused]] CString recordName);
107     static CString MakeNewRecord(const JSPandaFile *jsPandaFile, CString &baseFileName,
108                                  const CString &recordName, const CString &requestName);
109     static CString FindOhpmEntryPoint(const JSPandaFile *jsPandaFile, const CString &ohpmPath,
110                                       const CString &requestName);
111     static CString FindPackageInTopLevelWithNamespace(const JSPandaFile *jsPandaFile, const CString &requestName,
112                                                       const CString &recordName);
113     static CString ParseOhpmPackage(const JSPandaFile *jsPandaFile, const CString &recordName,
114                                     const CString &requestName);
115     static CString ParseThirdPartyPackage(const JSPandaFile *jsPandaFile, const CString &recordName,
116                                           const CString &requestName, const CString &packagePath);
117     static CString ParseThirdPartyPackage(const JSPandaFile *jsPandaFile, const CString &recordName,
118                                           const CString &requestName);
119     static void ResolveCurrentPath(JSThread *thread, JSMutableHandle<JSTaggedValue> &dirPath,
120                                    JSMutableHandle<JSTaggedValue> &fileName, const JSPandaFile *jsPandaFile);
121     static CString FindNpmEntryPoint(const JSPandaFile *jsPandaFile, const CString &packageEntryPoint);
122     static CString FindPackageInTopLevel(const JSPandaFile *jsPandaFile, const CString &requestName,
123                                          const CString &packagePath);
124     static bool IsImportFile(const CString &moduleRequestName);
125     static CString RemoveSuffix(const CString &requestName);
126     static bool NeedTranstale(const CString &requestName);
127     static void TranstaleExpressionInput(JSThread *thread, CString &requestPath, const JSPandaFile *jsPandaFile,
128                                          JSHandle<EcmaString> &specifierString);
129     static CString GetModuleNameWithBaseFile(const CString &baseFileName);
130     static CString TranslateExpressionInputWithEts(JSThread *thread, const JSPandaFile *jsPandaFile,
131                                                    CString &baseFileName, const CString &requestName);
132     /*
133      * Before: data/storage/el1/bundle/moduleName/ets/modules.abc
134      * After:  bundle/moduleName
135      */
ParseHapPath(const CString & baseFileName)136     inline static std::string ParseHapPath(const CString &baseFileName)
137     {
138         CString bundleSubInstallName(BUNDLE_SUB_INSTALL_PATH);
139         size_t startStrLen = bundleSubInstallName.length();
140         if (baseFileName.length() > startStrLen && baseFileName.compare(0, startStrLen, bundleSubInstallName) == 0) {
141             CString hapPath = baseFileName.substr(startStrLen);
142             size_t pos = hapPath.find(MERGE_ABC_ETS_MODULES);
143             if (pos != CString::npos) {
144                 return hapPath.substr(0, pos).c_str();
145             }
146         }
147         return std::string();
148     }
149 
150     /*
151      * Before: xxx
152      * After:  xxx || xxx/index
153      */
ConfirmLoadingIndexOrNot(const JSPandaFile * jsPandaFile,const CString & packageEntryPoint)154     inline static CString ConfirmLoadingIndexOrNot(const JSPandaFile *jsPandaFile, const CString &packageEntryPoint)
155     {
156         CString entryPoint = packageEntryPoint;
157         if (jsPandaFile->HasRecord(entryPoint)) {
158             return entryPoint;
159         }
160         // Possible import directory
161         entryPoint += PACKAGE_ENTRY_FILE;
162         entryPoint = PathHelper::NormalizePath(entryPoint);
163         if (jsPandaFile->HasRecord(entryPoint)) {
164             return entryPoint;
165         }
166         return CString();
167     }
168 
IsNativeModuleRequest(const CString & requestName)169     inline static bool IsNativeModuleRequest(const CString &requestName)
170     {
171         if (requestName[0] != PathHelper::NAME_SPACE_TAG) {
172             return false;
173         }
174         if (StringHelper::StringStartWith(requestName, ModulePathHelper::REQUIRE_NAPI_OHOS_PREFIX) ||
175             StringHelper::StringStartWith(requestName, ModulePathHelper::REQUIRE_NAPI_APP_PREFIX) ||
176             StringHelper::StringStartWith(requestName, ModulePathHelper::REQUIRE_NAITVE_MODULE_PREFIX)) {
177             return true;
178         }
179         return false;
180     }
181 
182     /*
183      * Before: bundleName/moduleName/ets/xxx/xxx
184      * After:  moduleName
185      */
GetModuleName(const CString recordName)186     inline static CString GetModuleName(const CString recordName)
187     {
188         size_t pos1 = recordName.find(PathHelper::SLASH_TAG);
189         if (pos1 != CString::npos) {
190             pos1++;
191             size_t pos2 = recordName.find(PathHelper::SLASH_TAG, pos1);
192             if (pos2 != CString::npos) {
193                 CString moduleName = recordName.substr(pos1, pos2 - pos1);
194                 PathHelper::DeleteNamespace(moduleName);
195                 return moduleName;
196             }
197         }
198         return CString();
199     }
200 
201     /*
202      * Before: @xxx.
203      * After:  @xxx:
204      */
ChangeTag(CString & path)205     inline static bool ChangeTag(CString &path)
206     {
207         if (path[0] == PathHelper::NAME_SPACE_TAG) {
208             size_t pos = path.find(PathHelper::POINT_TAG);
209             if (pos != CString::npos) {
210                 path.replace(pos, 1, PathHelper::COLON_TAG); // 1: length
211                 return true;
212             }
213         }
214         return false;
215     }
216 };
217 } // namespace panda::ecmascript
218 #endif // ECMASCRIPT_MODULE_MODULE_PATH_HELPER_H