2023-07-12 12:34:30 +00:00
|
|
|
/*
|
2024-02-26 07:00:42 +00:00
|
|
|
* Copyright (c) 2024 Huawei Device Co., Ltd.
|
2023-07-12 12:34:30 +00:00
|
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
* you may not use this file except in compliance with the License.
|
|
|
|
* You may obtain a copy of the License at
|
|
|
|
*
|
|
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
*
|
|
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
* See the License for the specific language governing permissions and
|
|
|
|
* limitations under the License.
|
|
|
|
*/
|
|
|
|
#include "ecmascript/module/module_path_helper.h"
|
|
|
|
|
|
|
|
namespace panda::ecmascript {
|
|
|
|
/*
|
|
|
|
* This function use recordName, requestName to get baseFileName and entryPoint.
|
|
|
|
*/
|
|
|
|
CString ModulePathHelper::ConcatFileNameWithMerge(JSThread *thread, const JSPandaFile *jsPandaFile,
|
|
|
|
CString &baseFileName, CString recordName, CString requestName)
|
|
|
|
{
|
2024-04-06 06:44:00 +00:00
|
|
|
if (thread->GetEcmaVM()->IsNormalizedOhmUrlPack()) {
|
2024-04-25 13:38:17 +00:00
|
|
|
return ConcatMergeFileNameToNormalized(thread, jsPandaFile, baseFileName, recordName, requestName);
|
2024-04-06 06:44:00 +00:00
|
|
|
}
|
|
|
|
|
2023-07-12 12:34:30 +00:00
|
|
|
if (StringHelper::StringStartWith(requestName, PREFIX_BUNDLE)) {
|
2024-03-10 12:20:18 +00:00
|
|
|
return ParsePrefixBundle(thread, jsPandaFile, baseFileName, requestName, recordName);
|
2023-07-12 12:34:30 +00:00
|
|
|
} else if (StringHelper::StringStartWith(requestName, PREFIX_PACKAGE)) {
|
2024-04-30 03:34:40 +00:00
|
|
|
if (thread->GetCurrentEcmaContext()->GetStageOfHotReload() == StageOfHotReload::BEGIN_EXECUTE_PATCHMAIN) {
|
|
|
|
baseFileName = thread->GetEcmaVM()->GetAssetPath();
|
|
|
|
}
|
2024-03-10 12:20:18 +00:00
|
|
|
return requestName.substr(PREFIX_PACKAGE_LEN);
|
2023-07-12 12:34:30 +00:00
|
|
|
} else if (IsImportFile(requestName)) {
|
2023-09-18 07:50:38 +00:00
|
|
|
// this branch save for require/dynamic import/old version sdk
|
2023-07-12 12:34:30 +00:00
|
|
|
// load a relative pathName.
|
|
|
|
// requestName: ./ || ./xxx/xxx.js || ../xxx/xxx.js || ./xxx/xxx
|
2024-05-11 08:16:43 +00:00
|
|
|
return MakeNewRecord(thread, jsPandaFile, baseFileName, recordName, requestName);
|
2024-01-23 07:01:46 +00:00
|
|
|
} else if (StringHelper::StringStartWith(requestName, PREFIX_ETS)) {
|
2024-03-10 12:20:18 +00:00
|
|
|
CString entryPoint = TranslateExpressionInputWithEts(thread, jsPandaFile, baseFileName, requestName);
|
|
|
|
if (entryPoint.empty()) {
|
|
|
|
THROW_MODULE_NOT_FOUND_ERROR_WITH_RETURN_VALUE(thread, requestName, recordName, entryPoint);
|
|
|
|
}
|
|
|
|
return entryPoint;
|
2023-07-12 12:34:30 +00:00
|
|
|
} else {
|
2023-09-18 07:50:38 +00:00
|
|
|
// this branch save for require/dynamic import/old version sdk
|
2023-07-12 12:34:30 +00:00
|
|
|
// requestName: requestPkgName
|
2024-03-10 12:20:18 +00:00
|
|
|
CString entryPoint = ParseThirdPartyPackage(jsPandaFile, recordName, requestName);
|
2024-03-14 06:57:27 +00:00
|
|
|
if (entryPoint.empty() && thread->GetEcmaVM()->EnableReportModuleResolvingFailure()) {
|
2024-03-10 12:20:18 +00:00
|
|
|
THROW_MODULE_NOT_FOUND_ERROR_WITH_RETURN_VALUE(thread, requestName, recordName, entryPoint);
|
|
|
|
}
|
|
|
|
return entryPoint;
|
2023-07-12 12:34:30 +00:00
|
|
|
}
|
2024-03-10 12:20:18 +00:00
|
|
|
LOG_FULL(FATAL) << "this branch is unreachable";
|
|
|
|
UNREACHABLE();
|
|
|
|
}
|
|
|
|
|
2024-04-25 13:38:17 +00:00
|
|
|
CString ModulePathHelper::ConcatMergeFileNameToNormalized(JSThread *thread, const JSPandaFile *jsPandaFile,
|
|
|
|
CString &baseFileName, CString recordName, CString requestName)
|
|
|
|
{
|
|
|
|
if (!StringHelper::StringStartWith(requestName, PREFIX_NORMALIZED)) {
|
|
|
|
if (StringHelper::StringStartWith(requestName, PREFIX_BUNDLE) ||
|
|
|
|
StringHelper::StringStartWith(requestName, PREFIX_PACKAGE) ||
|
|
|
|
StringHelper::StringStartWith(requestName, PREFIX_ETS)) {
|
|
|
|
CString msg = "can not use different packing ways in same app, current requestName is " + requestName;
|
|
|
|
THROW_REFERENCE_ERROR_AND_RETURN(thread, msg.c_str(), "");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (IsImportFile(requestName)) {
|
|
|
|
ConcatImportFileNormalizedOhmurlWithRecordName(recordName, requestName);
|
|
|
|
} else {
|
|
|
|
// this branch save for require npm
|
|
|
|
TranslateExpressionToNormalized(thread, jsPandaFile, baseFileName, recordName, requestName);
|
|
|
|
}
|
|
|
|
return ParseNormalizedOhmUrl(thread, baseFileName, requestName);
|
|
|
|
}
|
|
|
|
|
|
|
|
CString ModulePathHelper::ConcatImportFileNormalizedOhmurlWithRecordName(CString &recordName, CString &requestName)
|
|
|
|
{
|
|
|
|
CVector<CString> res = SplitNormalizedRecordName(recordName);
|
|
|
|
CString path = PathHelper::NORMALIZED_OHMURL_TAG + res[NORMALIZED_IMPORT_PATH_INDEX];
|
|
|
|
CString version = res[NORMALIZED_VERSION_INDEX];
|
|
|
|
requestName = RemoveSuffix(requestName);
|
|
|
|
size_t pos = requestName.find(PathHelper::CURRENT_DIREATORY_TAG);
|
|
|
|
if (pos == 0) {
|
|
|
|
requestName = requestName.substr(CURRENT_DIREATORY_TAG_LEN);
|
|
|
|
}
|
|
|
|
pos = path.rfind(PathHelper::SLASH_TAG);
|
|
|
|
if (pos != CString::npos) {
|
|
|
|
requestName = ConcatImportFileNormalizedOhmurl(path.substr(0, pos + 1),
|
|
|
|
requestName, version);
|
|
|
|
}
|
|
|
|
return requestName;
|
|
|
|
}
|
|
|
|
|
2024-03-10 12:20:18 +00:00
|
|
|
CString ModulePathHelper::ReformatPath(CString requestName)
|
|
|
|
{
|
|
|
|
CString normalizeStr;
|
|
|
|
if (StringHelper::StringStartWith(requestName, PACKAGE_PATH_SEGMENT) ||
|
|
|
|
StringHelper::StringStartWith(requestName, PREFIX_PACKAGE)) {
|
|
|
|
auto pos = requestName.rfind(PACKAGE_PATH_SEGMENT);
|
|
|
|
ASSERT(pos != CString::npos);
|
|
|
|
normalizeStr = requestName.substr(pos + 1);
|
|
|
|
} else if (StringHelper::StringStartWith(requestName, REQUIRE_NAPI_APP_PREFIX)) {
|
|
|
|
auto pos = requestName.find(PathHelper::SLASH_TAG);
|
|
|
|
pos = requestName.find(PathHelper::SLASH_TAG, pos + 1);
|
|
|
|
ASSERT(pos != CString::npos);
|
|
|
|
normalizeStr = requestName.substr(pos + 1);
|
2024-04-06 06:44:00 +00:00
|
|
|
} else {
|
|
|
|
normalizeStr = requestName;
|
2024-03-10 12:20:18 +00:00
|
|
|
}
|
|
|
|
return normalizeStr;
|
2023-07-12 12:34:30 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
2023-11-30 11:09:23 +00:00
|
|
|
* Before: inputFileName: 1. /data/storage/el1/bundle/moduleName@namespace/ets/xxx/xxx.abc
|
2023-07-12 12:34:30 +00:00
|
|
|
2. @bundle:bundleName/moduleName/ets/xxx/xxx.abc
|
|
|
|
3. moduleName/ets/xxx/xxx.abc
|
|
|
|
4. .test/xxx/xxx.abc
|
|
|
|
5. xxx/xxx.abc
|
|
|
|
* After: outBaseFileName: /data/storage/el1/bundle/moduleName/ets/modules.abc
|
|
|
|
* outEntryPoint: bundleName/moduleName/ets/xxx/xxx
|
|
|
|
*/
|
2024-04-06 06:44:00 +00:00
|
|
|
void ModulePathHelper::ParseAbcPathAndOhmUrl(EcmaVM *vm, const CString &inputFileName,
|
2023-07-12 12:34:30 +00:00
|
|
|
CString &outBaseFileName, CString &outEntryPoint)
|
|
|
|
{
|
|
|
|
size_t pos = CString::npos;
|
2024-01-02 06:02:53 +00:00
|
|
|
if (inputFileName.length() > BUNDLE_INSTALL_PATH_LEN &&
|
|
|
|
inputFileName.compare(0, BUNDLE_INSTALL_PATH_LEN, BUNDLE_INSTALL_PATH) == 0) {
|
|
|
|
pos = BUNDLE_INSTALL_PATH_LEN;
|
2023-07-12 12:34:30 +00:00
|
|
|
}
|
|
|
|
if (pos != CString::npos) {
|
2023-11-30 11:09:23 +00:00
|
|
|
// inputFileName: /data/storage/el1/bundle/moduleName@namespace/ets/xxx/xxx.abc
|
2024-01-02 06:02:53 +00:00
|
|
|
pos = inputFileName.find(PathHelper::SLASH_TAG, BUNDLE_INSTALL_PATH_LEN);
|
2023-07-12 12:34:30 +00:00
|
|
|
if (pos == CString::npos) {
|
|
|
|
LOG_FULL(FATAL) << "Invalid Ohm url, please check.";
|
|
|
|
}
|
2024-01-02 06:02:53 +00:00
|
|
|
CString moduleName = inputFileName.substr(BUNDLE_INSTALL_PATH_LEN, pos - BUNDLE_INSTALL_PATH_LEN);
|
2023-11-30 11:09:23 +00:00
|
|
|
PathHelper::DeleteNamespace(moduleName);
|
2023-07-12 12:34:30 +00:00
|
|
|
outBaseFileName = BUNDLE_INSTALL_PATH + moduleName + MERGE_ABC_ETS_MODULES;
|
2024-01-02 06:02:53 +00:00
|
|
|
outEntryPoint = vm->GetBundleName() + PathHelper::SLASH_TAG + inputFileName.substr(BUNDLE_INSTALL_PATH_LEN);
|
2023-07-12 12:34:30 +00:00
|
|
|
} else {
|
|
|
|
// Temporarily handle the relative path sent by arkui
|
|
|
|
// inputFileName: @bundle:bundleName/moduleName/ets/xxx/xxx.abc
|
|
|
|
if (StringHelper::StringStartWith(inputFileName, PREFIX_BUNDLE)) {
|
|
|
|
outEntryPoint = inputFileName.substr(PREFIX_BUNDLE_LEN);
|
|
|
|
outBaseFileName = ParseUrl(vm, outEntryPoint);
|
|
|
|
} else {
|
|
|
|
#if !defined(PANDA_TARGET_WINDOWS) && !defined(PANDA_TARGET_MACOS)
|
|
|
|
// inputFileName: moduleName/ets/xxx/xxx.abc
|
|
|
|
outEntryPoint = vm->GetBundleName() + PathHelper::SLASH_TAG + inputFileName;
|
|
|
|
#else
|
|
|
|
// if the inputFileName starts with '.test', the preview test page is started.
|
|
|
|
// in this case, the path ets does not need to be combined.
|
|
|
|
// inputFileName: .test/xxx/xxx.abc
|
|
|
|
if (StringHelper::StringStartWith(inputFileName, PREVIER_TEST_DIR)) {
|
|
|
|
outEntryPoint = vm->GetBundleName() + PathHelper::SLASH_TAG + vm->GetModuleName() +
|
|
|
|
PathHelper::SLASH_TAG + inputFileName;
|
|
|
|
} else {
|
|
|
|
// inputFileName: xxx/xxx.abc
|
|
|
|
outEntryPoint = vm->GetBundleName() + PathHelper::SLASH_TAG + vm->GetModuleName() +
|
|
|
|
MODULE_DEFAULE_ETS + inputFileName;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (StringHelper::StringEndWith(outEntryPoint, EXT_NAME_ABC)) {
|
|
|
|
outEntryPoint.erase(outEntryPoint.length() - EXT_NAME_ABC_LEN, EXT_NAME_ABC_LEN);
|
|
|
|
}
|
2024-04-06 06:44:00 +00:00
|
|
|
if (vm->IsNormalizedOhmUrlPack()) {
|
2024-05-11 10:36:09 +00:00
|
|
|
outEntryPoint = TransformToNormalizedOhmUrl(vm, inputFileName, outBaseFileName, outEntryPoint);
|
2024-04-06 06:44:00 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Unified ohmUrl used be cached: [<bundle name>?]&<pkg name + /src/main + path>&[<version>?]
|
2024-05-04 10:28:21 +00:00
|
|
|
CString ModulePathHelper::ConcatUnifiedOhmUrl(const CString &bundleName, const CString &pkgname,
|
|
|
|
const CString &entryPath, const CString &path, const CString &version)
|
2024-04-06 06:44:00 +00:00
|
|
|
{
|
2024-05-04 10:28:21 +00:00
|
|
|
if (entryPath.size() != 0) {
|
|
|
|
// entryPath is src/xxx/
|
|
|
|
return bundleName + PathHelper::NORMALIZED_OHMURL_TAG + pkgname + PathHelper::SLASH_TAG + entryPath + path +
|
|
|
|
PathHelper::NORMALIZED_OHMURL_TAG + version;
|
|
|
|
}
|
2024-04-06 06:44:00 +00:00
|
|
|
return bundleName + PathHelper::NORMALIZED_OHMURL_TAG + pkgname + PHYCICAL_FILE_PATH + path +
|
|
|
|
PathHelper::NORMALIZED_OHMURL_TAG + version;
|
|
|
|
}
|
|
|
|
|
|
|
|
CString ModulePathHelper::ConcatUnifiedOhmUrl(const CString &bundleName, const CString &normalizedpath,
|
|
|
|
const CString &version)
|
|
|
|
{
|
|
|
|
return bundleName + PathHelper::NORMALIZED_OHMURL_TAG + normalizedpath + PathHelper::NORMALIZED_OHMURL_TAG +
|
|
|
|
version;
|
|
|
|
}
|
|
|
|
|
2024-05-11 10:36:09 +00:00
|
|
|
CString ModulePathHelper::ConcatPreviewTestUnifiedOhmUrl(const CString &bundleName, const CString &pkgname,
|
|
|
|
const CString &path, const CString &version)
|
|
|
|
{
|
|
|
|
return bundleName + PathHelper::NORMALIZED_OHMURL_TAG + pkgname + path + PathHelper::NORMALIZED_OHMURL_TAG +
|
|
|
|
version;
|
|
|
|
}
|
|
|
|
|
2024-04-06 06:44:00 +00:00
|
|
|
CString ModulePathHelper::ConcatHspFileNameCrossBundle(const CString &bundleName, const CString &moduleName)
|
|
|
|
{
|
|
|
|
CString bundlePath = BUNDLE_INSTALL_PATH;
|
|
|
|
return bundlePath + bundleName + PathHelper::SLASH_TAG + moduleName + PathHelper::SLASH_TAG + moduleName +
|
|
|
|
MERGE_ABC_ETS_MODULES;
|
|
|
|
}
|
|
|
|
|
|
|
|
CString ModulePathHelper::ConcatHspFileName(const CString &moduleName)
|
|
|
|
{
|
|
|
|
CString bundlePath = BUNDLE_INSTALL_PATH;
|
|
|
|
return bundlePath + moduleName + MERGE_ABC_ETS_MODULES;
|
|
|
|
}
|
|
|
|
|
2024-05-11 10:36:09 +00:00
|
|
|
CString ModulePathHelper::TransformToNormalizedOhmUrl(EcmaVM *vm, const CString &inputFileName,
|
|
|
|
const CString &baseFileName, const CString &oldEntryPoint)
|
2024-04-06 06:44:00 +00:00
|
|
|
{
|
|
|
|
CString prefix(1, PathHelper::NORMALIZED_OHMURL_TAG);
|
|
|
|
if (oldEntryPoint == ENTRY_MAIN_FUNCTION || StringHelper::StringStartWith(oldEntryPoint, prefix)) {
|
|
|
|
return oldEntryPoint;
|
|
|
|
}
|
|
|
|
size_t pos = oldEntryPoint.find(PathHelper::SLASH_TAG);
|
|
|
|
size_t pathPos = oldEntryPoint.find(PathHelper::SLASH_TAG, pos + 1);
|
|
|
|
LOG_ECMA(INFO) << "TransformToNormalizedOhmUrl oldEntryPoint: " << oldEntryPoint;
|
|
|
|
if (pos == CString::npos && pathPos == CString::npos) {
|
|
|
|
LOG_FULL(ERROR) << "TransformToNormalizedOhmUrl Invalid Ohmurl, please check.";
|
|
|
|
return oldEntryPoint;
|
|
|
|
}
|
|
|
|
CString path = oldEntryPoint.substr(pathPos);
|
|
|
|
CString moduleName = oldEntryPoint.substr(pos + 1, pathPos - pos - 1);
|
|
|
|
if (moduleName.find(PathHelper::NAME_SPACE_TAG) != CString::npos) {
|
|
|
|
moduleName = PathHelper::GetHarName(moduleName);
|
|
|
|
}
|
|
|
|
CString pkgname = vm->GetPkgName(moduleName);
|
|
|
|
if (pkgname.size() == 0) {
|
|
|
|
return oldEntryPoint;
|
|
|
|
}
|
2024-05-04 10:28:21 +00:00
|
|
|
CString currentModuleName = GetModuleNameWithBaseFile(baseFileName);
|
|
|
|
if (currentModuleName.size() == 0) {
|
|
|
|
currentModuleName = moduleName;
|
|
|
|
}
|
|
|
|
CVector<CString> data = GetPkgContextInfoListElements(vm, currentModuleName, pkgname);
|
|
|
|
CString version;
|
|
|
|
CString entryPath;
|
|
|
|
if (data.size() > 0) {
|
|
|
|
version = data[PKGINFO_VERSION_INDEX];
|
|
|
|
entryPath = data[PKGINFO_ENTRY_PATH_INDEX];
|
|
|
|
}
|
2024-05-11 10:36:09 +00:00
|
|
|
// If the inputFileName contains '.test', it is a preview test, no need to splice the entry path.
|
|
|
|
if (inputFileName.find(PREVIER_TEST_DIR) != CString::npos) {
|
|
|
|
return ConcatPreviewTestUnifiedOhmUrl("", pkgname, path, version);
|
|
|
|
}
|
2024-05-04 10:28:21 +00:00
|
|
|
// When the entry path ends with a slash (/), use the entry path to concatenate ohmurl.
|
|
|
|
CString endStr(1, PathHelper::SLASH_TAG);
|
|
|
|
if (entryPath.size() != 0 && StringHelper::StringEndWith(entryPath, endStr)) {
|
|
|
|
size_t endPos = entryPath.rfind(PathHelper::SLASH_TAG);
|
|
|
|
entryPath = entryPath.substr(0, endPos);
|
|
|
|
return ConcatUnifiedOhmUrl("", pkgname, entryPath, path, version);
|
|
|
|
}
|
|
|
|
// bundleName and entryPath is empty.
|
|
|
|
return ConcatUnifiedOhmUrl("", pkgname, "", path, version);
|
2023-07-12 12:34:30 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
2024-01-26 02:09:26 +00:00
|
|
|
* Before: recordName: bundleName/moduleName@namespace/xxx/xxx.abc
|
2023-07-12 12:34:30 +00:00
|
|
|
* After: Intra-application cross hap: /data/storage/el1/bundle/bundleName/ets/modules.abc
|
|
|
|
* Cross-application: /data/storage/el1/bundle/bundleName/moduleName/moduleName/ets/modules.abc
|
|
|
|
*/
|
|
|
|
CString ModulePathHelper::ParseUrl(EcmaVM *vm, const CString &recordName)
|
|
|
|
{
|
|
|
|
CVector<CString> vec;
|
|
|
|
StringHelper::SplitString(recordName, vec, 0, SEGMENTS_LIMIT_TWO);
|
|
|
|
if (vec.size() < SEGMENTS_LIMIT_TWO) {
|
|
|
|
LOG_ECMA(DEBUG) << "ParseUrl SplitString filed, please check Url" << recordName;
|
|
|
|
return CString();
|
|
|
|
}
|
|
|
|
CString bundleName = vec[0];
|
|
|
|
CString moduleName = vec[1];
|
|
|
|
PathHelper::DeleteNamespace(moduleName);
|
|
|
|
|
|
|
|
CString baseFileName;
|
|
|
|
if (bundleName != vm->GetBundleName()) {
|
|
|
|
// Cross-application
|
|
|
|
baseFileName = BUNDLE_INSTALL_PATH + bundleName + PathHelper::SLASH_TAG + moduleName +
|
|
|
|
PathHelper::SLASH_TAG + moduleName + MERGE_ABC_ETS_MODULES;
|
|
|
|
} else {
|
|
|
|
// Intra-application cross hap
|
|
|
|
baseFileName = BUNDLE_INSTALL_PATH + moduleName + MERGE_ABC_ETS_MODULES;
|
|
|
|
}
|
|
|
|
return baseFileName;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Before: moduleRequestName: @bundle:bundleName/moduleName@namespace/ets/xxx
|
|
|
|
* After: baseFileName: 1./data/storage/el1/bundle/bundleName/ets/modules.abc
|
|
|
|
* 2./data/storage/el1/bundle/bundleName/moduleName/moduleName/ets/modules.abc
|
|
|
|
* entryPoint: bundleName/moduleName@namespace/ets/xxx
|
|
|
|
*/
|
|
|
|
CString ModulePathHelper::ParsePrefixBundle(JSThread *thread, const JSPandaFile *jsPandaFile,
|
|
|
|
[[maybe_unused]] CString &baseFileName, CString moduleRequestName, [[maybe_unused]] CString recordName)
|
|
|
|
{
|
|
|
|
EcmaVM *vm = thread->GetEcmaVM();
|
|
|
|
moduleRequestName = moduleRequestName.substr(PREFIX_BUNDLE_LEN);
|
|
|
|
CString entryPoint = moduleRequestName;
|
|
|
|
if (jsPandaFile->IsRecordWithBundleName()) {
|
|
|
|
CVector<CString> vec;
|
|
|
|
StringHelper::SplitString(moduleRequestName, vec, 0, SEGMENTS_LIMIT_TWO);
|
|
|
|
if (vec.size() < SEGMENTS_LIMIT_TWO) {
|
2024-05-17 07:47:26 +00:00
|
|
|
LOG_ECMA(FATAL) << " Exceptional module path : " << moduleRequestName << ", abc path: " <<
|
|
|
|
baseFileName << ", current file name: " << recordName;
|
2023-07-12 12:34:30 +00:00
|
|
|
}
|
|
|
|
CString bundleName = vec[0];
|
|
|
|
CString moduleName = vec[1];
|
|
|
|
PathHelper::DeleteNamespace(moduleName);
|
|
|
|
|
|
|
|
#if !defined(PANDA_TARGET_WINDOWS) && !defined(PANDA_TARGET_MACOS)
|
|
|
|
if (bundleName != vm->GetBundleName()) {
|
|
|
|
baseFileName = BUNDLE_INSTALL_PATH + bundleName + PathHelper::SLASH_TAG + moduleName +
|
|
|
|
PathHelper::SLASH_TAG + moduleName + MERGE_ABC_ETS_MODULES;
|
|
|
|
} else if (moduleName != vm->GetModuleName()) {
|
|
|
|
baseFileName = BUNDLE_INSTALL_PATH + moduleName + MERGE_ABC_ETS_MODULES;
|
|
|
|
} else {
|
|
|
|
// Support multi-module card service
|
|
|
|
baseFileName = vm->GetAssetPath();
|
|
|
|
}
|
|
|
|
#else
|
|
|
|
CVector<CString> currentVec;
|
2023-09-16 08:06:31 +00:00
|
|
|
StringHelper::SplitString(moduleRequestName, currentVec, 0, SEGMENTS_LIMIT_TWO);
|
2023-07-12 12:34:30 +00:00
|
|
|
if (currentVec.size() < SEGMENTS_LIMIT_TWO) {
|
2024-05-17 07:47:26 +00:00
|
|
|
LOG_ECMA(FATAL) << " Exceptional module path : " << moduleRequestName << ", abc path: " <<
|
|
|
|
baseFileName << ", current file name: " << recordName;
|
2023-07-12 12:34:30 +00:00
|
|
|
}
|
|
|
|
CString currentModuleName = currentVec[1];
|
|
|
|
PathHelper::DeleteNamespace(currentModuleName);
|
2023-09-16 08:06:31 +00:00
|
|
|
if (bundleName != vm->GetBundleName()) {
|
2023-11-03 02:49:30 +00:00
|
|
|
baseFileName = BUNDLE_INSTALL_PATH + bundleName + PathHelper::SLASH_TAG + moduleName +
|
|
|
|
PathHelper::SLASH_TAG + moduleName + MERGE_ABC_ETS_MODULES;
|
2023-09-16 08:06:31 +00:00
|
|
|
} else if (currentModuleName != vm->GetModuleName()) {
|
|
|
|
baseFileName = BUNDLE_INSTALL_PATH + moduleName + MERGE_ABC_ETS_MODULES;
|
2023-07-12 12:34:30 +00:00
|
|
|
}
|
|
|
|
#endif
|
|
|
|
} else {
|
|
|
|
PathHelper::AdaptOldIsaRecord(entryPoint);
|
|
|
|
}
|
|
|
|
return entryPoint;
|
|
|
|
}
|
|
|
|
|
2024-04-06 06:44:00 +00:00
|
|
|
|
|
|
|
CString ModulePathHelper::ParseNormalizedOhmUrl(JSThread *thread, CString &baseFileName, CString requestName)
|
|
|
|
{
|
|
|
|
ASSERT(StringHelper::StringStartWith(requestName, PREFIX_NORMALIZED_NOT_SO));
|
|
|
|
CVector<CString> res = SplitNormalizedOhmurl(requestName);
|
|
|
|
if (res.size() != NORMALIZED_OHMURL_ARGS_NUM) {
|
|
|
|
LOG_FULL(FATAL) << "Invalid normalized ohmurl";
|
|
|
|
}
|
|
|
|
CString moduleName = res[NORMALIZED_MODULE_NAME_INDEX];
|
|
|
|
CString bundleName = res[NORMALIZED_BUNDLE_NAME_INDEX];
|
|
|
|
if (!bundleName.empty() && !moduleName.empty()) {
|
|
|
|
baseFileName = ConcatHspFileNameCrossBundle(bundleName, moduleName);
|
|
|
|
} else if (!moduleName.empty()) {
|
|
|
|
baseFileName = ConcatHspFileName(moduleName);
|
|
|
|
} else if (baseFileName.empty()) {
|
|
|
|
// Support multi-module card service
|
|
|
|
baseFileName = thread->GetEcmaVM()->GetAssetPath();
|
|
|
|
// test card service
|
|
|
|
}
|
|
|
|
CString importPath = res[NORMALIZED_IMPORT_PATH_INDEX];
|
|
|
|
CString version = res[NORMALIZED_VERSION_INDEX];
|
|
|
|
return ConcatUnifiedOhmUrl(bundleName, importPath, version);
|
|
|
|
}
|
|
|
|
|
2023-07-12 12:34:30 +00:00
|
|
|
/*
|
|
|
|
* Before: requestName: ../xxx1/xxx2 || ./b
|
|
|
|
* recordName: pkg_modules/.ohpm/pkgName/pkg_modules/pkgName/xxx1/xxx3 || a
|
|
|
|
* After: entryPoint: pkg_modules/.ohpm/pkgName/pkg_modules/pkgName/xxx1/xxx2 || b
|
|
|
|
* baseFileName: /data/storage/el1/bundle/moduleName/ets/modules.abc || /home/user/src/a
|
|
|
|
*/
|
2024-05-11 08:16:43 +00:00
|
|
|
CString ModulePathHelper::MakeNewRecord(JSThread *thread, const JSPandaFile *jsPandaFile, CString &baseFileName,
|
2023-07-12 12:34:30 +00:00
|
|
|
const CString &recordName, const CString &requestName)
|
|
|
|
{
|
|
|
|
CString entryPoint;
|
|
|
|
CString moduleRequestName = RemoveSuffix(requestName);
|
|
|
|
size_t pos = moduleRequestName.find(PathHelper::CURRENT_DIREATORY_TAG);
|
|
|
|
if (pos == 0) {
|
|
|
|
moduleRequestName = moduleRequestName.substr(2); // 2 means jump "./"
|
|
|
|
}
|
|
|
|
pos = recordName.rfind(PathHelper::SLASH_TAG);
|
|
|
|
if (pos != CString::npos) {
|
|
|
|
// entryPoint: pkg_modules/.ohpm/pkgName/pkg_modules/pkgName/xxx1/../xxx1/xxx2
|
|
|
|
entryPoint = recordName.substr(0, pos + 1) + moduleRequestName;
|
|
|
|
} else {
|
|
|
|
entryPoint = moduleRequestName;
|
|
|
|
}
|
|
|
|
// entryPoint: pkg_modules/.ohpm/pkgName/pkg_modules/pkgName/xxx1/xxx2
|
|
|
|
entryPoint = PathHelper::NormalizePath(entryPoint);
|
|
|
|
entryPoint = ConfirmLoadingIndexOrNot(jsPandaFile, entryPoint);
|
|
|
|
if (!entryPoint.empty()) {
|
|
|
|
return entryPoint;
|
|
|
|
}
|
|
|
|
// the package name may have a '.js' suffix, try to parseThirdPartyPackage
|
|
|
|
entryPoint = ParseThirdPartyPackage(jsPandaFile, recordName, requestName);
|
|
|
|
if (!entryPoint.empty()) {
|
|
|
|
return entryPoint;
|
|
|
|
}
|
2024-05-11 08:16:43 +00:00
|
|
|
// An exception is thrown when the module cannot be found in bundlePack mode.
|
|
|
|
if (StringHelper::StringStartWith(baseFileName, BUNDLE_INSTALL_PATH) && !jsPandaFile->IsBundlePack() &&
|
|
|
|
!jsPandaFile->HasRecord(entryPoint)) {
|
|
|
|
THROW_MODULE_NOT_FOUND_ERROR_WITH_RETURN_VALUE(thread, requestName, recordName, entryPoint);
|
|
|
|
}
|
2023-07-12 12:34:30 +00:00
|
|
|
// Execute abc locally
|
|
|
|
pos = baseFileName.rfind(PathHelper::SLASH_TAG);
|
|
|
|
if (pos != CString::npos) {
|
|
|
|
baseFileName = baseFileName.substr(0, pos + 1) + moduleRequestName + EXT_NAME_ABC;
|
|
|
|
} else {
|
|
|
|
baseFileName = moduleRequestName + EXT_NAME_ABC;
|
|
|
|
}
|
|
|
|
pos = moduleRequestName.rfind(PathHelper::SLASH_TAG);
|
|
|
|
if (pos != CString::npos) {
|
|
|
|
entryPoint = moduleRequestName.substr(pos + 1);
|
|
|
|
} else {
|
|
|
|
entryPoint = moduleRequestName;
|
|
|
|
}
|
|
|
|
return entryPoint;
|
|
|
|
}
|
|
|
|
|
|
|
|
CString ModulePathHelper::FindOhpmEntryPoint(const JSPandaFile *jsPandaFile,
|
|
|
|
const CString& ohpmPath, const CString& requestName)
|
|
|
|
{
|
|
|
|
CVector<CString> vec;
|
|
|
|
StringHelper::SplitString(requestName, vec, 0);
|
2024-05-04 10:22:49 +00:00
|
|
|
ASSERT(vec.size() > 0);
|
2023-07-12 12:34:30 +00:00
|
|
|
size_t maxIndex = vec.size() - 1;
|
|
|
|
CString ohpmKey;
|
|
|
|
size_t index = 0;
|
|
|
|
// first we find the ohpmKey by splicing the requestName
|
|
|
|
while (index <= maxIndex) {
|
|
|
|
CString maybeKey = ohpmPath + PathHelper::SLASH_TAG + StringHelper::JoinString(vec, 0, index);
|
2023-12-27 07:43:42 +00:00
|
|
|
if (jsPandaFile->FindOhmUrlInPF(maybeKey, ohpmKey)) {
|
2023-07-12 12:34:30 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
++index;
|
|
|
|
}
|
|
|
|
if (ohpmKey.empty()) {
|
|
|
|
return CString();
|
|
|
|
}
|
|
|
|
// second If the ohpmKey is not empty, we will use it to obtain the real entrypoint
|
|
|
|
CString entryPoint;
|
|
|
|
if (index == maxIndex) {
|
|
|
|
// requestName is a packageName
|
|
|
|
entryPoint = jsPandaFile->GetEntryPoint(ohpmKey);
|
|
|
|
} else {
|
|
|
|
// import a specific file or directory
|
|
|
|
ohpmKey = ohpmKey + PathHelper::SLASH_TAG + StringHelper::JoinString(vec, index + 1, maxIndex);
|
|
|
|
entryPoint = ConfirmLoadingIndexOrNot(jsPandaFile, ohpmKey);
|
|
|
|
}
|
|
|
|
return entryPoint;
|
|
|
|
}
|
|
|
|
|
|
|
|
CString ModulePathHelper::FindPackageInTopLevelWithNamespace(const JSPandaFile *jsPandaFile,
|
|
|
|
const CString& requestName, const CString &recordName)
|
|
|
|
{
|
|
|
|
// find in current module <PACKAGE_PATH_SEGMENT>@[moduleName|namespace]/<requestName>
|
|
|
|
CString entryPoint;
|
|
|
|
CString ohpmPath;
|
|
|
|
if (StringHelper::StringStartWith(recordName, PACKAGE_PATH_SEGMENT)) {
|
|
|
|
size_t pos = recordName.find(PathHelper::SLASH_TAG);
|
|
|
|
if (pos == CString::npos) {
|
|
|
|
LOG_ECMA(DEBUG) << "wrong recordname : " << recordName;
|
|
|
|
return CString();
|
|
|
|
}
|
|
|
|
ohpmPath = recordName.substr(0, pos);
|
|
|
|
entryPoint = FindOhpmEntryPoint(jsPandaFile, recordName.substr(0, pos), requestName);
|
|
|
|
} else {
|
2024-02-05 13:13:10 +00:00
|
|
|
// recordName: moduleName/xxx/xxx
|
2023-07-12 12:34:30 +00:00
|
|
|
CVector<CString> vec;
|
|
|
|
StringHelper::SplitString(recordName, vec, 0, SEGMENTS_LIMIT_TWO);
|
|
|
|
if (vec.size() < SEGMENTS_LIMIT_TWO) {
|
|
|
|
LOG_ECMA(DEBUG) << "SplitString filed, please check moduleRequestName";
|
|
|
|
return CString();
|
|
|
|
}
|
|
|
|
CString moduleName = vec[1];
|
|
|
|
// If namespace exists, use namespace as moduleName
|
|
|
|
size_t pos = moduleName.find(PathHelper::NAME_SPACE_TAG);
|
|
|
|
if (pos != CString::npos) {
|
|
|
|
moduleName = moduleName.substr(pos + 1);
|
|
|
|
}
|
|
|
|
ohpmPath = CString(PACKAGE_PATH_SEGMENT) + PathHelper::NAME_SPACE_TAG + moduleName;
|
|
|
|
entryPoint = FindOhpmEntryPoint(jsPandaFile, ohpmPath, requestName);
|
2024-01-30 06:37:56 +00:00
|
|
|
// If haven't find with namespace, then use moduleName
|
|
|
|
if ((pos != CString::npos) && entryPoint.empty()) {
|
|
|
|
moduleName = vec[1].substr(0, pos);
|
|
|
|
ohpmPath = CString(PACKAGE_PATH_SEGMENT) + PathHelper::NAME_SPACE_TAG + moduleName;
|
|
|
|
entryPoint = FindOhpmEntryPoint(jsPandaFile, ohpmPath, requestName);
|
|
|
|
}
|
2023-07-12 12:34:30 +00:00
|
|
|
}
|
|
|
|
if (!entryPoint.empty()) {
|
|
|
|
return entryPoint;
|
|
|
|
}
|
|
|
|
// find in project directory <packagePath>/<requestName>
|
|
|
|
return FindOhpmEntryPoint(jsPandaFile, PACKAGE_PATH_SEGMENT, requestName);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Before: requestName: requestPkgName
|
|
|
|
* recordName: pkg_modules/.ohpm/pkgName/pkg_modules/pkgName/xxx
|
|
|
|
* After: entryPoint: pkg_modules/.ohpm/requestPkgName/pkg_modules/requestPkgName/xxx
|
|
|
|
*/
|
|
|
|
CString ModulePathHelper::ParseOhpmPackage(const JSPandaFile *jsPandaFile,
|
|
|
|
const CString &recordName, const CString &requestName)
|
|
|
|
{
|
|
|
|
CString entryPoint;
|
|
|
|
if (StringHelper::StringStartWith(recordName, PACKAGE_PATH_SEGMENT)) {
|
|
|
|
// this way is thirdPartyPackage import ThirdPartyPackage
|
|
|
|
auto info = const_cast<JSPandaFile *>(jsPandaFile)->FindRecordInfo(recordName);
|
|
|
|
// packageName: pkg_modules/.ohpm/pkgName/pkg_modules/pkgName
|
|
|
|
CString packageName = info.npmPackageName;
|
|
|
|
size_t pos = packageName.rfind(PACKAGE_PATH_SEGMENT);
|
|
|
|
if (pos != CString::npos) {
|
|
|
|
packageName.erase(pos, packageName.size() - pos);
|
|
|
|
// ohpmPath: pkg_modules/.ohpm/pkgName/pkg_modules
|
|
|
|
CString ohpmPath = packageName + PACKAGE_PATH_SEGMENT;
|
|
|
|
// entryPoint: pkg_modules/.ohpm/requestPkgName/pkg_modules/requestPkgName/xxx
|
|
|
|
entryPoint = FindOhpmEntryPoint(jsPandaFile, ohpmPath, requestName);
|
|
|
|
if (!entryPoint.empty()) {
|
|
|
|
return entryPoint;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// Import packages under the current module or project directory
|
|
|
|
return FindPackageInTopLevelWithNamespace(jsPandaFile, requestName, recordName);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Before: requestName: requestPkgName
|
|
|
|
* recordName: pkg_modules/.ohpm/pkgName/pkg_modules/pkgName/xxx
|
|
|
|
* packagePath: pkg_modules || node_modules
|
|
|
|
* After: entryPoint: pkg_modules/.ohpm/requestPkgName/pkg_modules/requestPkgName/xxx
|
|
|
|
*/
|
|
|
|
CString ModulePathHelper::ParseThirdPartyPackage(const JSPandaFile *jsPandaFile,
|
|
|
|
const CString &recordName, const CString &requestName, const CString &packagePath)
|
|
|
|
{
|
|
|
|
CString entryPoint;
|
|
|
|
if (StringHelper::StringStartWith(recordName, packagePath)) {
|
|
|
|
auto info = const_cast<JSPandaFile *>(jsPandaFile)->FindRecordInfo(recordName);
|
|
|
|
CString packageName = info.npmPackageName; // pkg_modules/.ohpm/pkgName/pkg_modules/pkgName
|
|
|
|
size_t pos = 0;
|
|
|
|
while (true) {
|
|
|
|
CString key = packageName + PathHelper::SLASH_TAG + packagePath + PathHelper::SLASH_TAG + requestName;
|
|
|
|
entryPoint = FindNpmEntryPoint(jsPandaFile, key);
|
|
|
|
if (!entryPoint.empty()) {
|
|
|
|
return entryPoint;
|
|
|
|
}
|
2024-05-04 10:22:49 +00:00
|
|
|
size_t index = packageName.rfind(packagePath);
|
|
|
|
ASSERT(index > 0);
|
|
|
|
pos = index - 1;
|
2023-07-12 12:34:30 +00:00
|
|
|
if (pos == CString::npos || pos < 0) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
packageName.erase(pos, packageName.size() - pos);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return FindPackageInTopLevel(jsPandaFile, requestName, packagePath);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Before: requestName: requestPkgName
|
|
|
|
* recordName: pkg_modules/.ohpm/pkgName/pkg_modules/pkgName/xxx
|
|
|
|
* After: entryPoint: pkg_modules/.ohpm/requestPkgName/pkg_modules/requestPkgName/xxx
|
|
|
|
*/
|
|
|
|
CString ModulePathHelper::ParseThirdPartyPackage(const JSPandaFile *jsPandaFile,
|
|
|
|
const CString &recordName, const CString &requestName)
|
|
|
|
{
|
|
|
|
// We need to deal with scenarios like this 'json5/' -> 'json5'
|
|
|
|
CString normalizeRequestName = PathHelper::NormalizePath(requestName);
|
|
|
|
CString entryPoint = ParseOhpmPackage(jsPandaFile, recordName, normalizeRequestName);
|
|
|
|
if (!entryPoint.empty()) {
|
|
|
|
return entryPoint;
|
|
|
|
}
|
|
|
|
|
|
|
|
static CVector<CString> packagePaths = {CString(PACKAGE_PATH_SEGMENT), CString(NPM_PATH_SEGMENT)};
|
|
|
|
// Package compatible with old soft link format
|
|
|
|
for (size_t i = 0; i < packagePaths.size(); ++i) {
|
|
|
|
entryPoint = ParseThirdPartyPackage(jsPandaFile, recordName, normalizeRequestName, packagePaths[i]);
|
|
|
|
if (!entryPoint.empty()) {
|
|
|
|
return entryPoint;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return CString();
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Before: dirPath: Undefined
|
|
|
|
* fileName: Undefined
|
|
|
|
* After: dirPath: pkg_modules/.ohpm/pkgName/pkg_modules/pkgName/xxx/
|
|
|
|
* fileName: pkg_modules/.ohpm/pkgName/pkg_modules/pkgName/xxx/xxx.abc
|
|
|
|
*/
|
|
|
|
void ModulePathHelper::ResolveCurrentPath(JSThread *thread, JSMutableHandle<JSTaggedValue> &dirPath,
|
|
|
|
JSMutableHandle<JSTaggedValue> &fileName, const JSPandaFile *jsPandaFile)
|
|
|
|
{
|
|
|
|
ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
|
|
|
|
CString fullName = jsPandaFile->GetJSPandaFileDesc();
|
|
|
|
JSHandle<EcmaString> dirPathName = PathHelper::ResolveDirPath(thread, fullName);
|
|
|
|
dirPath.Update(dirPathName.GetTaggedValue());
|
|
|
|
|
|
|
|
// Get filename from JSPandaFile
|
|
|
|
JSHandle<EcmaString> cbFileName = factory->NewFromUtf8(fullName);
|
|
|
|
fileName.Update(cbFileName.GetTaggedValue());
|
|
|
|
}
|
|
|
|
|
|
|
|
CString ModulePathHelper::FindNpmEntryPoint(const JSPandaFile *jsPandaFile, const CString &packageEntryPoint)
|
|
|
|
{
|
|
|
|
// if we are currently importing a specific file or directory, we will get the entryPoint here
|
|
|
|
CString entryPoint = ConfirmLoadingIndexOrNot(jsPandaFile, packageEntryPoint);
|
|
|
|
if (!entryPoint.empty()) {
|
|
|
|
return entryPoint;
|
|
|
|
}
|
|
|
|
// When you come here, must import a packageName
|
|
|
|
return jsPandaFile->GetEntryPoint(packageEntryPoint);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Before: requestName: requestPkgName
|
|
|
|
* packagePath: pkg_modules || node_modules
|
|
|
|
* After: entryPoint: pkg_modules/.ohpm/requestPkgName/pkg_modules/requestPkgName/xxx
|
|
|
|
*/
|
|
|
|
CString ModulePathHelper::FindPackageInTopLevel(const JSPandaFile *jsPandaFile,
|
|
|
|
const CString& requestName, const CString &packagePath)
|
|
|
|
{
|
|
|
|
// we find packagePath/0/xxx or packagePath/1/xxx
|
|
|
|
CString entryPoint;
|
|
|
|
for (size_t level = 0; level <= MAX_PACKAGE_LEVEL; ++level) {
|
|
|
|
CString levelStr = std::to_string(level).c_str();
|
|
|
|
CString key = packagePath + PathHelper::SLASH_TAG + levelStr + PathHelper::SLASH_TAG + requestName;
|
|
|
|
entryPoint = FindNpmEntryPoint(jsPandaFile, key);
|
|
|
|
if (!entryPoint.empty()) {
|
|
|
|
return entryPoint;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return CString();
|
|
|
|
}
|
|
|
|
|
|
|
|
bool ModulePathHelper::IsImportFile(const CString &moduleRequestName)
|
|
|
|
{
|
|
|
|
if (moduleRequestName[0] == PathHelper::POINT_TAG) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
size_t pos = moduleRequestName.rfind(PathHelper::POINT_TAG);
|
|
|
|
if (pos != CString::npos) {
|
|
|
|
CString suffix = moduleRequestName.substr(pos);
|
|
|
|
if (suffix == EXT_NAME_JS || suffix == EXT_NAME_TS || suffix == EXT_NAME_ETS || suffix == EXT_NAME_JSON) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Before: xxx/xxx.js || xxx/xxx.ts || xxx/xxx.ets ||xxx/xxx.json
|
|
|
|
* After: xxx/xxx
|
|
|
|
*/
|
|
|
|
CString ModulePathHelper::RemoveSuffix(const CString &requestName)
|
|
|
|
{
|
|
|
|
CString res = requestName;
|
|
|
|
size_t pos = res.rfind(PathHelper::POINT_TAG);
|
|
|
|
if (pos != CString::npos) {
|
|
|
|
CString suffix = res.substr(pos);
|
2024-04-25 13:38:17 +00:00
|
|
|
if (IsShouldRemoveSuffix(suffix)) {
|
2023-07-12 12:34:30 +00:00
|
|
|
res.erase(pos, suffix.length());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return res;
|
|
|
|
}
|
2023-12-27 07:43:42 +00:00
|
|
|
|
|
|
|
bool ModulePathHelper::NeedTranstale(const CString &requestName)
|
|
|
|
{
|
|
|
|
if (StringHelper::StringStartWith(requestName, PREFIX_BUNDLE) ||
|
|
|
|
StringHelper::StringStartWith(requestName, PREFIX_PACKAGE) ||
|
|
|
|
requestName[0] == PathHelper::POINT_TAG || // ./
|
|
|
|
(requestName[0] == PathHelper::NAME_SPACE_TAG && // @***:
|
|
|
|
requestName.find(PathHelper::COLON_TAG) != CString::npos)) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Adapt dynamic import using expression input, translate include NativeModule/ohpm/hsp/har.
|
2024-02-05 13:13:10 +00:00
|
|
|
void ModulePathHelper::TranstaleExpressionInput(const JSPandaFile *jsPandaFile, CString &requestPath)
|
2023-12-27 07:43:42 +00:00
|
|
|
{
|
|
|
|
LOG_ECMA(DEBUG) << "Enter Translate OhmUrl for DynamicImport, requestPath: " << requestPath;
|
|
|
|
if (StringHelper::StringStartWith(requestPath, RAW_ARKUIX_PREFIX)) {
|
|
|
|
requestPath = StringHelper::Replace(requestPath, RAW_ARKUIX_PREFIX, REQUIRE_NAPI_OHOS_PREFIX);
|
2024-02-05 13:13:10 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
CString outEntryPoint;
|
|
|
|
// FindOhmUrlInPF: frontend generate mapping in abc,
|
|
|
|
// all we need to do is to find the corresponding mapping result.
|
|
|
|
// EXCEPTION: @ohos. @hms. is translated all by runtime.
|
|
|
|
if (jsPandaFile->FindOhmUrlInPF(requestPath, outEntryPoint)) {
|
|
|
|
requestPath = outEntryPoint;
|
2023-12-27 07:43:42 +00:00
|
|
|
} else {
|
2024-02-05 13:13:10 +00:00
|
|
|
ParseCrossModuleFile(jsPandaFile, requestPath);
|
2023-12-27 07:43:42 +00:00
|
|
|
}
|
2024-02-05 13:13:10 +00:00
|
|
|
// change origin: @ohos. @hms. -> @ohos: @hms:
|
|
|
|
// change mapping result: @package. @bundle. @xxx. -> @package: @bundle: @xxx:
|
|
|
|
ChangeTag(requestPath);
|
2023-12-27 07:43:42 +00:00
|
|
|
}
|
2024-01-23 07:01:46 +00:00
|
|
|
|
2024-02-05 13:13:10 +00:00
|
|
|
/*
|
2024-04-25 13:38:17 +00:00
|
|
|
* Before: 1. /data/storage/el1/bundle/moduleName/ets/xxx/xxx.abc
|
|
|
|
* 2. /data/storage/el1/bundle/bundleName/moduleName/moduleName/ets/modules.abc
|
2024-02-05 13:13:10 +00:00
|
|
|
* After: moduleName
|
|
|
|
*/
|
2024-01-23 07:01:46 +00:00
|
|
|
CString ModulePathHelper::GetModuleNameWithBaseFile(const CString &baseFileName)
|
|
|
|
{
|
|
|
|
size_t pos = CString::npos;
|
|
|
|
if (baseFileName.length() > BUNDLE_INSTALL_PATH_LEN &&
|
|
|
|
baseFileName.compare(0, BUNDLE_INSTALL_PATH_LEN, BUNDLE_INSTALL_PATH) == 0) {
|
|
|
|
pos = BUNDLE_INSTALL_PATH_LEN;
|
|
|
|
}
|
|
|
|
CString moduleName;
|
|
|
|
if (pos != CString::npos) {
|
|
|
|
// baseFileName: /data/storage/el1/bundle/moduleName/ets/xxx/xxx.abc
|
|
|
|
pos = baseFileName.find(PathHelper::SLASH_TAG, BUNDLE_INSTALL_PATH_LEN);
|
|
|
|
if (pos == CString::npos) {
|
|
|
|
LOG_FULL(FATAL) << "Invalid Ohm url, please check.";
|
|
|
|
}
|
|
|
|
moduleName = baseFileName.substr(BUNDLE_INSTALL_PATH_LEN, pos - BUNDLE_INSTALL_PATH_LEN);
|
2024-04-25 13:38:17 +00:00
|
|
|
// baseFileName /data/storage/el1/bundle/bundleName/moduleName/moduleName/ets/modules.abc
|
|
|
|
if (moduleName.find(PathHelper::POINT_STRING_TAG) != CString::npos) {
|
|
|
|
// length of /data/storage/el1/bundle/bundleName/
|
|
|
|
size_t pathLength = BUNDLE_INSTALL_PATH_LEN + moduleName.size() + 1;
|
|
|
|
pos = baseFileName.find(PathHelper::SLASH_TAG, pathLength);
|
|
|
|
moduleName = baseFileName.substr(pathLength, pos - pathLength);
|
|
|
|
}
|
2024-01-23 07:01:46 +00:00
|
|
|
}
|
|
|
|
return moduleName;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Before: ets/xxx/xxx
|
|
|
|
* After: bundleName/moduleName/ets/xxx/xxx
|
|
|
|
*/
|
|
|
|
CString ModulePathHelper::TranslateExpressionInputWithEts(JSThread *thread, const JSPandaFile *jsPandaFile,
|
|
|
|
CString &baseFileName, const CString &requestName)
|
|
|
|
{
|
|
|
|
CString entryPoint;
|
|
|
|
EcmaVM *vm = thread->GetEcmaVM();
|
|
|
|
CString moduleName = GetModuleNameWithBaseFile(baseFileName);
|
|
|
|
entryPoint = vm->GetBundleName() + PathHelper::SLASH_TAG + moduleName + PathHelper::SLASH_TAG + requestName;
|
|
|
|
if (!jsPandaFile->HasRecord(entryPoint)) {
|
2024-03-10 12:20:18 +00:00
|
|
|
return CString();
|
2024-01-23 07:01:46 +00:00
|
|
|
}
|
|
|
|
return entryPoint;
|
|
|
|
}
|
2024-02-05 13:13:10 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* input requestPath: moduleName/src/main/xxx/xxx/xxx
|
|
|
|
* moduleName/xxx/xxx
|
|
|
|
* output requestPath: @bundle.bundleName/moduleName/xxx/xxx/xxx
|
|
|
|
* @bundle.bundleName/moduleName/xxx/xxx
|
|
|
|
*/
|
|
|
|
void ModulePathHelper::ParseCrossModuleFile(const JSPandaFile *jsPandaFile, CString &requestPath)
|
|
|
|
{
|
|
|
|
size_t pos = requestPath.find(PathHelper::SLASH_TAG);
|
|
|
|
CString moduleName = requestPath.substr(0, pos);
|
|
|
|
CString outEntryPoint;
|
|
|
|
if (jsPandaFile->FindOhmUrlInPF(moduleName, outEntryPoint)) {
|
|
|
|
// outEntryPoint: @bundle.bundleName/moduleName/Index
|
|
|
|
CString relativePath = requestPath.substr(pos);
|
|
|
|
size_t index = outEntryPoint.rfind(PathHelper::SLASH_TAG);
|
|
|
|
if (relativePath.find(PHYCICAL_FILE_PATH, 0) == 0) {
|
|
|
|
requestPath = outEntryPoint.substr(0, index) + PathHelper::SLASH_TAG +
|
|
|
|
requestPath.substr(pos + PHYCICAL_FILE_PATH_LEN);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
requestPath = outEntryPoint.substr(0, index) + requestPath.substr(pos);
|
|
|
|
}
|
|
|
|
}
|
2024-02-26 07:00:42 +00:00
|
|
|
|
|
|
|
CString ModulePathHelper::ParseFileNameToVMAName(const CString &filename)
|
|
|
|
{
|
|
|
|
CString tag = VMA_NAME_ARKTS_CODE;
|
|
|
|
size_t pos = CString::npos;
|
|
|
|
if (filename.empty()) {
|
|
|
|
return tag;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (filename.find(EXT_NAME_JS) != CString::npos) {
|
|
|
|
pos = filename.find(EXT_NAME_Z_SO);
|
|
|
|
if (pos == CString::npos) {
|
|
|
|
return tag;
|
|
|
|
}
|
|
|
|
CString moduleName = filename.substr(0, pos);
|
|
|
|
pos = moduleName.rfind(PathHelper::POINT_TAG);
|
|
|
|
if (pos == CString::npos) {
|
|
|
|
return tag + PathHelper::COLON_TAG + filename;
|
|
|
|
}
|
|
|
|
CString realModuleName = moduleName.substr(pos + 1);
|
|
|
|
CString realFileName = realModuleName;
|
|
|
|
std::transform(realFileName.begin(), realFileName.end(), realFileName.begin(), ::tolower);
|
|
|
|
CString file = PREFIX_LIB + realFileName + EXT_NAME_Z_SO + PathHelper::SLASH_TAG + realModuleName + EXT_NAME_JS;
|
|
|
|
return tag + PathHelper::COLON_TAG + file;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (filename.find(EXT_NAME_ABC) != CString::npos) {
|
2024-03-19 01:39:47 +00:00
|
|
|
pos = filename.find(BUNDLE_INSTALL_PATH);
|
|
|
|
if (pos == CString::npos) {
|
|
|
|
return tag + PathHelper::COLON_TAG + filename;
|
|
|
|
}
|
2024-02-26 07:00:42 +00:00
|
|
|
CString file = filename.substr(BUNDLE_INSTALL_PATH_LEN);
|
|
|
|
return tag + PathHelper::COLON_TAG + file;
|
|
|
|
}
|
|
|
|
|
|
|
|
return tag;
|
|
|
|
}
|
2024-04-06 06:44:00 +00:00
|
|
|
|
2024-05-04 10:28:21 +00:00
|
|
|
CVector<CString> ModulePathHelper::GetPkgContextInfoListElements(EcmaVM *vm, CString &moduleName,
|
2024-04-06 06:44:00 +00:00
|
|
|
CString &packageName)
|
|
|
|
{
|
|
|
|
CVector<CString> resultList;
|
|
|
|
if (packageName.size() == 0) {
|
|
|
|
return resultList;
|
|
|
|
}
|
|
|
|
CMap<CString, CMap<CString, CVector<CString>>> pkgContextList = vm->GetPkgContextInfoLit();
|
|
|
|
if (pkgContextList.find(moduleName) == pkgContextList.end()) {
|
|
|
|
return resultList;
|
|
|
|
}
|
|
|
|
CMap<CString, CVector<CString>> pkgList = pkgContextList[moduleName];
|
|
|
|
if (pkgList.find(packageName) == pkgList.end()) {
|
|
|
|
return resultList;
|
|
|
|
}
|
|
|
|
resultList = pkgList[packageName];
|
|
|
|
return resultList;
|
|
|
|
}
|
|
|
|
|
2024-04-25 13:38:17 +00:00
|
|
|
CString ModulePathHelper::ConcatImportFileNormalizedOhmurl(const CString &recordPath, const CString &requestName,
|
|
|
|
const CString &version)
|
2024-04-06 06:44:00 +00:00
|
|
|
{
|
|
|
|
CString prefix = PREFIX_NORMALIZED_NOT_SO;
|
|
|
|
return prefix + PathHelper::NORMALIZED_OHMURL_TAG + PathHelper::NORMALIZED_OHMURL_TAG +
|
2024-04-25 13:38:17 +00:00
|
|
|
recordPath + requestName + PathHelper::NORMALIZED_OHMURL_TAG + version;
|
2024-04-06 06:44:00 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
CString ModulePathHelper::ConcatNativeSoNormalizedOhmurl(const CString &moduleName, const CString &bundleName,
|
|
|
|
const CString &pkgName, const CString &version)
|
|
|
|
{
|
|
|
|
CString prefix = PREFIX_NORMALIZED_SO;
|
|
|
|
return prefix + PathHelper::NORMALIZED_OHMURL_TAG + moduleName + PathHelper::NORMALIZED_OHMURL_TAG +
|
|
|
|
bundleName + PathHelper::NORMALIZED_OHMURL_TAG + pkgName + PathHelper::NORMALIZED_OHMURL_TAG + version;
|
|
|
|
}
|
|
|
|
|
|
|
|
CString ModulePathHelper::ConcatNotSoNormalizedOhmurl(const CString &moduleName, const CString &bundleName,
|
|
|
|
const CString &pkgName, const CString &entryPath, const CString &version)
|
|
|
|
{
|
|
|
|
CString prefix = PREFIX_NORMALIZED_NOT_SO;
|
|
|
|
return prefix + PathHelper::NORMALIZED_OHMURL_TAG + moduleName + PathHelper::NORMALIZED_OHMURL_TAG +
|
|
|
|
bundleName + PathHelper::NORMALIZED_OHMURL_TAG + pkgName + PathHelper::SLASH_TAG + entryPath +
|
|
|
|
PathHelper::NORMALIZED_OHMURL_TAG + version;
|
|
|
|
}
|
|
|
|
|
2024-04-12 06:23:09 +00:00
|
|
|
bool ModulePathHelper::NeedTranslateToNormalized(const CString &requestName)
|
2024-04-06 06:44:00 +00:00
|
|
|
{
|
2024-04-12 06:23:09 +00:00
|
|
|
// if start with @normalized:xxx @native:xxx.xxx @ohos:xxx
|
|
|
|
// no translation is required
|
|
|
|
if (StringHelper::StringStartWith(requestName, PREFIX_NORMALIZED) ||
|
|
|
|
(requestName[0] == PathHelper::NAME_SPACE_TAG &&
|
|
|
|
requestName.find(PathHelper::COLON_TAG) != CString::npos)) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
void ModulePathHelper::TranslateExpressionToNormalized(JSThread *thread, const JSPandaFile *jsPandaFile,
|
|
|
|
[[maybe_unused]] CString &baseFileName, CString recordName, CString &requestPath)
|
|
|
|
{
|
|
|
|
if (!NeedTranslateToNormalized(requestPath)) {
|
2024-04-06 06:44:00 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
EcmaVM *vm = thread->GetEcmaVM();
|
|
|
|
if (IsImportFile(requestPath)) {
|
|
|
|
CString moduleRequestName = RemoveSuffix(requestPath);
|
|
|
|
size_t pos = moduleRequestName.find(PathHelper::CURRENT_DIREATORY_TAG);
|
|
|
|
if (pos == 0) {
|
2024-04-12 06:23:09 +00:00
|
|
|
moduleRequestName = moduleRequestName.substr(CURRENT_DIREATORY_TAG_LEN);
|
2024-04-06 06:44:00 +00:00
|
|
|
}
|
|
|
|
pos = recordName.rfind(PathHelper::SLASH_TAG);
|
|
|
|
if (pos != CString::npos) {
|
|
|
|
requestPath = ConcatImportFileNormalizedOhmurl(recordName.substr(0, pos + 1), moduleRequestName);
|
|
|
|
}
|
|
|
|
} else if (StringHelper::StringStartWith(requestPath, PREFIX_ETS)) {
|
|
|
|
size_t pos = recordName.find(PREFIX_ETS);
|
|
|
|
if (pos != CString::npos) {
|
|
|
|
requestPath = ConcatImportFileNormalizedOhmurl(recordName.substr(0, pos), requestPath);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
CString currentModuleName = GetModuleNameWithBaseFile(baseFileName);
|
|
|
|
CString pkgName = vm->GetPkgNameWithAlias(requestPath);
|
2024-05-04 10:28:21 +00:00
|
|
|
CVector<CString> data = GetPkgContextInfoListElements(vm, currentModuleName, pkgName);
|
2024-04-06 06:44:00 +00:00
|
|
|
if (data.size() == 0) {
|
2024-04-12 06:23:09 +00:00
|
|
|
CString outEntryPoint;
|
|
|
|
if (jsPandaFile->FindOhmUrlInPF(requestPath, outEntryPoint)) {
|
|
|
|
requestPath = outEntryPoint;
|
|
|
|
}
|
2024-04-06 06:44:00 +00:00
|
|
|
ChangeTag(requestPath);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
CString bundleName = data[PKGINFO_BUDNLE_NAME_INDEX];
|
|
|
|
CString moduleName = data[PKGINFO_MODULE_NAME_INDEX];
|
|
|
|
CString version = data[PKGINFO_VERSION_INDEX];
|
|
|
|
CString entryPath = data[PKGINFO_ENTRY_PATH_INDEX];
|
|
|
|
CString isSO = data[PKGINFO_IS_SO_INDEX];
|
|
|
|
size_t pos = entryPath.find(PathHelper::CURRENT_DIREATORY_TAG);
|
|
|
|
if (pos == 0) {
|
2024-04-12 06:23:09 +00:00
|
|
|
entryPath = entryPath.substr(CURRENT_DIREATORY_TAG_LEN);
|
2024-04-06 06:44:00 +00:00
|
|
|
}
|
|
|
|
if (isSO == TRUE_FLAG) {
|
|
|
|
requestPath = ConcatNativeSoNormalizedOhmurl(moduleName, bundleName, pkgName, version);
|
|
|
|
} else {
|
|
|
|
entryPath = RemoveSuffix(entryPath);
|
|
|
|
requestPath = ConcatNotSoNormalizedOhmurl(moduleName, bundleName, pkgName, entryPath, version);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
CString ModulePathHelper::TranslateNapiFileRequestPath(JSThread *thread, const CString &modulePath,
|
|
|
|
const CString &requestName)
|
|
|
|
{
|
|
|
|
if (thread->GetEcmaVM()->IsNormalizedOhmUrlPack()) {
|
|
|
|
CString moduleName = GetModuleNameWithPath(modulePath);
|
|
|
|
return PathHelper::NORMALIZED_OHMURL_TAG + moduleName + PHYCICAL_FILE_PATH + PathHelper::SLASH_TAG +
|
|
|
|
requestName + PathHelper::NORMALIZED_OHMURL_TAG;
|
|
|
|
} else {
|
|
|
|
return modulePath + PathHelper::SLASH_TAG + requestName;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
CVector<CString> ModulePathHelper::SplitNormalizedOhmurl(const CString &ohmurl)
|
|
|
|
{
|
|
|
|
CVector<CString> res;
|
|
|
|
size_t start = 0;
|
|
|
|
size_t pos = ohmurl.find(PathHelper::NORMALIZED_OHMURL_TAG);
|
|
|
|
while (pos != CString::npos) {
|
|
|
|
CString element = ohmurl.substr(start, pos - start);
|
|
|
|
res.emplace_back(element);
|
|
|
|
start = pos + 1;
|
|
|
|
pos = ohmurl.find(PathHelper::NORMALIZED_OHMURL_TAG, start);
|
|
|
|
}
|
|
|
|
CString tail = ohmurl.substr(start);
|
|
|
|
res.emplace_back(tail);
|
|
|
|
return res;
|
|
|
|
}
|
2024-04-07 04:06:12 +00:00
|
|
|
|
|
|
|
bool ModulePathHelper::SkipDefaultBundleFile(JSThread *thread, const CString &moduleFileName)
|
|
|
|
{
|
|
|
|
// relative file path like "../../xxxx" can't be loaded rightly in aot compilation phase
|
|
|
|
// just to skip misunderstanding error log in LoadJSPandaFile when we ignore Module Resolving Failure.
|
|
|
|
return !thread->GetEcmaVM()->EnableReportModuleResolvingFailure() &&
|
|
|
|
(IsSandboxPath(moduleFileName) || IsRelativeFilePath(moduleFileName));
|
|
|
|
}
|
2024-04-25 13:38:17 +00:00
|
|
|
|
|
|
|
CVector<CString> ModulePathHelper::SplitNormalizedRecordName(const CString &recordName)
|
|
|
|
{
|
|
|
|
CVector<CString> res(NORMALIZED_OHMURL_ARGS_NUM);
|
|
|
|
int index = NORMALIZED_OHMURL_ARGS_NUM - 1;
|
|
|
|
CString temp;
|
2024-05-13 11:38:42 +00:00
|
|
|
int endIndex = static_cast<int>(recordName.size()) - 1;
|
2024-04-25 13:38:17 +00:00
|
|
|
for (int i = endIndex; i >= 0; i--) {
|
|
|
|
char element = recordName[i];
|
|
|
|
if (element == PathHelper::NORMALIZED_OHMURL_TAG) {
|
|
|
|
res[index] = temp;
|
|
|
|
index--;
|
|
|
|
temp = "";
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
temp = element + temp;
|
|
|
|
}
|
|
|
|
if (temp.size()) {
|
|
|
|
res[index] = temp;
|
|
|
|
}
|
|
|
|
return res;
|
|
|
|
}
|
2023-12-27 07:43:42 +00:00
|
|
|
} // namespace panda::ecmascript
|