nixd
Loading...
Searching...
No Matches
DocumentHighlight.cpp
Go to the documentation of this file.
1/// \file
2/// \brief This implements [Document Highlight].
3/// [Document Highlight]:
4/// https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#textDocument_documentHighlight
5
6#include "CheckReturn.h"
7#include "Convert.h"
8#include "Definition.h"
9
11
12#include <boost/asio/post.hpp>
13#include <lspserver/Protocol.h>
14#include <nixf/Sema/ParentMap.h>
16
17#include <exception>
18
19using namespace lspserver;
20using namespace nixd;
21using namespace llvm;
22using namespace nixf;
23
24namespace {
25
26std::vector<DocumentHighlight> highlight(const nixf::Node &Desc,
27 const ParentMapAnalysis &PMA,
28 const VariableLookupAnalysis &VLA,
29 const URIForFile &URI,
30 llvm::StringRef Src) {
31 // Find "definition"
32 auto Def = findDefinition(Desc, PMA, VLA);
33
34 std::vector<DocumentHighlight> Highlights;
35 // OK, iterate all uses.
36 for (const auto *Use : Def.uses()) {
37 assert(Use);
38 Highlights.emplace_back(DocumentHighlight{
39 .range = toLSPRange(Src, Use->range()),
40 .kind = DocumentHighlightKind::Read,
41 });
42 }
43 if (Def.syntax()) {
44 const Node &Syntax = *Def.syntax();
45 Highlights.emplace_back(DocumentHighlight{
46 .range = toLSPRange(Src, Syntax.range()),
47 .kind = DocumentHighlightKind::Write,
48 });
49 }
50
51 return Highlights;
52}
53
54} // namespace
55
56void Controller::onDocumentHighlight(
57 const TextDocumentPositionParams &Params,
58 Callback<std::vector<DocumentHighlight>> Reply) {
59 using CheckTy = std::vector<DocumentHighlight>;
60 auto Action = [Reply = std::move(Reply), URI = Params.textDocument.uri,
61 Pos = toNixfPosition(Params.position), this]() mutable {
62 std::string File(URI.file());
63 return Reply([&]() -> llvm::Expected<CheckTy> {
64 const auto TU = CheckDefault(getTU(File));
65 const auto AST = CheckDefault(getAST(*TU));
66
67 const auto &Desc = *CheckDefault(AST->descend({Pos, Pos}));
68 try {
69 const auto &PM = *TU->parentMap();
70 const auto &VLA = *TU->variableLookup();
71 return highlight(Desc, PM, VLA, URI, TU->src());
72 } catch (std::exception &E) {
73 elog("textDocument/documentHighlight failed: {0}", E.what());
74 return CheckTy{};
75 }
76 }());
77 };
78 boost::asio::post(Pool, std::move(Action));
79}
#define CheckDefault(x)
Variant of CheckReturn, but returns default constructed CheckTy
Definition CheckReturn.h:16
Convert between LSP and nixf types.
Lookup variable names, from it's parent scope.
LexerCursorRange range() const
Definition Basic.h:35
ParentMap analysis.
Whether current platform treats paths case insensitively.
Definition Connection.h:11
llvm::unique_function< void(llvm::Expected< T >)> Callback
Definition Function.h:14
void elog(const char *Fmt, Ts &&...Vals)
Definition Logger.h:52
nixf::Position toNixfPosition(const lspserver::Position &P)
Definition Convert.cpp:32
const nixf::Definition & findDefinition(const nixf::Node &N, const nixf::ParentMapAnalysis &PMA, const nixf::VariableLookupAnalysis &VLA)
Heuristically find definition on some node.
lspserver::Range toLSPRange(llvm::StringRef Code, const nixf::LexerCursorRange &R)
Definition Convert.cpp:40
Position position
The position inside the text document.
TextDocumentIdentifier textDocument
The text document.