diff --git a/clang-tools-extra/clangd/ClangdLSPServer.h b/clang-tools-extra/clangd/ClangdLSPServer.h --- a/clang-tools-extra/clangd/ClangdLSPServer.h +++ b/clang-tools-extra/clangd/ClangdLSPServer.h @@ -32,7 +32,7 @@ /// MessageHandler binds the implemented LSP methods (e.g. onInitialize) to /// corresponding JSON-RPC methods ("initialize"). /// The server also supports $/cancelRequest (MessageHandler provides this). -class ClangdLSPServer : private DiagnosticsConsumer { +class ClangdLSPServer : private ClangdServer::Callbacks { public: /// If \p CompileCommandsDir has a value, compile_commands.json will be /// loaded only from \p CompileCommandsDir. Otherwise, clangd will look @@ -54,7 +54,7 @@ bool run(); private: - // Implement DiagnosticsConsumer. + // Implement ClangdServer::Callbacks. void onDiagnosticsReady(PathRef File, std::vector Diagnostics) override; void onFileUpdated(PathRef File, const TUStatus &Status) override; void diff --git a/clang-tools-extra/clangd/ClangdLSPServer.cpp b/clang-tools-extra/clangd/ClangdLSPServer.cpp --- a/clang-tools-extra/clangd/ClangdLSPServer.cpp +++ b/clang-tools-extra/clangd/ClangdLSPServer.cpp @@ -500,8 +500,8 @@ if (NegotiatedOffsetEncoding) WithOffsetEncoding.emplace(kCurrentOffsetEncoding, *NegotiatedOffsetEncoding); - Server.emplace(*CDB, FSProvider, static_cast(*this), - ClangdServerOpts); + Server.emplace(*CDB, FSProvider, ClangdServerOpts, + static_cast(this)); } applyConfiguration(Params.initializationOptions.ConfigSettings); diff --git a/clang-tools-extra/clangd/ClangdServer.h b/clang-tools-extra/clangd/ClangdServer.h --- a/clang-tools-extra/clangd/ClangdServer.h +++ b/clang-tools-extra/clangd/ClangdServer.h @@ -41,26 +41,6 @@ namespace clang { namespace clangd { -// FIXME: find a better name. -class DiagnosticsConsumer { -public: - virtual ~DiagnosticsConsumer() = default; - - /// Called by ClangdServer when \p Diagnostics for \p File are ready. - virtual void onDiagnosticsReady(PathRef File, - std::vector Diagnostics) = 0; - /// Called whenever the file status is updated. - virtual void onFileUpdated(PathRef File, const TUStatus &Status){}; - - /// Called by ClangdServer when some \p Highlightings for \p File are ready. - virtual void - onHighlightingsReady(PathRef File, - std::vector Highlightings) {} - - // Called when background indexing tasks are enqueued, started, or completed. - virtual void onBackgroundIndexProgress(const BackgroundQueue::Stats &Stats) {} -}; - /// When set, used by ClangdServer to get clang-tidy options for each particular /// file. Must be thread-safe. We use this instead of ClangTidyOptionsProvider /// to allow reading tidy configs from the VFS used for parsing. @@ -82,6 +62,31 @@ /// (ClangdLSPServer uses this to implement $/cancelRequest). class ClangdServer { public: + /// Interface with hooks for users of ClangdServer to be notified of events. + class Callbacks { + public: + virtual ~Callbacks() = default; + + /// Called by ClangdServer when \p Diagnostics for \p File are ready. + /// May be called concurrently for separate files, not for a single file. + virtual void onDiagnosticsReady(PathRef File, + std::vector Diagnostics) {} + /// Called whenever the file status is updated. + /// May be called concurrently for separate files, not for a single file. + virtual void onFileUpdated(PathRef File, const TUStatus &Status){}; + + /// Called by ClangdServer when some \p Highlightings for \p File are ready. + /// May be called concurrently for separate files, not for a single file. + virtual void + onHighlightingsReady(PathRef File, + std::vector Highlightings) {} + + /// Called when background indexing tasks are enqueued/started/completed. + /// Not called concurrently. + virtual void + onBackgroundIndexProgress(const BackgroundQueue::Stats &Stats) {} + }; + struct Options { /// To process requests asynchronously, ClangdServer spawns worker threads. /// If this is zero, no threads are spawned. All work is done on the calling @@ -156,14 +161,15 @@ /// added file (i.e., when processing a first call to addDocument) and reuses /// those arguments for subsequent reparses. However, ClangdServer will check /// if compilation arguments changed on calls to forceReparse(). - /// - /// After each parsing request finishes, ClangdServer reports diagnostics to - /// \p DiagConsumer. Note that a callback to \p DiagConsumer happens on a - /// worker thread. Therefore, instances of \p DiagConsumer must properly - /// synchronize access to shared state. ClangdServer(const GlobalCompilationDatabase &CDB, - const FileSystemProvider &FSProvider, - DiagnosticsConsumer &DiagConsumer, const Options &Opts); + const FileSystemProvider &FSProvider, const Options &Opts, + Callbacks *Callbacks = nullptr); + + // FIXME: remove this compatibility alias. + ClangdServer(const GlobalCompilationDatabase &CDB, + const FileSystemProvider &FSProvider, Callbacks &Callbacks, + const Options &Opts) + : ClangdServer(CDB, FSProvider, Opts, &Callbacks) {} /// Add a \p File to the list of tracked C++ files or update the contents if /// \p File is already tracked. Also schedules parsing of the AST for it on a @@ -353,6 +359,9 @@ TUScheduler WorkScheduler; }; +// FIXME: Remove this compatibility alias. +using DiagnosticsConsumer = ClangdServer::Callbacks; + } // namespace clangd } // namespace clang diff --git a/clang-tools-extra/clangd/ClangdServer.cpp b/clang-tools-extra/clangd/ClangdServer.cpp --- a/clang-tools-extra/clangd/ClangdServer.cpp +++ b/clang-tools-extra/clangd/ClangdServer.cpp @@ -56,9 +56,10 @@ // Update the FileIndex with new ASTs and plumb the diagnostics responses. struct UpdateIndexCallbacks : public ParsingCallbacks { - UpdateIndexCallbacks(FileIndex *FIndex, DiagnosticsConsumer &DiagConsumer, + UpdateIndexCallbacks(FileIndex *FIndex, + ClangdServer::Callbacks *ServerCallbacks, bool SemanticHighlighting) - : FIndex(FIndex), DiagConsumer(DiagConsumer), + : FIndex(FIndex), ServerCallbacks(ServerCallbacks), SemanticHighlighting(SemanticHighlighting) {} void onPreambleAST(PathRef Path, ASTContext &Ctx, @@ -77,25 +78,28 @@ if (SemanticHighlighting) Highlightings = getSemanticHighlightings(AST); - Publish([&]() { - DiagConsumer.onDiagnosticsReady(Path, std::move(Diagnostics)); - if (SemanticHighlighting) - DiagConsumer.onHighlightingsReady(Path, std::move(Highlightings)); - }); + if (ServerCallbacks) + Publish([&]() { + ServerCallbacks->onDiagnosticsReady(Path, std::move(Diagnostics)); + if (SemanticHighlighting) + ServerCallbacks->onHighlightingsReady(Path, std::move(Highlightings)); + }); } void onFailedAST(PathRef Path, std::vector Diags, PublishFn Publish) override { - Publish([&]() { DiagConsumer.onDiagnosticsReady(Path, Diags); }); + if (ServerCallbacks) + Publish([&]() { ServerCallbacks->onDiagnosticsReady(Path, Diags); }); } void onFileUpdated(PathRef File, const TUStatus &Status) override { - DiagConsumer.onFileUpdated(File, Status); + if (ServerCallbacks) + ServerCallbacks->onFileUpdated(File, Status); } private: FileIndex *FIndex; - DiagnosticsConsumer &DiagConsumer; + ClangdServer::Callbacks *ServerCallbacks; bool SemanticHighlighting; }; } // namespace @@ -111,8 +115,7 @@ ClangdServer::ClangdServer(const GlobalCompilationDatabase &CDB, const FileSystemProvider &FSProvider, - DiagnosticsConsumer &DiagConsumer, - const Options &Opts) + const Options &Opts, Callbacks *Callbacks) : FSProvider(FSProvider), DynamicIdx(Opts.BuildDynamicSymbolIndex ? new FileIndex(Opts.HeavyweightDynamicSymbolIndex) @@ -126,11 +129,10 @@ // is parsed. // FIXME(ioeric): this can be slow and we may be able to index on less // critical paths. - WorkScheduler( - CDB, Opts.AsyncThreadsCount, Opts.StorePreamblesInMemory, - std::make_unique(DynamicIdx.get(), DiagConsumer, - Opts.SemanticHighlighting), - Opts.UpdateDebounce, Opts.RetentionPolicy) { + WorkScheduler(CDB, Opts.AsyncThreadsCount, Opts.StorePreamblesInMemory, + std::make_unique( + DynamicIdx.get(), Callbacks, Opts.SemanticHighlighting), + Opts.UpdateDebounce, Opts.RetentionPolicy) { // Adds an index to the stack, at higher priority than existing indexes. auto AddIndex = [&](SymbolIndex *Idx) { if (this->Index != nullptr) { @@ -148,8 +150,9 @@ BackgroundIndexStorage::createDiskBackedStorageFactory( [&CDB](llvm::StringRef File) { return CDB.getProjectInfo(File); }), std::max(Opts.AsyncThreadsCount, 1u), - [&DiagConsumer](BackgroundQueue::Stats S) { - DiagConsumer.onBackgroundIndexProgress(S); + [Callbacks](BackgroundQueue::Stats S) { + if (Callbacks) + Callbacks->onBackgroundIndexProgress(S); }); AddIndex(BackgroundIdx.get()); } diff --git a/clang-tools-extra/clangd/unittests/ClangdTests.cpp b/clang-tools-extra/clangd/unittests/ClangdTests.cpp --- a/clang-tools-extra/clangd/unittests/ClangdTests.cpp +++ b/clang-tools-extra/clangd/unittests/ClangdTests.cpp @@ -59,7 +59,7 @@ return false; } -class ErrorCheckingDiagConsumer : public DiagnosticsConsumer { +class ErrorCheckingCallbacks : public ClangdServer::Callbacks { public: void onDiagnosticsReady(PathRef File, std::vector Diagnostics) override { @@ -80,7 +80,7 @@ /// For each file, record whether the last published diagnostics contained at /// least one error. -class MultipleErrorCheckingDiagConsumer : public DiagnosticsConsumer { +class MultipleErrorCheckingCallbacks : public ClangdServer::Callbacks { public: void onDiagnosticsReady(PathRef File, std::vector Diagnostics) override { @@ -142,9 +142,9 @@ std::vector> ExtraFiles = {}, bool ExpectErrors = false) { MockFSProvider FS; - ErrorCheckingDiagConsumer DiagConsumer; + ErrorCheckingCallbacks DiagConsumer; MockCompilationDatabase CDB; - ClangdServer Server(CDB, FS, DiagConsumer, ClangdServer::optsForTest()); + ClangdServer Server(CDB, FS, ClangdServer::optsForTest(), &DiagConsumer); for (const auto &FileWithContents : ExtraFiles) FS.Files[testPath(FileWithContents.first)] = FileWithContents.second; @@ -194,9 +194,9 @@ TEST_F(ClangdVFSTest, Reparse) { MockFSProvider FS; - ErrorCheckingDiagConsumer DiagConsumer; + ErrorCheckingCallbacks DiagConsumer; MockCompilationDatabase CDB; - ClangdServer Server(CDB, FS, DiagConsumer, ClangdServer::optsForTest()); + ClangdServer Server(CDB, FS, ClangdServer::optsForTest(), &DiagConsumer); const auto SourceContents = R"cpp( #include "foo.h" @@ -229,9 +229,9 @@ TEST_F(ClangdVFSTest, ReparseOnHeaderChange) { MockFSProvider FS; - ErrorCheckingDiagConsumer DiagConsumer; + ErrorCheckingCallbacks DiagConsumer; MockCompilationDatabase CDB; - ClangdServer Server(CDB, FS, DiagConsumer, ClangdServer::optsForTest()); + ClangdServer Server(CDB, FS, ClangdServer::optsForTest(), &DiagConsumer); const auto SourceContents = R"cpp( #include "foo.h" @@ -274,24 +274,24 @@ } mutable int Got; } FS; - struct DiagConsumer : public DiagnosticsConsumer { + struct Callbacks : public ClangdServer::Callbacks { void onDiagnosticsReady(PathRef File, std::vector Diagnostics) override { Got = Context::current().getExisting(Secret); } int Got; - } DiagConsumer; + } Callbacks; MockCompilationDatabase CDB; // Verify that the context is plumbed to the FS provider and diagnostics. - ClangdServer Server(CDB, FS, DiagConsumer, ClangdServer::optsForTest()); + ClangdServer Server(CDB, FS, ClangdServer::optsForTest(), &Callbacks); { WithContextValue Entrypoint(Secret, 42); Server.addDocument(testPath("foo.cpp"), "void main(){}"); } ASSERT_TRUE(Server.blockUntilIdleForTest()); EXPECT_EQ(FS.Got, 42); - EXPECT_EQ(DiagConsumer.Got, 42); + EXPECT_EQ(Callbacks.Got, 42); } // Only enable this test on Unix @@ -299,13 +299,13 @@ TEST_F(ClangdVFSTest, SearchLibDir) { // Checks that searches for GCC installation is done through vfs. MockFSProvider FS; - ErrorCheckingDiagConsumer DiagConsumer; + ErrorCheckingCallbacks DiagConsumer; MockCompilationDatabase CDB; CDB.ExtraClangFlags.insert(CDB.ExtraClangFlags.end(), {"-xc++", "-target", "x86_64-linux-unknown", "-m64", "--gcc-toolchain=/randomusr", "-stdlib=libstdc++"}); - ClangdServer Server(CDB, FS, DiagConsumer, ClangdServer::optsForTest()); + ClangdServer Server(CDB, FS, ClangdServer::optsForTest(), &DiagConsumer); // Just a random gcc version string SmallString<8> Version("4.9.3"); @@ -348,9 +348,9 @@ TEST_F(ClangdVFSTest, ForceReparseCompileCommand) { MockFSProvider FS; - ErrorCheckingDiagConsumer DiagConsumer; + ErrorCheckingCallbacks DiagConsumer; MockCompilationDatabase CDB; - ClangdServer Server(CDB, FS, DiagConsumer, ClangdServer::optsForTest()); + ClangdServer Server(CDB, FS, ClangdServer::optsForTest(), &DiagConsumer); auto FooCpp = testPath("foo.cpp"); const auto SourceContents1 = R"cpp( @@ -384,9 +384,9 @@ TEST_F(ClangdVFSTest, ForceReparseCompileCommandDefines) { MockFSProvider FS; - ErrorCheckingDiagConsumer DiagConsumer; + ErrorCheckingCallbacks DiagConsumer; MockCompilationDatabase CDB; - ClangdServer Server(CDB, FS, DiagConsumer, ClangdServer::optsForTest()); + ClangdServer Server(CDB, FS, ClangdServer::optsForTest(), &DiagConsumer); auto FooCpp = testPath("foo.cpp"); const auto SourceContents = R"cpp( @@ -437,8 +437,8 @@ MockFSProvider FS; MockCompilationDatabase CDB; - MultipleErrorCheckingDiagConsumer DiagConsumer; - ClangdServer Server(CDB, FS, DiagConsumer, ClangdServer::optsForTest()); + MultipleErrorCheckingCallbacks DiagConsumer; + ClangdServer Server(CDB, FS, ClangdServer::optsForTest(), &DiagConsumer); auto FooCpp = testPath("foo.cpp"); auto BarCpp = testPath("bar.cpp"); @@ -480,9 +480,9 @@ TEST_F(ClangdVFSTest, MemoryUsage) { MockFSProvider FS; - ErrorCheckingDiagConsumer DiagConsumer; + ErrorCheckingCallbacks DiagConsumer; MockCompilationDatabase CDB; - ClangdServer Server(CDB, FS, DiagConsumer, ClangdServer::optsForTest()); + ClangdServer Server(CDB, FS, ClangdServer::optsForTest(), &DiagConsumer); Path FooCpp = testPath("foo.cpp"); const auto SourceContents = R"cpp( @@ -515,10 +515,10 @@ TEST_F(ClangdVFSTest, InvalidCompileCommand) { MockFSProvider FS; - ErrorCheckingDiagConsumer DiagConsumer; + ErrorCheckingCallbacks DiagConsumer; MockCompilationDatabase CDB; - ClangdServer Server(CDB, FS, DiagConsumer, ClangdServer::optsForTest()); + ClangdServer Server(CDB, FS, ClangdServer::optsForTest(), &DiagConsumer); auto FooCpp = testPath("foo.cpp"); // clang cannot create CompilerInvocation if we pass two files in the @@ -589,7 +589,7 @@ bool HadErrorsInLastDiags = false; }; - class TestDiagConsumer : public DiagnosticsConsumer { + class TestDiagConsumer : public ClangdServer::Callbacks { public: TestDiagConsumer() : Stats(FilesCount, FileStat()) {} @@ -635,7 +635,7 @@ TestDiagConsumer DiagConsumer; { MockCompilationDatabase CDB; - ClangdServer Server(CDB, FS, DiagConsumer, ClangdServer::optsForTest()); + ClangdServer Server(CDB, FS, ClangdServer::optsForTest(), &DiagConsumer); // Prepare some random distributions for the test. std::random_device RandGen; @@ -766,7 +766,7 @@ } TEST_F(ClangdThreadingTest, NoConcurrentDiagnostics) { - class NoConcurrentAccessDiagConsumer : public DiagnosticsConsumer { + class NoConcurrentAccessDiagConsumer : public ClangdServer::Callbacks { public: std::atomic Count = {0}; @@ -818,7 +818,7 @@ NoConcurrentAccessDiagConsumer DiagConsumer(std::move(StartSecondPromise)); MockCompilationDatabase CDB; - ClangdServer Server(CDB, FS, DiagConsumer, ClangdServer::optsForTest()); + ClangdServer Server(CDB, FS, ClangdServer::optsForTest(), &DiagConsumer); Server.addDocument(FooCpp, SourceContentsWithErrors); StartSecond.wait(); Server.addDocument(FooCpp, SourceContentsWithoutErrors); @@ -828,9 +828,9 @@ TEST_F(ClangdVFSTest, FormatCode) { MockFSProvider FS; - ErrorCheckingDiagConsumer DiagConsumer; + ErrorCheckingCallbacks DiagConsumer; MockCompilationDatabase CDB; - ClangdServer Server(CDB, FS, DiagConsumer, ClangdServer::optsForTest()); + ClangdServer Server(CDB, FS, ClangdServer::optsForTest(), &DiagConsumer); auto Path = testPath("foo.cpp"); std::string Code = R"cpp( @@ -857,9 +857,9 @@ TEST_F(ClangdVFSTest, ChangedHeaderFromISystem) { MockFSProvider FS; - ErrorCheckingDiagConsumer DiagConsumer; + ErrorCheckingCallbacks DiagConsumer; MockCompilationDatabase CDB; - ClangdServer Server(CDB, FS, DiagConsumer, ClangdServer::optsForTest()); + ClangdServer Server(CDB, FS, ClangdServer::optsForTest(), &DiagConsumer); auto SourcePath = testPath("source/foo.cpp"); auto HeaderPath = testPath("headers/foo.h"); @@ -932,9 +932,9 @@ llvm::StringMap CountStats; ListenStatsFSProvider FS(CountStats); - ErrorCheckingDiagConsumer DiagConsumer; + ErrorCheckingCallbacks DiagConsumer; MockCompilationDatabase CDB; - ClangdServer Server(CDB, FS, DiagConsumer, ClangdServer::optsForTest()); + ClangdServer Server(CDB, FS, ClangdServer::optsForTest(), &DiagConsumer); auto SourcePath = testPath("foo.cpp"); auto HeaderPath = testPath("foo.h"); @@ -961,9 +961,9 @@ TEST_F(ClangdVFSTest, FallbackWhenPreambleIsNotReady) { MockFSProvider FS; - ErrorCheckingDiagConsumer DiagConsumer; + ErrorCheckingCallbacks DiagConsumer; MockCompilationDatabase CDB; - ClangdServer Server(CDB, FS, DiagConsumer, ClangdServer::optsForTest()); + ClangdServer Server(CDB, FS, ClangdServer::optsForTest(), &DiagConsumer); auto FooCpp = testPath("foo.cpp"); Annotations Code(R"cpp( @@ -1007,7 +1007,7 @@ TEST_F(ClangdVFSTest, FallbackWhenWaitingForCompileCommand) { MockFSProvider FS; - ErrorCheckingDiagConsumer DiagConsumer; + ErrorCheckingCallbacks DiagConsumer; // Returns compile command only when notified. class DelayedCompilationDatabase : public GlobalCompilationDatabase { public: @@ -1033,7 +1033,7 @@ Notification CanReturnCommand; DelayedCompilationDatabase CDB(CanReturnCommand); - ClangdServer Server(CDB, FS, DiagConsumer, ClangdServer::optsForTest()); + ClangdServer Server(CDB, FS, ClangdServer::optsForTest(), &DiagConsumer); auto FooCpp = testPath("foo.cpp"); Annotations Code(R"cpp( diff --git a/clang-tools-extra/clangd/unittests/CodeCompleteTests.cpp b/clang-tools-extra/clangd/unittests/CodeCompleteTests.cpp --- a/clang-tools-extra/clangd/unittests/CodeCompleteTests.cpp +++ b/clang-tools-extra/clangd/unittests/CodeCompleteTests.cpp @@ -45,11 +45,6 @@ using ::testing::Not; using ::testing::UnorderedElementsAre; -class IgnoreDiagnostics : public DiagnosticsConsumer { - void onDiagnosticsReady(PathRef File, - std::vector Diagnostics) override {} -}; - // GMock helpers for matching completion items. MATCHER_P(Named, Name, "") { return arg.Name == Name; } MATCHER_P(NameStartsWith, Prefix, "") { @@ -143,8 +138,7 @@ MockCompilationDatabase CDB; // To make sure our tests for completiopns inside templates work on Windows. CDB.ExtraClangFlags = {"-fno-delayed-template-parsing"}; - IgnoreDiagnostics DiagConsumer; - ClangdServer Server(CDB, FS, DiagConsumer, ClangdServer::optsForTest()); + ClangdServer Server(CDB, FS, ClangdServer::optsForTest()); return completions(Server, Text, std::move(IndexSymbols), std::move(Opts), FilePath); } @@ -670,8 +664,7 @@ std::string BarHeader = testPath("sub/bar.h"); FS.Files[BarHeader] = ""; - IgnoreDiagnostics DiagConsumer; - ClangdServer Server(CDB, FS, DiagConsumer, ClangdServer::optsForTest()); + ClangdServer Server(CDB, FS, ClangdServer::optsForTest()); auto BarURI = URI::create(BarHeader).toString(); Symbol Sym = cls("ns::X"); Sym.CanonicalDeclaration.FileURI = BarURI.c_str(); @@ -709,8 +702,7 @@ MockFSProvider FS; MockCompilationDatabase CDB; - IgnoreDiagnostics DiagConsumer; - ClangdServer Server(CDB, FS, DiagConsumer, ClangdServer::optsForTest()); + ClangdServer Server(CDB, FS, ClangdServer::optsForTest()); Symbol SymX = cls("ns::X"); Symbol SymY = cls("ns::Y"); std::string BarHeader = testPath("bar.h"); @@ -737,8 +729,7 @@ TEST(CompletionTest, IndexSuppressesPreambleCompletions) { MockFSProvider FS; MockCompilationDatabase CDB; - IgnoreDiagnostics DiagConsumer; - ClangdServer Server(CDB, FS, DiagConsumer, ClangdServer::optsForTest()); + ClangdServer Server(CDB, FS, ClangdServer::optsForTest()); FS.Files[testPath("bar.h")] = R"cpp(namespace ns { struct preamble { int member; }; })cpp"; @@ -787,10 +778,9 @@ TEST(CompletionTest, DynamicIndexIncludeInsertion) { MockFSProvider FS; MockCompilationDatabase CDB; - IgnoreDiagnostics DiagConsumer; ClangdServer::Options Opts = ClangdServer::optsForTest(); Opts.BuildDynamicSymbolIndex = true; - ClangdServer Server(CDB, FS, DiagConsumer, Opts); + ClangdServer Server(CDB, FS, Opts); FS.Files[testPath("foo_header.h")] = R"cpp( #pragma once @@ -816,10 +806,9 @@ TEST(CompletionTest, DynamicIndexMultiFile) { MockFSProvider FS; MockCompilationDatabase CDB; - IgnoreDiagnostics DiagConsumer; auto Opts = ClangdServer::optsForTest(); Opts.BuildDynamicSymbolIndex = true; - ClangdServer Server(CDB, FS, DiagConsumer, Opts); + ClangdServer Server(CDB, FS, Opts); FS.Files[testPath("foo.h")] = R"cpp( namespace ns { class XYZ {}; void foo(int x) {} } @@ -877,12 +866,11 @@ TEST(CompletionTest, CommentsFromSystemHeaders) { MockFSProvider FS; MockCompilationDatabase CDB; - IgnoreDiagnostics DiagConsumer; auto Opts = ClangdServer::optsForTest(); Opts.BuildDynamicSymbolIndex = true; - ClangdServer Server(CDB, FS, DiagConsumer, Opts); + ClangdServer Server(CDB, FS, Opts); FS.Files[testPath("foo.h")] = R"cpp( #pragma GCC system_header @@ -1050,11 +1038,10 @@ MockFSProvider FS; MockCompilationDatabase CDB; - IgnoreDiagnostics DiagConsumer; ClangdServer::Options Opts = ClangdServer::optsForTest(); Opts.StaticIndex = Index.get(); - ClangdServer Server(CDB, FS, DiagConsumer, Opts); + ClangdServer Server(CDB, FS, Opts); auto File = testPath("foo.cpp"); runAddDocument(Server, File, Text); return llvm::cantFail(runSignatureHelp(Server, File, Point)); @@ -1502,8 +1489,7 @@ FS.Files[FooCpp] = ""; MockCompilationDatabase CDB; - IgnoreDiagnostics DiagConsumer; - ClangdServer Server(CDB, FS, DiagConsumer, ClangdServer::optsForTest()); + ClangdServer Server(CDB, FS, ClangdServer::optsForTest()); Annotations Source(R"cpp( #include "foo.h" @@ -1537,8 +1523,7 @@ FS.Files[FooCpp] = ""; MockCompilationDatabase CDB; - IgnoreDiagnostics DiagConsumer; - ClangdServer Server(CDB, FS, DiagConsumer, ClangdServer::optsForTest()); + ClangdServer Server(CDB, FS, ClangdServer::optsForTest()); Annotations Source(R"cpp( // We ignore namespace comments, for rationale see CodeCompletionStrings.h. @@ -1602,11 +1587,10 @@ auto FooCpp = testPath("foo.cpp"); MockCompilationDatabase CDB; - IgnoreDiagnostics DiagConsumer; MockFSProvider FS; FS.Files[FooCpp] = "// empty file"; - ClangdServer Server(CDB, FS, DiagConsumer, ClangdServer::optsForTest()); + ClangdServer Server(CDB, FS, ClangdServer::optsForTest()); // Run completion outside the file range. Position Pos; Pos.line = 100; @@ -1726,8 +1710,7 @@ TEST(CompletionTest, FixItForArrowToDot) { MockFSProvider FS; MockCompilationDatabase CDB; - IgnoreDiagnostics DiagConsumer; - ClangdServer Server(CDB, FS, DiagConsumer, ClangdServer::optsForTest()); + ClangdServer Server(CDB, FS, ClangdServer::optsForTest()); CodeCompleteOptions Opts; Opts.IncludeFixIts = true; @@ -1766,8 +1749,7 @@ TEST(CompletionTest, FixItForDotToArrow) { MockFSProvider FS; MockCompilationDatabase CDB; - IgnoreDiagnostics DiagConsumer; - ClangdServer Server(CDB, FS, DiagConsumer, ClangdServer::optsForTest()); + ClangdServer Server(CDB, FS, ClangdServer::optsForTest()); CodeCompleteOptions Opts; Opts.IncludeFixIts = true; @@ -1846,8 +1828,7 @@ TEST(CompletionTest, CompletionTokenRange) { MockFSProvider FS; MockCompilationDatabase CDB; - IgnoreDiagnostics DiagConsumer; - ClangdServer Server(CDB, FS, DiagConsumer, ClangdServer::optsForTest()); + ClangdServer Server(CDB, FS, ClangdServer::optsForTest()); constexpr const char *TestCodes[] = { R"cpp( @@ -2004,10 +1985,9 @@ TEST(SignatureHelpTest, DynamicIndexDocumentation) { MockFSProvider FS; MockCompilationDatabase CDB; - IgnoreDiagnostics DiagConsumer; ClangdServer::Options Opts = ClangdServer::optsForTest(); Opts.BuildDynamicSymbolIndex = true; - ClangdServer Server(CDB, FS, DiagConsumer, Opts); + ClangdServer Server(CDB, FS, Opts); FS.Files[testPath("foo.h")] = R"cpp( struct Foo { @@ -2176,8 +2156,7 @@ TEST(CompletionTest, EnableSpeculativeIndexRequest) { MockFSProvider FS; MockCompilationDatabase CDB; - IgnoreDiagnostics DiagConsumer; - ClangdServer Server(CDB, FS, DiagConsumer, ClangdServer::optsForTest()); + ClangdServer Server(CDB, FS, ClangdServer::optsForTest()); auto File = testPath("foo.cpp"); Annotations Test(R"cpp( @@ -2235,8 +2214,7 @@ std::string FooHeader = testPath("foo.h"); FS.Files[FooHeader] = ""; - IgnoreDiagnostics DiagConsumer; - ClangdServer Server(CDB, FS, DiagConsumer, ClangdServer::optsForTest()); + ClangdServer Server(CDB, FS, ClangdServer::optsForTest()); std::string DeclFile = URI::create(testPath("foo")).toString(); Symbol Sym = func("Func"); @@ -2266,8 +2244,7 @@ MockCompilationDatabase CDB; std::string FooHeader = testPath("foo.h"); FS.Files[FooHeader] = "#define CLANGD_PREAMBLE_HEADER x\n"; - IgnoreDiagnostics DiagConsumer; - ClangdServer Server(CDB, FS, DiagConsumer, ClangdServer::optsForTest()); + ClangdServer Server(CDB, FS, ClangdServer::optsForTest()); auto Results = completions( R"cpp(#include "foo.h" #define CLANGD_PREAMBLE_MAIN x @@ -2396,8 +2373,7 @@ CDB.ExtraClangFlags = {SearchDirArg.c_str()}; std::string BarHeader = testPath("sub/bar.h"); FS.Files[BarHeader] = ""; - IgnoreDiagnostics DiagConsumer; - ClangdServer Server(CDB, FS, DiagConsumer, ClangdServer::optsForTest()); + ClangdServer Server(CDB, FS, ClangdServer::optsForTest()); auto Results = completions(Server, R"cpp( #include "^" diff --git a/clang-tools-extra/clangd/unittests/FindSymbolsTests.cpp b/clang-tools-extra/clangd/unittests/FindSymbolsTests.cpp --- a/clang-tools-extra/clangd/unittests/FindSymbolsTests.cpp +++ b/clang-tools-extra/clangd/unittests/FindSymbolsTests.cpp @@ -25,11 +25,6 @@ using ::testing::IsEmpty; using ::testing::UnorderedElementsAre; -class IgnoreDiagnostics : public DiagnosticsConsumer { - void onDiagnosticsReady(PathRef File, - std::vector Diagnostics) override {} -}; - // GMock helpers for matching SymbolInfos items. MATCHER_P(QName, Name, "") { if (arg.containerName.empty()) @@ -56,8 +51,7 @@ class WorkspaceSymbolsTest : public ::testing::Test { public: - WorkspaceSymbolsTest() - : Server(CDB, FSProvider, DiagConsumer, optsForTests()) { + WorkspaceSymbolsTest() : Server(CDB, FSProvider, optsForTests()) { // Make sure the test root directory is created. FSProvider.Files[testPath("unused")] = ""; CDB.ExtraClangFlags = {"-xc++"}; @@ -66,7 +60,6 @@ protected: MockFSProvider FSProvider; MockCompilationDatabase CDB; - IgnoreDiagnostics DiagConsumer; ClangdServer Server; int Limit = 0; @@ -316,13 +309,11 @@ namespace { class DocumentSymbolsTest : public ::testing::Test { public: - DocumentSymbolsTest() - : Server(CDB, FSProvider, DiagConsumer, optsForTests()) {} + DocumentSymbolsTest() : Server(CDB, FSProvider, optsForTests()) {} protected: MockFSProvider FSProvider; MockCompilationDatabase CDB; - IgnoreDiagnostics DiagConsumer; ClangdServer Server; std::vector getSymbols(PathRef File) { diff --git a/clang-tools-extra/clangd/unittests/HeaderSourceSwitchTests.cpp b/clang-tools-extra/clangd/unittests/HeaderSourceSwitchTests.cpp --- a/clang-tools-extra/clangd/unittests/HeaderSourceSwitchTests.cpp +++ b/clang-tools-extra/clangd/unittests/HeaderSourceSwitchTests.cpp @@ -249,10 +249,6 @@ } TEST(HeaderSourceSwitchTest, ClangdServerIntegration) { - class IgnoreDiagnostics : public DiagnosticsConsumer { - void onDiagnosticsReady(PathRef File, - std::vector Diagnostics) override {} - } DiagConsumer; MockCompilationDatabase CDB; CDB.ExtraClangFlags = {"-I" + testPath("src/include")}; // add search directory. @@ -268,7 +264,7 @@ FS.Files[CppPath] = FileContent; auto Options = ClangdServer::optsForTest(); Options.BuildDynamicSymbolIndex = true; - ClangdServer Server(CDB, FS, DiagConsumer, Options); + ClangdServer Server(CDB, FS, Options); runAddDocument(Server, CppPath, FileContent); EXPECT_EQ(HeaderPath, *llvm::cantFail(runSwitchHeaderSource(Server, CppPath))); diff --git a/clang-tools-extra/clangd/unittests/RenameTests.cpp b/clang-tools-extra/clangd/unittests/RenameTests.cpp --- a/clang-tools-extra/clangd/unittests/RenameTests.cpp +++ b/clang-tools-extra/clangd/unittests/RenameTests.cpp @@ -755,10 +755,6 @@ TEST(CrossFileRenameTests, WithUpToDateIndex) { MockCompilationDatabase CDB; CDB.ExtraClangFlags = {"-xc++"}; - class IgnoreDiagnostics : public DiagnosticsConsumer { - void onDiagnosticsReady(PathRef File, - std::vector Diagnostics) override {} - } DiagConsumer; // rename is runnning on all "^" points in FooH, and "[[]]" ranges are the // expected rename occurrences. struct Case { @@ -902,7 +898,7 @@ auto ServerOpts = ClangdServer::optsForTest(); ServerOpts.CrossFileRename = true; ServerOpts.BuildDynamicSymbolIndex = true; - ClangdServer Server(CDB, FS, DiagConsumer, ServerOpts); + ClangdServer Server(CDB, FS, ServerOpts); // Add all files to clangd server to make sure the dynamic index has been // built. diff --git a/clang-tools-extra/clangd/unittests/SemanticHighlightingTests.cpp b/clang-tools-extra/clangd/unittests/SemanticHighlightingTests.cpp --- a/clang-tools-extra/clangd/unittests/SemanticHighlightingTests.cpp +++ b/clang-tools-extra/clangd/unittests/SemanticHighlightingTests.cpp @@ -696,11 +696,10 @@ } TEST(SemanticHighlighting, GeneratesHighlightsWhenFileChange) { - class HighlightingsCounterDiagConsumer : public DiagnosticsConsumer { + class HighlightingsCounter : public ClangdServer::Callbacks { public: std::atomic Count = {0}; - void onDiagnosticsReady(PathRef, std::vector) override {} void onHighlightingsReady( PathRef File, std::vector Highlightings) override { ++Count; @@ -712,11 +711,11 @@ FS.Files[FooCpp] = ""; MockCompilationDatabase MCD; - HighlightingsCounterDiagConsumer DiagConsumer; - ClangdServer Server(MCD, FS, DiagConsumer, ClangdServer::optsForTest()); + HighlightingsCounter Counter; + ClangdServer Server(MCD, FS, ClangdServer::optsForTest(), &Counter); Server.addDocument(FooCpp, "int a;"); ASSERT_TRUE(Server.blockUntilIdleForTest()) << "Waiting for server"; - ASSERT_EQ(DiagConsumer.Count, 1); + ASSERT_EQ(Counter.Count, 1); } TEST(SemanticHighlighting, toSemanticHighlightingInformation) { diff --git a/clang-tools-extra/clangd/unittests/SemanticSelectionTests.cpp b/clang-tools-extra/clangd/unittests/SemanticSelectionTests.cpp --- a/clang-tools-extra/clangd/unittests/SemanticSelectionTests.cpp +++ b/clang-tools-extra/clangd/unittests/SemanticSelectionTests.cpp @@ -26,11 +26,6 @@ namespace { using ::testing::ElementsAreArray; -class IgnoreDiagnostics : public DiagnosticsConsumer { - void onDiagnosticsReady(PathRef File, - std::vector Diagnostics) override {} -}; - TEST(SemanticSelection, All) { const char *Tests[] = { R"cpp( // Single statement in a function body. @@ -146,9 +141,8 @@ TEST(SemanticSelection, RunViaClangDServer) { MockFSProvider FS; - IgnoreDiagnostics DiagConsumer; MockCompilationDatabase CDB; - ClangdServer Server(CDB, FS, DiagConsumer, ClangdServer::optsForTest()); + ClangdServer Server(CDB, FS, ClangdServer::optsForTest()); auto FooH = testPath("foo.h"); FS.Files[FooH] = R"cpp( diff --git a/clang-tools-extra/clangd/unittests/TUSchedulerTests.cpp b/clang-tools-extra/clangd/unittests/TUSchedulerTests.cpp --- a/clang-tools-extra/clangd/unittests/TUSchedulerTests.cpp +++ b/clang-tools-extra/clangd/unittests/TUSchedulerTests.cpp @@ -700,7 +700,7 @@ } TEST_F(TUSchedulerTests, TUStatus) { - class CaptureTUStatus : public DiagnosticsConsumer { + class CaptureTUStatus : public ClangdServer::Callbacks { public: void onDiagnosticsReady(PathRef File, std::vector Diagnostics) override {} @@ -721,7 +721,7 @@ } CaptureTUStatus; MockFSProvider FS; MockCompilationDatabase CDB; - ClangdServer Server(CDB, FS, CaptureTUStatus, ClangdServer::optsForTest()); + ClangdServer Server(CDB, FS, ClangdServer::optsForTest(), &CaptureTUStatus); Annotations Code("int m^ain () {}"); // We schedule the following tasks in the queue: diff --git a/clang-tools-extra/clangd/unittests/XRefsTests.cpp b/clang-tools-extra/clangd/unittests/XRefsTests.cpp --- a/clang-tools-extra/clangd/unittests/XRefsTests.cpp +++ b/clang-tools-extra/clangd/unittests/XRefsTests.cpp @@ -42,11 +42,6 @@ using ::testing::Matcher; using ::testing::UnorderedElementsAreArray; -class IgnoreDiagnostics : public DiagnosticsConsumer { - void onDiagnosticsReady(PathRef File, - std::vector Diagnostics) override {} -}; - MATCHER_P2(FileRange, File, Range, "") { return Location{URIForFile::canonicalize(File, testRoot()), Range} == arg; } @@ -692,9 +687,8 @@ std::string BuildDir = testPath("build"); MockCompilationDatabase CDB(BuildDir, RelPathPrefix); - IgnoreDiagnostics DiagConsumer; MockFSProvider FS; - ClangdServer Server(CDB, FS, DiagConsumer, ClangdServer::optsForTest()); + ClangdServer Server(CDB, FS, ClangdServer::optsForTest()); // Fill the filesystem. auto FooCpp = testPath("src/foo.cpp"); @@ -729,9 +723,8 @@ TEST(GoToInclude, All) { MockFSProvider FS; - IgnoreDiagnostics DiagConsumer; MockCompilationDatabase CDB; - ClangdServer Server(CDB, FS, DiagConsumer, ClangdServer::optsForTest()); + ClangdServer Server(CDB, FS, ClangdServer::optsForTest()); auto FooCpp = testPath("foo.cpp"); const char *SourceContents = R"cpp( @@ -804,9 +797,8 @@ // Test stragety: AST should always use the latest preamble instead of last // good preamble. MockFSProvider FS; - IgnoreDiagnostics DiagConsumer; MockCompilationDatabase CDB; - ClangdServer Server(CDB, FS, DiagConsumer, ClangdServer::optsForTest()); + ClangdServer Server(CDB, FS, ClangdServer::optsForTest()); auto FooCpp = testPath("foo.cpp"); // The trigger locations must be the same.