[Mlir-commits] [llvm] [mlir] [mlir][lsp] Use rootUri and rootPath for source files (PR #185479)

Jacques Pienaar llvmlistbot at llvm.org
Mon Apr 6 22:55:31 PDT 2026


https://github.com/jpienaar updated https://github.com/llvm/llvm-project/pull/185479

>From d58ffb0f1d361c01b3214baeb50cf8b255870ace Mon Sep 17 00:00:00 2001
From: Jacques Pienaar <jacques+gh at japienaar.info>
Date: Mon, 9 Mar 2026 17:47:20 +0000
Subject: [PATCH 1/4] [mlir][lsp] Use rootUri and rootPath for source files

When looking up source files, consider the rootUri and rootPath (if set)
and filename is non local path.
---
 llvm/include/llvm/Support/LSP/Protocol.h      |  7 ++
 llvm/lib/Support/LSP/Protocol.cpp             |  2 +
 mlir/lib/Tools/mlir-lsp-server/LSPServer.cpp  | 11 +++
 mlir/lib/Tools/mlir-lsp-server/MLIRServer.cpp | 89 +++++++++++++------
 mlir/lib/Tools/mlir-lsp-server/MLIRServer.h   |  3 +
 .../mlir-lsp-server/rooturi_rel_path.test     | 35 ++++++++
 6 files changed, 119 insertions(+), 28 deletions(-)
 create mode 100644 mlir/test/mlir-lsp-server/rooturi_rel_path.test

diff --git a/llvm/include/llvm/Support/LSP/Protocol.h b/llvm/include/llvm/Support/LSP/Protocol.h
index a75ac291d1bcc..f4cb879f77bd3 100644
--- a/llvm/include/llvm/Support/LSP/Protocol.h
+++ b/llvm/include/llvm/Support/LSP/Protocol.h
@@ -215,6 +215,13 @@ struct InitializeParams {
 
   /// The initial trace setting. If omitted trace is disabled ('off').
   std::optional<TraceLevel> trace;
+
+  /// The root URI of the workspace. Is null if no folder is open.
+  std::optional<std::string> rootUri;
+
+  /// The root path of the workspace. Is null if no folder is open.
+  /// This is deprecated, use rootUri instead, but kept for more compatibility.
+  std::optional<std::string> rootPath;
 };
 
 /// Add support for JSON serialization.
diff --git a/llvm/lib/Support/LSP/Protocol.cpp b/llvm/lib/Support/LSP/Protocol.cpp
index 5c2379431e900..c1abdb0f4d732 100644
--- a/llvm/lib/Support/LSP/Protocol.cpp
+++ b/llvm/lib/Support/LSP/Protocol.cpp
@@ -335,6 +335,8 @@ bool llvm::lsp::fromJSON(const llvm::json::Value &Value,
   // We deliberately don't fail if we can't parse individual fields.
   O.map("capabilities", Result.capabilities);
   O.map("trace", Result.trace);
+  O.map("rootUri", Result.rootUri);
+  O.map("rootPath", Result.rootPath);
   mapOptOrNull(Value, "clientInfo", Result.clientInfo, Path);
 
   return true;
diff --git a/mlir/lib/Tools/mlir-lsp-server/LSPServer.cpp b/mlir/lib/Tools/mlir-lsp-server/LSPServer.cpp
index 1bbbcdecb57af..73ebe6a6b1f09 100644
--- a/mlir/lib/Tools/mlir-lsp-server/LSPServer.cpp
+++ b/mlir/lib/Tools/mlir-lsp-server/LSPServer.cpp
@@ -130,6 +130,17 @@ struct LSPServer {
 
 void LSPServer::onInitialize(const InitializeParams &params,
                              Callback<llvm::json::Value> reply) {
+  // Configure the workspace root if it was provided.
+  if (params.rootUri) {
+    llvm::Expected<URIForFile> rootURI = URIForFile::fromURI(*params.rootUri);
+    if (rootURI)
+      server.setWorkspaceRoot(rootURI->file());
+    else
+      consumeError(rootURI.takeError());
+  } else if (params.rootPath) {
+    server.setWorkspaceRoot(*params.rootPath);
+  }
+
   // Send a response with the capabilities of this server.
   llvm::json::Object serverCaps{
       {"textDocumentSync",
diff --git a/mlir/lib/Tools/mlir-lsp-server/MLIRServer.cpp b/mlir/lib/Tools/mlir-lsp-server/MLIRServer.cpp
index 05ab4fb4f07cd..f5a5c538d5ba5 100644
--- a/mlir/lib/Tools/mlir-lsp-server/MLIRServer.cpp
+++ b/mlir/lib/Tools/mlir-lsp-server/MLIRServer.cpp
@@ -20,6 +20,7 @@
 #include "llvm/ADT/StringExtras.h"
 #include "llvm/Support/Base64.h"
 #include "llvm/Support/LSP/Logging.h"
+#include "llvm/Support/Path.h"
 #include "llvm/Support/SourceMgr.h"
 #include <optional>
 
@@ -34,14 +35,21 @@ static SMRange convertTokenLocToRange(SMLoc loc) {
 
 /// Returns a language server location from the given MLIR file location.
 /// `uriScheme` is the scheme to use when building new uris.
-static std::optional<lsp::Location> getLocationFromLoc(StringRef uriScheme,
-                                                       FileLineColLoc loc) {
+static std::optional<lsp::Location>
+getLocationFromLoc(StringRef uriScheme, FileLineColLoc loc,
+                   StringRef workspaceRoot) {
+  StringRef filename = loc.getFilename();
+  SmallString<128> absPath;
+  if (!llvm::sys::path::is_absolute(filename) && !workspaceRoot.empty()) {
+    llvm::sys::path::append(absPath, workspaceRoot, filename);
+    filename = absPath;
+  }
+
   llvm::Expected<lsp::URIForFile> sourceURI =
-      lsp::URIForFile::fromFile(loc.getFilename(), uriScheme);
+      lsp::URIForFile::fromFile(filename, uriScheme);
   if (!sourceURI) {
     llvm::lsp::Logger::error("Failed to create URI for file `{0}`: {1}",
-                             loc.getFilename(),
-                             llvm::toString(sourceURI.takeError()));
+                             filename, llvm::toString(sourceURI.takeError()));
     return std::nullopt;
   }
 
@@ -57,15 +65,16 @@ static std::optional<lsp::Location> getLocationFromLoc(StringRef uriScheme,
 /// present, is used to filter sub locations that do not share the same uri.
 static std::optional<lsp::Location>
 getLocationFromLoc(llvm::SourceMgr &sourceMgr, Location loc,
-                   StringRef uriScheme, const lsp::URIForFile *uri = nullptr) {
+                   StringRef uriScheme, StringRef workspaceRoot,
+                   const lsp::URIForFile *uri = nullptr) {
   std::optional<lsp::Location> location;
   loc->walk([&](Location nestedLoc) {
-    FileLineColLoc fileLoc = dyn_cast<FileLineColLoc>(nestedLoc);
+    auto fileLoc = dyn_cast<FileLineColLoc>(nestedLoc);
     if (!fileLoc)
       return WalkResult::advance();
 
     std::optional<lsp::Location> sourceLoc =
-        getLocationFromLoc(uriScheme, fileLoc);
+        getLocationFromLoc(uriScheme, fileLoc, workspaceRoot);
     if (sourceLoc && (!uri || sourceLoc->uri == *uri)) {
       location = *sourceLoc;
       SMLoc loc = sourceMgr.FindLocForLineAndColumn(
@@ -90,7 +99,8 @@ getLocationFromLoc(llvm::SourceMgr &sourceMgr, Location loc,
 /// contained within the given URI.
 static void collectLocationsFromLoc(Location loc,
                                     std::vector<lsp::Location> &locations,
-                                    const lsp::URIForFile &uri) {
+                                    const lsp::URIForFile &uri,
+                                    StringRef workspaceRoot) {
   SetVector<Location> visitedLocs;
   loc->walk([&](Location nestedLoc) {
     FileLineColLoc fileLoc = dyn_cast<FileLineColLoc>(nestedLoc);
@@ -98,7 +108,7 @@ static void collectLocationsFromLoc(Location loc,
       return WalkResult::advance();
 
     std::optional<lsp::Location> sourceLoc =
-        getLocationFromLoc(uri.scheme(), fileLoc);
+        getLocationFromLoc(uri.scheme(), fileLoc, workspaceRoot);
     if (sourceLoc && sourceLoc->uri != uri)
       locations.push_back(*sourceLoc);
     return WalkResult::advance();
@@ -193,7 +203,8 @@ static void printDefBlockName(raw_ostream &os,
 /// Convert the given MLIR diagnostic to the LSP form.
 static lsp::Diagnostic getLspDiagnoticFromDiag(llvm::SourceMgr &sourceMgr,
                                                Diagnostic &diag,
-                                               const lsp::URIForFile &uri) {
+                                               const lsp::URIForFile &uri,
+                                               StringRef workspaceRoot) {
   lsp::Diagnostic lspDiag;
   lspDiag.source = "mlir";
 
@@ -205,8 +216,8 @@ static lsp::Diagnostic getLspDiagnoticFromDiag(llvm::SourceMgr &sourceMgr,
   // TODO: For simplicity, we just grab the first one. It may be likely that we
   // will need a more interesting heuristic here.'
   StringRef uriScheme = uri.scheme();
-  std::optional<lsp::Location> lspLocation =
-      getLocationFromLoc(sourceMgr, diag.getLocation(), uriScheme, &uri);
+  std::optional<lsp::Location> lspLocation = getLocationFromLoc(
+      sourceMgr, diag.getLocation(), uriScheme, workspaceRoot, &uri);
   if (lspLocation)
     lspDiag.range = lspLocation->range;
 
@@ -230,8 +241,8 @@ static lsp::Diagnostic getLspDiagnoticFromDiag(llvm::SourceMgr &sourceMgr,
   std::vector<llvm::lsp::DiagnosticRelatedInformation> relatedDiags;
   for (Diagnostic &note : diag.getNotes()) {
     lsp::Location noteLoc;
-    if (std::optional<lsp::Location> loc =
-            getLocationFromLoc(sourceMgr, note.getLocation(), uriScheme))
+    if (std::optional<lsp::Location> loc = getLocationFromLoc(
+            sourceMgr, note.getLocation(), uriScheme, workspaceRoot))
       noteLoc = *loc;
     else
       noteLoc.uri = uri;
@@ -252,7 +263,8 @@ namespace {
 /// document.
 struct MLIRDocument {
   MLIRDocument(MLIRContext &context, const lsp::URIForFile &uri,
-               StringRef contents, std::vector<lsp::Diagnostic> &diagnostics);
+               StringRef contents, StringRef workspaceRoot,
+               std::vector<lsp::Diagnostic> &diagnostics);
   MLIRDocument(const MLIRDocument &) = delete;
   MLIRDocument &operator=(const MLIRDocument &) = delete;
 
@@ -337,14 +349,19 @@ struct MLIRDocument {
 
   /// The source manager containing the contents of the input file.
   llvm::SourceMgr sourceMgr;
+
+  /// The workspace root of the server.
+  std::string workspaceRoot;
 };
 } // namespace
 
 MLIRDocument::MLIRDocument(MLIRContext &context, const lsp::URIForFile &uri,
-                           StringRef contents,
-                           std::vector<lsp::Diagnostic> &diagnostics) {
+                           StringRef contents, StringRef workspaceRoot,
+                           std::vector<lsp::Diagnostic> &diagnostics)
+    : workspaceRoot(workspaceRoot.str()) {
   ScopedDiagnosticHandler handler(&context, [&](Diagnostic &diag) {
-    diagnostics.push_back(getLspDiagnoticFromDiag(sourceMgr, diag, uri));
+    diagnostics.push_back(
+        getLspDiagnoticFromDiag(sourceMgr, diag, uri, workspaceRoot));
   });
 
   // Try to parsed the given IR string.
@@ -387,14 +404,17 @@ void MLIRDocument::getLocationsOf(const lsp::URIForFile &uri,
   // Check all definitions related to operations.
   for (const AsmParserState::OperationDefinition &op : asmState.getOpDefs()) {
     if (contains(op.loc, posLoc))
-      return collectLocationsFromLoc(op.op->getLoc(), locations, uri);
+      return collectLocationsFromLoc(op.op->getLoc(), locations, uri,
+                                     workspaceRoot);
     for (const auto &result : op.resultGroups)
       if (containsPosition(result.definition))
-        return collectLocationsFromLoc(op.op->getLoc(), locations, uri);
+        return collectLocationsFromLoc(op.op->getLoc(), locations, uri,
+                                       workspaceRoot);
     for (const auto &symUse : op.symbolUses) {
       if (contains(symUse, posLoc)) {
         locations.emplace_back(uri, sourceMgr, op.loc);
-        return collectLocationsFromLoc(op.op->getLoc(), locations, uri);
+        return collectLocationsFromLoc(op.op->getLoc(), locations, uri,
+                                       workspaceRoot);
       }
     }
   }
@@ -968,8 +988,10 @@ namespace {
 struct MLIRTextFileChunk {
   MLIRTextFileChunk(MLIRContext &context, uint64_t lineOffset,
                     const lsp::URIForFile &uri, StringRef contents,
+                    StringRef workspaceRoot,
                     std::vector<lsp::Diagnostic> &diagnostics)
-      : lineOffset(lineOffset), document(context, uri, contents, diagnostics) {}
+      : lineOffset(lineOffset),
+        document(context, uri, contents, workspaceRoot, diagnostics) {}
 
   /// Adjust the line number of the given range to anchor at the beginning of
   /// the file, instead of the beginning of this chunk.
@@ -998,6 +1020,7 @@ class MLIRTextFile {
 public:
   MLIRTextFile(const lsp::URIForFile &uri, StringRef fileContents,
                int64_t version, lsp::DialectRegistryFn registryFn,
+               StringRef workspaceRoot,
                std::vector<lsp::Diagnostic> &diagnostics);
 
   /// Return the current version of this text file.
@@ -1047,6 +1070,7 @@ class MLIRTextFile {
 
 MLIRTextFile::MLIRTextFile(const lsp::URIForFile &uri, StringRef fileContents,
                            int64_t version, lsp::DialectRegistryFn registryFn,
+                           StringRef workspaceRoot,
                            std::vector<lsp::Diagnostic> &diagnostics)
     : context(registryFn(uri), MLIRContext::Threading::DISABLED),
       contents(fileContents.str()), version(version) {
@@ -1056,13 +1080,14 @@ MLIRTextFile::MLIRTextFile(const lsp::URIForFile &uri, StringRef fileContents,
   SmallVector<StringRef, 8> subContents;
   StringRef(contents).split(subContents, kDefaultSplitMarker);
   chunks.emplace_back(std::make_unique<MLIRTextFileChunk>(
-      context, /*lineOffset=*/0, uri, subContents.front(), diagnostics));
+      context, /*lineOffset=*/0, uri, subContents.front(), workspaceRoot,
+      diagnostics));
 
   uint64_t lineOffset = subContents.front().count('\n');
   for (StringRef docContents : llvm::drop_begin(subContents)) {
     unsigned currentNumDiags = diagnostics.size();
-    auto chunk = std::make_unique<MLIRTextFileChunk>(context, lineOffset, uri,
-                                                     docContents, diagnostics);
+    auto chunk = std::make_unique<MLIRTextFileChunk>(
+        context, lineOffset, uri, docContents, workspaceRoot, diagnostics);
     lineOffset += docContents.count('\n');
 
     // Adjust locations used in diagnostics to account for the offset from the
@@ -1271,6 +1296,9 @@ struct lsp::MLIRServer::Impl {
 
   /// The files held by the server, mapped by their URI file name.
   llvm::StringMap<std::unique_ptr<MLIRTextFile>> files;
+
+  /// The workspace root of the server.
+  std::string workspaceRoot;
 };
 
 //===----------------------------------------------------------------------===//
@@ -1284,8 +1312,9 @@ lsp::MLIRServer::~MLIRServer() = default;
 void lsp::MLIRServer::addOrUpdateDocument(
     const URIForFile &uri, StringRef contents, int64_t version,
     std::vector<llvm::lsp::Diagnostic> &diagnostics) {
-  impl->files[uri.file()] = std::make_unique<MLIRTextFile>(
-      uri, contents, version, impl->registryFn, diagnostics);
+  impl->files[uri.file()] =
+      std::make_unique<MLIRTextFile>(uri, contents, version, impl->registryFn,
+                                     impl->workspaceRoot, diagnostics);
 }
 
 std::optional<int64_t> lsp::MLIRServer::removeDocument(const URIForFile &uri) {
@@ -1407,3 +1436,7 @@ lsp::MLIRServer::convertToBytecode(const URIForFile &uri) {
   }
   return fileIt->second->convertToBytecode();
 }
+
+void lsp::MLIRServer::setWorkspaceRoot(StringRef root) {
+  impl->workspaceRoot = root.str();
+}
diff --git a/mlir/lib/Tools/mlir-lsp-server/MLIRServer.h b/mlir/lib/Tools/mlir-lsp-server/MLIRServer.h
index 31a01fec8bbc9..aafe36ba82e0e 100644
--- a/mlir/lib/Tools/mlir-lsp-server/MLIRServer.h
+++ b/mlir/lib/Tools/mlir-lsp-server/MLIRServer.h
@@ -87,6 +87,9 @@ class MLIRServer {
   llvm::Expected<MLIRConvertBytecodeResult>
   convertToBytecode(const URIForFile &uri);
 
+  /// Set the workspace root for the server.
+  void setWorkspaceRoot(StringRef root);
+
 private:
   struct Impl;
 
diff --git a/mlir/test/mlir-lsp-server/rooturi_rel_path.test b/mlir/test/mlir-lsp-server/rooturi_rel_path.test
new file mode 100644
index 0000000000000..a80dea4698a9d
--- /dev/null
+++ b/mlir/test/mlir-lsp-server/rooturi_rel_path.test
@@ -0,0 +1,35 @@
+// RUN: mlir-lsp-server -lit-test < %s | FileCheck -strict-whitespace %s
+{"jsonrpc":"2.0","id":0,"method":"initialize","params":{"processId":123,"rootUri":"test://root/","capabilities":{},"trace":"off"}}
+// -----
+{"jsonrpc":"2.0","method":"textDocument/didOpen","params":{"textDocument":{
+  "uri":"test:///foo.mlir",
+  "languageId":"mlir",
+  "version":1,
+  "text":"func.func @foo() {\n  %0 = arith.constant true loc(\"indexer.cc\":10:10)\n  return\n}"
+}}}
+// -----
+{"jsonrpc":"2.0","id":1,"method":"textDocument/definition","params":{
+  "textDocument":{"uri":"test:///foo.mlir"},
+  "position":{"line":1,"character":12}
+}}
+//      CHECK:  "id": 1
+// CHECK-NEXT:  "jsonrpc": "2.0",
+// CHECK-NEXT:  "result": [
+// CHECK-NEXT:    {
+// CHECK-NEXT:      "range": {
+// CHECK-NEXT:        "end": {
+// CHECK-NEXT:          "character": 9,
+// CHECK-NEXT:          "line": 9
+// CHECK-NEXT:        },
+// CHECK-NEXT:        "start": {
+// CHECK-NEXT:          "character": 9,
+// CHECK-NEXT:          "line": 9
+// CHECK-NEXT:        }
+// CHECK-NEXT:      },
+// CHECK-NEXT:      "uri": "test://root/indexer.cc"
+// CHECK-NEXT:    }
+// CHECK-NEXT:  ]
+// -----
+{"jsonrpc":"2.0","id":3,"method":"shutdown"}
+// -----
+{"jsonrpc":"2.0","method":"exit"}

>From 94f1047874028480651e00120314ef2eb75cdcb7 Mon Sep 17 00:00:00 2001
From: Jacques Pienaar <jacques+gh at japienaar.info>
Date: Tue, 7 Apr 2026 04:13:17 +0000
Subject: [PATCH 2/4] Attempt fixing file uri failure

---
 mlir/test/mlir-lsp-server/rooturi_rel_path.test | 4 ++--
 mlir/utils/vscode/package.json                  | 2 +-
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/mlir/test/mlir-lsp-server/rooturi_rel_path.test b/mlir/test/mlir-lsp-server/rooturi_rel_path.test
index a80dea4698a9d..a825507957c2e 100644
--- a/mlir/test/mlir-lsp-server/rooturi_rel_path.test
+++ b/mlir/test/mlir-lsp-server/rooturi_rel_path.test
@@ -1,5 +1,5 @@
 // RUN: mlir-lsp-server -lit-test < %s | FileCheck -strict-whitespace %s
-{"jsonrpc":"2.0","id":0,"method":"initialize","params":{"processId":123,"rootUri":"test://root/","capabilities":{},"trace":"off"}}
+{"jsonrpc":"2.0","id":0,"method":"initialize","params":{"processId":123,"rootUri":"test:///root/","capabilities":{},"trace":"off"}}
 // -----
 {"jsonrpc":"2.0","method":"textDocument/didOpen","params":{"textDocument":{
   "uri":"test:///foo.mlir",
@@ -26,7 +26,7 @@
 // CHECK-NEXT:          "line": 9
 // CHECK-NEXT:        }
 // CHECK-NEXT:      },
-// CHECK-NEXT:      "uri": "test://root/indexer.cc"
+// CHECK-NEXT:      "uri": "test:///root/indexer.cc"
 // CHECK-NEXT:    }
 // CHECK-NEXT:  ]
 // -----
diff --git a/mlir/utils/vscode/package.json b/mlir/utils/vscode/package.json
index c52da0af1b18b..6b9b35a30f27d 100644
--- a/mlir/utils/vscode/package.json
+++ b/mlir/utils/vscode/package.json
@@ -2,7 +2,7 @@
   "name": "vscode-mlir",
   "displayName": "MLIR",
   "description": "MLIR Language Extension",
-  "version": "0.0.14",
+  "version": "0.0.15",
   "publisher": "llvm-vs-code-extensions",
   "homepage": "https://mlir.llvm.org/",
   "icon": "icon.png",

>From ce51da33fea107cd0a1ca2fb19cebaf6f9e53eb7 Mon Sep 17 00:00:00 2001
From: Jacques Pienaar <jacques+gh at japienaar.info>
Date: Tue, 7 Apr 2026 04:58:54 +0000
Subject: [PATCH 3/4] Make path explicitly absolute

---
 mlir/lib/Tools/mlir-lsp-server/MLIRServer.cpp | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/mlir/lib/Tools/mlir-lsp-server/MLIRServer.cpp b/mlir/lib/Tools/mlir-lsp-server/MLIRServer.cpp
index f5a5c538d5ba5..cef47ba38f588 100644
--- a/mlir/lib/Tools/mlir-lsp-server/MLIRServer.cpp
+++ b/mlir/lib/Tools/mlir-lsp-server/MLIRServer.cpp
@@ -19,6 +19,7 @@
 #include "mlir/Tools/lsp-server-support/SourceMgrUtils.h"
 #include "llvm/ADT/StringExtras.h"
 #include "llvm/Support/Base64.h"
+#include "llvm/Support/FileSystem.h"
 #include "llvm/Support/LSP/Logging.h"
 #include "llvm/Support/Path.h"
 #include "llvm/Support/SourceMgr.h"
@@ -42,6 +43,7 @@ getLocationFromLoc(StringRef uriScheme, FileLineColLoc loc,
   SmallString<128> absPath;
   if (!llvm::sys::path::is_absolute(filename) && !workspaceRoot.empty()) {
     llvm::sys::path::append(absPath, workspaceRoot, filename);
+    llvm::sys::fs::make_absolute(absPath);
     filename = absPath;
   }
 

>From af3c41569bb4de1e58cb26036f10b41ed0bd7995 Mon Sep 17 00:00:00 2001
From: Jacques Pienaar <jacques+gh at japienaar.info>
Date: Tue, 7 Apr 2026 05:50:47 +0000
Subject: [PATCH 4/4] Address matching given explicit path

---
 mlir/lib/Tools/mlir-lsp-server/MLIRServer.cpp   | 8 ++++++--
 mlir/test/mlir-lsp-server/diagnostics.test      | 4 ++--
 mlir/test/mlir-lsp-server/rooturi_rel_path.test | 2 +-
 3 files changed, 9 insertions(+), 5 deletions(-)

diff --git a/mlir/lib/Tools/mlir-lsp-server/MLIRServer.cpp b/mlir/lib/Tools/mlir-lsp-server/MLIRServer.cpp
index cef47ba38f588..d2bebdbdabd0c 100644
--- a/mlir/lib/Tools/mlir-lsp-server/MLIRServer.cpp
+++ b/mlir/lib/Tools/mlir-lsp-server/MLIRServer.cpp
@@ -41,8 +41,12 @@ getLocationFromLoc(StringRef uriScheme, FileLineColLoc loc,
                    StringRef workspaceRoot) {
   StringRef filename = loc.getFilename();
   SmallString<128> absPath;
-  if (!llvm::sys::path::is_absolute(filename) && !workspaceRoot.empty()) {
-    llvm::sys::path::append(absPath, workspaceRoot, filename);
+  // Always make the path absolute.
+  if (!llvm::sys::path::is_absolute(filename)) {
+    if (!workspaceRoot.empty())
+      llvm::sys::path::append(absPath, workspaceRoot, filename);
+    else
+      absPath = filename;
     llvm::sys::fs::make_absolute(absPath);
     filename = absPath;
   }
diff --git a/mlir/test/mlir-lsp-server/diagnostics.test b/mlir/test/mlir-lsp-server/diagnostics.test
index 99edd11b574f5..25c57ba531f3b 100644
--- a/mlir/test/mlir-lsp-server/diagnostics.test
+++ b/mlir/test/mlir-lsp-server/diagnostics.test
@@ -27,7 +27,7 @@
 // CHECK-NEXT:         "source": "mlir"
 // CHECK-NEXT:       }
 // CHECK-NEXT:     ],
-// CHECK-NEXT:     "uri": "test:///foo.mlir",
+// CHECK-NEXT:     "uri": "test:///{{([a-zA-Z]:/)?}}foo.mlir",
 // CHECK-NEXT:     "version": 1
 // CHECK-NEXT:   }
 // -----
@@ -57,7 +57,7 @@
 // CHECK-NEXT:         "source": "mlir"
 // CHECK-NEXT:       }
 // CHECK-NEXT:     ],
-// CHECK-NEXT:     "uri": "test:///foo.mlir",
+// CHECK-NEXT:     "uri": "test:///{{([a-zA-Z]:/)?}}foo.mlir",
 // CHECK-NEXT:     "version": 1
 // CHECK-NEXT:   }
 // -----
diff --git a/mlir/test/mlir-lsp-server/rooturi_rel_path.test b/mlir/test/mlir-lsp-server/rooturi_rel_path.test
index a825507957c2e..14dc7c192ed9b 100644
--- a/mlir/test/mlir-lsp-server/rooturi_rel_path.test
+++ b/mlir/test/mlir-lsp-server/rooturi_rel_path.test
@@ -26,7 +26,7 @@
 // CHECK-NEXT:          "line": 9
 // CHECK-NEXT:        }
 // CHECK-NEXT:      },
-// CHECK-NEXT:      "uri": "test:///root/indexer.cc"
+// CHECK-NEXT:      "uri": "test:///{{([a-zA-Z]:/)?}}root/indexer.cc"
 // CHECK-NEXT:    }
 // CHECK-NEXT:  ]
 // -----



More information about the Mlir-commits mailing list