ioeric created this revision.
ioeric added reviewers: sammccall, malaperle.
Herald added subscribers: cfe-commits, jkorous, MaskRay, ilya-biryukov.

Some URI schemes require a hint path to be provided, and workspace root
path seems to be a good fit.


Repository:
  rCTE Clang Tools Extra

https://reviews.llvm.org/D48290

Files:
  clangd/ClangdServer.cpp
  clangd/FindSymbols.cpp
  clangd/FindSymbols.h
  unittests/clangd/FileIndexTests.cpp
  unittests/clangd/FindSymbolsTests.cpp
  unittests/clangd/SymbolCollectorTests.cpp
  unittests/clangd/TestFS.cpp

Index: unittests/clangd/TestFS.cpp
===================================================================
--- unittests/clangd/TestFS.cpp
+++ unittests/clangd/TestFS.cpp
@@ -66,7 +66,8 @@
   return Path.str();
 }
 
-/// unittest: is a scheme that refers to files relative to testRoot()
+/// unittest: is a scheme that refers to files relative to testRoot().
+/// URI body is relative path to testRoot().
 class TestScheme : public URIScheme {
 public:
   static const char *Scheme;
@@ -89,7 +90,7 @@
           llvm::inconvertibleErrorCode());
 
     return URI(Scheme, /*Authority=*/"",
-               llvm::sys::path::convert_to_slash(Body));
+               StringRef(llvm::sys::path::convert_to_slash(Body)).ltrim('/'));
   }
 };
 
Index: unittests/clangd/SymbolCollectorTests.cpp
===================================================================
--- unittests/clangd/SymbolCollectorTests.cpp
+++ unittests/clangd/SymbolCollectorTests.cpp
@@ -379,7 +379,7 @@
   TestFileName = testPath("x.cpp");
   runSymbolCollector("class Foo {};", /*Main=*/"");
   EXPECT_THAT(Symbols, UnorderedElementsAre(
-                           AllOf(QName("Foo"), DeclURI("unittest:///x.h"))));
+                           AllOf(QName("Foo"), DeclURI("unittest:x.h"))));
 }
 
 TEST_F(SymbolCollectorTest, InvalidURIScheme) {
Index: unittests/clangd/FindSymbolsTests.cpp
===================================================================
--- unittests/clangd/FindSymbolsTests.cpp
+++ unittests/clangd/FindSymbolsTests.cpp
@@ -40,13 +40,18 @@
 ClangdServer::Options optsForTests() {
   auto ServerOpts = ClangdServer::optsForTest();
   ServerOpts.BuildDynamicSymbolIndex = true;
+  ServerOpts.URISchemes = {"unittest", "file"};
   return ServerOpts;
 }
 
 class WorkspaceSymbolsTest : public ::testing::Test {
 public:
   WorkspaceSymbolsTest()
-      : Server(CDB, FSProvider, DiagConsumer, optsForTests()) {}
+      : Server(CDB, FSProvider, DiagConsumer, optsForTests()) {
+    // Make sure the test root directory is created.
+    FSProvider.Files[testPath("unused")] = "";
+    Server.setRootPath(testRoot());
+  }
 
 protected:
   MockFSProvider FSProvider;
Index: unittests/clangd/FileIndexTests.cpp
===================================================================
--- unittests/clangd/FileIndexTests.cpp
+++ unittests/clangd/FileIndexTests.cpp
@@ -104,7 +104,7 @@
   Req.Query = "";
   bool SeenSymbol = false;
   M.fuzzyFind(Req, [&](const Symbol &Sym) {
-    EXPECT_EQ(Sym.CanonicalDeclaration.FileURI, "unittest:///f.h");
+    EXPECT_EQ(Sym.CanonicalDeclaration.FileURI, "unittest:f.h");
     SeenSymbol = true;
   });
   EXPECT_TRUE(SeenSymbol);
Index: clangd/FindSymbols.h
===================================================================
--- clangd/FindSymbols.h
+++ clangd/FindSymbols.h
@@ -27,9 +27,11 @@
 /// "::". For example, "std::" will list all children of the std namespace and
 /// "::" alone will list all children of the global namespace.
 /// \p Limit limits the number of results returned (0 means no limit).
+/// \p RootPath Root path of the workspace. This is used as the hint path when
+/// resolving URIs.
 llvm::Expected<std::vector<SymbolInformation>>
 getWorkspaceSymbols(llvm::StringRef Query, int Limit,
-                    const SymbolIndex *const Index);
+                    const SymbolIndex *const Index, llvm::StringRef RootPath);
 
 } // namespace clangd
 } // namespace clang
Index: clangd/FindSymbols.cpp
===================================================================
--- clangd/FindSymbols.cpp
+++ clangd/FindSymbols.cpp
@@ -95,8 +95,8 @@
 } // namespace
 
 llvm::Expected<std::vector<SymbolInformation>>
-getWorkspaceSymbols(StringRef Query, int Limit,
-                    const SymbolIndex *const Index) {
+getWorkspaceSymbols(StringRef Query, int Limit, const SymbolIndex *const Index,
+                    StringRef RootPath) {
   std::vector<SymbolInformation> Result;
   if (Query.empty() || !Index)
     return Result;
@@ -116,7 +116,7 @@
     Req.MaxCandidateCount = Limit;
   TopN<ScoredSymbolInfo, ScoredSymbolGreater> Top(Req.MaxCandidateCount);
   FuzzyMatcher Filter(Req.Query);
-  Index->fuzzyFind(Req, [&Top, &Filter](const Symbol &Sym) {
+  Index->fuzzyFind(Req, [RootPath, &Top, &Filter](const Symbol &Sym) {
     // Prefer the definition over e.g. a function declaration in a header
     auto &CD = Sym.Definition ? Sym.Definition : Sym.CanonicalDeclaration;
     auto Uri = URI::parse(CD.FileURI);
@@ -126,9 +126,7 @@
           CD.FileURI, Sym.Name));
       return;
     }
-    // FIXME: Passing no HintPath here will work for "file" and "test" schemes
-    // because they don't use it but this might not work for other custom ones.
-    auto Path = URI::resolve(*Uri);
+    auto Path = URI::resolve(*Uri, RootPath);
     if (!Path) {
       log(llvm::formatv("Workspace symbol: Could not resolve path for URI "
                         "'{0}' for symbol '{1}'.",
Index: clangd/ClangdServer.cpp
===================================================================
--- clangd/ClangdServer.cpp
+++ clangd/ClangdServer.cpp
@@ -115,10 +115,15 @@
 }
 
 void ClangdServer::setRootPath(PathRef RootPath) {
-  std::string NewRootPath = llvm::sys::path::convert_to_slash(
-      RootPath, llvm::sys::path::Style::posix);
-  if (llvm::sys::fs::is_directory(NewRootPath))
-    this->RootPath = NewRootPath;
+  auto FS = FSProvider.getFileSystem();
+  auto Status = FS->status(RootPath);
+  if (!Status)
+    log("Failed to get status for RootPath " + RootPath + ": " +
+        Status.getError().message());
+  else if (Status->isDirectory())
+    this->RootPath = RootPath;
+  else
+    log("The provided RootPath " + RootPath + " is not a directory.");
 }
 
 void ClangdServer::addDocument(PathRef File, StringRef Contents,
@@ -446,7 +451,8 @@
 
 void ClangdServer::workspaceSymbols(
     StringRef Query, int Limit, Callback<std::vector<SymbolInformation>> CB) {
-  CB(clangd::getWorkspaceSymbols(Query, Limit, Index));
+  CB(clangd::getWorkspaceSymbols(Query, Limit, Index,
+                                 RootPath ? *RootPath : ""));
 }
 
 std::vector<std::pair<Path, std::size_t>>
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to