hokein updated this revision to Diff 178455.
hokein added a comment.
Update:
- avoid using terms that C++ programmers are unfamiliar with.
- textDocument/fileStatus => textDocument/clangd.fileStatus
Repository:
rCTE Clang Tools Extra
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D55363/new/
https://reviews.llvm.org/D55363
Files:
clangd/ClangdLSPServer.cpp
clangd/ClangdLSPServer.h
clangd/Protocol.cpp
clangd/Protocol.h
clangd/TUScheduler.cpp
clangd/TUScheduler.h
test/clangd/filestatus.test
Index: test/clangd/filestatus.test
===================================================================
--- /dev/null
+++ test/clangd/filestatus.test
@@ -0,0 +1,14 @@
+# RUN: clangd -lit-test < %s | FileCheck -strict-whitespace %s
+{"jsonrpc":"2.0","id":0,"method":"initialize","params":{"processId":123,"rootPath":"clangd","capabilities":{},"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: "details": [],
+# CHECK-NEXT: "state": "Parsing includes",
+# CHECK-NEXT: "uri": "{{.*}}/main.cpp"
+# CHECK-NEXT: }
+---
+{"jsonrpc":"2.0","id":3,"method":"shutdown"}
+---
+{"jsonrpc":"2.0","method":"exit"}
Index: clangd/TUScheduler.h
===================================================================
--- clangd/TUScheduler.h
+++ clangd/TUScheduler.h
@@ -77,6 +77,8 @@
/// 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;
Index: clangd/TUScheduler.cpp
===================================================================
--- clangd/TUScheduler.cpp
+++ clangd/TUScheduler.cpp
@@ -729,6 +729,34 @@
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 << "Queued";
+ break;
+ case TUAction::RunningAction:
+ OS << "RunningAction"
+ << "(" << 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 +769,17 @@
return HardwareConcurrency;
}
+FileStatus TUStatus::render(PathRef File) const {
+ FileStatus FStatus;
+ FStatus.uri = URIForFile::canonicalize(File, /*TUPath=*/File);
+ FStatus.state = renderTUAction(Action);
+ if (Details.BuildFailed)
+ FStatus.details.push_back({MessageType::Error, "failed to build the file"});
+ if (Details.ReuseAST)
+ FStatus.details.push_back({MessageType::Info, "reused the AST"});
+ return FStatus;
+}
+
struct TUScheduler::FileData {
/// Latest inputs, passed to TUScheduler::update().
std::string Contents;
Index: clangd/Protocol.h
===================================================================
--- clangd/Protocol.h
+++ clangd/Protocol.h
@@ -973,6 +973,33 @@
};
bool fromJSON(const llvm::json::Value &, ReferenceParams &);
+enum class MessageType {
+ Error = 1,
+ Warning = 2,
+ Info = 3,
+ Log = 4,
+};
+struct ShowMessageParams {
+ /// The message type.
+ MessageType type;
+ /// The actual message.
+ std::string message;
+};
+llvm::json::Value toJSON(const ShowMessageParams &);
+
+/// Clangd extension: indicates the current state of the file in clangd,
+/// sent from server via the `textDocument/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;
+ /// Details of the state that are worth sufacing to users.
+ std::vector<ShowMessageParams> details;
+};
+llvm::json::Value toJSON(const FileStatus &FStatus);
+
} // namespace clangd
} // namespace clang
Index: clangd/Protocol.cpp
===================================================================
--- clangd/Protocol.cpp
+++ clangd/Protocol.cpp
@@ -716,6 +716,20 @@
};
}
+llvm::json::Value toJSON(const ShowMessageParams &S) {
+ return json::Object{
+ {"type", static_cast<int>(S.type)}, {"message", S.message},
+ };
+}
+
+llvm::json::Value toJSON(const FileStatus &FStatus) {
+ return json::Object{
+ {"uri", FStatus.uri},
+ {"state", FStatus.state},
+ {"details", FStatus.details},
+ };
+}
+
raw_ostream &operator<<(raw_ostream &O, const DocumentHighlight &V) {
O << V.range;
if (V.kind == DocumentHighlightKind::Read)
Index: clangd/ClangdLSPServer.h
===================================================================
--- clangd/ClangdLSPServer.h
+++ clangd/ClangdLSPServer.h
@@ -52,6 +52,7 @@
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>).
Index: clangd/ClangdLSPServer.cpp
===================================================================
--- clangd/ClangdLSPServer.cpp
+++ clangd/ClangdLSPServer.cpp
@@ -802,6 +802,10 @@
});
}
+void ClangdLSPServer::onFileUpdated(PathRef File, const TUStatus &Status) {
+ notify("textDocument/clangd.fileStatus", Status.render(File));
+}
+
void ClangdLSPServer::reparseOpenedFiles() {
for (const Path &FilePath : DraftMgr.getActiveFiles())
Server->addDocument(FilePath, *DraftMgr.getDraft(FilePath),
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits