nixd
Toggle main menu visibility
Loading...
Searching...
No Matches
nixd
lib
Controller
CodeActions
ConvertToInherit.cpp
Go to the documentation of this file.
1
/// \file
2
/// \brief Implementation of convert to inherit code action.
3
4
#include "
ConvertToInherit.h
"
5
#include "
Utils.h
"
6
7
#include "
../Convert.h
"
8
9
#include <
nixf/Basic/Nodes/Attrs.h
>
10
#include <
nixf/Basic/Nodes/Expr.h
>
11
#include <
nixf/Basic/Nodes/Simple.h
>
12
13
namespace
nixd
{
14
15
void
addConvertToInheritAction
(
const
nixf::Node
&N,
16
const
nixf::ParentMapAnalysis
&PM,
17
const
std::string &FileURI, llvm::StringRef Src,
18
std::vector<lspserver::CodeAction> &Actions) {
19
// Find if we're inside a Binding node
20
const
nixf::Node
*BindingNode = PM.
upTo
(N, nixf::Node::NK_Binding);
21
if
(!BindingNode)
22
return
;
23
24
const
auto
&Bind =
static_cast<
const
nixf::Binding
&
>
(*BindingNode);
25
26
// Must have a single-segment path
27
const
auto
&Names = Bind.
path
().
names
();
28
if
(Names.size() != 1)
29
return
;
30
31
// Path must be static (not interpolated)
32
const
auto
&AttrNameNode = Names[0];
33
if
(!AttrNameNode || !AttrNameNode->isStatic())
34
return
;
35
36
const
std::string &AttrName = AttrNameNode->staticName();
37
38
// Must have a value
39
if
(!Bind.value())
40
return
;
41
42
const
nixf::Expr
&
Value
= *Bind.value();
43
44
// Case 1: { x = x; } -> { inherit x; }
45
if
(
Value
.kind() == nixf::Node::NK_ExprVar) {
46
const
auto
&Var =
static_cast<
const
nixf::ExprVar
&
>
(
Value
);
47
if
(Var.id().name() == AttrName) {
48
std::string NewText =
"inherit "
+
quoteNixAttrKey
(AttrName) +
";"
;
49
Actions.emplace_back(
createSingleEditAction
(
50
"Convert to `inherit`"
,
lspserver::CodeAction::REFACTOR_REWRITE_KIND
,
51
FileURI,
toLSPRange
(Src, Bind.range()), std::move(NewText)));
52
}
53
return
;
54
}
55
56
// Case 2: { a = source.a; } -> { inherit (source) a; }
57
// Also handles { a = lib.nested.a; } -> { inherit (lib.nested) a; }
58
if
(
Value
.kind() == nixf::Node::NK_ExprSelect) {
59
const
auto
&Sel =
static_cast<
const
nixf::ExprSelect
&
>
(
Value
);
60
61
// Must not have a default value
62
if
(Sel.defaultExpr())
63
return
;
64
65
// Must have a path
66
if
(!Sel.path())
67
return
;
68
69
// Selector path must have at least one segment
70
const
auto
&SelPath = Sel.
path
()->
names
();
71
if
(SelPath.empty())
72
return
;
73
74
// The last segment must be static and match the attribute name
75
const
auto
&LastSegment = SelPath.back();
76
if
(!LastSegment || !LastSegment->isStatic())
77
return
;
78
79
if
(LastSegment->staticName() != AttrName)
80
return
;
81
82
// Build the source expression text:
83
// - Start with the base expression (e.g., "lib" from lib.nested.x)
84
// - Add any intermediate path segments (e.g., ".nested")
85
const
nixf::Expr
&BaseExpr = Sel.expr();
86
std::string SourceText =
87
Src.slice(BaseExpr.
lCur
().
offset
(), BaseExpr.
rCur
().
offset
()).str();
88
89
// Add intermediate path segments (all except the last one)
90
for
(
size_t
I = 0; I + 1 < SelPath.size(); ++I) {
91
const
auto
&Segment = SelPath[I];
92
if
(!Segment || !Segment->isStatic())
93
return
;
// Bail out if any intermediate segment is dynamic
94
SourceText +=
"."
;
95
SourceText +=
quoteNixAttrKey
(Segment->staticName());
96
}
97
98
std::string NewText =
99
"inherit ("
+ SourceText +
") "
+
quoteNixAttrKey
(AttrName) +
";"
;
100
Actions.emplace_back(
createSingleEditAction
(
101
"Convert to `inherit ("
+ SourceText +
")`"
,
102
lspserver::CodeAction::REFACTOR_REWRITE_KIND
, FileURI,
103
toLSPRange
(Src, Bind.range()), std::move(NewText)));
104
}
105
}
106
107
}
// namespace nixd
Attrs.h
ConvertToInherit.h
Code action for converting bindings to inherit syntax.
Convert.h
Convert between LSP and nixf types.
Expr.h
Simple.h
Utils.h
Shared utilities for code actions.
nixf::AttrPath::names
const std::vector< std::shared_ptr< AttrName > > & names() const
Definition
Attrs.h:100
nixf::Binding
Definition
Attrs.h:115
nixf::Binding::path
const AttrPath & path() const
Definition
Attrs.h:131
nixf::ExprSelect
Definition
Expr.h:7
nixf::ExprSelect::path
AttrPath * path() const
Definition
Expr.h:35
nixf::ExprVar
Definition
Simple.h:192
nixf::Expr
Definition
Basic.h:70
nixf::LexerCursor::offset
std::size_t offset() const
Offset in the source file, starting from 0.
Definition
Range.h:102
nixf::Node
Definition
Basic.h:12
nixf::Node::lCur
LexerCursor lCur() const
Definition
Basic.h:37
nixf::Node::rCur
LexerCursor rCur() const
Definition
Basic.h:38
nixf::ParentMapAnalysis
Definition
ParentMap.h:15
nixf::ParentMapAnalysis::upTo
const Node * upTo(const Node &N, Node::NodeKind Kind) const
Search up until some kind of node is found.
Definition
ParentMap.cpp:27
lspserver::CompletionItemKind::Value
@ Value
Definition
lspserver/include/lspserver/Protocol.h:408
nixd
Definition
CommandLine/Configuration.h:9
nixd::addConvertToInheritAction
void addConvertToInheritAction(const nixf::Node &N, const nixf::ParentMapAnalysis &PM, const std::string &FileURI, llvm::StringRef Src, std::vector< lspserver::CodeAction > &Actions)
Add code action to convert binding to inherit syntax.
Definition
ConvertToInherit.cpp:15
nixd::createSingleEditAction
lspserver::CodeAction createSingleEditAction(const std::string &Title, llvm::StringLiteral Kind, const std::string &FileURI, const lspserver::Range &EditRange, std::string NewText)
Create a CodeAction with a single text edit.
Definition
Utils.cpp:10
nixd::toLSPRange
lspserver::Range toLSPRange(llvm::StringRef Code, const nixf::LexerCursorRange &R)
Definition
Convert.cpp:40
nixd::quoteNixAttrKey
std::string quoteNixAttrKey(const std::string &Key)
Quote and escape a Nix attribute key if necessary.
Definition
Utils.cpp:89
lspserver::CodeAction::REFACTOR_REWRITE_KIND
static const llvm::StringLiteral REFACTOR_REWRITE_KIND
Definition
lspserver/include/lspserver/Protocol.h:1131
Generated by
1.17.0