[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