From 99e2d38f78d4b8047e309167a8ff6adee5fa7952 Mon Sep 17 00:00:00 2001 From: zenghang Date: Thu, 5 Jun 2025 20:05:14 +0800 Subject: [PATCH] adjust to fileLevel Issue: ICC75O Signed-off-by: zenghang Change-Id: I516e64ad01650da77d707406e8d65bcbabd06978 --- .../dependency_analyzer/dep_analyzer.cpp | 5 + ets2panda/util/arktsconfig.cpp | 9 +- ets2panda/util/arktsconfig.h | 5 + ets2panda/util/importPathManager.cpp | 137 +++++++++++++++--- ets2panda/util/importPathManager.h | 13 +- 5 files changed, 143 insertions(+), 26 deletions(-) diff --git a/ets2panda/driver/dependency_analyzer/dep_analyzer.cpp b/ets2panda/driver/dependency_analyzer/dep_analyzer.cpp index 1ea40a4e2b..54346b1021 100644 --- a/ets2panda/driver/dependency_analyzer/dep_analyzer.cpp +++ b/ets2panda/driver/dependency_analyzer/dep_analyzer.cpp @@ -202,8 +202,13 @@ static void AddFileList(std::string &fileListPath, std::vector &fil std::cerr << "Error when opening a file " << fileListPath << std::endl; return; } + std::string line; while (getline(inFile, line)) { + while (!line.empty() && std::isspace(static_cast(line.back())) != 0) { + line.pop_back(); + } + if (!line.empty()) { fileList.emplace_back(line); } diff --git a/ets2panda/util/arktsconfig.cpp b/ets2panda/util/arktsconfig.cpp index d58d6220f2..f4b1356fae 100644 --- a/ets2panda/util/arktsconfig.cpp +++ b/ets2panda/util/arktsconfig.cpp @@ -347,7 +347,8 @@ static std::string ValueOrEmptyString(const JsonObject::JsonObjPointer *json, co static void ResolvePathInDependenciesImpl(ArkTsConfig *arktsConfig, std::map, CompareByLength> &paths, - std::unordered_map &entries) + std::unordered_map &entries, + std::unordered_map &moduleInfos) { for (const auto &dependencyPath : arktsConfig->Paths()) { paths.emplace(dependencyPath.first, dependencyPath.second); @@ -355,14 +356,16 @@ static void ResolvePathInDependenciesImpl(ArkTsConfig *arktsConfig, if (!arktsConfig->Entry().empty()) { entries.emplace(arktsConfig->Package(), arktsConfig->Entry()); } + moduleInfos.emplace(arktsConfig->Package(), arktsConfig->BaseUrl()); + for (const auto &config : arktsConfig->Dependencies()) { - ResolvePathInDependenciesImpl(config.second.get(), paths, entries); + ResolvePathInDependenciesImpl(config.second.get(), paths, entries, moduleInfos); } } void ArkTsConfig::ResolveAllDependenciesInArkTsConfig() { - ResolvePathInDependenciesImpl(this, paths_, entries_); + ResolvePathInDependenciesImpl(this, paths_, entries_, moduleInfos_); } bool ArkTsConfig::ParseCompilerOptions(std::string &arktsConfigDir, std::unordered_set &parsedConfigPath, diff --git a/ets2panda/util/arktsconfig.h b/ets2panda/util/arktsconfig.h index fec474785a..910663b29a 100644 --- a/ets2panda/util/arktsconfig.h +++ b/ets2panda/util/arktsconfig.h @@ -164,6 +164,10 @@ public: { return entries_; } + const std::unordered_map &ModuleInfos() const + { + return moduleInfos_; + } const std::vector &Files() const { return files_; @@ -244,6 +248,7 @@ private: std::unordered_map> dependencies_ {}; // key: package name; value: entry's absolute path std::unordered_map entries_; + std::unordered_map moduleInfos_; #ifdef ARKTSCONFIG_USE_FILESYSTEM std::vector include_ {}; std::vector exclude_ {}; diff --git a/ets2panda/util/importPathManager.cpp b/ets2panda/util/importPathManager.cpp index 7cf0466927..0ee9ce7789 100644 --- a/ets2panda/util/importPathManager.cpp +++ b/ets2panda/util/importPathManager.cpp @@ -68,7 +68,7 @@ ImportPathManager::ImportMetadata ImportPathManager::GatherImportMetadata(parser // instead of 'AbsoluteName'. isDynamic_ = program->ModuleInfo().isDeclForDynamicStaticInterop; auto curModulePath = isDynamic_ ? program->ModuleInfo().moduleName : program->AbsoluteName(); - auto [resolvedImportPath, resolvedIsDynamic] = ResolvePath(curModulePath.Utf8(), importPath); + auto [resolvedImportPath, resolvedIsDynamic] = ResolvePath(curModulePath.Utf8(), importPath, program); if (resolvedImportPath.empty()) { ES2PANDA_ASSERT(diagnosticEngine_.IsAnyError()); return ImportMetadata {util::ImportFlags::NONE, Language::Id::COUNT, ERROR_LITERAL}; @@ -120,29 +120,45 @@ util::StringView ImportPathManager::ResolvePathAPI(StringView curModulePath, ir: } ImportPathManager::ResolvedPathRes ImportPathManager::ResolvePath(std::string_view curModulePath, - ir::StringLiteral *importPath) const + ir::StringLiteral *importPath, + parser::Program *program) const { if (importPath->Str().Empty()) { diagnosticEngine_.LogDiagnostic(diagnostic::EMPTY_IMPORT_PATH, util::DiagnosticMessageParams {}); return {*importPath}; } + const auto &entriesMap = arktsConfig_->Entries(); if (auto it = entriesMap.find(importPath->Str().Mutf8()); it != entriesMap.cend()) { return {UString(it->second, allocator_).View().Utf8()}; } - if (IsRelativePath(*importPath)) { - const size_t pos = curModulePath.find_last_of("/\\"); - ES2PANDA_ASSERT(pos != std::string::npos); + if (!IsRelativePath(*importPath)) { + return ResolveAbsolutePath(*importPath); + } + const size_t pos = curModulePath.find_last_of("/\\"); + ES2PANDA_ASSERT(pos != std::string::npos); + auto currentDirectory = curModulePath.substr(0, pos); + auto resolvedPath = UString(currentDirectory, allocator_); + resolvedPath.Append(pathDelimiter_); + resolvedPath.Append(*importPath); + + // try to find dynamicPath with relative path + auto queryDynamicResult = TryFindDynamicPathFromAbsolutePath(resolvedPath.View()); + if (!queryDynamicResult.resolvedPath.empty()) { + return queryDynamicResult; + } - auto currentDirectory = curModulePath.substr(0, pos); - auto resolvedPath = UString(currentDirectory, allocator_); - resolvedPath.Append(pathDelimiter_); - resolvedPath.Append(*importPath); - // NOTE(dkofanov): Suspicious shortcut: shouldn't it fallthrough into `ResolveAbsolutePath`? - return AppendExtensionOrIndexFileIfOmitted(resolvedPath.View()); + auto result = AppendExtensionOrIndexFileIfOmitted(resolvedPath.View()); + if (!result.resolvedPath.empty()) { + return result; } - return ResolveAbsolutePath(*importPath); + // Convert dynamic moduleName to real path under baseUrl to access actual 1.2 source file + auto staticResult = ResolvePathFromDynamicModule(program->ModuleInfo().moduleName, importPath); + if (!staticResult.resolvedPath.empty()) { + return staticResult; + } + return {""}; } ImportPathManager::ResolvedPathRes ImportPathManager::ResolveAbsolutePath(const ir::StringLiteral &importPathNode) const @@ -335,7 +351,8 @@ std::string_view ImportPathManager::DirOrDirWithIndexFile(StringView dir) const } // NOTE(dkofanov): Be cautious: potentially no-op and may retrun the input string view. Make sure 'basePath' won't go // out of scope. -ImportPathManager::ResolvedPathRes ImportPathManager::AppendExtensionOrIndexFileIfOmitted(StringView basePath) const +ImportPathManager::ResolvedPathRes ImportPathManager::AppendExtensionOrIndexFileIfOmitted(StringView basePath, + bool suppressError) const { auto fixedPath = basePath.Mutf8(); char delim = pathDelimiter_.at(0); @@ -365,8 +382,10 @@ ImportPathManager::ResolvedPathRes ImportPathManager::AppendExtensionOrIndexFile } } - diagnosticEngine_.LogDiagnostic(diagnostic::UNSUPPORTED_PATH, - util::DiagnosticMessageParams {util::StringView(path.Mutf8())}, *srcPos_); + if (!suppressError) { + diagnosticEngine_.LogDiagnostic(diagnostic::UNSUPPORTED_PATH, + util::DiagnosticMessageParams {util::StringView(path.Mutf8())}, *srcPos_); + } return {""}; } @@ -404,7 +423,7 @@ static std::string FormRelativeModuleName(std::string relPath) return relPath; } -util::StringView ImportPathManager::FormModuleNameSolelyByAbsolutePath(const util::Path &path) +util::StringView ImportPathManager::FormModuleNameSolelyByAbsolutePath(const util::Path &path) const { std::string filePath(path.GetAbsolutePath()); if (filePath.rfind(absoluteEtsPath_, 0) != 0) { @@ -438,7 +457,8 @@ util::StringView ImportPathManager::FormModuleName(const util::Path &path, const return FormModuleName(path); } -util::StringView ImportPathManager::FormModuleName(const util::Path &path) +// CC-OFFNXT(huge_method[C++], G.FUN.01-CPP) solid logic +util::StringView ImportPathManager::FormModuleName(const util::Path &path, bool suppressError) const { if (!absoluteEtsPath_.empty()) { return FormModuleNameSolelyByAbsolutePath(path); @@ -491,8 +511,15 @@ util::StringView ImportPathManager::FormModuleName(const util::Path &path) return util::UString(res.value(), allocator_).View(); } - diagnosticEngine_.LogDiagnostic(diagnostic::UNRESOLVED_MODULE, - util::DiagnosticMessageParams {util::StringView(filePath)}, *srcPos_); + for (auto const &[unitName, unitPath] : arktsConfig_->ModuleInfos()) { + if (auto res = tryFormModuleName(unitName, unitPath); res) { + return util::UString(res.value(), allocator_).View(); + } + } + if (!suppressError) { + diagnosticEngine_.LogDiagnostic(diagnostic::UNRESOLVED_MODULE, + util::DiagnosticMessageParams {util::StringView(filePath)}, *srcPos_); + } return ""; } @@ -547,5 +574,77 @@ util::StringView ImportPathManager::FormRelativePath(const util::Path &path) return path.GetFileNameWithExtension(); } +UString ImportPathManager::BuildPath(std::initializer_list parts) const +{ + std::string tempPath; + { + std::string firstPart = parts.begin()->Mutf8(); + size_t lastDotPos = firstPart.rfind('.'); + if (lastDotPos != std::string::npos) { + std::string dirPart = firstPart.substr(0, lastDotPos); + + size_t pos = 0; + while ((pos = dirPart.find('.', pos)) != std::string::npos) { + dirPart.replace(pos, 1, pathDelimiter_.data(), pathDelimiter_.size()); + pos += pathDelimiter_.size(); + } + tempPath += dirPart; + } else { + tempPath += firstPart; + } + } + + for (auto it = parts.begin() + 1; it != parts.end(); ++it) { + tempPath.append(pathDelimiter_.data(), pathDelimiter_.size()); + tempPath += it->Mutf8(); + } + + return UString(tempPath, allocator_); +} + +ImportPathManager::ResolvedPathRes ImportPathManager::TryFindDynamicPathFromAbsolutePath(StringView filePath) const +{ + if (isDynamic_) { + return {""}; + } + + std::string normalizedPath = ark::os::NormalizePath(filePath.Mutf8()); + std::array supportedExtensions = {".ets", ".d.ets", ".sts", + ".d.sts", ".ts", ".d.ts"}; + for (const auto &extension : supportedExtensions) { + auto fileName = normalizedPath + extension; + if (!ark::os::file::File::IsRegularFile(fileName)) { + continue; + } + util::Path dynamicFilePath(fileName, allocator_); + auto moduleName = FormModuleName(dynamicFilePath, true); + std::string dynamicModulePath(moduleName.Utf8()); + for (size_t idx = 0; (idx = dynamicModulePath.find('.', idx)) != std::string::npos; + idx += pathDelimiter_.length()) { + dynamicModulePath.replace(idx, 1, pathDelimiter_); + } + if (auto matched = TryMatchDynamicPath(dynamicModulePath); !matched.empty()) { + return {UString(matched, allocator_).View().Utf8(), true}; + } + } + return {""}; +} + +ImportPathManager::ResolvedPathRes ImportPathManager::ResolvePathFromDynamicModule(StringView moduleName, + ir::StringLiteral *importPath) const +{ + if (!isDynamic_) { + return {""}; + } + + std::string_view baseUrl = arktsConfig_->BaseUrl(); + size_t lastSlash = baseUrl.find_last_of("/\\"); + std::string_view parentDir = (lastSlash != std::string_view::npos) ? baseUrl.substr(0, lastSlash) : baseUrl; + + auto dynPath = BuildPath({parentDir, moduleName, importPath->Str()}); + std::string normDynPath = ark::os::NormalizePath(std::string(dynPath.View())); + return AppendExtensionOrIndexFileIfOmitted(UString(normDynPath, allocator_).View()); +} + } // namespace ark::es2panda::util #undef USE_UNIX_SYSCALL diff --git a/ets2panda/util/importPathManager.h b/ets2panda/util/importPathManager.h index 9e011a2159..a048ef11e5 100644 --- a/ets2panda/util/importPathManager.h +++ b/ets2panda/util/importPathManager.h @@ -147,8 +147,8 @@ public: util::StringView FormRelativePath(const util::Path &path); private: - util::StringView FormModuleNameSolelyByAbsolutePath(const util::Path &path); - util::StringView FormModuleName(const util::Path &path); + util::StringView FormModuleNameSolelyByAbsolutePath(const util::Path &path) const; + util::StringView FormModuleName(const util::Path &path, bool suppressError = false) const; struct ResolvedPathRes { // On successfull resolving, 2 variants are possible: @@ -159,12 +159,17 @@ private: bool resolvedIsDynamic {false}; // NOLINTEND(misc-non-private-member-variables-in-classes) }; - ResolvedPathRes ResolvePath(std::string_view curModulePath, ir::StringLiteral *importPath) const; + ResolvedPathRes ResolvePath(std::string_view curModulePath, ir::StringLiteral *importPath, + parser::Program *program = nullptr) const; ResolvedPathRes ResolveAbsolutePath(const ir::StringLiteral &importPathNode) const; std::string_view DirOrDirWithIndexFile(StringView dir) const; - ResolvedPathRes AppendExtensionOrIndexFileIfOmitted(StringView basePath) const; + // suppressError is for some retry find + ResolvedPathRes AppendExtensionOrIndexFileIfOmitted(StringView basePath, bool suppressError = false) const; std::string TryMatchDynamicPath(std::string_view fixedPath) const; StringView GetRealPath(StringView path) const; + UString BuildPath(std::initializer_list parts) const; + ResolvedPathRes TryFindDynamicPathFromAbsolutePath(StringView filePath) const; + ResolvedPathRes ResolvePathFromDynamicModule(StringView moduleName, ir::StringLiteral *importPath) const; public: void AddToParseList(ImportMetadata importMetadata); -- Gitee