summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--clang-tools-extra/clangd/ClangdServer.cpp16
-rw-r--r--clang-tools-extra/clangd/ClangdServer.h4
-rw-r--r--clang-tools-extra/clangd/unittests/SemanticSelectionTests.cpp38
-rw-r--r--clang-tools-extra/clangd/unittests/SyncAPI.cpp7
-rw-r--r--clang-tools-extra/clangd/unittests/SyncAPI.h3
5 files changed, 66 insertions, 2 deletions
diff --git a/clang-tools-extra/clangd/ClangdServer.cpp b/clang-tools-extra/clangd/ClangdServer.cpp
index 5b850e6ab47..71a1a99a330 100644
--- a/clang-tools-extra/clangd/ClangdServer.cpp
+++ b/clang-tools-extra/clangd/ClangdServer.cpp
@@ -17,6 +17,7 @@
#include "Preamble.h"
#include "Protocol.h"
#include "SemanticHighlighting.h"
+#include "SemanticSelection.h"
#include "SourceCode.h"
#include "TUScheduler.h"
#include "Trace.h"
@@ -125,8 +126,8 @@ ClangdServer::ClangdServer(const GlobalCompilationDatabase &CDB,
// critical paths.
WorkScheduler(
CDB, Opts.AsyncThreadsCount, Opts.StorePreamblesInMemory,
- std::make_unique<UpdateIndexCallbacks>(
- DynamicIdx.get(), DiagConsumer, Opts.SemanticHighlighting),
+ std::make_unique<UpdateIndexCallbacks>(DynamicIdx.get(), DiagConsumer,
+ Opts.SemanticHighlighting),
Opts.UpdateDebounce, Opts.RetentionPolicy) {
// Adds an index to the stack, at higher priority than existing indexes.
auto AddIndex = [&](SymbolIndex *Idx) {
@@ -620,6 +621,17 @@ void ClangdServer::symbolInfo(PathRef File, Position Pos,
WorkScheduler.runWithAST("SymbolInfo", File, std::move(Action));
}
+void ClangdServer::semanticRanges(PathRef File, Position Pos,
+ Callback<std::vector<Range>> CB) {
+ auto Action =
+ [Pos, CB = std::move(CB)](llvm::Expected<InputsAndAST> InpAST) mutable {
+ if (!InpAST)
+ return CB(InpAST.takeError());
+ CB(clangd::getSemanticRanges(InpAST->AST, Pos));
+ };
+ WorkScheduler.runWithAST("SemanticRanges", File, std::move(Action));
+}
+
std::vector<std::pair<Path, std::size_t>>
ClangdServer::getUsedBytesPerFile() const {
return WorkScheduler.getUsedBytesPerFile();
diff --git a/clang-tools-extra/clangd/ClangdServer.h b/clang-tools-extra/clangd/ClangdServer.h
index 36e4a894da6..4d268bf3628 100644
--- a/clang-tools-extra/clangd/ClangdServer.h
+++ b/clang-tools-extra/clangd/ClangdServer.h
@@ -277,6 +277,10 @@ public:
void symbolInfo(PathRef File, Position Pos,
Callback<std::vector<SymbolDetails>> CB);
+ /// Get semantic ranges around a specified position in a file.
+ void semanticRanges(PathRef File, Position Pos,
+ Callback<std::vector<Range>> CB);
+
/// Returns estimated memory usage for each of the currently open files.
/// The order of results is unspecified.
/// Overall memory usage of clangd may be significantly more than reported
diff --git a/clang-tools-extra/clangd/unittests/SemanticSelectionTests.cpp b/clang-tools-extra/clangd/unittests/SemanticSelectionTests.cpp
index cd29da2a43d..b9ca0273a82 100644
--- a/clang-tools-extra/clangd/unittests/SemanticSelectionTests.cpp
+++ b/clang-tools-extra/clangd/unittests/SemanticSelectionTests.cpp
@@ -7,10 +7,13 @@
//===----------------------------------------------------------------------===//
#include "Annotations.h"
+#include "ClangdServer.h"
#include "Matchers.h"
#include "Protocol.h"
#include "SemanticSelection.h"
#include "SourceCode.h"
+#include "SyncAPI.h"
+#include "TestFS.h"
#include "TestTU.h"
#include "clang/Basic/SourceLocation.h"
#include "clang/Basic/SourceManager.h"
@@ -23,6 +26,11 @@ namespace clangd {
namespace {
using ::testing::ElementsAreArray;
+class IgnoreDiagnostics : public DiagnosticsConsumer {
+ void onDiagnosticsReady(PathRef File,
+ std::vector<Diag> Diagnostics) override {}
+};
+
TEST(SemanticSelection, All) {
const char *Tests[] = {
R"cpp( // Single statement in a function body.
@@ -138,6 +146,36 @@ TEST(SemanticSelection, All) {
<< Test;
}
}
+
+TEST(SemanticSelection, RunViaClangDServer) {
+ MockFSProvider FS;
+ IgnoreDiagnostics DiagConsumer;
+ MockCompilationDatabase CDB;
+ ClangdServer Server(CDB, FS, DiagConsumer, ClangdServer::optsForTest());
+
+ auto FooH = testPath("foo.h");
+ FS.Files[FooH] = R"cpp(
+ int foo(int x);
+ #define HASH(x) ((x) % 10)
+ )cpp";
+
+ auto FooCpp = testPath("Foo.cpp");
+ const char *SourceContents = R"cpp(
+ #include "foo.h"
+ [[void bar(int& inp) [[{
+ // inp = HASH(foo(inp));
+ [[inp = [[HASH([[foo([[in^p]])]])]]]];
+ }]]]]
+ )cpp";
+ Annotations SourceAnnotations(SourceContents);
+ FS.Files[FooCpp] = SourceAnnotations.code();
+ Server.addDocument(FooCpp, SourceAnnotations.code());
+
+ auto Ranges = runSemanticRanges(Server, FooCpp, SourceAnnotations.point());
+ ASSERT_TRUE(bool(Ranges))
+ << "getSemanticRange returned an error: " << Ranges.takeError();
+ EXPECT_THAT(*Ranges, ElementsAreArray(SourceAnnotations.ranges()));
+}
} // namespace
} // namespace clangd
} // namespace clang
diff --git a/clang-tools-extra/clangd/unittests/SyncAPI.cpp b/clang-tools-extra/clangd/unittests/SyncAPI.cpp
index af9ef9ffa1e..ac7c2dcabbd 100644
--- a/clang-tools-extra/clangd/unittests/SyncAPI.cpp
+++ b/clang-tools-extra/clangd/unittests/SyncAPI.cpp
@@ -145,5 +145,12 @@ RefSlab getRefs(const SymbolIndex &Index, SymbolID ID) {
return std::move(Slab).build();
}
+llvm::Expected<std::vector<Range>>
+runSemanticRanges(ClangdServer &Server, PathRef File, Position Pos) {
+ llvm::Optional<llvm::Expected<std::vector<Range>>> Result;
+ Server.semanticRanges(File, Pos, capture(Result));
+ return std::move(*Result);
+}
+
} // namespace clangd
} // namespace clang
diff --git a/clang-tools-extra/clangd/unittests/SyncAPI.h b/clang-tools-extra/clangd/unittests/SyncAPI.h
index c1416524153..1ba9c0b3d23 100644
--- a/clang-tools-extra/clangd/unittests/SyncAPI.h
+++ b/clang-tools-extra/clangd/unittests/SyncAPI.h
@@ -53,6 +53,9 @@ SymbolSlab runFuzzyFind(const SymbolIndex &Index, StringRef Query);
SymbolSlab runFuzzyFind(const SymbolIndex &Index, const FuzzyFindRequest &Req);
RefSlab getRefs(const SymbolIndex &Index, SymbolID ID);
+llvm::Expected<std::vector<Range>>
+runSemanticRanges(ClangdServer &Server, PathRef File, Position Pos);
+
} // namespace clangd
} // namespace clang
OpenPOWER on IntegriCloud