hokein created this revision.
hokein added a reviewer: sammccall.
Herald added subscribers: usaxena95, kadircet, arphaman, jkorous, MaskRay, 
ilya-biryukov.
Herald added a project: clang.

so that clangd C++ API users (via ClangdServer) can access it.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D70380

Files:
  clang-tools-extra/clangd/ClangdLSPServer.cpp
  clang-tools-extra/clangd/ClangdServer.cpp
  clang-tools-extra/clangd/ClangdServer.h
  clang-tools-extra/clangd/XRefs.cpp
  clang-tools-extra/clangd/XRefs.h
  clang-tools-extra/clangd/unittests/XRefsTests.cpp

Index: clang-tools-extra/clangd/unittests/XRefsTests.cpp
===================================================================
--- clang-tools-extra/clangd/unittests/XRefsTests.cpp
+++ clang-tools-extra/clangd/unittests/XRefsTests.cpp
@@ -2096,7 +2096,7 @@
     std::vector<Matcher<Location>> ExpectedLocations;
     for (const auto &R : T.ranges())
       ExpectedLocations.push_back(RangeIs(R));
-    EXPECT_THAT(findReferences(AST, T.point(), 0),
+    EXPECT_THAT(findReferences(AST, T.point(), 0).Refs,
                 ElementsAreArray(ExpectedLocations))
         << Test;
   }
@@ -2157,7 +2157,7 @@
     for (const auto &R : T.ranges())
       ExpectedLocations.push_back(RangeIs(R));
     ASSERT_THAT(ExpectedLocations, Not(IsEmpty()));
-    EXPECT_THAT(findReferences(AST, T.point(), 0),
+    EXPECT_THAT(findReferences(AST, T.point(), 0).Refs,
                 ElementsAreArray(ExpectedLocations))
         << Test;
   }
@@ -2172,7 +2172,7 @@
   auto AST = TU.build();
 
   // References in main file are returned without index.
-  EXPECT_THAT(findReferences(AST, Main.point(), 0, /*Index=*/nullptr),
+  EXPECT_THAT(findReferences(AST, Main.point(), 0, /*Index=*/nullptr).Refs,
               ElementsAre(RangeIs(Main.range())));
   Annotations IndexedMain(R"cpp(
     int main() { [[f^oo]](); }
@@ -2183,17 +2183,18 @@
   IndexedTU.Code = IndexedMain.code();
   IndexedTU.Filename = "Indexed.cpp";
   IndexedTU.HeaderCode = Header;
-  EXPECT_THAT(findReferences(AST, Main.point(), 0, IndexedTU.index().get()),
-              ElementsAre(RangeIs(Main.range()), RangeIs(IndexedMain.range())));
-
-  EXPECT_EQ(1u, findReferences(AST, Main.point(), /*Limit*/ 1,
-                               IndexedTU.index().get())
-                    .size());
+  EXPECT_THAT(
+      findReferences(AST, Main.point(), 0, IndexedTU.index().get()).Refs,
+      ElementsAre(RangeIs(Main.range()), RangeIs(IndexedMain.range())));
+  auto LimitRefs =
+      findReferences(AST, Main.point(), /*Limit*/ 1, IndexedTU.index().get());
+  EXPECT_EQ(1u, LimitRefs.Refs.size());
+  EXPECT_TRUE(LimitRefs.InComplete);
 
   // If the main file is in the index, we don't return duplicates.
   // (even if the references are in a different location)
   TU.Code = ("\n\n" + Main.code()).str();
-  EXPECT_THAT(findReferences(AST, Main.point(), 0, TU.index().get()),
+  EXPECT_THAT(findReferences(AST, Main.point(), 0, TU.index().get()).Refs,
               ElementsAre(RangeIs(Main.range())));
 }
 
Index: clang-tools-extra/clangd/XRefs.h
===================================================================
--- clang-tools-extra/clangd/XRefs.h
+++ clang-tools-extra/clangd/XRefs.h
@@ -124,11 +124,14 @@
                                    format::FormatStyle Style,
                                    const SymbolIndex *Index);
 
-/// Returns reference locations of the symbol at a specified \p Pos.
+struct References {
+  std::vector<Location> Refs; // reference locations of the symbol.
+  bool InComplete = false;    // true if the result is incomplete.
+};
+/// Returns references of the symbol at a specified \p Pos.
 /// \p Limit limits the number of results returned (0 means no limit).
-std::vector<Location> findReferences(ParsedAST &AST, Position Pos,
-                                     uint32_t Limit,
-                                     const SymbolIndex *Index = nullptr);
+References findReferences(ParsedAST &AST, Position Pos, uint32_t Limit,
+                          const SymbolIndex *Index = nullptr);
 
 /// Get info about symbols at \p Pos.
 std::vector<SymbolDetails> getSymbolInfo(ParsedAST &AST, Position Pos);
Index: clang-tools-extra/clangd/XRefs.cpp
===================================================================
--- clang-tools-extra/clangd/XRefs.cpp
+++ clang-tools-extra/clangd/XRefs.cpp
@@ -883,11 +883,12 @@
   return HI;
 }
 
-std::vector<Location> findReferences(ParsedAST &AST, Position Pos,
-                                     uint32_t Limit, const SymbolIndex *Index) {
+References findReferences(ParsedAST &AST, Position Pos, uint32_t Limit,
+                          const SymbolIndex *Index) {
   if (!Limit)
     Limit = std::numeric_limits<uint32_t>::max();
-  std::vector<Location> Results;
+  References Results;
+  // std::vector<Location> Results;
   const SourceManager &SM = AST.getSourceManager();
   auto MainFilePath =
       getCanonicalPath(SM.getFileEntryForID(SM.getMainFileID()), SM);
@@ -922,12 +923,11 @@
       Location Result;
       Result.range = *Range;
       Result.uri = URIForFile::canonicalize(*MainFilePath, *MainFilePath);
-      Results.push_back(std::move(Result));
+      Results.Refs.push_back(std::move(Result));
     }
   }
-
   // Now query the index for references from other files.
-  if (Index && Results.size() < Limit) {
+  if (Index && Results.Refs.size() <= Limit) {
     RefsRequest Req;
     Req.Limit = Limit;
 
@@ -942,15 +942,22 @@
     }
     if (Req.IDs.empty())
       return Results;
-    Index->refs(Req, [&](const Ref &R) {
+    Results.InComplete |= Index->refs(Req, [&](const Ref &R) {
+      // no need to continue process if we reach the limit.
+      if (Results.Refs.size() > Limit)
+        return;
       auto LSPLoc = toLSPLocation(R.Location, *MainFilePath);
       // Avoid indexed results for the main file - the AST is authoritative.
-      if (LSPLoc && LSPLoc->uri.file() != *MainFilePath)
-        Results.push_back(std::move(*LSPLoc));
+      if (!LSPLoc || LSPLoc->uri.file() == *MainFilePath)
+        return;
+
+      Results.Refs.push_back(std::move(*LSPLoc));
     });
   }
-  if (Results.size() > Limit)
-    Results.resize(Limit);
+  if (Results.Refs.size() > Limit) {
+    Results.InComplete = true;
+    Results.Refs.resize(Limit);
+  }
   return Results;
 }
 
Index: clang-tools-extra/clangd/ClangdServer.h
===================================================================
--- clang-tools-extra/clangd/ClangdServer.h
+++ clang-tools-extra/clangd/ClangdServer.h
@@ -225,7 +225,7 @@
 
   /// Retrieve locations for symbol references.
   void findReferences(PathRef File, Position Pos, uint32_t Limit,
-                      Callback<std::vector<Location>> CB);
+                      Callback<References> CB);
 
   /// Run formatting for \p Rng inside \p File with content \p Code.
   llvm::Expected<tooling::Replacements> formatRange(StringRef Code,
Index: clang-tools-extra/clangd/ClangdServer.cpp
===================================================================
--- clang-tools-extra/clangd/ClangdServer.cpp
+++ clang-tools-extra/clangd/ClangdServer.cpp
@@ -562,7 +562,7 @@
 }
 
 void ClangdServer::findReferences(PathRef File, Position Pos, uint32_t Limit,
-                                  Callback<std::vector<Location>> CB) {
+                                  Callback<References> CB) {
   auto Action = [Pos, Limit, CB = std::move(CB),
                  this](llvm::Expected<InputsAndAST> InpAST) mutable {
     if (!InpAST)
Index: clang-tools-extra/clangd/ClangdLSPServer.cpp
===================================================================
--- clang-tools-extra/clangd/ClangdLSPServer.cpp
+++ clang-tools-extra/clangd/ClangdLSPServer.cpp
@@ -1151,8 +1151,13 @@
 
 void ClangdLSPServer::onReference(const ReferenceParams &Params,
                                   Callback<std::vector<Location>> Reply) {
-  Server->findReferences(Params.textDocument.uri.file(), Params.position,
-                         CCOpts.Limit, std::move(Reply));
+  Server->findReferences(
+      Params.textDocument.uri.file(), Params.position, CCOpts.Limit,
+      [Reply = std::move(Reply)](llvm::Expected<References> Refs) mutable {
+        if (!Refs)
+          return Reply(Refs.takeError());
+        return Reply(std::move(Refs->Refs));
+      });
 }
 
 void ClangdLSPServer::onSymbolInfo(const TextDocumentPositionParams &Params,
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to