From 871d50000fb9f4eebcd108653bc2d27a4f4686aa Mon Sep 17 00:00:00 2001 From: Yingchi Long Date: Sun, 2 Jul 2023 16:20:32 +0800 Subject: [PATCH] nixd/Server: move rename to controller --- nixd/include/nixd/AST/ParseAST.h | 12 ++++++ nixd/include/nixd/Server/Server.h | 54 ++++++++++++++++++++++++-- nixd/lib/Server/Controller.cpp | 64 ++++++++++++++++++------------- nixd/lib/Server/Static.cpp | 25 ------------ 4 files changed, 100 insertions(+), 55 deletions(-) diff --git a/nixd/include/nixd/AST/ParseAST.h b/nixd/include/nixd/AST/ParseAST.h index 8597186aa..6e9ba7896 100644 --- a/nixd/include/nixd/AST/ParseAST.h +++ b/nixd/include/nixd/AST/ParseAST.h @@ -153,6 +153,18 @@ class ParseAST { return rename(def(Var), NewName); }; + [[nodiscard]] std::optional + rename(lspserver::Position Pos, const std::string &NewName) const { + if (const auto *EVar = + dynamic_cast(lookupContainMin(Pos))) { + return rename(EVar, NewName); + } + if (auto Def = lookupDef(Pos)) { + return rename(*Def, NewName); + } + return std::nullopt; + }; + // Document Symbol [[nodiscard]] Symbols documentSymbol(const nix::SymbolTable &STable) const; diff --git a/nixd/include/nixd/Server/Server.h b/nixd/include/nixd/Server/Server.h index 9c4a16bad..f2bd24df5 100644 --- a/nixd/include/nixd/Server/Server.h +++ b/nixd/include/nixd/Server/Server.h @@ -96,6 +96,57 @@ class Server : public lspserver::LSPServer { ~ReplyRAII() { R(std::move(Response)); }; }; + template + void withParseData(ReplyRAII &&RR, const std::string &Path, + llvm::unique_function &&RR, + std::unique_ptr Data, + const std::string &Version)> + Action) noexcept { + using namespace lspserver; + auto ActionWrapped = + [&, Action = std::move(Action)]( + const EvalDraftStore::Draft &Draft) mutable noexcept { + try { + Action(std::move(RR), parse(*Draft.Contents, Path), Draft.Version); + } catch (std::exception &E) { + RR.Response = + error("something uncaught in the AST action, reason {0}", + stripANSI(E.what())); + } catch (...) { + RR.Response = error("something uncaught in the AST action"); + } + }; + + try { + auto Draft = DraftMgr.getDraft(Path); + if (!Draft) + throw std::logic_error("no draft stored for requested file"); + ActionWrapped(*Draft); + } catch (std::exception &E) { + RR.Response = error(stripANSI(E.what())); + } catch (...) { + RR.Response = error("encountered unknown exception"); + } + } + + template + void withParseAST( + ReplyRAII &&RR, const std::string &Path, + llvm::unique_function &&RR, ParseAST &&AST, + const std::string &Version)> + Action) noexcept { + withParseData( + std::move(RR), Path, + [Action = std::move(Action)](ReplyRAII &&RR, + std::unique_ptr Data, + const std::string &Version) mutable { + auto AST = ParseAST(std::move(Data)); + AST.bindVars(); + AST.staticAnalysis(); + Action(std::move(RR), std::move(AST), Version); + }); + } + private: bool WaitWorker = false; @@ -333,9 +384,6 @@ class Server : public lspserver::LSPServer { const lspserver::TextDocumentIdentifier &, lspserver::Callback>); - void onStaticRename(const lspserver::RenameParams &, - lspserver::Callback>); - // Worker::Nix::Eval void switchToEvaluator(); diff --git a/nixd/lib/Server/Controller.cpp b/nixd/lib/Server/Controller.cpp index df8c024bc..f0644ca2e 100644 --- a/nixd/lib/Server/Controller.cpp +++ b/nixd/lib/Server/Controller.cpp @@ -1,6 +1,8 @@ #include "nixd-config.h" #include "nixd/Expr/Expr.h" +#include "nixd/Parser/Parser.h" +#include "nixd/Parser/Require.h" #include "nixd/Server/EvalDraftStore.h" #include "nixd/Server/Server.h" #include "nixd/Support/Diagnostic.h" @@ -518,16 +520,23 @@ void Server::onCompletion( void Server::onRename(const lspserver::RenameParams &Params, lspserver::Callback Reply) { - auto Task = [=, Reply = std::move(Reply), this]() mutable { - auto Responses = askWC>( - "nixd/ipc/textDocument/rename", Params, - {StaticWorkers, StaticWorkerLock, 1e5}); - auto Edits = latestMatchOr>( - Responses, - [](const std::vector &) -> bool { return true; }); - std::map> Changes; - Changes[Params.textDocument.uri.uri()] = std::move(Edits); - Reply(lspserver::WorkspaceEdit{.changes = std::move(Changes)}); + auto Task = [Params, Reply = std::move(Reply), this]() mutable { + auto URI = Params.textDocument.uri; + auto Path = URI.file().str(); + auto Action = [&URI, &Params](ReplyRAII &&RR, + ParseAST &&AST, const std::string &Version) { + std::map> Changes; + if (auto Edits = AST.rename(Params.position, Params.newName)) { + Changes[URI.uri()] = std::move(*Edits); + RR.Response = lspserver::WorkspaceEdit{.changes = Changes}; + return; + } + RR.Response = lspserver::error("no rename edits available"); + return; + }; + withParseAST( + ReplyRAII(std::move(Reply)), Path, + std::move(Action)); }; boost::asio::post(Pool, std::move(Task)); @@ -536,24 +545,25 @@ void Server::onRename(const lspserver::RenameParams &Params, void Server::onPrepareRename( const lspserver::TextDocumentPositionParams &Params, lspserver::Callback Reply) { - auto Task = [=, Reply = std::move(Reply), this]() mutable { - auto Responses = askWC>( - "nixd/ipc/textDocument/rename", - lspserver::RenameParams{ - .textDocument = Params.textDocument, - .position = Params.position, - }, - {StaticWorkers, StaticWorkerLock, 1e5}); - auto Edits = latestMatchOr>( - Responses, - [](const std::vector &) -> bool { return true; }); - for (const auto &Edit : Edits) { - if (Edit.range.contains(Params.position)) { - Reply(Edit.range); - return; + auto Task = [Params, Reply = std::move(Reply), this]() mutable { + auto Path = Params.textDocument.uri.file().str(); + auto Action = [&Params](ReplyRAII &&RR, ParseAST &&AST, + const std::string &Version) { + auto Pos = Params.position; + if (auto Edits = AST.rename(Pos, "")) { + for (const auto &Edit : *Edits) { + if (Edit.range.contains(Pos)) { + RR.Response = Edit.range; + return; + } + } } - } - Reply(lspserver::error("no rename edits available")); + RR.Response = lspserver::error("no rename edits available"); + return; + }; + withParseAST( + ReplyRAII(std::move(Reply)), Path, + std::move(Action)); }; boost::asio::post(Pool, std::move(Task)); diff --git a/nixd/lib/Server/Static.cpp b/nixd/lib/Server/Static.cpp index a8e5ddaed..94d44c6f2 100644 --- a/nixd/lib/Server/Static.cpp +++ b/nixd/lib/Server/Static.cpp @@ -18,9 +18,6 @@ void Server::switchToStatic() { Registry.addMethod("nixd/ipc/textDocument/definition", this, &Server::onStaticDefinition); - Registry.addMethod("nixd/ipc/textDocument/rename", this, - &Server::onStaticRename); - evalInstallable(Config.getEvalDepth()); mkOutNotifiction("nixd/ipc/finished")( ipc::WorkerMessage{WorkspaceVersion}); @@ -52,28 +49,6 @@ void Server::onStaticDocumentLink( }); } -void Server::onStaticRename( - const lspserver::RenameParams &Params, - lspserver::Callback> Reply) { - using namespace lspserver; - using TextEdits = std::vector; - auto Action = [&Params](const nix::ref &AST, - ReplyRAII &&RR) { - RR.Response = error("no suitable renaming action available"); - if (const auto *EVar = dynamic_cast( - AST->lookupContainMin(Params.position))) { - RR.Response = AST->rename(EVar, Params.newName); - return; - } - if (auto Def = AST->lookupDef(Params.position)) { - RR.Response = AST->rename(*Def, Params.newName); - return; - } - }; - withAST(Params.textDocument.uri.file().str(), - ReplyRAII(std::move(Reply)), std::move(Action)); -} - void Server::onStaticCompletion(const lspserver::CompletionParams &Params, lspserver::Callback Reply) { using namespace lspserver;