jvikstrom updated this revision to Diff 206792.
jvikstrom added a comment.
Herald added a subscriber: jfb.

Moved semantic highlighting to be processed in onMainAST


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D63821/new/

https://reviews.llvm.org/D63821

Files:
  clang-tools-extra/clangd/ClangdLSPServer.cpp
  clang-tools-extra/clangd/ClangdLSPServer.h
  clang-tools-extra/clangd/ClangdServer.cpp
  clang-tools-extra/clangd/ClangdServer.h
  clang-tools-extra/clangd/SemanticHighlighting.cpp
  clang-tools-extra/clangd/SemanticHighlighting.h
  clang-tools-extra/clangd/unittests/ClangdTests.cpp
  clang-tools-extra/clangd/unittests/CodeCompleteTests.cpp
  clang-tools-extra/clangd/unittests/FindSymbolsTests.cpp
  clang-tools-extra/clangd/unittests/TUSchedulerTests.cpp
  clang-tools-extra/clangd/unittests/XRefsTests.cpp

Index: clang-tools-extra/clangd/unittests/XRefsTests.cpp
===================================================================
--- clang-tools-extra/clangd/unittests/XRefsTests.cpp
+++ clang-tools-extra/clangd/unittests/XRefsTests.cpp
@@ -36,6 +36,10 @@
 class IgnoreDiagnostics : public DiagnosticsConsumer {
   void onDiagnosticsReady(PathRef File,
                           std::vector<Diag> Diagnostics) override {}
+
+  virtual void
+  onHighlightingsReady(PathRef File,
+                    std::vector<HighlightingToken> Highlightings) override {}
 };
 
 MATCHER_P2(FileRange, File, Range, "") {
Index: clang-tools-extra/clangd/unittests/TUSchedulerTests.cpp
===================================================================
--- clang-tools-extra/clangd/unittests/TUSchedulerTests.cpp
+++ clang-tools-extra/clangd/unittests/TUSchedulerTests.cpp
@@ -677,6 +677,9 @@
       AllStatus.push_back(Status);
     }
 
+    virtual void onHighlightingsReady(
+        PathRef File, std::vector<HighlightingToken> Highlightings) override {}
+
     std::vector<TUStatus> allStatus() {
       std::lock_guard<std::mutex> Lock(Mutex);
       return AllStatus;
Index: clang-tools-extra/clangd/unittests/FindSymbolsTests.cpp
===================================================================
--- clang-tools-extra/clangd/unittests/FindSymbolsTests.cpp
+++ clang-tools-extra/clangd/unittests/FindSymbolsTests.cpp
@@ -29,6 +29,9 @@
 class IgnoreDiagnostics : public DiagnosticsConsumer {
   void onDiagnosticsReady(PathRef File,
                           std::vector<Diag> Diagnostics) override {}
+  virtual void
+  onHighlightingsReady(PathRef File,
+                    std::vector<HighlightingToken> Highlightings) override {}
 };
 
 // GMock helpers for matching SymbolInfos items.
Index: clang-tools-extra/clangd/unittests/CodeCompleteTests.cpp
===================================================================
--- clang-tools-extra/clangd/unittests/CodeCompleteTests.cpp
+++ clang-tools-extra/clangd/unittests/CodeCompleteTests.cpp
@@ -45,6 +45,9 @@
 class IgnoreDiagnostics : public DiagnosticsConsumer {
   void onDiagnosticsReady(PathRef File,
                           std::vector<Diag> Diagnostics) override {}
+  virtual void
+  onHighlightingsReady(PathRef File,
+                    std::vector<HighlightingToken> Highlightings) override {}
 };
 
 // GMock helpers for matching completion items.
Index: clang-tools-extra/clangd/unittests/ClangdTests.cpp
===================================================================
--- clang-tools-extra/clangd/unittests/ClangdTests.cpp
+++ clang-tools-extra/clangd/unittests/ClangdTests.cpp
@@ -73,6 +73,10 @@
     return HadErrorInLastDiags;
   }
 
+  virtual void
+  onHighlightingsReady(PathRef File,
+                    std::vector<HighlightingToken> Highlightings) override {}
+
 private:
   std::mutex Mutex;
   bool HadErrorInLastDiags = false;
@@ -101,6 +105,10 @@
     return Result;
   }
 
+  virtual void
+  onHighlightingsReady(PathRef File,
+                    std::vector<HighlightingToken> Highlightings) override {}
+
   void clear() {
     std::lock_guard<std::mutex> Lock(Mutex);
     LastDiagsHadError.clear();
@@ -279,6 +287,9 @@
                             std::vector<Diag> Diagnostics) override {
       Got = Context::current().getExisting(Secret);
     }
+  virtual void
+  onHighlightingsReady(PathRef File,
+                    std::vector<HighlightingToken> Highlightings) override {}
     int Got;
   } DiagConsumer;
   MockCompilationDatabase CDB;
@@ -610,6 +621,10 @@
       Stats[FileIndex].HadErrorsInLastDiags = HadError;
     }
 
+    virtual void
+    onHighlightingsReady(PathRef File,
+                      std::vector<HighlightingToken> Highlightings) override {}
+
     std::vector<FileStat> takeFileStats() {
       std::lock_guard<std::mutex> Lock(Mutex);
       return std::move(Stats);
@@ -845,6 +860,7 @@
   class NoConcurrentAccessDiagConsumer : public DiagnosticsConsumer {
   public:
     std::atomic<int> Count = {0};
+    std::atomic<int> HighlightingCount = {0};
 
     NoConcurrentAccessDiagConsumer(std::promise<void> StartSecondReparse)
         : StartSecondReparse(std::move(StartSecondReparse)) {}
@@ -865,6 +881,11 @@
       }
     }
 
+    virtual void onHighlightingsReady(
+        PathRef File, std::vector<HighlightingToken> Highlightings) override {
+      ++HighlightingCount;
+    }
+
   private:
     std::mutex Mutex;
     bool FirstRequest = true;
@@ -900,6 +921,7 @@
   Server.addDocument(FooCpp, SourceContentsWithoutErrors);
   ASSERT_TRUE(Server.blockUntilIdleForTest()) << "Waiting for diagnostics";
   ASSERT_EQ(DiagConsumer.Count, 2); // Sanity check - we actually ran both?
+  ASSERT_EQ(DiagConsumer.HighlightingCount, 2);
 }
 
 TEST_F(ClangdVFSTest, FormatCode) {
Index: clang-tools-extra/clangd/SemanticHighlighting.h
===================================================================
--- clang-tools-extra/clangd/SemanticHighlighting.h
+++ clang-tools-extra/clangd/SemanticHighlighting.h
@@ -30,6 +30,10 @@
 // Returns all HighlightingTokens from an AST. Only generates highlights for the
 // main AST.
 std::vector<HighlightingToken> getSemanticHighlightings(ParsedAST &AST);
+// Returns a map where all HighlightingKinds are mapped to a vector of TextMate
+// scopes.
+std::map<HighlightingKind, std::vector<std::string>>
+getSemanticHighlightingScopes();
 
 } // namespace clangd
 } // namespace clang
Index: clang-tools-extra/clangd/SemanticHighlighting.cpp
===================================================================
--- clang-tools-extra/clangd/SemanticHighlighting.cpp
+++ clang-tools-extra/clangd/SemanticHighlighting.cpp
@@ -74,5 +74,11 @@
   return HighlightingTokenCollector(AST).collectTokens();
 }
 
+std::map<HighlightingKind, std::vector<std::string>>
+getSemanticHighlightingScopes() {
+  return {{HighlightingKind::Variable, {"variable.cpp"}},
+          {HighlightingKind::Function, {"entity.name.function.cpp"}}};
+}
+
 } // namespace clangd
 } // namespace clang
Index: clang-tools-extra/clangd/ClangdServer.h
===================================================================
--- clang-tools-extra/clangd/ClangdServer.h
+++ clang-tools-extra/clangd/ClangdServer.h
@@ -18,6 +18,7 @@
 #include "Function.h"
 #include "GlobalCompilationDatabase.h"
 #include "Protocol.h"
+#include "SemanticHighlighting.h"
 #include "TUScheduler.h"
 #include "XRefs.h"
 #include "index/Background.h"
@@ -49,6 +50,10 @@
                                   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) = 0;
 };
 
 /// When set, used by ClangdServer to get clang-tidy options for each particular
@@ -131,6 +136,10 @@
     /// Clangd will execute compiler drivers matching one of these globs to
     /// fetch system include path.
     std::vector<std::string> QueryDriverGlobs;
+
+    // If true Clangd will generate semantic highlightings for the current
+    // document when it changes.
+    bool SemanticHighlightingEnabled = false;
   };
   // Sensible default options for use in tests.
   // Features like indexing must be enabled if desired.
@@ -148,6 +157,9 @@
   /// \p DiagConsumer. Note that a callback to \p DiagConsumer happens on a
   /// worker thread. Therefore, instances of \p DiagConsumer must properly
   /// synchronize access to shared state.
+  /// If semantic highlighting is enabled ClangdServer also generates semantic
+  /// highlightings for the file after each parsing request. When highlightings
+  /// are done generating they are sent to \p DiagConsumer.
   ClangdServer(const GlobalCompilationDatabase &CDB,
                const FileSystemProvider &FSProvider,
                DiagnosticsConsumer &DiagConsumer, const Options &Opts);
@@ -304,6 +316,9 @@
   // can be caused by missing includes (e.g. member access in incomplete type).
   bool SuggestMissingIncludes = false;
   bool EnableHiddenFeatures = false;
+  
+  // If this is true semantic highlighting will be generated.
+  bool SemanticHighlightingEnabled = false;
 
   // GUARDED_BY(CachedCompletionFuzzyFindRequestMutex)
   llvm::StringMap<llvm::Optional<FuzzyFindRequest>>
Index: clang-tools-extra/clangd/ClangdServer.cpp
===================================================================
--- clang-tools-extra/clangd/ClangdServer.cpp
+++ clang-tools-extra/clangd/ClangdServer.cpp
@@ -48,8 +48,10 @@
 
 // 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 SemanticHighlightingEnabled)
+      : FIndex(FIndex), DiagConsumer(DiagConsumer),
+        SemanticHighlightingEnabled(SemanticHighlightingEnabled) {}
 
   void onPreambleAST(PathRef Path, ASTContext &Ctx,
                      std::shared_ptr<clang::Preprocessor> PP,
@@ -61,6 +63,8 @@
   void onMainAST(PathRef Path, ParsedAST &AST) override {
     if (FIndex)
       FIndex->updateMain(Path, AST);
+    if (SemanticHighlightingEnabled)
+      DiagConsumer.onHighlightingsReady(Path, getSemanticHighlightings(AST));
   }
 
   void onDiagnostics(PathRef File, std::vector<Diag> Diags) override {
@@ -74,6 +78,7 @@
 private:
   FileIndex *FIndex;
   DiagnosticsConsumer &DiagConsumer;
+  bool SemanticHighlightingEnabled;
 };
 } // namespace
 
@@ -82,6 +87,7 @@
   Opts.UpdateDebounce = std::chrono::steady_clock::duration::zero(); // Faster!
   Opts.StorePreamblesInMemory = true;
   Opts.AsyncThreadsCount = 4; // Consistent!
+  Opts.SemanticHighlightingEnabled = true;
   return Opts;
 }
 
@@ -96,16 +102,18 @@
       GetClangTidyOptions(Opts.GetClangTidyOptions),
       SuggestMissingIncludes(Opts.SuggestMissingIncludes),
       EnableHiddenFeatures(Opts.HiddenFeatures),
+      SemanticHighlightingEnabled(Opts.SemanticHighlightingEnabled),
       WorkspaceRoot(Opts.WorkspaceRoot),
       // Pass a callback into `WorkScheduler` to extract symbols from a newly
       // parsed file and rebuild the file index synchronously each time an AST
       // 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.SemanticHighlightingEnabled),
+          Opts.UpdateDebounce, Opts.RetentionPolicy) {
   // Adds an index to the stack, at higher priority than existing indexes.
   auto AddIndex = [&](SymbolIndex *Idx) {
     if (this->Index != nullptr) {
Index: clang-tools-extra/clangd/ClangdLSPServer.h
===================================================================
--- clang-tools-extra/clangd/ClangdLSPServer.h
+++ clang-tools-extra/clangd/ClangdLSPServer.h
@@ -16,6 +16,7 @@
 #include "GlobalCompilationDatabase.h"
 #include "Path.h"
 #include "Protocol.h"
+#include "SemanticHighlighting.h"
 #include "Transport.h"
 #include "clang/Tooling/Core/Replacement.h"
 #include "llvm/ADT/Optional.h"
@@ -55,6 +56,8 @@
   // Implement DiagnosticsConsumer.
   void onDiagnosticsReady(PathRef File, std::vector<Diag> Diagnostics) override;
   void onFileUpdated(PathRef File, const TUStatus &Status) override;
+  void onHighlightingsReady(PathRef File,
+                         std::vector<HighlightingToken> Highlightings) override;
 
   // LSP methods. Notifications have signature void(const Params&).
   // Calls have signature void(const Params&, Callback<Response>).
Index: clang-tools-extra/clangd/ClangdLSPServer.cpp
===================================================================
--- clang-tools-extra/clangd/ClangdLSPServer.cpp
+++ clang-tools-extra/clangd/ClangdLSPServer.cpp
@@ -1063,6 +1063,11 @@
   return true;
 }
 
+void ClangdLSPServer::onHighlightingsReady(PathRef File,
+                                        std::vector<HighlightingToken> Highlightings) {
+
+}
+
 void ClangdLSPServer::onDiagnosticsReady(PathRef File,
                                          std::vector<Diag> Diagnostics) {
   auto URI = URIForFile::canonicalize(File, /*TUPath=*/File);
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to