[clang-tools-extra] r349768 - [clangd] Expose FileStatus to LSP.

Haojian Wu via cfe-commits cfe-commits at lists.llvm.org
Thu Dec 20 07:39:12 PST 2018


Author: hokein
Date: Thu Dec 20 07:39:12 2018
New Revision: 349768

URL: http://llvm.org/viewvc/llvm-project?rev=349768&view=rev
Log:
[clangd] Expose FileStatus to LSP.

Summary:
Add an LSP extension "textDocument/clangd.fileStatus" to emit file-status information.

Reviewers: ilya-biryukov

Subscribers: javed.absar, ioeric, MaskRay, jkorous, arphaman, kadircet, cfe-commits

Differential Revision: https://reviews.llvm.org/D55363

Added:
    clang-tools-extra/trunk/test/clangd/filestatus.test
Modified:
    clang-tools-extra/trunk/clangd/ClangdLSPServer.cpp
    clang-tools-extra/trunk/clangd/ClangdLSPServer.h
    clang-tools-extra/trunk/clangd/Protocol.cpp
    clang-tools-extra/trunk/clangd/Protocol.h
    clang-tools-extra/trunk/clangd/TUScheduler.cpp
    clang-tools-extra/trunk/clangd/TUScheduler.h

Modified: clang-tools-extra/trunk/clangd/ClangdLSPServer.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/ClangdLSPServer.cpp?rev=349768&r1=349767&r2=349768&view=diff
==============================================================================
--- clang-tools-extra/trunk/clangd/ClangdLSPServer.cpp (original)
+++ clang-tools-extra/trunk/clangd/ClangdLSPServer.cpp Thu Dec 20 07:39:12 2018
@@ -294,7 +294,7 @@ void ClangdLSPServer::onInitialize(const
   SupportsCodeAction = Params.capabilities.CodeActionStructure;
   SupportsHierarchicalDocumentSymbol =
       Params.capabilities.HierarchicalDocumentSymbol;
-
+  SupportFileStatus = Params.initializationOptions.FileStatus;
   Reply(json::Object{
       {{"capabilities",
         json::Object{
@@ -802,6 +802,19 @@ void ClangdLSPServer::onDiagnosticsReady
          });
 }
 
+void ClangdLSPServer::onFileUpdated(PathRef File, const TUStatus &Status) {
+  if (!SupportFileStatus)
+    return;
+  // FIXME: we don't emit "BuildingFile" and `RunningAction`, as these
+  // two statuses are running faster in practice, which leads the UI constantly
+  // changing, and doesn't provide much value. We may want to emit status at a
+  // reasonable time interval (e.g. 0.5s).
+  if (Status.Action.S == TUAction::BuildingFile ||
+      Status.Action.S == TUAction::RunningAction)
+    return;
+  notify("textDocument/clangd.fileStatus", Status.render(File));
+}
+
 void ClangdLSPServer::reparseOpenedFiles() {
   for (const Path &FilePath : DraftMgr.getActiveFiles())
     Server->addDocument(FilePath, *DraftMgr.getDraft(FilePath),

Modified: clang-tools-extra/trunk/clangd/ClangdLSPServer.h
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/ClangdLSPServer.h?rev=349768&r1=349767&r2=349768&view=diff
==============================================================================
--- clang-tools-extra/trunk/clangd/ClangdLSPServer.h (original)
+++ clang-tools-extra/trunk/clangd/ClangdLSPServer.h Thu Dec 20 07:39:12 2018
@@ -52,6 +52,7 @@ public:
 private:
   // Implement DiagnosticsConsumer.
   void onDiagnosticsReady(PathRef File, std::vector<Diag> Diagnostics) override;
+  void onFileUpdated(PathRef File, const TUStatus &Status) override;
 
   // LSP methods. Notifications have signature void(const Params&).
   // Calls have signature void(const Params&, Callback<Response>).
@@ -132,11 +133,12 @@ private:
   SymbolKindBitset SupportedSymbolKinds;
   /// The supported completion item kinds of the client.
   CompletionItemKindBitset SupportedCompletionItemKinds;
-  // Whether the client supports CodeAction response objects.
+  /// Whether the client supports CodeAction response objects.
   bool SupportsCodeAction = false;
   /// From capabilities of textDocument/documentSymbol.
   bool SupportsHierarchicalDocumentSymbol = false;
-
+  /// Whether the client supports showing file status.
+  bool SupportFileStatus = false;
   // Store of the current versions of the open documents.
   DraftStore DraftMgr;
 

Modified: clang-tools-extra/trunk/clangd/Protocol.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/Protocol.cpp?rev=349768&r1=349767&r2=349768&view=diff
==============================================================================
--- clang-tools-extra/trunk/clangd/Protocol.cpp (original)
+++ clang-tools-extra/trunk/clangd/Protocol.cpp Thu Dec 20 07:39:12 2018
@@ -716,6 +716,12 @@ json::Value toJSON(const DocumentHighlig
   };
 }
 
+llvm::json::Value toJSON(const FileStatus &FStatus) {
+  return json::Object{
+      {"uri", FStatus.uri}, {"state", FStatus.state},
+  };
+}
+
 raw_ostream &operator<<(raw_ostream &O, const DocumentHighlight &V) {
   O << V.range;
   if (V.kind == DocumentHighlightKind::Read)
@@ -752,6 +758,7 @@ bool fromJSON(const json::Value &Params,
   fromJSON(Params, Opts.ConfigSettings);
   O.map("compilationDatabasePath", Opts.compilationDatabasePath);
   O.map("fallbackFlags", Opts.fallbackFlags);
+  O.map("clangdFileStatus", Opts.FileStatus);
   return true;
 }
 

Modified: clang-tools-extra/trunk/clangd/Protocol.h
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/Protocol.h?rev=349768&r1=349767&r2=349768&view=diff
==============================================================================
--- clang-tools-extra/trunk/clangd/Protocol.h (original)
+++ clang-tools-extra/trunk/clangd/Protocol.h Thu Dec 20 07:39:12 2018
@@ -397,6 +397,9 @@ struct InitializationOptions {
   // the compilation database doesn't describe an opened file.
   // The command used will be approximately `clang $FILE $fallbackFlags`.
   std::vector<std::string> fallbackFlags;
+
+  /// Clients supports show file status for textDocument/clangd.fileStatus.
+  bool FileStatus = false;
 };
 bool fromJSON(const llvm::json::Value &, InitializationOptions &);
 
@@ -973,6 +976,18 @@ struct ReferenceParams : public TextDocu
 };
 bool fromJSON(const llvm::json::Value &, ReferenceParams &);
 
+/// Clangd extension: indicates the current state of the file in clangd,
+/// sent from server via the `textDocument/clangd.fileStatus` notification.
+struct FileStatus {
+  /// The text document's URI.
+  URIForFile uri;
+  /// The human-readable string presents the current state of the file, can be
+  /// shown in the UI (e.g. status bar).
+  std::string state;
+  // FIXME: add detail messages.
+};
+llvm::json::Value toJSON(const FileStatus &FStatus);
+
 } // namespace clangd
 } // namespace clang
 

Modified: clang-tools-extra/trunk/clangd/TUScheduler.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/TUScheduler.cpp?rev=349768&r1=349767&r2=349768&view=diff
==============================================================================
--- clang-tools-extra/trunk/clangd/TUScheduler.cpp (original)
+++ clang-tools-extra/trunk/clangd/TUScheduler.cpp Thu Dec 20 07:39:12 2018
@@ -729,6 +729,33 @@ bool ASTWorker::blockUntilIdle(Deadline
   return wait(Lock, RequestsCV, Timeout, [&] { return Requests.empty(); });
 }
 
+// Render a TUAction to a user-facing string representation.
+// TUAction represents clangd-internal states, we don't intend to expose them
+// to users (say C++ programmers) directly to avoid confusion, we use terms that
+// are familiar by C++ programmers.
+std::string renderTUAction(const TUAction &Action) {
+  std::string Result;
+  raw_string_ostream OS(Result);
+  switch (Action.S) {
+  case TUAction::Queued:
+    OS << "file is queued";
+    break;
+  case TUAction::RunningAction:
+    OS << "running " << Action.Name;
+    break;
+  case TUAction::BuildingPreamble:
+    OS << "parsing includes";
+    break;
+  case TUAction::BuildingFile:
+    OS << "parsing main file";
+    break;
+  case TUAction::Idle:
+    OS << "idle";
+    break;
+  }
+  return OS.str();
+}
+
 } // namespace
 
 unsigned getDefaultAsyncThreadsCount() {
@@ -741,6 +768,13 @@ unsigned getDefaultAsyncThreadsCount() {
   return HardwareConcurrency;
 }
 
+FileStatus TUStatus::render(PathRef File) const {
+  FileStatus FStatus;
+  FStatus.uri = URIForFile::canonicalize(File, /*TUPath=*/File);
+  FStatus.state = renderTUAction(Action);
+  return FStatus;
+}
+
 struct TUScheduler::FileData {
   /// Latest inputs, passed to TUScheduler::update().
   std::string Contents;

Modified: clang-tools-extra/trunk/clangd/TUScheduler.h
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/TUScheduler.h?rev=349768&r1=349767&r2=349768&view=diff
==============================================================================
--- clang-tools-extra/trunk/clangd/TUScheduler.h (original)
+++ clang-tools-extra/trunk/clangd/TUScheduler.h Thu Dec 20 07:39:12 2018
@@ -77,6 +77,8 @@ struct TUStatus {
     /// Indicates whether we reused the prebuilt AST.
     bool ReuseAST = false;
   };
+  /// Serialize this to an LSP file status item.
+  FileStatus render(PathRef File) const;
 
   TUAction Action;
   BuildDetails Details;

Added: clang-tools-extra/trunk/test/clangd/filestatus.test
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clangd/filestatus.test?rev=349768&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clangd/filestatus.test (added)
+++ clang-tools-extra/trunk/test/clangd/filestatus.test Thu Dec 20 07:39:12 2018
@@ -0,0 +1,13 @@
+# RUN: clangd -lit-test < %s | FileCheck -strict-whitespace %s
+{"jsonrpc":"2.0","id":0,"method":"initialize","params":{"processId":123,"rootPath":"clangd","capabilities":{},"initializationOptions":{"clangdFileStatus": true},"trace":"off"}}
+---
+{"jsonrpc":"2.0","method":"textDocument/didOpen","params":{"textDocument":{"uri":"test:///main.cpp","languageId":"cpp","version":1,"text":"int x; int y = x;"}}}
+#      CHECK:  "method": "textDocument/clangd.fileStatus",
+# CHECK-NEXT:  "params": {
+# CHECK-NEXT:    "state": "parsing includes",
+# CHECK-NEXT:    "uri": "{{.*}}/main.cpp"
+# CHECK-NEXT:  }
+---
+{"jsonrpc":"2.0","id":3,"method":"shutdown"}
+---
+{"jsonrpc":"2.0","method":"exit"}




More information about the cfe-commits mailing list