// Update the FileIndex with new ASTs and plumb the diagnostics responses.
struct UpdateIndexCallbacks : public ParsingCallbacks {
- UpdateIndexCallbacks(FileIndex *FIndex, DiagnosticsConsumer &DiagConsumer)
- : FIndex(FIndex), DiagConsumer(DiagConsumer) {}
+ UpdateIndexCallbacks(FileIndex *FIndex, DiagnosticsConsumer &DiagConsumer,
+ bool SemanticHighlighting)
+ : FIndex(FIndex), DiagConsumer(DiagConsumer),
+ SemanticHighlighting(SemanticHighlighting) {}
void onPreambleAST(PathRef Path, ASTContext &Ctx,
std::shared_ptr<clang::Preprocessor> PP,
void onMainAST(PathRef Path, ParsedAST &AST) override {
if (FIndex)
FIndex->updateMain(Path, AST);
+ if (SemanticHighlighting)
+ DiagConsumer.onHighlightingsReady(Path, getSemanticHighlightings(AST));
}
void onDiagnostics(PathRef File, std::vector<Diag> Diags) override {
private:
FileIndex *FIndex;
DiagnosticsConsumer &DiagConsumer;
+ bool SemanticHighlighting;
};
} // namespace
Opts.UpdateDebounce = std::chrono::steady_clock::duration::zero(); // Faster!
Opts.StorePreamblesInMemory = true;
Opts.AsyncThreadsCount = 4; // Consistent!
+ Opts.SemanticHighlighting = true;
return Opts;
}
// 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,
- llvm::make_unique<UpdateIndexCallbacks>(DynamicIdx.get(),
- DiagConsumer),
- Opts.UpdateDebounce, Opts.RetentionPolicy) {
+ WorkScheduler(
+ CDB, Opts.AsyncThreadsCount, Opts.StorePreamblesInMemory,
+ llvm::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) {
if (this->Index != nullptr) {
#include "Function.h"
#include "GlobalCompilationDatabase.h"
#include "Protocol.h"
+#include "SemanticHighlighting.h"
#include "TUScheduler.h"
#include "XRefs.h"
#include "index/Background.h"
std::vector<Diag> 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<HighlightingToken> Highlightings) {}
};
/// When set, used by ClangdServer to get clang-tidy options for each particular
/// Clangd will execute compiler drivers matching one of these globs to
/// fetch system include path.
std::vector<std::string> QueryDriverGlobs;
+
+ /// Enable semantic highlighting features.
+ bool SemanticHighlighting = false;
};
// Sensible default options for use in tests.
// Features like indexing must be enabled if desired.
// can be caused by missing includes (e.g. member access in incomplete type).
bool SuggestMissingIncludes = false;
bool EnableHiddenFeatures = false;
-
+
// GUARDED_BY(CachedCompletionFuzzyFindRequestMutex)
llvm::StringMap<llvm::Optional<FuzzyFindRequest>>
CachedCompletionFuzzyFindRequestByFile;
//===----------------------------------------------------------------------===//
#include "Annotations.h"
+#include "ClangdServer.h"
#include "SemanticHighlighting.h"
+#include "TestFS.h"
#include "TestTU.h"
#include "gmock/gmock.h"
}
}
+TEST(ClangdSemanticHighlightingTest, GeneratesHighlightsWhenFileChange) {
+ class HighlightingsCounterDiagConsumer : public DiagnosticsConsumer {
+ public:
+ std::atomic<int> Count = {0};
+
+ void onDiagnosticsReady(PathRef, std::vector<Diag>) override {}
+ void onHighlightingsReady(
+ PathRef File, std::vector<HighlightingToken> Highlightings) override {
+ ++Count;
+ }
+ };
+
+ auto FooCpp = testPath("foo.cpp");
+ MockFSProvider FS;
+ FS.Files[FooCpp] = "";
+
+ MockCompilationDatabase MCD;
+ HighlightingsCounterDiagConsumer DiagConsumer;
+ ClangdServer Server(MCD, FS, DiagConsumer, ClangdServer::optsForTest());
+ Server.addDocument(FooCpp, "int a;");
+ ASSERT_TRUE(Server.blockUntilIdleForTest()) << "Waiting for server";
+ ASSERT_EQ(DiagConsumer.Count, 1);
+}
+
} // namespace
} // namespace clangd
} // namespace clang