Skip to content

Commit 519d688

Browse files
committed
nixd/Controller: handle UTF-16 code units for locations
1 parent 2f515e0 commit 519d688

File tree

13 files changed

+138
-95
lines changed

13 files changed

+138
-95
lines changed

nixd/lib/Controller/CodeAction.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,14 @@ void Controller::onCodeAction(const lspserver::CodeActionParams &Params,
1919
std::string File(Params.textDocument.uri.file());
2020
Range Range = Params.range;
2121
auto Action = [Reply = std::move(Reply), File, Range, this]() mutable {
22+
auto Draft = Store.getDraft(File)->Contents;
23+
auto Src = llvm::StringRef(*Draft);
2224
if (auto TU = getTU(File, Reply)) {
2325
std::vector<nixf::Diagnostic> Diagnostics = TU->diagnostics();
2426
std::vector<CodeAction> Actions;
2527
Actions.reserve(Diagnostics.size());
2628
for (const nixf::Diagnostic &D : Diagnostics) {
27-
auto DRange = toLSPRange(D.range());
29+
auto DRange = toLSPRange(Src, D.range());
2830
if (!Range.overlap(DRange))
2931
continue;
3032

@@ -34,7 +36,7 @@ void Controller::onCodeAction(const lspserver::CodeActionParams &Params,
3436
Edits.reserve(F.edits().size());
3537
for (const nixf::TextEdit &TE : F.edits()) {
3638
Edits.emplace_back(TextEdit{
37-
.range = toLSPRange(TE.oldRange()),
39+
.range = toLSPRange(Src, TE.oldRange()),
3840
.newText = std::string(TE.newText()),
3941
});
4042
}

nixd/lib/Controller/Convert.cpp

Lines changed: 16 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,14 @@
11
#include "Convert.h"
2+
23
#include "nixf/Basic/Diagnostic.h"
34

4-
using namespace lspserver;
5+
#include "lspserver/SourceCode.h"
56

6-
namespace nixd {
7+
#include <llvm/ADT/StringRef.h>
78

8-
int getLSPSeverity(nixf::Diagnostic::DiagnosticKind Kind) {
9+
using namespace lspserver;
10+
11+
int nixd::getLSPSeverity(nixf::Diagnostic::DiagnosticKind Kind) {
912
switch (nixf::Diagnostic::severity(Kind)) {
1013
case nixf::Diagnostic::DS_Fatal:
1114
case nixf::Diagnostic::DS_Error:
@@ -21,25 +24,27 @@ int getLSPSeverity(nixf::Diagnostic::DiagnosticKind Kind) {
2124
__builtin_unreachable();
2225
}
2326

24-
lspserver::Position toLSPPosition(const nixf::LexerCursor &P) {
25-
return lspserver::Position{static_cast<int>(P.line()),
26-
static_cast<int>(P.column())};
27+
lspserver::Position nixd::toLSPPosition(llvm::StringRef Code,
28+
const nixf::LexerCursor &P) {
29+
return lspserver::offsetToPosition(Code, P.offset());
2730
}
2831

29-
nixf::Position toNixfPosition(const lspserver::Position &P) {
32+
nixf::Position nixd::toNixfPosition(const lspserver::Position &P) {
3033
return {P.line, P.character};
3134
}
3235

33-
nixf::PositionRange toNixfRange(const lspserver::Range &P) {
36+
nixf::PositionRange nixd::toNixfRange(const lspserver::Range &P) {
3437
return {toNixfPosition(P.start), toNixfPosition(P.end)};
3538
}
3639

37-
lspserver::Range toLSPRange(const nixf::LexerCursorRange &R) {
38-
return lspserver::Range{toLSPPosition(R.lCur()), toLSPPosition(R.rCur())};
40+
lspserver::Range nixd::toLSPRange(llvm::StringRef Code,
41+
const nixf::LexerCursorRange &R) {
42+
return lspserver::Range{toLSPPosition(Code, R.lCur()),
43+
toLSPPosition(Code, R.rCur())};
3944
}
4045

4146
llvm::SmallVector<lspserver::DiagnosticTag, 1>
42-
toLSPTags(const std::vector<nixf::DiagnosticTag> &Tags) {
47+
nixd::toLSPTags(const std::vector<nixf::DiagnosticTag> &Tags) {
4348
llvm::SmallVector<lspserver::DiagnosticTag, 1> Result;
4449
Result.reserve(Tags.size());
4550
for (const nixf::DiagnosticTag &Tag : Tags) {
@@ -54,5 +59,3 @@ toLSPTags(const std::vector<nixf::DiagnosticTag> &Tags) {
5459
}
5560
return Result;
5661
}
57-
58-
} // namespace nixd

nixd/lib/Controller/Convert.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,15 @@
1010

1111
namespace nixd {
1212

13-
lspserver::Position toLSPPosition(const nixf::LexerCursor &P);
13+
lspserver::Position toLSPPosition(llvm::StringRef Code,
14+
const nixf::LexerCursor &P);
1415

1516
nixf::Position toNixfPosition(const lspserver::Position &P);
1617

1718
nixf::PositionRange toNixfRange(const lspserver::Range &P);
1819

19-
lspserver::Range toLSPRange(const nixf::LexerCursorRange &R);
20+
lspserver::Range toLSPRange(llvm::StringRef Code,
21+
const nixf::LexerCursorRange &R);
2022

2123
int getLSPSeverity(nixf::Diagnostic::DiagnosticKind Kind);
2224

nixd/lib/Controller/Definition.cpp

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -113,10 +113,11 @@ const Definition &findVarDefinition(const ExprVar &Var,
113113
}
114114

115115
/// \brief Convert nixf::Definition to lspserver::Location
116-
Location convertToLocation(const Definition &Def, URIForFile URI) {
116+
Location convertToLocation(llvm::StringRef Src, const Definition &Def,
117+
URIForFile URI) {
117118
return Location{
118119
.uri = std::move(URI),
119-
.range = toLSPRange(Def.syntax()->range()),
120+
.range = toLSPRange(Src, Def.syntax()->range()),
120121
};
121122
}
122123

@@ -280,9 +281,9 @@ Locations defineSelect(const ExprSelect &Sel, const VariableLookupAnalysis &VLA,
280281
}
281282

282283
Locations defineVarStatic(const ExprVar &Var, const VariableLookupAnalysis &VLA,
283-
const URIForFile &URI) {
284+
const URIForFile &URI, llvm::StringRef Src) {
284285
const Definition &Def = findVarDefinition(Var, VLA);
285-
return {convertToLocation(Def, URI)};
286+
return {convertToLocation(Src, Def, URI)};
286287
}
287288

288289
template <class T>
@@ -293,9 +294,9 @@ std::vector<T> mergeVec(std::vector<T> A, const std::vector<T> &B) {
293294

294295
Locations defineVar(const ExprVar &Var, const VariableLookupAnalysis &VLA,
295296
const ParentMapAnalysis &PM, AttrSetClient &NixpkgsClient,
296-
const URIForFile &URI) {
297+
const URIForFile &URI, llvm::StringRef Src) {
297298
try {
298-
Locations StaticLocs = defineVarStatic(Var, VLA, URI);
299+
Locations StaticLocs = defineVarStatic(Var, VLA, URI, Src);
299300

300301
// Nixpkgs locations.
301302
try {
@@ -353,6 +354,8 @@ void Controller::onDefinition(const TextDocumentPositionParams &Params,
353354
auto Action = [Reply = std::move(Reply), URI = Params.textDocument.uri,
354355
Pos = toNixfPosition(Params.position), this]() mutable {
355356
std::string File(URI.file());
357+
auto Draft = Store.getDraft(File)->Contents;
358+
auto Src = llvm::StringRef(*Draft);
356359
if (std::shared_ptr<NixTU> TU = getTU(File, Reply)) [[likely]] {
357360
if (std::shared_ptr<Node> AST = getAST(*TU, Reply)) [[likely]] {
358361
const VariableLookupAnalysis &VLA = *TU->variableLookup();
@@ -374,12 +377,12 @@ void Controller::onDefinition(const TextDocumentPositionParams &Params,
374377
return Reply(squash([&]() -> llvm::Expected<Locations> {
375378
// Special case for inherited names.
376379
if (const ExprVar *Var = findInheritVar(N, PM, VLA))
377-
return defineVar(*Var, VLA, PM, *nixpkgsClient(), URI);
380+
return defineVar(*Var, VLA, PM, *nixpkgsClient(), URI, Src);
378381

379382
switch (UpExpr.kind()) {
380383
case Node::NK_ExprVar: {
381384
const auto &Var = static_cast<const ExprVar &>(UpExpr);
382-
return defineVar(Var, VLA, PM, *nixpkgsClient(), URI);
385+
return defineVar(Var, VLA, PM, *nixpkgsClient(), URI, Src);
383386
}
384387
case Node::NK_ExprSelect: {
385388
const auto &Sel = static_cast<const ExprSelect &>(UpExpr);

nixd/lib/Controller/Diagnostics.cpp

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,8 @@ void Controller::publishDiagnostics(
4444
const std::vector<nixf::Diagnostic> &Diagnostics) {
4545
std::vector<Diagnostic> LSPDiags;
4646
LSPDiags.reserve(Diagnostics.size());
47+
auto Draft = Store.getDraft(File)->Contents;
48+
auto Src = llvm::StringRef(*Draft);
4749
for (const nixf::Diagnostic &D : Diagnostics) {
4850
// Before actually doing anything,
4951
// let's check if the diagnostic is suppressed.
@@ -67,7 +69,7 @@ void Controller::publishDiagnostics(
6769
}
6870

6971
Diagnostic &Diag = LSPDiags.emplace_back(Diagnostic{
70-
.range = toLSPRange(D.range()),
72+
.range = toLSPRange(Src, D.range()),
7173
.severity = getLSPSeverity(D.kind()),
7274
.code = D.sname(),
7375
.source = "nixf",
@@ -83,7 +85,7 @@ void Controller::publishDiagnostics(
8385
.location =
8486
Location{
8587
.uri = URIForFile::canonicalize(File, File),
86-
.range = toLSPRange(N.range()),
88+
.range = toLSPRange(Src, N.range()),
8789
},
8890
.message = N.format(),
8991
});
@@ -93,7 +95,7 @@ void Controller::publishDiagnostics(
9395

9496
for (const nixf::Note &N : Notes) {
9597
LSPDiags.emplace_back(Diagnostic{
96-
.range = toLSPRange(N.range()),
98+
.range = toLSPRange(Src, N.range()),
9799
.severity = 4,
98100
.code = N.sname(),
99101
.source = "nixf",

nixd/lib/Controller/DocumentHighlight.cpp

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,8 @@ namespace {
2525
std::vector<DocumentHighlight> highlight(const nixf::Node &Desc,
2626
const ParentMapAnalysis &PMA,
2727
const VariableLookupAnalysis &VLA,
28-
const URIForFile &URI) {
28+
const URIForFile &URI,
29+
llvm::StringRef Src) {
2930
// Find "definition"
3031
auto Def = findDefinition(Desc, PMA, VLA);
3132

@@ -34,14 +35,14 @@ std::vector<DocumentHighlight> highlight(const nixf::Node &Desc,
3435
for (const auto *Use : Def.uses()) {
3536
assert(Use);
3637
Highlights.emplace_back(DocumentHighlight{
37-
.range = toLSPRange(Use->range()),
38+
.range = toLSPRange(Src, Use->range()),
3839
.kind = DocumentHighlightKind::Read,
3940
});
4041
}
4142
if (Def.syntax()) {
4243
const Node &Syntax = *Def.syntax();
4344
Highlights.emplace_back(DocumentHighlight{
44-
.range = toLSPRange(Syntax.range()),
45+
.range = toLSPRange(Src, Syntax.range()),
4546
.kind = DocumentHighlightKind::Write,
4647
});
4748
}
@@ -57,6 +58,8 @@ void Controller::onDocumentHighlight(
5758
auto Action = [Reply = std::move(Reply), URI = Params.textDocument.uri,
5859
Pos = toNixfPosition(Params.position), this]() mutable {
5960
std::string File(URI.file());
61+
auto Draft = Store.getDraft(File)->Contents;
62+
auto Src = llvm::StringRef(*Draft);
6063
if (std::shared_ptr<NixTU> TU = getTU(File, Reply)) [[likely]] {
6164
if (std::shared_ptr<nixf::Node> AST = getAST(*TU, Reply)) [[likely]] {
6265
const nixf::Node *Desc = AST->descend({Pos, Pos});
@@ -67,7 +70,7 @@ void Controller::onDocumentHighlight(
6770
try {
6871
const auto &PM = *TU->parentMap();
6972
const auto &VLA = *TU->variableLookup();
70-
return Reply(highlight(*Desc, PM, VLA, URI));
73+
return Reply(highlight(*Desc, PM, VLA, URI, Src));
7174
} catch (std::exception &E) {
7275
elog("textDocument/documentHighlight failed: {0}", E.what());
7376
return Reply(std::vector<DocumentHighlight>{});

nixd/lib/Controller/DocumentLink.cpp

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ std::optional<std::string> resolveExprPath(const std::string &BasePath,
4747
}
4848

4949
void dfs(const Node *N, const std::string &BasePath,
50-
std::vector<DocumentLink> &Links) {
50+
std::vector<DocumentLink> &Links, llvm::StringRef Src) {
5151
if (!N)
5252
return;
5353

@@ -59,7 +59,7 @@ void dfs(const Node *N, const std::string &BasePath,
5959
// Provide literal path linking.
6060
if (auto Link = resolveExprPath(BasePath, Path.parts().literal())) {
6161
Links.emplace_back(
62-
DocumentLink{.range = toLSPRange(N->range()),
62+
DocumentLink{.range = toLSPRange(Src, N->range()),
6363
.target = URIForFile::canonicalize(*Link, *Link)});
6464
}
6565
}
@@ -71,7 +71,7 @@ void dfs(const Node *N, const std::string &BasePath,
7171

7272
// Traverse on all children
7373
for (const Node *Ch : N->children()) {
74-
dfs(Ch, BasePath, Links);
74+
dfs(Ch, BasePath, Links, Src);
7575
}
7676
}
7777

@@ -82,11 +82,13 @@ void Controller::onDocumentLink(
8282
lspserver::Callback<std::vector<DocumentLink>> Reply) {
8383
auto Action = [File = Params.textDocument.uri.file().str(),
8484
Reply = std::move(Reply), this]() mutable {
85+
auto Draft = Store.getDraft(File)->Contents;
86+
auto Src = llvm::StringRef(*Draft);
8587
if (std::shared_ptr<NixTU> TU = getTU(File, Reply)) [[likely]] {
8688
if (std::shared_ptr<nixf::Node> AST = getAST(*TU, Reply)) [[likely]] {
8789
// Traverse the AST, provide the links
8890
std::vector<DocumentLink> Links;
89-
dfs(AST.get(), File, Links);
91+
dfs(AST.get(), File, Links, Src);
9092
Reply(std::move(Links));
9193
}
9294
}

0 commit comments

Comments
 (0)