From 6e41ed30f8f40681ee5cfabd8c13556ae6bfe408 Mon Sep 17 00:00:00 2001 From: vadimdolgachev Date: Tue, 5 Nov 2024 17:38:08 +0700 Subject: [PATCH] Fixes compilation of ArkTS code on Windows es2panda now compiles ArkTS code correctly on Windows Correct processing of module import path for Windows Issue: https://gitee.com/openharmony/arkcompiler_ets_frontend/issues/IB2GTZ?from=project-issue --- ets2panda/util/arktsconfig.cpp | 24 ++++++++++++++++++++---- ets2panda/util/importPathManager.cpp | 17 ++++++++++++----- 2 files changed, 32 insertions(+), 9 deletions(-) diff --git a/ets2panda/util/arktsconfig.cpp b/ets2panda/util/arktsconfig.cpp index fc8c263731..f95b1c3abd 100644 --- a/ets2panda/util/arktsconfig.cpp +++ b/ets2panda/util/arktsconfig.cpp @@ -115,9 +115,24 @@ std::string ArkTsConfig::Pattern::GetSearchRoot() const bool ArkTsConfig::Pattern::Match(const std::string &path) const { ASSERT(fs::path(path).is_absolute()); - fs::path value = fs::path(value_); + const fs::path value = fs::weakly_canonical(value_); std::string pattern = value.is_absolute() ? value.string() : (base_ / value).string(); +#ifdef PANDA_TARGET_WINDOWS + // Backslash escape except for regexp control sequences + pattern = std::regex_replace( + std::regex_replace(pattern, std::regex(R"(\\)"), R"(\\)"), + std::regex(R"(\\[\.])"), "."); + // Replace arktsconfig special symbols with regular expressions + if (IsPattern()) { + // '**' matches any directory nested to any level + pattern = std::regex_replace(pattern, std::regex(R"(\*\*\\\\)"), ".*"); + // '*' matches zero or more characters (excluding directory separators) + pattern = std::regex_replace(pattern, std::regex(R"(([^\.])\*)"), R"($1[^\\]*)"); + // '?' matches any one character (excluding directory separators) + pattern = std::regex_replace(pattern, std::regex(R"("\?")"), R"([^\\])"); + } +#else // Replace arktsconfig special symbols with regular expressions if (IsPattern()) { // '**' matches any directory nested to any level @@ -131,6 +146,7 @@ bool ArkTsConfig::Pattern::Match(const std::string &path) const // default extensions to match pattern += R"(.*(\.ts|\.d\.ts|\.sts)$)"; } +#endif // PANDA_TARGET_WINDOWS std::smatch m; auto res = std::regex_match(path, m, std::regex(pattern)); return res; @@ -459,7 +475,7 @@ static std::vector GetSourceList(const std::shared_ptr &a // Collect "include" // TSC traverses folders for sources starting from 'include' rather than from 'rootDir', so we do the same for (auto &include : includes) { - auto traverseRoot = fs::path(include.GetSearchRoot()); + auto traverseRoot = fs::weakly_canonical(include.GetSearchRoot()); if (!fs::exists(traverseRoot)) { continue; } @@ -471,7 +487,7 @@ static std::vector GetSourceList(const std::shared_ptr &a } for (const auto &dirEntry : fs::recursive_directory_iterator(traverseRoot)) { if (include.Match(dirEntry.path().string()) && !MatchExcludes(dirEntry, excludes)) { - sourceList.emplace_back(dirEntry); + sourceList.emplace_back(fs::weakly_canonical(dirEntry)); } } } @@ -484,7 +500,7 @@ static fs::path Relative(const fs::path &src, const fs::path &base) { fs::path tmpPath = src; fs::path relPath; - while (!fs::equivalent(tmpPath, base)) { + while (!fs::equivalent(fs::weakly_canonical(tmpPath), fs::weakly_canonical(base))) { relPath = relPath.empty() ? tmpPath.filename() : tmpPath.filename() / relPath; if (tmpPath == tmpPath.parent_path()) { return fs::path(); diff --git a/ets2panda/util/importPathManager.cpp b/ets2panda/util/importPathManager.cpp index 177a50d018..3e41de7e2b 100644 --- a/ets2panda/util/importPathManager.cpp +++ b/ets2panda/util/importPathManager.cpp @@ -29,6 +29,13 @@ namespace fs = std::filesystem; namespace fs = std::experimental::filesystem; #endif #endif + +#ifdef PANDA_TARGET_WINDOWS +constexpr std::string_view importPathDelimiter = "/"; +#else +constexpr std::string_view importPathDelimiter = ark::os::file::File::GetPathDelim(); +#endif + namespace ark::es2panda::util { constexpr size_t SUPPORTED_INDEX_FILES_SIZE = 2; @@ -58,7 +65,7 @@ StringView ImportPathManager::ResolvePath(const StringView ¤tModulePath, c } std::string baseUrl; - if (importPath.Mutf8()[0] == pathDelimiter_.at(0)) { + if (importPath.Mutf8()[0] == importPathDelimiter.at(0)) { baseUrl = arktsConfig_->BaseUrl(); baseUrl.append(importPath.Mutf8(), 0, importPath.Mutf8().length()); return AppendExtensionOrIndexFileIfOmitted(UString(baseUrl, allocator_).View()); @@ -69,12 +76,12 @@ StringView ImportPathManager::ResolvePath(const StringView ¤tModulePath, c return AppendExtensionOrIndexFileIfOmitted(importPath); } - const size_t pos = importPath.Mutf8().find(pathDelimiter_); + const size_t pos = importPath.Mutf8().find(importPathDelimiter); bool containsDelim = (pos != std::string::npos); auto rootPart = containsDelim ? importPath.Substr(0, pos) : importPath; if (!stdLib_.empty() && (rootPart.Is("std") || rootPart.Is("escompat"))) { // Get std or escompat path from CLI if provided - baseUrl = stdLib_ + pathDelimiter_.at(0) + rootPart.Mutf8(); + baseUrl = stdLib_ + importPathDelimiter.at(0) + rootPart.Mutf8(); } else { ASSERT(arktsConfig_ != nullptr); auto resolvedPath = arktsConfig_->ResolvePath(importPath.Mutf8()); @@ -228,8 +235,8 @@ bool ImportPathManager::IsRelativePath(const StringView &path) const std::string currentDirReference = "."; std::string parentDirReference = ".."; - currentDirReference.append(pathDelimiter_); - parentDirReference.append(pathDelimiter_); + currentDirReference.append(importPathDelimiter); + parentDirReference.append(importPathDelimiter); return ((path.Mutf8().find(currentDirReference) == 0) || (path.Mutf8().find(parentDirReference) == 0)); } -- Gitee