diff options
-rw-r--r-- | clang-tools-extra/clangd/ClangdServer.cpp | 16 | ||||
-rw-r--r-- | clang-tools-extra/clangd/FindSymbols.cpp | 10 | ||||
-rw-r--r-- | clang-tools-extra/clangd/FindSymbols.h | 4 | ||||
-rw-r--r-- | clang-tools-extra/unittests/clangd/FindSymbolsTests.cpp | 7 | ||||
-rw-r--r-- | clang-tools-extra/unittests/clangd/TestFS.cpp | 8 | ||||
-rw-r--r-- | clang-tools-extra/unittests/clangd/URITests.cpp | 2 |
6 files changed, 32 insertions, 15 deletions
diff --git a/clang-tools-extra/clangd/ClangdServer.cpp b/clang-tools-extra/clangd/ClangdServer.cpp index 3ca694c68e9..17d09e6f241 100644 --- a/clang-tools-extra/clangd/ClangdServer.cpp +++ b/clang-tools-extra/clangd/ClangdServer.cpp @@ -115,10 +115,15 @@ ClangdServer::ClangdServer(GlobalCompilationDatabase &CDB, } 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::onFileEvent(const DidChangeWatchedFilesParams &Params) { 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>> diff --git a/clang-tools-extra/clangd/FindSymbols.cpp b/clang-tools-extra/clangd/FindSymbols.cpp index 3ecbd709085..66608dde4af 100644 --- a/clang-tools-extra/clangd/FindSymbols.cpp +++ b/clang-tools-extra/clangd/FindSymbols.cpp @@ -95,8 +95,8 @@ struct ScoredSymbolGreater { } // 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 HintPath) { std::vector<SymbolInformation> Result; if (Query.empty() || !Index) return Result; @@ -116,7 +116,7 @@ getWorkspaceSymbols(StringRef Query, int Limit, Req.MaxCandidateCount = Limit; TopN<ScoredSymbolInfo, ScoredSymbolGreater> Top(Req.MaxCandidateCount); FuzzyMatcher Filter(Req.Query); - Index->fuzzyFind(Req, [&Top, &Filter](const Symbol &Sym) { + Index->fuzzyFind(Req, [HintPath, &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 @@ getWorkspaceSymbols(StringRef Query, int Limit, 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, HintPath); if (!Path) { log(llvm::formatv("Workspace symbol: Could not resolve path for URI " "'{0}' for symbol '{1}'.", diff --git a/clang-tools-extra/clangd/FindSymbols.h b/clang-tools-extra/clangd/FindSymbols.h index 118917564d2..49c20f3809b 100644 --- a/clang-tools-extra/clangd/FindSymbols.h +++ b/clang-tools-extra/clangd/FindSymbols.h @@ -27,9 +27,11 @@ class SymbolIndex; /// "::". 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 HintPath This is used when resolving URIs. If empty, URI resolution can +/// fail if a hint path is required for the scheme of a specific URI. llvm::Expected<std::vector<SymbolInformation>> getWorkspaceSymbols(llvm::StringRef Query, int Limit, - const SymbolIndex *const Index); + const SymbolIndex *const Index, llvm::StringRef HintPath); } // namespace clangd } // namespace clang diff --git a/clang-tools-extra/unittests/clangd/FindSymbolsTests.cpp b/clang-tools-extra/unittests/clangd/FindSymbolsTests.cpp index d8483e98df1..09b298595b6 100644 --- a/clang-tools-extra/unittests/clangd/FindSymbolsTests.cpp +++ b/clang-tools-extra/unittests/clangd/FindSymbolsTests.cpp @@ -40,13 +40,18 @@ MATCHER_P(WithKind, Kind, "") { return arg.kind == Kind; } 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; diff --git a/clang-tools-extra/unittests/clangd/TestFS.cpp b/clang-tools-extra/unittests/clangd/TestFS.cpp index 000d55854dc..741eb8cee7c 100644 --- a/clang-tools-extra/unittests/clangd/TestFS.cpp +++ b/clang-tools-extra/unittests/clangd/TestFS.cpp @@ -66,7 +66,9 @@ std::string testPath(PathRef File) { 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 a path relative to testRoot() e.g. unittest:///x.h for +/// /clangd-test/x.h. class TestScheme : public URIScheme { public: static const char *Scheme; @@ -75,6 +77,10 @@ public: getAbsolutePath(llvm::StringRef /*Authority*/, llvm::StringRef Body, llvm::StringRef HintPath) const override { assert(HintPath.startswith(testRoot())); + if (!Body.consume_front("/")) + return llvm::make_error<llvm::StringError>( + "Body of an unittest: URI must start with '/'", + llvm::inconvertibleErrorCode()); llvm::SmallString<16> Path(Body.begin(), Body.end()); llvm::sys::path::native(Path); return testPath(Path); diff --git a/clang-tools-extra/unittests/clangd/URITests.cpp b/clang-tools-extra/unittests/clangd/URITests.cpp index f6ac0c6b7f0..84d5ca10941 100644 --- a/clang-tools-extra/unittests/clangd/URITests.cpp +++ b/clang-tools-extra/unittests/clangd/URITests.cpp @@ -144,7 +144,7 @@ TEST(URITest, Resolve) { "/(x)/y/ z"); EXPECT_THAT(resolveOrDie(parseOrDie("file:///c:/x/y/z")), "c:/x/y/z"); #endif - EXPECT_EQ(resolveOrDie(parseOrDie("unittest:a"), testPath("x")), + EXPECT_EQ(resolveOrDie(parseOrDie("unittest:///a"), testPath("x")), testPath("a")); } |