[clang-tools-extra] r304214 - [clangd] Mark results of clangd requests with a tag provided by the FileSystemProvider.

Ilya Biryukov via cfe-commits cfe-commits at lists.llvm.org
Tue May 30 08:11:03 PDT 2017


Author: ibiryukov
Date: Tue May 30 10:11:02 2017
New Revision: 304214

URL: http://llvm.org/viewvc/llvm-project?rev=304214&view=rev
Log:
[clangd] Mark results of clangd requests with a tag provided by the FileSystemProvider.

Summary:
This allows an implementation of FileSystemProvider that can track which vfs::FileSystem
were used for each of the requests.

Reviewers: bkramer, krasimir

Reviewed By: bkramer

Subscribers: klimek, cfe-commits

Tags: #clang-tools-extra

Differential Revision: https://reviews.llvm.org/D33678

Modified:
    clang-tools-extra/trunk/clangd/ClangdLSPServer.cpp
    clang-tools-extra/trunk/clangd/ClangdServer.cpp
    clang-tools-extra/trunk/clangd/ClangdServer.h
    clang-tools-extra/trunk/unittests/clangd/ClangdTests.cpp

Modified: clang-tools-extra/trunk/clangd/ClangdLSPServer.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/ClangdLSPServer.cpp?rev=304214&r1=304213&r2=304214&view=diff
==============================================================================
--- clang-tools-extra/trunk/clangd/ClangdLSPServer.cpp (original)
+++ clang-tools-extra/trunk/clangd/ClangdLSPServer.cpp Tue May 30 10:11:02 2017
@@ -43,8 +43,8 @@ public:
   LSPDiagnosticsConsumer(ClangdLSPServer &Server) : Server(Server) {}
 
   virtual void onDiagnosticsReady(PathRef File,
-                                  std::vector<DiagWithFixIts> Diagnostics) {
-    Server.consumeDiagnostics(File, Diagnostics);
+                                  Tagged<std::vector<DiagWithFixIts>> Diagnostics) {
+    Server.consumeDiagnostics(File, Diagnostics.Value);
   }
 
 private:
@@ -181,7 +181,7 @@ void ClangdLSPServer::LSPProtocolCallbac
 
   auto Items = LangServer.Server.codeComplete(
       Params.textDocument.uri.file,
-      Position{Params.position.line, Params.position.character});
+      Position{Params.position.line, Params.position.character}).Value;
 
   std::string Completions;
   for (const auto &Item : Items) {

Modified: clang-tools-extra/trunk/clangd/ClangdServer.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/ClangdServer.cpp?rev=304214&r1=304213&r2=304214&view=diff
==============================================================================
--- clang-tools-extra/trunk/clangd/ClangdServer.cpp (original)
+++ clang-tools-extra/trunk/clangd/ClangdServer.cpp Tue May 30 10:11:02 2017
@@ -58,8 +58,9 @@ Position clangd::offsetToPosition(String
   return {Lines, Cols};
 }
 
-IntrusiveRefCntPtr<vfs::FileSystem> RealFileSystemProvider::getFileSystem() {
-  return vfs::getRealFileSystem();
+Tagged<IntrusiveRefCntPtr<vfs::FileSystem>>
+RealFileSystemProvider::getTaggedFileSystem() {
+  return make_tagged(vfs::getRealFileSystem(), VFSTag());
 }
 
 ClangdScheduler::ClangdScheduler(bool RunSynchronously)
@@ -156,11 +157,13 @@ void ClangdServer::addDocument(PathRef F
 
     assert(FileContents.Draft &&
            "No contents inside a file that was scheduled for reparse");
-    Units.runOnUnit(FileStr, *FileContents.Draft, *CDB, PCHs,
-                    FSProvider->getFileSystem(), [&](ClangdUnit const &Unit) {
-                      DiagConsumer->onDiagnosticsReady(
-                          FileStr, Unit.getLocalDiagnostics());
-                    });
+    auto TaggedFS = FSProvider->getTaggedFileSystem();
+    Units.runOnUnit(
+        FileStr, *FileContents.Draft, *CDB, PCHs, TaggedFS.Value,
+        [&](ClangdUnit const &Unit) {
+          DiagConsumer->onDiagnosticsReady(
+              FileStr, make_tagged(Unit.getLocalDiagnostics(), TaggedFS.Tag));
+        });
   });
 }
 
@@ -181,18 +184,18 @@ void ClangdServer::forceReparse(PathRef
   addDocument(File, getDocument(File));
 }
 
-std::vector<CompletionItem> ClangdServer::codeComplete(PathRef File,
-                                                       Position Pos) {
+Tagged<std::vector<CompletionItem>> ClangdServer::codeComplete(PathRef File,
+                                                               Position Pos) {
   auto FileContents = DraftMgr.getDraft(File);
   assert(FileContents.Draft && "codeComplete is called for non-added document");
 
   std::vector<CompletionItem> Result;
-  auto VFS = FSProvider->getFileSystem();
+  auto TaggedFS = FSProvider->getTaggedFileSystem();
   Units.runOnUnitWithoutReparse(
-      File, *FileContents.Draft, *CDB, PCHs, VFS, [&](ClangdUnit &Unit) {
-        Result = Unit.codeComplete(*FileContents.Draft, Pos, VFS);
+      File, *FileContents.Draft, *CDB, PCHs, TaggedFS.Value, [&](ClangdUnit &Unit) {
+        Result = Unit.codeComplete(*FileContents.Draft, Pos, TaggedFS.Value);
       });
-  return Result;
+  return make_tagged(std::move(Result), TaggedFS.Tag);
 }
 
 std::vector<tooling::Replacement> ClangdServer::formatRange(PathRef File,

Modified: clang-tools-extra/trunk/clangd/ClangdServer.h
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/ClangdServer.h?rev=304214&r1=304213&r2=304214&view=diff
==============================================================================
--- clang-tools-extra/trunk/clangd/ClangdServer.h (original)
+++ clang-tools-extra/trunk/clangd/ClangdServer.h Tue May 30 10:11:02 2017
@@ -28,6 +28,7 @@
 #include <mutex>
 #include <string>
 #include <thread>
+#include <type_traits>
 #include <utility>
 
 namespace clang {
@@ -41,24 +42,54 @@ size_t positionToOffset(StringRef Code,
 /// Turn an offset in Code into a [line, column] pair.
 Position offsetToPosition(StringRef Code, size_t Offset);
 
+/// A tag supplied by the FileSytemProvider.
+typedef int VFSTag;
+
+/// A value of an arbitrary type and VFSTag that was supplied by the
+/// FileSystemProvider when this value was computed.
+template <class T> class Tagged {
+public:
+  template <class U>
+  Tagged(U &&Value, VFSTag Tag) : Value(std::forward<U>(Value)), Tag(Tag) {}
+
+  template <class U>
+  Tagged(const Tagged<U> &Other) : Value(Other.Value), Tag(Other.Tag) {}
+
+  template <class U>
+  Tagged(Tagged<U> &&Other) : Value(std::move(Other.Value)), Tag(Other.Tag) {}
+
+  T Value;
+  VFSTag Tag;
+};
+
+template <class T>
+Tagged<typename std::decay<T>::type> make_tagged(T &&Value, VFSTag Tag) {
+  return Tagged<T>(std::forward<T>(Value), Tag);
+}
+
 class DiagnosticsConsumer {
 public:
   virtual ~DiagnosticsConsumer() = default;
 
   /// Called by ClangdServer when \p Diagnostics for \p File are ready.
-  virtual void onDiagnosticsReady(PathRef File,
-                                  std::vector<DiagWithFixIts> Diagnostics) = 0;
+  virtual void
+  onDiagnosticsReady(PathRef File,
+                     Tagged<std::vector<DiagWithFixIts>> Diagnostics) = 0;
 };
 
 class FileSystemProvider {
 public:
   virtual ~FileSystemProvider() = default;
-  virtual IntrusiveRefCntPtr<vfs::FileSystem> getFileSystem() = 0;
+  /// \return A filesystem that will be used for all file accesses in clangd.
+  /// A Tag returned by this method will be propagated to all results of clangd
+  /// that will use this filesystem.
+  virtual Tagged<IntrusiveRefCntPtr<vfs::FileSystem>> getTaggedFileSystem() = 0;
 };
 
 class RealFileSystemProvider : public FileSystemProvider {
 public:
-  IntrusiveRefCntPtr<vfs::FileSystem> getFileSystem() override;
+  /// \return getRealFileSystem() tagged with default tag, i.e. VFSTag()
+  Tagged<IntrusiveRefCntPtr<vfs::FileSystem>> getTaggedFileSystem() override;
 };
 
 class ClangdServer;
@@ -120,7 +151,7 @@ public:
   void forceReparse(PathRef File);
 
   /// Run code completion for \p File at \p Pos.
-  std::vector<CompletionItem> codeComplete(PathRef File, Position Pos);
+  Tagged<std::vector<CompletionItem>> codeComplete(PathRef File, Position Pos);
 
   /// Run formatting for \p Rng inside \p File.
   std::vector<tooling::Replacement> formatRange(PathRef File, Range Rng);

Modified: clang-tools-extra/trunk/unittests/clangd/ClangdTests.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/unittests/clangd/ClangdTests.cpp?rev=304214&r1=304213&r2=304214&view=diff
==============================================================================
--- clang-tools-extra/trunk/unittests/clangd/ClangdTests.cpp (original)
+++ clang-tools-extra/trunk/unittests/clangd/ClangdTests.cpp Tue May 30 10:11:02 2017
@@ -133,9 +133,9 @@ namespace {
 class ErrorCheckingDiagConsumer : public DiagnosticsConsumer {
 public:
   void onDiagnosticsReady(PathRef File,
-                          std::vector<DiagWithFixIts> Diagnostics) override {
+                          Tagged<std::vector<DiagWithFixIts>> Diagnostics) override {
     bool HadError = false;
-    for (const auto &DiagAndFixIts : Diagnostics) {
+    for (const auto &DiagAndFixIts : Diagnostics.Value) {
       // FIXME: severities returned by clangd should have a descriptive
       // diagnostic severity enum
       const int ErrorSeverity = 1;
@@ -144,6 +144,7 @@ public:
 
     std::lock_guard<std::mutex> Lock(Mutex);
     HadErrorInLastDiags = HadError;
+    LastVFSTag = Diagnostics.Tag;
   }
 
   bool hadErrorInLastDiags() {
@@ -151,9 +152,14 @@ public:
     return HadErrorInLastDiags;
   }
 
+  VFSTag lastVFSTag() {
+    return LastVFSTag;
+  }
+
 private:
   std::mutex Mutex;
   bool HadErrorInLastDiags = false;
+  VFSTag LastVFSTag = VFSTag();
 };
 
 class MockCompilationDatabase : public GlobalCompilationDatabase {
@@ -166,7 +172,7 @@ public:
 
 class MockFSProvider : public FileSystemProvider {
 public:
-  IntrusiveRefCntPtr<vfs::FileSystem> getFileSystem() override {
+  Tagged<IntrusiveRefCntPtr<vfs::FileSystem>> getTaggedFileSystem() override {
     IntrusiveRefCntPtr<vfs::InMemoryFileSystem> MemFS(
         new vfs::InMemoryFileSystem);
     for (auto &FileAndContents : Files)
@@ -177,10 +183,11 @@ public:
     auto OverlayFS = IntrusiveRefCntPtr<vfs::OverlayFileSystem>(
         new vfs::OverlayFileSystem(vfs::getTempOnlyFS()));
     OverlayFS->pushOverlay(std::move(MemFS));
-    return OverlayFS;
+    return make_tagged(OverlayFS, Tag);
   }
 
   llvm::StringMap<std::string> Files;
+  VFSTag Tag = VFSTag();
 };
 
 /// Replaces all patterns of the form 0x123abc with spaces
@@ -366,5 +373,30 @@ int b = a;
   EXPECT_NE(DumpParse1, DumpParseDifferent);
 }
 
+TEST_F(ClangdVFSTest, CheckVersions) {
+  MockFSProvider *FS;
+  ErrorCheckingDiagConsumer *DiagConsumer;
+
+  ClangdServer Server(
+      llvm::make_unique<MockCompilationDatabase>(),
+      getAndMove(llvm::make_unique<ErrorCheckingDiagConsumer>(), DiagConsumer),
+      getAndMove(llvm::make_unique<MockFSProvider>(), FS),
+      /*RunSynchronously=*/true);
+
+  auto FooCpp = getVirtualTestFilePath("foo.cpp");
+  const auto SourceContents = "int a;";
+  FS->Files[FooCpp] = SourceContents;
+  FS->Tag = 123;
+
+  Server.addDocument(FooCpp, SourceContents);
+  EXPECT_EQ(DiagConsumer->lastVFSTag(), FS->Tag);
+  EXPECT_EQ(Server.codeComplete(FooCpp, Position{0, 0}).Tag, FS->Tag);
+
+  FS->Tag = 321;
+  Server.addDocument(FooCpp, SourceContents);
+  EXPECT_EQ(DiagConsumer->lastVFSTag(), FS->Tag);
+  EXPECT_EQ(Server.codeComplete(FooCpp, Position{0, 0}).Tag, FS->Tag);
+}
+
 } // namespace clangd
 } // namespace clang




More information about the cfe-commits mailing list