[clang-tools-extra] 32626bc - [clangd] Add ClangdServer::customAction() extension point
Sam McCall via cfe-commits
cfe-commits at lists.llvm.org
Thu Aug 13 03:26:45 PDT 2020
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
More information about the cfe-commits
mailing list