https://github.com/blaadje updated 
https://github.com/llvm/llvm-project/pull/155191

>From c62dd6a9640ce42f38557d802097759f81cc2657 Mon Sep 17 00:00:00 2001
From: openhands <openha...@all-hands.dev>
Date: Sun, 24 Aug 2025 12:17:50 +0200
Subject: [PATCH 01/14] PathMapping: add verbose vlog instrumentation for
 inbound/outbound path mapping

---
 clang-tools-extra/clangd/PathMapping.cpp | 24 ++++++++++++++++++++++--
 1 file changed, 22 insertions(+), 2 deletions(-)

diff --git a/clang-tools-extra/clangd/PathMapping.cpp 
b/clang-tools-extra/clangd/PathMapping.cpp
index 4b93ff2c60c5c..e2dfb5158fecd 100644
--- a/clang-tools-extra/clangd/PathMapping.cpp
+++ b/clang-tools-extra/clangd/PathMapping.cpp
@@ -84,21 +84,31 @@ class PathMappingMessageHandler : public 
Transport::MessageHandler {
       : WrappedHandler(Handler), Mappings(Mappings) {}
 
   bool onNotify(llvm::StringRef Method, llvm::json::Value Params) override {
+    vlog("PathMapping: inbound onNotify Method={0}", Method);
+    vlog("PathMapping: inbound Params before={0}", Params);
     applyPathMappings(Params, PathMapping::Direction::ClientToServer, 
Mappings);
+    vlog("PathMapping: inbound Params after={0}", Params);
     return WrappedHandler.onNotify(Method, std::move(Params));
   }
 
   bool onCall(llvm::StringRef Method, llvm::json::Value Params,
               llvm::json::Value ID) override {
+    vlog("PathMapping: inbound onCall Method={0}", Method);
+    vlog("PathMapping: inbound Params before={0}", Params);
     applyPathMappings(Params, PathMapping::Direction::ClientToServer, 
Mappings);
+    vlog("PathMapping: inbound Params after={0}", Params);
     return WrappedHandler.onCall(Method, std::move(Params), std::move(ID));
   }
 
   bool onReply(llvm::json::Value ID,
                llvm::Expected<llvm::json::Value> Result) override {
-    if (Result)
+    vlog("PathMapping: inbound onReply ID={0}", ID);
+    if (Result) {
+      vlog("PathMapping: inbound Result before={0}", *Result);
       applyPathMappings(*Result, PathMapping::Direction::ClientToServer,
                         Mappings);
+      vlog("PathMapping: inbound Result after={0}", *Result);
+    }
     return WrappedHandler.onReply(std::move(ID), std::move(Result));
   }
 
@@ -115,21 +125,31 @@ class PathMappingTransport : public Transport {
       : WrappedTransport(std::move(Transp)), Mappings(std::move(Mappings)) {}
 
   void notify(llvm::StringRef Method, llvm::json::Value Params) override {
+    vlog("PathMapping: outbound notify Method={0}", Method);
+    vlog("PathMapping: outbound Params before={0}", Params);
     applyPathMappings(Params, PathMapping::Direction::ServerToClient, 
Mappings);
+    vlog("PathMapping: outbound Params after={0}", Params);
     WrappedTransport->notify(Method, std::move(Params));
   }
 
   void call(llvm::StringRef Method, llvm::json::Value Params,
             llvm::json::Value ID) override {
+    vlog("PathMapping: outbound call Method={0}", Method);
+    vlog("PathMapping: outbound Params before={0}", Params);
     applyPathMappings(Params, PathMapping::Direction::ServerToClient, 
Mappings);
+    vlog("PathMapping: outbound Params after={0}", Params);
     WrappedTransport->call(Method, std::move(Params), std::move(ID));
   }
 
   void reply(llvm::json::Value ID,
              llvm::Expected<llvm::json::Value> Result) override {
-    if (Result)
+    vlog("PathMapping: outbound reply ID={0}", ID);
+    if (Result) {
+      vlog("PathMapping: outbound Result before={0}", *Result);
       applyPathMappings(*Result, PathMapping::Direction::ServerToClient,
                         Mappings);
+      vlog("PathMapping: outbound Result after={0}", *Result);
+    }
     WrappedTransport->reply(std::move(ID), std::move(Result));
   }
 

>From 3b781d77041260bae3e5e6833bc9b4a110b08590 Mon Sep 17 00:00:00 2001
From: alexandre-charlot_qonto <alexandre.char...@qonto.com>
Date: Sun, 24 Aug 2025 19:26:34 +0200
Subject: [PATCH 02/14] PathMapping: normalize URI bodies to handle mixed
 WSL/Windows paths

Normalize URI bodies before applying path mappings to handle cases where 
clients mix /mnt/c/ paths with embedded C:/ segments, and convert backslashes 
to forward slashes.

Co-authored-by: openhands <openha...@all-hands.dev>
---
 clang-tools-extra/clangd/PathMapping.cpp | 38 ++++++++++++++++++++----
 1 file changed, 32 insertions(+), 6 deletions(-)

diff --git a/clang-tools-extra/clangd/PathMapping.cpp 
b/clang-tools-extra/clangd/PathMapping.cpp
index e2dfb5158fecd..2a6411a4ba9b6 100644
--- a/clang-tools-extra/clangd/PathMapping.cpp
+++ b/clang-tools-extra/clangd/PathMapping.cpp
@@ -14,6 +14,7 @@
 #include <algorithm>
 #include <optional>
 #include <tuple>
+#include <cctype>
 
 namespace clang {
 namespace clangd {
@@ -21,13 +22,39 @@ std::optional<std::string> doPathMapping(llvm::StringRef S,
                                          PathMapping::Direction Dir,
                                          const PathMappings &Mappings) {
   // Return early to optimize for the common case, wherein S is not a file URI
-  if (!S.starts_with("file://"))
+  if (!S.startswith("file://"))
     return std::nullopt;
   auto Uri = URI::parse(S);
   if (!Uri) {
     llvm::consumeError(Uri.takeError());
     return std::nullopt;
   }
+
+  // Normalize the URI body to handle cases where a client mixes WSL and
+  // Windows paths (e.g. "/mnt/c/.../C:/..."), or uses backslashes. URI::parse
+  // decodes percent-encoded characters, so operate on the decoded body.
+  std::string BodyStr = (*Uri).body().str();
+  // Convert backslashes to forward slashes.
+  std::replace(BodyStr.begin(), BodyStr.end(), '\\', '/');
+  // If path starts with /mnt/<drive>/ and later contains "/<DriveLetter>:/",
+  // remove the duplicated "<DriveLetter>:" segment (replace "/C:/" with "/").
+  if (BodyStr.rfind("/mnt/", 0) == 0 && BodyStr.size() > 6) {
+    char mntDrive = BodyStr[5]; // '/mnt/x/' => x
+    for (size_t i = 0; i + 3 < BodyStr.size(); ++i) {
+      if (BodyStr[i] == '/' && std::isalpha((unsigned char)BodyStr[i + 1]) &&
+          BodyStr[i + 2] == ':' && BodyStr[i + 3] == '/') {
+        char dupDrive = BodyStr[i + 1];
+        if (std::tolower((unsigned char)dupDrive) ==
+            std::tolower((unsigned char)mntDrive)) {
+          // Replace "/C:/" with "/"
+          BodyStr.replace(i, 4, "/");
+          break;
+        }
+      }
+    }
+  }
+
+  llvm::StringRef BodyRef(BodyStr);
   for (const auto &Mapping : Mappings) {
     const std::string &From = Dir == PathMapping::Direction::ClientToServer
                                   ? Mapping.ClientPath
@@ -35,11 +62,10 @@ std::optional<std::string> doPathMapping(llvm::StringRef S,
     const std::string &To = Dir == PathMapping::Direction::ClientToServer
                                 ? Mapping.ServerPath
                                 : Mapping.ClientPath;
-    llvm::StringRef Body = Uri->body();
-    if (Body.consume_front(From) && (Body.empty() || Body.front() == '/')) {
-      std::string MappedBody = (To + Body).str();
-      return URI(Uri->scheme(), Uri->authority(), MappedBody)
-          .toString();
+    llvm::StringRef Working = BodyRef;
+    if (Working.consume_front(From) && (Working.empty() || Working.front() == 
'/')) {
+      std::string MappedBody = (To + Working).str();
+      return URI((*Uri).scheme(), (*Uri).authority(), MappedBody).toString();
     }
   }
   return std::nullopt;

>From 2ba09b136983636f997d378d3e97429ae84e71b2 Mon Sep 17 00:00:00 2001
From: alexandre-charlot_qonto <alexandre.char...@qonto.com>
Date: Sun, 24 Aug 2025 19:29:44 +0200
Subject: [PATCH 03/14] Fix StringRef method name: starts_with

Use starts_with instead of startswith.

Co-authored-by: openhands <openha...@all-hands.dev>
---
 clang-tools-extra/clangd/PathMapping.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/clang-tools-extra/clangd/PathMapping.cpp 
b/clang-tools-extra/clangd/PathMapping.cpp
index 2a6411a4ba9b6..84b85857b41dc 100644
--- a/clang-tools-extra/clangd/PathMapping.cpp
+++ b/clang-tools-extra/clangd/PathMapping.cpp
@@ -22,7 +22,7 @@ std::optional<std::string> doPathMapping(llvm::StringRef S,
                                          PathMapping::Direction Dir,
                                          const PathMappings &Mappings) {
   // Return early to optimize for the common case, wherein S is not a file URI
-  if (!S.startswith("file://"))
+  if (!S.starts_with("file://"))
     return std::nullopt;
   auto Uri = URI::parse(S);
   if (!Uri) {

>From 26066ca56e10b93d29f94c322a6dffc810a64818 Mon Sep 17 00:00:00 2001
From: alexandre-charlot_qonto <alexandre.char...@qonto.com>
Date: Sun, 24 Aug 2025 19:37:39 +0200
Subject: [PATCH 04/14] Fix StringRef starts_with usage in fallback pass

Use starts_with for llvm::StringRef in fallback mapping check.

Co-authored-by: openhands <openha...@all-hands.dev>
---
 clang-tools-extra/clangd/PathMapping.cpp | 44 ++++++++++++++++++++++--
 1 file changed, 41 insertions(+), 3 deletions(-)

diff --git a/clang-tools-extra/clangd/PathMapping.cpp 
b/clang-tools-extra/clangd/PathMapping.cpp
index 84b85857b41dc..992c6355f6e44 100644
--- a/clang-tools-extra/clangd/PathMapping.cpp
+++ b/clang-tools-extra/clangd/PathMapping.cpp
@@ -36,6 +36,11 @@ std::optional<std::string> doPathMapping(llvm::StringRef S,
   std::string BodyStr = (*Uri).body().str();
   // Convert backslashes to forward slashes.
   std::replace(BodyStr.begin(), BodyStr.end(), '\\', '/');
+
+  // Diagnostic logging to help debug mapping failures. This will show the
+  // normalized body and each mapping attempted.
+  vlog("PathMapping: doPathMapping S={0} normalized_body={1}", S, BodyStr);
+
   // If path starts with /mnt/<drive>/ and later contains "/<DriveLetter>:/",
   // remove the duplicated "<DriveLetter>:" segment (replace "/C:/" with "/").
   if (BodyStr.rfind("/mnt/", 0) == 0 && BodyStr.size() > 6) {
@@ -62,12 +67,45 @@ std::optional<std::string> doPathMapping(llvm::StringRef S,
     const std::string &To = Dir == PathMapping::Direction::ClientToServer
                                 ? Mapping.ServerPath
                                 : Mapping.ClientPath;
+    vlog("PathMapping: try mapping From={0} To={1}", From, To);
     llvm::StringRef Working = BodyRef;
-    if (Working.consume_front(From) && (Working.empty() || Working.front() == 
'/')) {
-      std::string MappedBody = (To + Working).str();
-      return URI((*Uri).scheme(), (*Uri).authority(), MappedBody).toString();
+    if (Working.consume_front(From)) {
+      // Accept the match if either the mapping 'From' ends with a slash 
(explicit
+      // directory mapping), or the remainder is empty or begins with '/'. This
+      // handles cases like From="/C:/" matching Body="/C:/Users/..." where
+      // consuming From leaves "Users/..." (which does not start with '/').
+      if (From.empty() || From.back() == '/' || Working.empty() || 
Working.front() == '/') {
+        std::string MappedBody = (To + Working).str();
+        vlog("PathMapping: matched From={0} To={1} => MappedBody={2}", From, 
To, MappedBody);
+        return URI((*Uri).scheme(), (*Uri).authority(), MappedBody).toString();
+      }
     }
   }
+
+  // Fallback: sometimes the body starts with a Server-style drive like 
"/C:/..."
+  // but the 'From' mapping may not include a trailing slash or may be slightly
+  // different. Try a relaxed matching pass for Server->Client direction.
+  if (Dir == PathMapping::Direction::ServerToClient) {
+    for (const auto &Mapping : Mappings) {
+      const std::string &From = Mapping.ServerPath;
+      const std::string &To = Mapping.ClientPath;
+      if (From.empty())
+        continue;
+      llvm::StringRef W = BodyRef;
+      // If the body starts with From (allowing missing trailing slash), 
accept it.
+      if (W.starts_with(From)) {
+        llvm::StringRef Rest = W.substr(From.size());
+        // If Rest begins with '/' or is empty, this is a reasonable match.
+        if (Rest.empty() || Rest.front() == '/') {
+          std::string MappedBody = (To + Rest).str();
+          vlog("PathMapping: fallback matched From={0} To={1} => 
MappedBody={2}", From, To, MappedBody);
+          return URI((*Uri).scheme(), (*Uri).authority(), 
MappedBody).toString();
+        }
+      }
+    }
+  }
+
+  vlog("PathMapping: no mapping matched for body={0}", BodyStr);
   return std::nullopt;
 }
 

>From 45b8ade3bb646b59ef26722a36d8ff5c01f6e6c8 Mon Sep 17 00:00:00 2001
From: alexandre-charlot_qonto <alexandre.char...@qonto.com>
Date: Sun, 24 Aug 2025 19:55:49 +0200
Subject: [PATCH 05/14] PathMapping: add unit tests for encoded Windows
 fragments and WSL<->Windows mapping

Add tests that cover inbound percent-encoded Windows fragments and outbound 
server-side Windows->WSL mapping.

Co-authored-by: openhands <openha...@all-hands.dev>
---
 .../clangd/unittests/PathMappingTests.cpp     | 22 +++++++++++++++++++
 1 file changed, 22 insertions(+)

diff --git a/clang-tools-extra/clangd/unittests/PathMappingTests.cpp 
b/clang-tools-extra/clangd/unittests/PathMappingTests.cpp
index 2e26148495a01..2b953006d2de1 100644
--- a/clang-tools-extra/clangd/unittests/PathMappingTests.cpp
+++ b/clang-tools-extra/clangd/unittests/PathMappingTests.cpp
@@ -212,6 +212,28 @@ TEST(ApplyPathMappingTests, MapsKeys) {
   EXPECT_EQ(*Params, *ExpectedParams);
 }
 
+
+TEST(DoPathMappingTests, HandlesEncodedWindowsFragmentsInbound) {
+  // Simulate a client sending a WSL-style path that embeds an encoded Windows
+  // fragment (percent-encoded backslashes and drive letter). The server should
+  // normalize and map it to a Windows-style path.
+  PathMappings Mappings{{"/mnt/c/", "/C:/"}};
+  const char *Orig = 
"file:///mnt/c/projects/cod2-asi/C:%5cUsers%5caukx%5cprojects%5ccod2-asi%5csrc%5cedge_detection.h";
+  std::optional<std::string> Mapped = doPathMapping(Orig, 
PathMapping::Direction::ClientToServer, Mappings);
+  ASSERT_TRUE(bool(Mapped));
+  EXPECT_EQ(*Mapped, 
std::string("file:///C:/projects/cod2-asi/src/edge_detection.h"));
+}
+
+TEST(DoPathMappingTests, HandlesWindowsToWslOutbound) {
+  // Server returns Windows-style URIs; they should be mapped back to the
+  // client's WSL-style paths before sending out.
+  PathMappings Mappings{{"/mnt/c/", "/C:/"}};
+  const char *Orig = "file:///C:/projects/cod2-asi/src/edge_detection.h";
+  std::optional<std::string> Mapped = doPathMapping(Orig, 
PathMapping::Direction::ServerToClient, Mappings);
+  ASSERT_TRUE(bool(Mapped));
+  EXPECT_EQ(*Mapped, 
std::string("file:///mnt/c/projects/cod2-asi/src/edge_detection.h"));
+}
+
 } // namespace
 } // namespace clangd
 } // namespace clang

>From 25c3f0e97f3c546076bb60445abd3f67a0e8fe10 Mon Sep 17 00:00:00 2001
From: alexandre-charlot_qonto <alexandre.char...@qonto.com>
Date: Sun, 24 Aug 2025 20:48:44 +0200
Subject: [PATCH 06/14] PathMapping: prefer embedded Windows drive fragment
 when normalizing /mnt/<x>/.../X:/ patterns

Adjust normalization to keep embedded Windows drive (e.g. /C:/...) instead of 
removing C:/ which caused duplicated path segments.

Co-authored-by: openhands <openha...@all-hands.dev>
---
 clang-tools-extra/clangd/PathMapping.cpp | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/clang-tools-extra/clangd/PathMapping.cpp 
b/clang-tools-extra/clangd/PathMapping.cpp
index 992c6355f6e44..133c5b3ca6f1f 100644
--- a/clang-tools-extra/clangd/PathMapping.cpp
+++ b/clang-tools-extra/clangd/PathMapping.cpp
@@ -51,8 +51,10 @@ std::optional<std::string> doPathMapping(llvm::StringRef S,
         char dupDrive = BodyStr[i + 1];
         if (std::tolower((unsigned char)dupDrive) ==
             std::tolower((unsigned char)mntDrive)) {
-          // Replace "/C:/" with "/"
-          BodyStr.replace(i, 4, "/");
+          // Replace the whole prefix up to the duplicated drive so the
+          // body becomes "/C:/..." (prefer the embedded Windows path). This
+          // avoids duplicating path segments when later mapping.
+          BodyStr = std::string("/") + BodyStr.substr(i + 1);
           break;
         }
       }

>From a08e2f3a2bf129258f4b301ce6b64bef31c1a7f1 Mon Sep 17 00:00:00 2001
From: alexandre-charlot_qonto <alexandre.char...@qonto.com>
Date: Sun, 24 Aug 2025 20:51:15 +0200
Subject: [PATCH 07/14] Adjust test expectation to include user path segment in
 normalized mapping

The normalization prefers the embedded Windows drive; tests should reflect the 
preserved leading user path when applicable.

Co-authored-by: openhands <openha...@all-hands.dev>
---
 clang-tools-extra/clangd/unittests/PathMappingTests.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/clang-tools-extra/clangd/unittests/PathMappingTests.cpp 
b/clang-tools-extra/clangd/unittests/PathMappingTests.cpp
index 2b953006d2de1..a5bc54e7c1d72 100644
--- a/clang-tools-extra/clangd/unittests/PathMappingTests.cpp
+++ b/clang-tools-extra/clangd/unittests/PathMappingTests.cpp
@@ -221,7 +221,7 @@ TEST(DoPathMappingTests, 
HandlesEncodedWindowsFragmentsInbound) {
   const char *Orig = 
"file:///mnt/c/projects/cod2-asi/C:%5cUsers%5caukx%5cprojects%5ccod2-asi%5csrc%5cedge_detection.h";
   std::optional<std::string> Mapped = doPathMapping(Orig, 
PathMapping::Direction::ClientToServer, Mappings);
   ASSERT_TRUE(bool(Mapped));
-  EXPECT_EQ(*Mapped, 
std::string("file:///C:/projects/cod2-asi/src/edge_detection.h"));
+  EXPECT_EQ(*Mapped, 
std::string("file:///C:/Users/aukx/projects/cod2-asi/src/edge_detection.h"));
 }
 
 TEST(DoPathMappingTests, HandlesWindowsToWslOutbound) {

>From c37efdbf382f8987abb0ae42c29342c6b96646cb Mon Sep 17 00:00:00 2001
From: alexandre-charlot_qonto <alexandre.char...@qonto.com>
Date: Sun, 24 Aug 2025 20:54:35 +0200
Subject: [PATCH 08/14] PathMapping: strip duplicated embedded drive when
 assembling mapped body to avoid duplicated segments

When mapping, detect repeated X:/ inside the remainder and prefer embedded 
drive fragment.

Co-authored-by: openhands <openha...@all-hands.dev>
---
 clang-tools-extra/clangd/PathMapping.cpp | 24 +++++++++++++++++++++++-
 1 file changed, 23 insertions(+), 1 deletion(-)

diff --git a/clang-tools-extra/clangd/PathMapping.cpp 
b/clang-tools-extra/clangd/PathMapping.cpp
index 133c5b3ca6f1f..f4da1b46c7458 100644
--- a/clang-tools-extra/clangd/PathMapping.cpp
+++ b/clang-tools-extra/clangd/PathMapping.cpp
@@ -77,7 +77,29 @@ std::optional<std::string> doPathMapping(llvm::StringRef S,
       // handles cases like From="/C:/" matching Body="/C:/Users/..." where
       // consuming From leaves "Users/..." (which does not start with '/').
       if (From.empty() || From.back() == '/' || Working.empty() || 
Working.front() == '/') {
-        std::string MappedBody = (To + Working).str();
+        // If the remainder contains a duplicated Windows drive fragment (e.g.
+        // "projects/.../C:/Users/..."), prefer the embedded Windows path by
+        // stripping everything before the duplicated driver when assembling 
the
+        // mapped body. This avoids producing "/C:/projects/.../C:/...".
+        llvm::StringRef Adjusted = Working;
+        // Try to infer the mapping drive from 'To' (expecting "/X:/" prefix).
+        char MappingDrive = 0;
+        if (To.size() >= 3 && To[0] == '/' && std::isalpha((unsigned 
char)To[1]) && To[2] == ':')
+          MappingDrive = To[1];
+        if (MappingDrive) {
+          for (size_t i = 0; i + 2 < (size_t)Working.size(); ++i) {
+            char c = Working[i];
+            if (std::isalpha((unsigned char)c) && Working[i + 1] == ':' && 
Working[i + 2] == '/') {
+              if (std::tolower((unsigned char)c) == std::tolower((unsigned 
char)MappingDrive)) {
+                // Strip everything up to and including the duplicated "X:/" so
+                // that appending to To yields "/X:/<rest>" without 
duplication.
+                Adjusted = Working.substr(i + 3);
+                break;
+              }
+            }
+          }
+        }
+        std::string MappedBody = (To + Adjusted).str();
         vlog("PathMapping: matched From={0} To={1} => MappedBody={2}", From, 
To, MappedBody);
         return URI((*Uri).scheme(), (*Uri).authority(), MappedBody).toString();
       }

>From fe7713903803e781a94ec2a614990a2e10bd1f3d Mon Sep 17 00:00:00 2001
From: alexandre-charlot_qonto <alexandre.char...@qonto.com>
Date: Sun, 24 Aug 2025 21:02:36 +0200
Subject: [PATCH 09/14] PathMapping: normalize incoming /mnt/.../C:/... cases
 by preferring embedded Windows drive fragment

For client->server URIs that embed a Windows drive fragment inside a WSL path, 
normalize the body to start at the embedded drive (e.g. /C:/...) to avoid 
mis-mapping.

Co-authored-by: openhands <openha...@all-hands.dev>
---
 clang-tools-extra/clangd/PathMapping.cpp | 28 +++++++++++-------------
 1 file changed, 13 insertions(+), 15 deletions(-)

diff --git a/clang-tools-extra/clangd/PathMapping.cpp 
b/clang-tools-extra/clangd/PathMapping.cpp
index f4da1b46c7458..afae00ee2d7f1 100644
--- a/clang-tools-extra/clangd/PathMapping.cpp
+++ b/clang-tools-extra/clangd/PathMapping.cpp
@@ -41,22 +41,20 @@ std::optional<std::string> doPathMapping(llvm::StringRef S,
   // normalized body and each mapping attempted.
   vlog("PathMapping: doPathMapping S={0} normalized_body={1}", S, BodyStr);
 
-  // If path starts with /mnt/<drive>/ and later contains "/<DriveLetter>:/",
-  // remove the duplicated "<DriveLetter>:" segment (replace "/C:/" with "/").
+  // If path starts with /mnt/<drive>/ and later contains an embedded
+  // Windows drive fragment like "/C:/", prefer the embedded Windows path.
+  // For incoming client->server URIs, normalize bodies like
+  // "/mnt/c/.../C:/Users/..." to "/C:/Users/..." by chopping everything
+  // before the embedded drive. This matches the expectation that the
+  // Windows path inside the body is the canonical file path.
   if (BodyStr.rfind("/mnt/", 0) == 0 && BodyStr.size() > 6) {
-    char mntDrive = BodyStr[5]; // '/mnt/x/' => x
-    for (size_t i = 0; i + 3 < BodyStr.size(); ++i) {
-      if (BodyStr[i] == '/' && std::isalpha((unsigned char)BodyStr[i + 1]) &&
-          BodyStr[i + 2] == ':' && BodyStr[i + 3] == '/') {
-        char dupDrive = BodyStr[i + 1];
-        if (std::tolower((unsigned char)dupDrive) ==
-            std::tolower((unsigned char)mntDrive)) {
-          // Replace the whole prefix up to the duplicated drive so the
-          // body becomes "/C:/..." (prefer the embedded Windows path). This
-          // avoids duplicating path segments when later mapping.
-          BodyStr = std::string("/") + BodyStr.substr(i + 1);
-          break;
-        }
+    for (size_t i = 0; i + 2 < BodyStr.size(); ++i) {
+      if (std::isalpha((unsigned char)BodyStr[i]) && BodyStr[i + 1] == ':' &&
+          BodyStr[i + 2] == '/') {
+        // Found an embedded drive at BodyStr[i]. Normalize to start at that
+        // drive (prepend a leading '/') so the body becomes "/C:/...".
+        BodyStr = std::string("/") + BodyStr.substr(i);
+        break;
       }
     }
   }

>From 4017775ca9f5684d8f430baf52e99df61b31510b Mon Sep 17 00:00:00 2001
From: alexandre-charlot_qonto <alexandre.char...@qonto.com>
Date: Sun, 24 Aug 2025 21:04:27 +0200
Subject: [PATCH 10/14] PathMapping: for ClientToServer, normalize embedded
 Windows drive and return normalized URI without additional mapping

If client sends /mnt/.../C:/..., prefer and return /C:/... directly.

Co-authored-by: openhands <openha...@all-hands.dev>
---
 clang-tools-extra/clangd/PathMapping.cpp | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/clang-tools-extra/clangd/PathMapping.cpp 
b/clang-tools-extra/clangd/PathMapping.cpp
index afae00ee2d7f1..860aab7bf0cda 100644
--- a/clang-tools-extra/clangd/PathMapping.cpp
+++ b/clang-tools-extra/clangd/PathMapping.cpp
@@ -59,6 +59,17 @@ std::optional<std::string> doPathMapping(llvm::StringRef S,
     }
   }
 
+  // If we've normalized to a Windows-style drive (e.g. "/C:/...") for an 
incoming
+  // client->server URI, return the normalized Windows path directly to avoid
+  // trying to map from the original /mnt/ prefix which no longer applies.
+  if (Dir == PathMapping::Direction::ClientToServer) {
+    if (BodyStr.size() >= 3 && BodyStr[0] == '/' &&
+        std::isalpha((unsigned char)BodyStr[1]) && BodyStr[2] == ':') {
+      vlog("PathMapping: normalized client->server Windows body={0}", BodyStr);
+      return URI((*Uri).scheme(), (*Uri).authority(), BodyStr).toString();
+    }
+  }
+
   llvm::StringRef BodyRef(BodyStr);
   for (const auto &Mapping : Mappings) {
     const std::string &From = Dir == PathMapping::Direction::ClientToServer

>From b7ab8c9d43f97c54437ff13072118bb3c996724c Mon Sep 17 00:00:00 2001
From: alexandre-charlot_qonto <alexandre.char...@qonto.com>
Date: Sun, 24 Aug 2025 21:29:54 +0200
Subject: [PATCH 11/14] PathMapping: only short-circuit returning normalized
 /C:/... for bodies that we explicitly preferred from /mnt/ embedded drive

This preserves mapping behavior for ordinary incoming Windows URIs.

Co-authored-by: openhands <openha...@all-hands.dev>
---
 clang-tools-extra/clangd/PathMapping.cpp | 10 +++++++---
 1 file changed, 7 insertions(+), 3 deletions(-)

diff --git a/clang-tools-extra/clangd/PathMapping.cpp 
b/clang-tools-extra/clangd/PathMapping.cpp
index 860aab7bf0cda..3db9a0c622abe 100644
--- a/clang-tools-extra/clangd/PathMapping.cpp
+++ b/clang-tools-extra/clangd/PathMapping.cpp
@@ -47,6 +47,7 @@ std::optional<std::string> doPathMapping(llvm::StringRef S,
   // "/mnt/c/.../C:/Users/..." to "/C:/Users/..." by chopping everything
   // before the embedded drive. This matches the expectation that the
   // Windows path inside the body is the canonical file path.
+  bool DidPreferEmbeddedDrive = false;
   if (BodyStr.rfind("/mnt/", 0) == 0 && BodyStr.size() > 6) {
     for (size_t i = 0; i + 2 < BodyStr.size(); ++i) {
       if (std::isalpha((unsigned char)BodyStr[i]) && BodyStr[i + 1] == ':' &&
@@ -54,15 +55,18 @@ std::optional<std::string> doPathMapping(llvm::StringRef S,
         // Found an embedded drive at BodyStr[i]. Normalize to start at that
         // drive (prepend a leading '/') so the body becomes "/C:/...".
         BodyStr = std::string("/") + BodyStr.substr(i);
+        DidPreferEmbeddedDrive = true;
         break;
       }
     }
   }
 
   // If we've normalized to a Windows-style drive (e.g. "/C:/...") for an 
incoming
-  // client->server URI, return the normalized Windows path directly to avoid
-  // trying to map from the original /mnt/ prefix which no longer applies.
-  if (Dir == PathMapping::Direction::ClientToServer) {
+  // client->server URI that came from an original /mnt/... path, return the
+  // normalized Windows path directly to avoid trying to map from the original
+  // /mnt/ prefix which no longer applies. Do not short-circuit normal incoming
+  // Windows URIs that should still be subject to mappings.
+  if (Dir == PathMapping::Direction::ClientToServer && DidPreferEmbeddedDrive) 
{
     if (BodyStr.size() >= 3 && BodyStr[0] == '/' &&
         std::isalpha((unsigned char)BodyStr[1]) && BodyStr[2] == ':') {
       vlog("PathMapping: normalized client->server Windows body={0}", BodyStr);

>From fdba14f99b78f9d1bf0ae8f4ac6ae72260908b9b Mon Sep 17 00:00:00 2001
From: openhands <openha...@all-hands.dev>
Date: Sun, 24 Aug 2025 22:12:19 +0200
Subject: [PATCH 12/14] PathMapping: remove verbose vlog instrumentation and
 inline comments for cleaner output before PR

---
 clang-tools-extra/clangd/PathMapping.cpp | 26 ------------------------
 1 file changed, 26 deletions(-)

diff --git a/clang-tools-extra/clangd/PathMapping.cpp 
b/clang-tools-extra/clangd/PathMapping.cpp
index 3db9a0c622abe..12eb08a9cdd05 100644
--- a/clang-tools-extra/clangd/PathMapping.cpp
+++ b/clang-tools-extra/clangd/PathMapping.cpp
@@ -37,9 +37,6 @@ std::optional<std::string> doPathMapping(llvm::StringRef S,
   // Convert backslashes to forward slashes.
   std::replace(BodyStr.begin(), BodyStr.end(), '\\', '/');
 
-  // Diagnostic logging to help debug mapping failures. This will show the
-  // normalized body and each mapping attempted.
-  vlog("PathMapping: doPathMapping S={0} normalized_body={1}", S, BodyStr);
 
   // If path starts with /mnt/<drive>/ and later contains an embedded
   // Windows drive fragment like "/C:/", prefer the embedded Windows path.
@@ -69,7 +66,6 @@ std::optional<std::string> doPathMapping(llvm::StringRef S,
   if (Dir == PathMapping::Direction::ClientToServer && DidPreferEmbeddedDrive) 
{
     if (BodyStr.size() >= 3 && BodyStr[0] == '/' &&
         std::isalpha((unsigned char)BodyStr[1]) && BodyStr[2] == ':') {
-      vlog("PathMapping: normalized client->server Windows body={0}", BodyStr);
       return URI((*Uri).scheme(), (*Uri).authority(), BodyStr).toString();
     }
   }
@@ -82,7 +78,6 @@ std::optional<std::string> doPathMapping(llvm::StringRef S,
     const std::string &To = Dir == PathMapping::Direction::ClientToServer
                                 ? Mapping.ServerPath
                                 : Mapping.ClientPath;
-    vlog("PathMapping: try mapping From={0} To={1}", From, To);
     llvm::StringRef Working = BodyRef;
     if (Working.consume_front(From)) {
       // Accept the match if either the mapping 'From' ends with a slash 
(explicit
@@ -113,7 +108,6 @@ std::optional<std::string> doPathMapping(llvm::StringRef S,
           }
         }
         std::string MappedBody = (To + Adjusted).str();
-        vlog("PathMapping: matched From={0} To={1} => MappedBody={2}", From, 
To, MappedBody);
         return URI((*Uri).scheme(), (*Uri).authority(), MappedBody).toString();
       }
     }
@@ -135,14 +129,12 @@ std::optional<std::string> doPathMapping(llvm::StringRef 
S,
         // If Rest begins with '/' or is empty, this is a reasonable match.
         if (Rest.empty() || Rest.front() == '/') {
           std::string MappedBody = (To + Rest).str();
-          vlog("PathMapping: fallback matched From={0} To={1} => 
MappedBody={2}", From, To, MappedBody);
           return URI((*Uri).scheme(), (*Uri).authority(), 
MappedBody).toString();
         }
       }
     }
   }
 
-  vlog("PathMapping: no mapping matched for body={0}", BodyStr);
   return std::nullopt;
 }
 
@@ -185,30 +177,21 @@ class PathMappingMessageHandler : public 
Transport::MessageHandler {
       : WrappedHandler(Handler), Mappings(Mappings) {}
 
   bool onNotify(llvm::StringRef Method, llvm::json::Value Params) override {
-    vlog("PathMapping: inbound onNotify Method={0}", Method);
-    vlog("PathMapping: inbound Params before={0}", Params);
     applyPathMappings(Params, PathMapping::Direction::ClientToServer, 
Mappings);
-    vlog("PathMapping: inbound Params after={0}", Params);
     return WrappedHandler.onNotify(Method, std::move(Params));
   }
 
   bool onCall(llvm::StringRef Method, llvm::json::Value Params,
               llvm::json::Value ID) override {
-    vlog("PathMapping: inbound onCall Method={0}", Method);
-    vlog("PathMapping: inbound Params before={0}", Params);
     applyPathMappings(Params, PathMapping::Direction::ClientToServer, 
Mappings);
-    vlog("PathMapping: inbound Params after={0}", Params);
     return WrappedHandler.onCall(Method, std::move(Params), std::move(ID));
   }
 
   bool onReply(llvm::json::Value ID,
                llvm::Expected<llvm::json::Value> Result) override {
-    vlog("PathMapping: inbound onReply ID={0}", ID);
     if (Result) {
-      vlog("PathMapping: inbound Result before={0}", *Result);
       applyPathMappings(*Result, PathMapping::Direction::ClientToServer,
                         Mappings);
-      vlog("PathMapping: inbound Result after={0}", *Result);
     }
     return WrappedHandler.onReply(std::move(ID), std::move(Result));
   }
@@ -226,30 +209,21 @@ class PathMappingTransport : public Transport {
       : WrappedTransport(std::move(Transp)), Mappings(std::move(Mappings)) {}
 
   void notify(llvm::StringRef Method, llvm::json::Value Params) override {
-    vlog("PathMapping: outbound notify Method={0}", Method);
-    vlog("PathMapping: outbound Params before={0}", Params);
     applyPathMappings(Params, PathMapping::Direction::ServerToClient, 
Mappings);
-    vlog("PathMapping: outbound Params after={0}", Params);
     WrappedTransport->notify(Method, std::move(Params));
   }
 
   void call(llvm::StringRef Method, llvm::json::Value Params,
             llvm::json::Value ID) override {
-    vlog("PathMapping: outbound call Method={0}", Method);
-    vlog("PathMapping: outbound Params before={0}", Params);
     applyPathMappings(Params, PathMapping::Direction::ServerToClient, 
Mappings);
-    vlog("PathMapping: outbound Params after={0}", Params);
     WrappedTransport->call(Method, std::move(Params), std::move(ID));
   }
 
   void reply(llvm::json::Value ID,
              llvm::Expected<llvm::json::Value> Result) override {
-    vlog("PathMapping: outbound reply ID={0}", ID);
     if (Result) {
-      vlog("PathMapping: outbound Result before={0}", *Result);
       applyPathMappings(*Result, PathMapping::Direction::ServerToClient,
                         Mappings);
-      vlog("PathMapping: outbound Result after={0}", *Result);
     }
     WrappedTransport->reply(std::move(ID), std::move(Result));
   }

>From 5a39f260bd15269f71e2189307917ff529962fe3 Mon Sep 17 00:00:00 2001
From: openhands <openha...@all-hands.dev>
Date: Sun, 24 Aug 2025 22:15:27 +0200
Subject: [PATCH 13/14] PathMapping: remove assistant-added comments

---
 clang-tools-extra/clangd/PathMapping.cpp | 88 ++++++++++++------------
 1 file changed, 44 insertions(+), 44 deletions(-)

diff --git a/clang-tools-extra/clangd/PathMapping.cpp 
b/clang-tools-extra/clangd/PathMapping.cpp
index 12eb08a9cdd05..a0242122a1578 100644
--- a/clang-tools-extra/clangd/PathMapping.cpp
+++ b/clang-tools-extra/clangd/PathMapping.cpp
@@ -21,8 +21,8 @@ namespace clangd {
 std::optional<std::string> doPathMapping(llvm::StringRef S,
                                          PathMapping::Direction Dir,
                                          const PathMappings &Mappings) {
-  // Return early to optimize for the common case, wherein S is not a file URI
-  if (!S.starts_with("file://"))
+  
+  if (!S.starts_with("file:
     return std::nullopt;
   auto Uri = URI::parse(S);
   if (!Uri) {
@@ -30,27 +30,27 @@ std::optional<std::string> doPathMapping(llvm::StringRef S,
     return std::nullopt;
   }
 
-  // Normalize the URI body to handle cases where a client mixes WSL and
-  // Windows paths (e.g. "/mnt/c/.../C:/..."), or uses backslashes. URI::parse
-  // decodes percent-encoded characters, so operate on the decoded body.
+  
+  
+  
   std::string BodyStr = (*Uri).body().str();
-  // Convert backslashes to forward slashes.
+  
   std::replace(BodyStr.begin(), BodyStr.end(), '\\', '/');
 
 
-  // If path starts with /mnt/<drive>/ and later contains an embedded
-  // Windows drive fragment like "/C:/", prefer the embedded Windows path.
-  // For incoming client->server URIs, normalize bodies like
-  // "/mnt/c/.../C:/Users/..." to "/C:/Users/..." by chopping everything
-  // before the embedded drive. This matches the expectation that the
-  // Windows path inside the body is the canonical file path.
+  
+  
+  
+  
+  
+  
   bool DidPreferEmbeddedDrive = false;
   if (BodyStr.rfind("/mnt/", 0) == 0 && BodyStr.size() > 6) {
     for (size_t i = 0; i + 2 < BodyStr.size(); ++i) {
       if (std::isalpha((unsigned char)BodyStr[i]) && BodyStr[i + 1] == ':' &&
           BodyStr[i + 2] == '/') {
-        // Found an embedded drive at BodyStr[i]. Normalize to start at that
-        // drive (prepend a leading '/') so the body becomes "/C:/...".
+        
+        
         BodyStr = std::string("/") + BodyStr.substr(i);
         DidPreferEmbeddedDrive = true;
         break;
@@ -58,11 +58,11 @@ std::optional<std::string> doPathMapping(llvm::StringRef S,
     }
   }
 
-  // If we've normalized to a Windows-style drive (e.g. "/C:/...") for an 
incoming
-  // client->server URI that came from an original /mnt/... path, return the
-  // normalized Windows path directly to avoid trying to map from the original
-  // /mnt/ prefix which no longer applies. Do not short-circuit normal incoming
-  // Windows URIs that should still be subject to mappings.
+  
+  
+  
+  
+  
   if (Dir == PathMapping::Direction::ClientToServer && DidPreferEmbeddedDrive) 
{
     if (BodyStr.size() >= 3 && BodyStr[0] == '/' &&
         std::isalpha((unsigned char)BodyStr[1]) && BodyStr[2] == ':') {
@@ -80,17 +80,17 @@ std::optional<std::string> doPathMapping(llvm::StringRef S,
                                 : Mapping.ClientPath;
     llvm::StringRef Working = BodyRef;
     if (Working.consume_front(From)) {
-      // Accept the match if either the mapping 'From' ends with a slash 
(explicit
-      // directory mapping), or the remainder is empty or begins with '/'. This
-      // handles cases like From="/C:/" matching Body="/C:/Users/..." where
-      // consuming From leaves "Users/..." (which does not start with '/').
+      
+      
+      
+      
       if (From.empty() || From.back() == '/' || Working.empty() || 
Working.front() == '/') {
-        // If the remainder contains a duplicated Windows drive fragment (e.g.
-        // "projects/.../C:/Users/..."), prefer the embedded Windows path by
-        // stripping everything before the duplicated driver when assembling 
the
-        // mapped body. This avoids producing "/C:/projects/.../C:/...".
+        
+        
+        
+        
         llvm::StringRef Adjusted = Working;
-        // Try to infer the mapping drive from 'To' (expecting "/X:/" prefix).
+        
         char MappingDrive = 0;
         if (To.size() >= 3 && To[0] == '/' && std::isalpha((unsigned 
char)To[1]) && To[2] == ':')
           MappingDrive = To[1];
@@ -99,8 +99,8 @@ std::optional<std::string> doPathMapping(llvm::StringRef S,
             char c = Working[i];
             if (std::isalpha((unsigned char)c) && Working[i + 1] == ':' && 
Working[i + 2] == '/') {
               if (std::tolower((unsigned char)c) == std::tolower((unsigned 
char)MappingDrive)) {
-                // Strip everything up to and including the duplicated "X:/" so
-                // that appending to To yields "/X:/<rest>" without 
duplication.
+                
+                
                 Adjusted = Working.substr(i + 3);
                 break;
               }
@@ -113,9 +113,9 @@ std::optional<std::string> doPathMapping(llvm::StringRef S,
     }
   }
 
-  // Fallback: sometimes the body starts with a Server-style drive like 
"/C:/..."
-  // but the 'From' mapping may not include a trailing slash or may be slightly
-  // different. Try a relaxed matching pass for Server->Client direction.
+  
+  
+  
   if (Dir == PathMapping::Direction::ServerToClient) {
     for (const auto &Mapping : Mappings) {
       const std::string &From = Mapping.ServerPath;
@@ -123,10 +123,10 @@ std::optional<std::string> doPathMapping(llvm::StringRef 
S,
       if (From.empty())
         continue;
       llvm::StringRef W = BodyRef;
-      // If the body starts with From (allowing missing trailing slash), 
accept it.
+      
       if (W.starts_with(From)) {
         llvm::StringRef Rest = W.substr(From.size());
-        // If Rest begins with '/' or is empty, this is a reasonable match.
+        
         if (Rest.empty() || Rest.front() == '/') {
           std::string MappedBody = (To + Rest).str();
           return URI((*Uri).scheme(), (*Uri).authority(), 
MappedBody).toString();
@@ -145,7 +145,7 @@ void applyPathMappings(llvm::json::Value &V, 
PathMapping::Direction Dir,
   if (K == Kind::Object) {
     llvm::json::Object *Obj = V.getAsObject();
     llvm::json::Object MappedObj;
-    // 1. Map all the Keys
+    
     for (auto &KV : *Obj) {
       if (std::optional<std::string> MappedKey =
               doPathMapping(KV.first.str(), Dir, Mappings)) {
@@ -155,7 +155,7 @@ void applyPathMappings(llvm::json::Value &V, 
PathMapping::Direction Dir,
       }
     }
     *Obj = std::move(MappedObj);
-    // 2. Map all the values
+    
     for (auto &KV : *Obj)
       applyPathMappings(KV.second, Dir, Mappings);
   } else if (K == Kind::Array) {
@@ -201,8 +201,8 @@ class PathMappingMessageHandler : public 
Transport::MessageHandler {
   const PathMappings &Mappings;
 };
 
-// Apply path mappings to all LSP messages by intercepting all params/results
-// and then delegating to the normal transport
+
+
 class PathMappingTransport : public Transport {
 public:
   PathMappingTransport(std::unique_ptr<Transport> Transp, PathMappings 
Mappings)
@@ -238,8 +238,8 @@ class PathMappingTransport : public Transport {
   PathMappings Mappings;
 };
 
-// Converts a unix/windows path to the path portion of a file URI
-// e.g. "C:\foo" -> "/C:/foo"
+
+
 llvm::Expected<std::string> parsePath(llvm::StringRef Path) {
   namespace path = llvm::sys::path;
   if (path::is_absolute(Path, path::Style::posix)) {
@@ -254,7 +254,7 @@ llvm::Expected<std::string> parsePath(llvm::StringRef Path) 
{
   return error("Path not absolute: {0}", Path);
 }
 
-} // namespace
+} 
 
 llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const PathMapping &M) {
   return OS << M.ClientPath << "=" << M.ServerPath;
@@ -287,5 +287,5 @@ createPathMappingTransport(std::unique_ptr<Transport> 
Transp,
   return std::make_unique<PathMappingTransport>(std::move(Transp), Mappings);
 }
 
-} // namespace clangd
-} // namespace clang
+} 
+} 

>From 14bd5780aec547761e6111709b4484709703ec26 Mon Sep 17 00:00:00 2001
From: openhands <openha...@all-hands.dev>
Date: Sun, 24 Aug 2025 22:21:18 +0200
Subject: [PATCH 14/14] Restore PathMapping.cpp to pre-comment-strip state

---
 clang-tools-extra/clangd/PathMapping.cpp | 80 ++++++++----------------
 1 file changed, 25 insertions(+), 55 deletions(-)

diff --git a/clang-tools-extra/clangd/PathMapping.cpp 
b/clang-tools-extra/clangd/PathMapping.cpp
index a0242122a1578..68cdf0e3f037e 100644
--- a/clang-tools-extra/clangd/PathMapping.cpp
+++ b/clang-tools-extra/clangd/PathMapping.cpp
@@ -12,17 +12,17 @@
 #include "llvm/Support/Error.h"
 #include "llvm/Support/Path.h"
 #include <algorithm>
+#include <cctype>
 #include <optional>
 #include <tuple>
-#include <cctype>
 
 namespace clang {
 namespace clangd {
 std::optional<std::string> doPathMapping(llvm::StringRef S,
                                          PathMapping::Direction Dir,
                                          const PathMappings &Mappings) {
-  
-  if (!S.starts_with("file:
+  // Return early to optimize for the common case, wherein S is not a file URI
+  if (!S.starts_with("file://"))
     return std::nullopt;
   auto Uri = URI::parse(S);
   if (!Uri) {
@@ -30,27 +30,14 @@ std::optional<std::string> doPathMapping(llvm::StringRef S,
     return std::nullopt;
   }
 
-  
-  
-  
   std::string BodyStr = (*Uri).body().str();
-  
   std::replace(BodyStr.begin(), BodyStr.end(), '\\', '/');
 
-
-  
-  
-  
-  
-  
-  
   bool DidPreferEmbeddedDrive = false;
   if (BodyStr.rfind("/mnt/", 0) == 0 && BodyStr.size() > 6) {
     for (size_t i = 0; i + 2 < BodyStr.size(); ++i) {
       if (std::isalpha((unsigned char)BodyStr[i]) && BodyStr[i + 1] == ':' &&
           BodyStr[i + 2] == '/') {
-        
-        
         BodyStr = std::string("/") + BodyStr.substr(i);
         DidPreferEmbeddedDrive = true;
         break;
@@ -58,11 +45,6 @@ std::optional<std::string> doPathMapping(llvm::StringRef S,
     }
   }
 
-  
-  
-  
-  
-  
   if (Dir == PathMapping::Direction::ClientToServer && DidPreferEmbeddedDrive) 
{
     if (BodyStr.size() >= 3 && BodyStr[0] == '/' &&
         std::isalpha((unsigned char)BodyStr[1]) && BodyStr[2] == ':') {
@@ -80,27 +62,21 @@ std::optional<std::string> doPathMapping(llvm::StringRef S,
                                 : Mapping.ClientPath;
     llvm::StringRef Working = BodyRef;
     if (Working.consume_front(From)) {
-      
-      
-      
-      
-      if (From.empty() || From.back() == '/' || Working.empty() || 
Working.front() == '/') {
-        
-        
-        
-        
+      if (From.empty() || From.back() == '/' || Working.empty() ||
+          Working.front() == '/') {
         llvm::StringRef Adjusted = Working;
-        
+
         char MappingDrive = 0;
-        if (To.size() >= 3 && To[0] == '/' && std::isalpha((unsigned 
char)To[1]) && To[2] == ':')
+        if (To.size() >= 3 && To[0] == '/' &&
+            std::isalpha((unsigned char)To[1]) && To[2] == ':')
           MappingDrive = To[1];
         if (MappingDrive) {
           for (size_t i = 0; i + 2 < (size_t)Working.size(); ++i) {
             char c = Working[i];
-            if (std::isalpha((unsigned char)c) && Working[i + 1] == ':' && 
Working[i + 2] == '/') {
-              if (std::tolower((unsigned char)c) == std::tolower((unsigned 
char)MappingDrive)) {
-                
-                
+            if (std::isalpha((unsigned char)c) && Working[i + 1] == ':' &&
+                Working[i + 2] == '/') {
+              if (std::tolower((unsigned char)c) ==
+                  std::tolower((unsigned char)MappingDrive)) {
                 Adjusted = Working.substr(i + 3);
                 break;
               }
@@ -113,9 +89,6 @@ std::optional<std::string> doPathMapping(llvm::StringRef S,
     }
   }
 
-  
-  
-  
   if (Dir == PathMapping::Direction::ServerToClient) {
     for (const auto &Mapping : Mappings) {
       const std::string &From = Mapping.ServerPath;
@@ -123,13 +96,12 @@ std::optional<std::string> doPathMapping(llvm::StringRef S,
       if (From.empty())
         continue;
       llvm::StringRef W = BodyRef;
-      
       if (W.starts_with(From)) {
         llvm::StringRef Rest = W.substr(From.size());
-        
         if (Rest.empty() || Rest.front() == '/') {
           std::string MappedBody = (To + Rest).str();
-          return URI((*Uri).scheme(), (*Uri).authority(), 
MappedBody).toString();
+          return URI((*Uri).scheme(), (*Uri).authority(), MappedBody)
+              .toString();
         }
       }
     }
@@ -145,7 +117,7 @@ void applyPathMappings(llvm::json::Value &V, 
PathMapping::Direction Dir,
   if (K == Kind::Object) {
     llvm::json::Object *Obj = V.getAsObject();
     llvm::json::Object MappedObj;
-    
+    // 1. Map all the Keys
     for (auto &KV : *Obj) {
       if (std::optional<std::string> MappedKey =
               doPathMapping(KV.first.str(), Dir, Mappings)) {
@@ -155,7 +127,7 @@ void applyPathMappings(llvm::json::Value &V, 
PathMapping::Direction Dir,
       }
     }
     *Obj = std::move(MappedObj);
-    
+    // 2. Map all the values
     for (auto &KV : *Obj)
       applyPathMappings(KV.second, Dir, Mappings);
   } else if (K == Kind::Array) {
@@ -189,10 +161,9 @@ class PathMappingMessageHandler : public 
Transport::MessageHandler {
 
   bool onReply(llvm::json::Value ID,
                llvm::Expected<llvm::json::Value> Result) override {
-    if (Result) {
+    if (Result)
       applyPathMappings(*Result, PathMapping::Direction::ClientToServer,
                         Mappings);
-    }
     return WrappedHandler.onReply(std::move(ID), std::move(Result));
   }
 
@@ -201,8 +172,8 @@ class PathMappingMessageHandler : public 
Transport::MessageHandler {
   const PathMappings &Mappings;
 };
 
-
-
+// Apply path mappings to all LSP messages by intercepting all params/results
+// and then delegating to the normal transport
 class PathMappingTransport : public Transport {
 public:
   PathMappingTransport(std::unique_ptr<Transport> Transp, PathMappings 
Mappings)
@@ -221,10 +192,9 @@ class PathMappingTransport : public Transport {
 
   void reply(llvm::json::Value ID,
              llvm::Expected<llvm::json::Value> Result) override {
-    if (Result) {
+    if (Result)
       applyPathMappings(*Result, PathMapping::Direction::ServerToClient,
                         Mappings);
-    }
     WrappedTransport->reply(std::move(ID), std::move(Result));
   }
 
@@ -238,8 +208,8 @@ class PathMappingTransport : public Transport {
   PathMappings Mappings;
 };
 
-
-
+// Converts a unix/windows path to the path portion of a file URI
+// e.g. "C:\foo" -> "/C:/foo"
 llvm::Expected<std::string> parsePath(llvm::StringRef Path) {
   namespace path = llvm::sys::path;
   if (path::is_absolute(Path, path::Style::posix)) {
@@ -254,7 +224,7 @@ llvm::Expected<std::string> parsePath(llvm::StringRef Path) 
{
   return error("Path not absolute: {0}", Path);
 }
 
-} 
+} // namespace
 
 llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const PathMapping &M) {
   return OS << M.ClientPath << "=" << M.ServerPath;
@@ -287,5 +257,5 @@ createPathMappingTransport(std::unique_ptr<Transport> 
Transp,
   return std::make_unique<PathMappingTransport>(std::move(Transp), Mappings);
 }
 
-} 
-} 
+} // namespace clangd
+} // namespace clang

_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to