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 "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
17using namespace lspserver;
18using namespace nixd;
19using namespace llvm;
20using namespace nixf;
21
22namespace {
23
24std::vector<Location> findReferences(const nixf::Node &Desc,
25 const ParentMapAnalysis &PMA,
26 const VariableLookupAnalysis &VLA,
27 const URIForFile &URI,
28 llvm::StringRef Src) {
29
30 // Two steps.
31 // 1. Find some "definition" for this node.
32 // 2. Find all "uses", and construct the vector.
33
34 // Find "definition"
35 auto Def = findDefinition(Desc, PMA, VLA);
36 std::vector<Location> Locations;
37 // OK, iterate all uses.
38 for (const auto *Use : Def.uses()) {
39 assert(Use);
40 Locations.emplace_back(Location{
41 .uri = URI,
42 .range = toLSPRange(Src, Use->range()),
43 });
44 }
45 return Locations;
46}
47
48} // namespace
49
50void Controller::onReferences(const TextDocumentPositionParams &Params,
51 Callback<std::vector<Location>> Reply) {
52 using CheckTy = std::vector<Location>;
53 auto Action = [Reply = std::move(Reply), URI = Params.textDocument.uri,
54 Pos = toNixfPosition(Params.position), this]() mutable {
55 std::string File(URI.file());
56 return Reply([&]() -> llvm::Expected<CheckTy> {
57 const auto TU = CheckDefault(getTU(File));
58 const auto AST = CheckDefault(getAST(*TU));
59 const auto &Desc = CheckDefault(AST->descend({Pos, Pos}));
60 const auto &PM = *TU->parentMap();
61 const auto &VLA = *TU->variableLookup();
62 try {
63 return findReferences(*Desc, PM, VLA, URI, TU->src());
64 } catch (std::exception &E) {
65 return error("references: {0}", E.what());
66 }
67 }());
68 };
69 boost::asio::post(Pool, std::move(Action));
70}
#define CheckDefault(x)
Variant of CheckReturn, but returns default constructed CheckTy
Definition CheckReturn.h:16
Convert between LSP and nixf types.
std::vector< Location > Locations
Lookup variable names, from it's parent scope.
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
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.