nixd
Loading...
Searching...
No Matches
FindReferences.cpp
Go to the documentation of this file.
1/// \file
2/// \brief This implements [Find References].
3/// [Find References]:
4/// https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#textDocument_references
5
6#include "Convert.h"
7#include "Definition.h"
8
10
11#include <boost/asio/post.hpp>
12#include <lspserver/Protocol.h>
13#include <nixf/Sema/ParentMap.h>
15
16using namespace lspserver;
17using namespace nixd;
18using namespace llvm;
19using namespace nixf;
20
21namespace {
22
23std::vector<Location> findReferences(const nixf::Node &Desc,
24 const ParentMapAnalysis &PMA,
25 const VariableLookupAnalysis &VLA,
26 const URIForFile &URI,
27 llvm::StringRef Src) {
28
29 // Two steps.
30 // 1. Find some "definition" for this node.
31 // 2. Find all "uses", and construct the vector.
32
33 // Find "definition"
34 auto Def = findDefinition(Desc, PMA, VLA);
35 std::vector<Location> Locations;
36 // OK, iterate all uses.
37 for (const auto *Use : Def.uses()) {
38 assert(Use);
39 Locations.emplace_back(Location{
40 .uri = URI,
41 .range = toLSPRange(Src, Use->range()),
42 });
43 }
44 return Locations;
45}
46
47} // namespace
48
49void Controller::onReferences(const TextDocumentPositionParams &Params,
50 Callback<std::vector<Location>> Reply) {
51 auto Action = [Reply = std::move(Reply), URI = Params.textDocument.uri,
52 Pos = toNixfPosition(Params.position), this]() mutable {
53 std::string File(URI.file());
54 if (std::shared_ptr<NixTU> TU = getTU(File, Reply)) [[likely]] {
55 if (std::shared_ptr<nixf::Node> AST = getAST(*TU, Reply)) [[likely]] {
56 const nixf::Node *Desc = AST->descend({Pos, Pos});
57 if (!Desc) {
58 return Reply(
59 error("cannot find corresponding node on given position"));
60 }
61 const auto &PM = *TU->parentMap();
62 const auto &VLA = *TU->variableLookup();
63 try {
64 return Reply(findReferences(*Desc, PM, VLA, URI, TU->src()));
65 } catch (std::exception &E) {
66 return Reply(error("references: {0}", E.what()));
67 }
68 }
69 }
70 };
71 boost::asio::post(Pool, std::move(Action));
72}
Convert between LSP and nixf types.
std::vector< Location > Locations
Lookup variable names, from it's parent scope.
const Node * descend(PositionRange Range) const
Descendant node that contains the given range.
Definition Basic.h:49
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
llvm::Error error(std::error_code EC, const char *Fmt, Ts &&...Vals)
Definition Logger.h:70
bool fromJSON(const llvm::json::Value &Params, Configuration::Diagnostic &R, llvm::json::Path P)
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
URIForFile uri
The text document's URI.