Author: Sam McCall Date: 2020-08-13T12:26:32+02:00 New Revision: 32626bcc0b9b1180db7eebc46c45faff7905bd05
URL: https://github.com/llvm/llvm-project/commit/32626bcc0b9b1180db7eebc46c45faff7905bd05 DIFF: https://github.com/llvm/llvm-project/commit/32626bcc0b9b1180db7eebc46c45faff7905bd05.diff LOG: [clangd] Add ClangdServer::customAction() extension point This lets basic AST-consuming actions be defined outside clangdserver. (it essentially exposes TUScheduler::runWithAST). Two use cases for now: - replace ClangdServer::dumpAST, which doesn't really belong in the public interface (a followup patch will do this) - allow embedders to add/experiment with extra features (e.g. I know some who want to try crazy AST+ML code completion...) Maybe in the future we should use this sort of mechanism to make ClangdServer less of a monolith, but that's not in scope for now. This would probably require a richer and more carefully-thought-out API. Differential Revision: https://reviews.llvm.org/D85883 Added: Modified: clang-tools-extra/clangd/ClangdServer.cpp clang-tools-extra/clangd/ClangdServer.h clang-tools-extra/clangd/unittests/ClangdTests.cpp clang-tools-extra/clangd/unittests/SyncAPI.cpp clang-tools-extra/clangd/unittests/SyncAPI.h Removed: ################################################################################ diff --git a/clang-tools-extra/clangd/ClangdServer.cpp b/clang-tools-extra/clangd/ClangdServer.cpp index ec4855659501..919d59ab09d0 100644 --- a/clang-tools-extra/clangd/ClangdServer.cpp +++ b/clang-tools-extra/clangd/ClangdServer.cpp @@ -754,6 +754,11 @@ void ClangdServer::semanticHighlights( TUScheduler::InvalidateOnUpdate); } +void ClangdServer::customAction(PathRef File, llvm::StringRef Name, + Callback<InputsAndAST> Action) { + WorkScheduler.runWithAST(Name, File, std::move(Action)); +} + llvm::StringMap<TUScheduler::FileStats> ClangdServer::fileStats() const { return WorkScheduler.fileStats(); } diff --git a/clang-tools-extra/clangd/ClangdServer.h b/clang-tools-extra/clangd/ClangdServer.h index 3529e5050aa3..7aed7d4f3d85 100644 --- a/clang-tools-extra/clangd/ClangdServer.h +++ b/clang-tools-extra/clangd/ClangdServer.h @@ -317,6 +317,13 @@ class ClangdServer { void semanticHighlights(PathRef File, Callback<std::vector<HighlightingToken>>); + /// Runs an arbitrary action that has access to the AST of the specified file. + /// The action will execute on one of ClangdServer's internal threads. + /// The AST is only valid for the duration of the callback. + /// As with other actions, the file must have been opened. + void customAction(PathRef File, llvm::StringRef Name, + Callback<InputsAndAST> Action); + /// Returns estimated memory usage and other statistics for each of the /// currently open files. /// Overall memory usage of clangd may be significantly more than reported diff --git a/clang-tools-extra/clangd/unittests/ClangdTests.cpp b/clang-tools-extra/clangd/unittests/ClangdTests.cpp index c21719d58bd6..585fabe60ab7 100644 --- a/clang-tools-extra/clangd/unittests/ClangdTests.cpp +++ b/clang-tools-extra/clangd/unittests/ClangdTests.cpp @@ -15,6 +15,7 @@ #include "Matchers.h" #include "SyncAPI.h" #include "TestFS.h" +#include "TestTU.h" #include "URI.h" #include "support/Path.h" #include "support/Threading.h" @@ -28,6 +29,7 @@ #include "llvm/Support/Errc.h" #include "llvm/Support/Path.h" #include "llvm/Support/Regex.h" +#include "llvm/Testing/Support/Error.h" #include "gmock/gmock.h" #include "gtest/gtest.h" #include <algorithm> @@ -1141,6 +1143,21 @@ TEST_F(ClangdVFSTest, FallbackWhenWaitingForCompileCommand) { Field(&CodeCompletion::Scope, "ns::")))); } +TEST(ClangdServerTest, CustomAction) { + OverlayCDB CDB(/*Base=*/nullptr); + MockFS FS; + ClangdServer Server(CDB, FS, ClangdServer::optsForTest()); + + Server.addDocument(testPath("foo.cc"), "void x();"); + Decl::Kind XKind = Decl::TranslationUnit; + EXPECT_THAT_ERROR(runCustomAction(Server, testPath("foo.cc"), + [&](InputsAndAST AST) { + XKind = findDecl(AST.AST, "x").getKind(); + }), + llvm::Succeeded()); + EXPECT_EQ(XKind, Decl::Function); +} + // Tests fails when built with asan due to stack overflow. So skip running the // test as a workaround. #if !defined(__has_feature) || !__has_feature(address_sanitizer) diff --git a/clang-tools-extra/clangd/unittests/SyncAPI.cpp b/clang-tools-extra/clangd/unittests/SyncAPI.cpp index 36b028bd4d87..c356fb08d5dd 100644 --- a/clang-tools-extra/clangd/unittests/SyncAPI.cpp +++ b/clang-tools-extra/clangd/unittests/SyncAPI.cpp @@ -154,5 +154,20 @@ runSwitchHeaderSource(ClangdServer &Server, PathRef File) { return std::move(*Result); } +llvm::Error runCustomAction(ClangdServer &Server, PathRef File, + llvm::function_ref<void(InputsAndAST)> Action) { + llvm::Error Result = llvm::Error::success(); + Notification Done; + Server.customAction(File, "Custom", [&](llvm::Expected<InputsAndAST> AST) { + if (!AST) + Result = AST.takeError(); + else + Action(*AST); + Done.notify(); + }); + Done.wait(); + return Result; +} + } // namespace clangd } // namespace clang diff --git a/clang-tools-extra/clangd/unittests/SyncAPI.h b/clang-tools-extra/clangd/unittests/SyncAPI.h index e16b9d8ff19b..63a128d4ddcd 100644 --- a/clang-tools-extra/clangd/unittests/SyncAPI.h +++ b/clang-tools-extra/clangd/unittests/SyncAPI.h @@ -60,6 +60,9 @@ runSemanticRanges(ClangdServer &Server, PathRef File, llvm::Expected<llvm::Optional<clangd::Path>> runSwitchHeaderSource(ClangdServer &Server, PathRef File); +llvm::Error runCustomAction(ClangdServer &Server, PathRef File, + llvm::function_ref<void(InputsAndAST)>); + } // namespace clangd } // namespace clang _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits