• 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 REQUIRE_NAITVE_MODULE_PREFIX[] = "@native:";
71     static constexpr char REQUIRE_NAPI_OHOS_PREFIX[] = "@ohos:";
72     static constexpr char REQUIRE_NAPI_APP_PREFIX[] = "@app:";
73     static constexpr char NPM_PATH_SEGMENT[] = "node_modules";
74     static constexpr char PACKAGE_PATH_SEGMENT[] = "pkg_modules";
75     static constexpr char PACKAGE_ENTRY_FILE[] = "/index";
76     static constexpr char BUNDLE_INSTALL_PATH[] = "/data/storage/el1/bundle/";
77     static constexpr char MERGE_ABC_ETS_MODULES[] = "/ets/modules.abc";
78     static constexpr char MODULE_DEFAULE_ETS[] = "/ets/";
79     static constexpr char BUNDLE_SUB_INSTALL_PATH[] = "/data/storage/el1/";
80     static constexpr char PREVIEW_OF_ACROSS_HAP_FLAG[] = "[preview]";
81     static constexpr char PREVIER_TEST_DIR[] = ".test";
82 
83     static constexpr size_t MAX_PACKAGE_LEVEL = 1;
84     static constexpr size_t SEGMENTS_LIMIT_TWO = 2;
85     static constexpr size_t EXT_NAME_ABC_LEN = 4;
86     static constexpr size_t EXT_NAME_ETS_LEN = 4;
87     static constexpr size_t EXT_NAME_TS_LEN = 3;
88     static constexpr size_t EXT_NAME_JS_LEN = 3;
89     static constexpr size_t EXT_NAME_JSON_LEN = 5;
90     static constexpr size_t PREFIX_BUNDLE_LEN = 8;
91     static constexpr size_t PREFIX_MODULE_LEN = 8;
92     static constexpr size_t PREFIX_PACKAGE_LEN = 9;
93     static constexpr size_t NATIVE_PREFIX_SIZE = 8;
94     static constexpr size_t OHOS_PREFIX_SIZE = 6;
95     static constexpr size_t APP_PREFIX_SIZE = 5;
96 
97     static CString ConcatFileNameWithMerge(JSThread *thread, const JSPandaFile *jsPandaFile,
98                                            CString &baseFileName, CString recordName, CString requestName);
99     static void ParseOhmUrl(EcmaVM *vm, const CString &inputFileName,
100                             CString &outBaseFileName, CString &outEntryPoint);
101     static CString ParseUrl(EcmaVM *vm, const CString &recordName);
102     static CString ParsePrefixBundle(JSThread *thread, const JSPandaFile *jsPandaFile,
103         [[maybe_unused]] CString &baseFileName, CString moduleRequestName, [[maybe_unused]] CString recordName);
104     static CString MakeNewRecord(const JSPandaFile *jsPandaFile, CString &baseFileName,
105                                  const CString &recordName, const CString &requestName);
106     static CString FindOhpmEntryPoint(const JSPandaFile *jsPandaFile, const CString &ohpmPath,
107                                       const CString &requestName);
108     static CString FindPackageInTopLevelWithNamespace(const JSPandaFile *jsPandaFile, const CString &requestName,
109                                                       const CString &recordName);
110     static CString ParseOhpmPackage(const JSPandaFile *jsPandaFile, const CString &recordName,
111                                     const CString &requestName);
112     static CString ParseThirdPartyPackage(const JSPandaFile *jsPandaFile, const CString &recordName,
113                                           const CString &requestName, const CString &packagePath);
114     static CString ParseThirdPartyPackage(const JSPandaFile *jsPandaFile, const CString &recordName,
115                                           const CString &requestName);
116     static void ResolveCurrentPath(JSThread *thread, JSMutableHandle<JSTaggedValue> &dirPath,
117                                    JSMutableHandle<JSTaggedValue> &fileName, const JSPandaFile *jsPandaFile);
118     static CString FindNpmEntryPoint(const JSPandaFile *jsPandaFile, const CString &packageEntryPoint);
119     static CString FindPackageInTopLevel(const JSPandaFile *jsPandaFile, const CString &requestName,
120                                          const CString &packagePath);
121     static bool IsImportFile(const CString &moduleRequestName);
122     static CString RemoveSuffix(const CString &requestName);
123 
124     /*
125      * Before: data/storage/el1/bundle/moduleName/ets/modules.abc
126      * After:  bundle/moduleName
127      */
ParseHapPath(const CString & baseFileName)128     inline static std::string ParseHapPath(const CString &baseFileName)
129     {
130         CString bundleSubInstallName(BUNDLE_SUB_INSTALL_PATH);
131         size_t startStrLen = bundleSubInstallName.length();
132         if (baseFileName.length() > startStrLen && baseFileName.compare(0, startStrLen, bundleSubInstallName) == 0) {
133             CString hapPath = baseFileName.substr(startStrLen);
134             size_t pos = hapPath.find(MERGE_ABC_ETS_MODULES);
135             if (pos != CString::npos) {
136                 return hapPath.substr(0, pos).c_str();
137             }
138         }
139         return std::string();
140     }
141 
142     /*
143      * Before: xxx
144      * After:  xxx || xxx/index
145      */
ConfirmLoadingIndexOrNot(const JSPandaFile * jsPandaFile,const CString & packageEntryPoint)146     inline static CString ConfirmLoadingIndexOrNot(const JSPandaFile *jsPandaFile, const CString &packageEntryPoint)
147     {
148         CString entryPoint = packageEntryPoint;
149         if (jsPandaFile->HasRecord(entryPoint)) {
150             return entryPoint;
151         }
152         // Possible import directory
153         entryPoint += PACKAGE_ENTRY_FILE;
154         if (jsPandaFile->HasRecord(entryPoint)) {
155             return entryPoint;
156         }
157         return CString();
158     }
159 
IsNativeModuleRequest(const CString & requestName)160     inline static bool IsNativeModuleRequest(const CString &requestName)
161     {
162         if (requestName[0] != PathHelper::NAME_SPACE_TAG) {
163             return false;
164         }
165         if (StringHelper::StringStartWith(requestName, ModulePathHelper::REQUIRE_NAPI_OHOS_PREFIX) ||
166             StringHelper::StringStartWith(requestName, ModulePathHelper::REQUIRE_NAPI_APP_PREFIX) ||
167             StringHelper::StringStartWith(requestName, ModulePathHelper::REQUIRE_NAITVE_MODULE_PREFIX)) {
168             return true;
169         }
170         return false;
171     }
172 };
173 } // namespace panda::ecmascript
174 #endif // ECMASCRIPT_MODULE_MODULE_PATH_HELPER_H