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 @@ -58,6 +58,8 @@ void onHighlightingsReady(PathRef File, std::vector Highlightings) override; + void onInactiveRegionsReady(PathRef File, + std::vector InactiveRegions) override; // LSP methods. Notifications have signature void(const Params&). // Calls have signature void(const Params&, Callback). @@ -125,6 +127,9 @@ /// Sends a "publishSemanticHighlighting" notification to the LSP client. void publishSemanticHighlighting(SemanticHighlightingParams Params); + /// Sends a "publishInactiveRegions" notification to the LSP client. + void publishInactiveRegions(InactiveRegionsParams Params); + /// Sends a "publishDiagnostics" notification to the LSP client. void publishDiagnostics(const URIForFile &File, std::vector Diagnostics); 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 @@ -1056,6 +1056,10 @@ notify("textDocument/semanticHighlighting", Params); } +void ClangdLSPServer::publishInactiveRegions(InactiveRegionsParams Params) { + notify("textDocument/inactiveRegions", Params); +} + void ClangdLSPServer::publishDiagnostics( const URIForFile &File, std::vector Diagnostics) { // Publish diagnostics. @@ -1211,6 +1215,12 @@ toSemanticHighlightingInformation(Diffed)}); } +void ClangdLSPServer::onInactiveRegionsReady( + PathRef File, std::vector InactiveRegions) { + publishInactiveRegions( + {{URIForFile::canonicalize(File, /*TUPath=*/File)}, InactiveRegions}); +} + void ClangdLSPServer::onDiagnosticsReady(PathRef File, std::vector Diagnostics) { auto URI = URIForFile::canonicalize(File, /*TUPath=*/File); 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 @@ -52,11 +52,13 @@ virtual void onFileUpdated(PathRef File, const TUStatus &Status){}; /// Called by ClangdServer when some \p Highlightings for \p File are ready. - /// \p NumLines are the number of lines in the file where the highlightings - /// where generated from. virtual void onHighlightingsReady(PathRef File, std::vector Highlightings) {} + + /// Called by ClangdServer when some \p InactiveRegions for \p File are ready. + virtual void onInactiveRegionsReady(PathRef File, + std::vector InactiveRegions) {} }; /// When set, used by ClangdServer to get clang-tidy options for each particular 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 @@ -53,9 +53,10 @@ // Update the FileIndex with new ASTs and plumb the diagnostics responses. struct UpdateIndexCallbacks : public ParsingCallbacks { UpdateIndexCallbacks(FileIndex *FIndex, DiagnosticsConsumer &DiagConsumer, - bool SemanticHighlighting) + bool SemanticHighlighting, bool CollectInactiveRegions) : FIndex(FIndex), DiagConsumer(DiagConsumer), - SemanticHighlighting(SemanticHighlighting) {} + SemanticHighlighting(SemanticHighlighting), + CollectInactiveRegions(CollectInactiveRegions) {} void onPreambleAST(PathRef Path, ASTContext &Ctx, std::shared_ptr PP, @@ -70,13 +71,18 @@ std::vector Diagnostics = AST.getDiagnostics(); std::vector Highlightings; + std::vector InactiveRegions; if (SemanticHighlighting) Highlightings = getSemanticHighlightings(AST); + if (CollectInactiveRegions) + InactiveRegions = getInactiveRegions(AST); Publish([&]() { DiagConsumer.onDiagnosticsReady(Path, std::move(Diagnostics)); if (SemanticHighlighting) DiagConsumer.onHighlightingsReady(Path, std::move(Highlightings)); + if (CollectInactiveRegions) + DiagConsumer.onInactiveRegionsReady(Path, std::move(InactiveRegions)); }); } @@ -93,6 +99,7 @@ FileIndex *FIndex; DiagnosticsConsumer &DiagConsumer; bool SemanticHighlighting; + bool CollectInactiveRegions; }; } // namespace @@ -124,7 +131,9 @@ WorkScheduler( CDB, Opts.AsyncThreadsCount, Opts.StorePreamblesInMemory, std::make_unique( - DynamicIdx.get(), DiagConsumer, Opts.SemanticHighlighting), + DynamicIdx.get(), DiagConsumer, Opts.SemanticHighlighting, + /*CollectInactiveRegions=*/true), // TODO(nridge): allow proper + // configuration Opts.UpdateDebounce, Opts.RetentionPolicy) { // Adds an index to the stack, at higher priority than existing indexes. auto AddIndex = [&](SymbolIndex *Idx) { diff --git a/clang-tools-extra/clangd/Compiler.cpp b/clang-tools-extra/clangd/Compiler.cpp --- a/clang-tools-extra/clangd/Compiler.cpp +++ b/clang-tools-extra/clangd/Compiler.cpp @@ -63,6 +63,7 @@ // createInvocationFromCommandLine sets DisableFree. CI->getFrontendOpts().DisableFree = false; CI->getLangOpts()->CommentOpts.ParseAllComments = true; + CI->getPreprocessorOpts().DetailedRecord = true; return CI; } diff --git a/clang-tools-extra/clangd/Protocol.h b/clang-tools-extra/clangd/Protocol.h --- a/clang-tools-extra/clangd/Protocol.h +++ b/clang-tools-extra/clangd/Protocol.h @@ -1222,6 +1222,15 @@ }; llvm::json::Value toJSON(const SemanticHighlightingParams &Highlighting); +/// Parameters for the inactive regions (server-side) push notification. +struct InactiveRegionsParams { + /// The textdocument these inactive regions belong to. + TextDocumentIdentifier TextDocument; + /// The inactive regions that should be sent. + std::vector InactiveRegions; +}; +llvm::json::Value toJSON(const InactiveRegionsParams &InactiveRegions); + } // namespace clangd } // namespace clang diff --git a/clang-tools-extra/clangd/Protocol.cpp b/clang-tools-extra/clangd/Protocol.cpp --- a/clang-tools-extra/clangd/Protocol.cpp +++ b/clang-tools-extra/clangd/Protocol.cpp @@ -1073,5 +1073,11 @@ }; } +llvm::json::Value toJSON(const InactiveRegionsParams &InactiveRegions) { + return llvm::json::Object{ + {"textDocument", InactiveRegions.TextDocument}, + {"regions", std::move(InactiveRegions.InactiveRegions)}}; +} + } // namespace clangd } // namespace clang diff --git a/clang-tools-extra/clangd/SemanticHighlighting.h b/clang-tools-extra/clangd/SemanticHighlighting.h --- a/clang-tools-extra/clangd/SemanticHighlighting.h +++ b/clang-tools-extra/clangd/SemanticHighlighting.h @@ -85,6 +85,10 @@ diffHighlightings(ArrayRef New, ArrayRef Old); +// Returns all inactive regions from an AST. Only generates inactive regions +// for the main AST. +std::vector getInactiveRegions(ParsedAST &AST); + } // namespace clangd } // namespace clang diff --git a/clang-tools-extra/clangd/SemanticHighlighting.cpp b/clang-tools-extra/clangd/SemanticHighlighting.cpp --- a/clang-tools-extra/clangd/SemanticHighlighting.cpp +++ b/clang-tools-extra/clangd/SemanticHighlighting.cpp @@ -479,5 +479,18 @@ llvm_unreachable("unhandled HighlightingKind"); } +std::vector getInactiveRegions(ParsedAST &AST) { + std::vector Result; + const SourceManager &SM = AST.getSourceManager(); + for (const SourceRange &R : + AST.getPreprocessor().getPreprocessingRecord()->getSkippedRanges()) { + if (isInsideMainFile(R.getBegin(), SM)) { + Result.push_back({sourceLocToPosition(SM, R.getBegin()), + sourceLocToPosition(SM, R.getEnd())}); + } + } + return Result; +} + } // namespace clangd } // namespace clang