nixd
Toggle main menu visibility
Loading...
Searching...
No Matches
nixd
lib
Controller
CodeActions
FlattenAttrs.cpp
Go to the documentation of this file.
1
/// \file
2
/// \brief Implementation of flatten nested attribute sets code action.
3
4
#include "
FlattenAttrs.h
"
5
#include "
Utils.h
"
6
7
#include "
../Convert.h
"
8
9
#include <
nixf/Basic/Nodes/Attrs.h
>
10
11
namespace
nixd
{
12
13
namespace
{
14
15
/// \brief Check if an ExprAttrs can be flattened (no rec, inherit, dynamic).
16
/// Returns the Binds node if flattenable, nullptr otherwise.
17
const
nixf::Binds *getFlattenableBinds(
const
nixf::ExprAttrs &Attrs) {
18
// Block if recursive attribute set
19
if
(Attrs.
isRecursive
())
20
return
nullptr
;
21
22
const
nixf::Binds *B = Attrs.
binds
();
23
if
(!B || B->
bindings
().empty())
24
return
nullptr
;
25
26
// Check all bindings: must be plain Binding nodes (no Inherit)
27
// and all attribute names must be static (no dynamic ${} interpolation)
28
for
(
const
auto
&Child : B->
bindings
()) {
29
if
(Child->kind() != nixf::Node::NK_Binding)
30
return
nullptr
;
// Inherit node found
31
32
const
auto
&Bind =
static_cast<
const
nixf::Binding &
>
(*Child);
33
for
(
const
auto
&Name : Bind.path().names()) {
34
if
(!Name->isStatic())
35
return
nullptr
;
// Dynamic attribute name
36
}
37
}
38
39
return
B;
40
}
41
42
}
// namespace
43
44
void
addFlattenAttrsAction
(
const
nixf::Node
&N,
45
const
nixf::ParentMapAnalysis
&PM,
46
const
std::string &FileURI, llvm::StringRef Src,
47
std::vector<lspserver::CodeAction> &Actions) {
48
// Find if we're inside a Binding
49
const
nixf::Node
*BindingNode = PM.
upTo
(N, nixf::Node::NK_Binding);
50
if
(!BindingNode)
51
return
;
52
53
const
auto
&Bind =
static_cast<
const
nixf::Binding
&
>
(*BindingNode);
54
55
// Check if the binding's value is an ExprAttrs
56
if
(!Bind.value() || Bind.value()->kind() != nixf::Node::NK_ExprAttrs)
57
return
;
58
59
const
auto
&NestedAttrs =
static_cast<
const
nixf::ExprAttrs
&
>
(*Bind.value());
60
61
// Check if flattenable
62
const
nixf::Binds
*NestedBinds = getFlattenableBinds(NestedAttrs);
63
if
(!NestedBinds)
64
return
;
65
66
// Check outer path is static too
67
for
(
const
auto
&Name : Bind.path().names()) {
68
if
(!Name->isStatic())
69
return
;
70
}
71
72
// Build the flattened text
73
std::string NewText;
74
const
auto
&NestedBindings = NestedBinds->
bindings
();
75
76
// Pre-allocate to reduce reallocations. The +40 accounts for inner path,
77
// " = ", value text, and ";". May under-allocate for complex expressions
78
// but still reduces reallocations significantly.
79
const
std::string_view OuterPath = Bind.path().src(Src);
80
size_t
EstimatedSize = NestedBindings.size() * (OuterPath.size() + 40);
81
NewText.reserve(EstimatedSize);
82
83
for
(
size_t
I = 0; I < NestedBindings.size(); ++I) {
84
const
auto
&InnerBind =
85
static_cast<
const
nixf::Binding
&
>
(*NestedBindings[I]);
86
87
// Build path: outer.inner
88
const
std::string_view InnerPath = InnerBind.
path
().
src
(Src);
89
90
NewText += OuterPath;
91
NewText +=
"."
;
92
NewText += InnerPath;
93
NewText +=
" = "
;
94
95
if
(InnerBind.value()) {
96
NewText += InnerBind.value()->src(Src);
97
}
98
NewText +=
";"
;
99
100
if
(I + 1 < NestedBindings.size())
101
NewText +=
" "
;
102
}
103
104
Actions.emplace_back(
createSingleEditAction
(
105
"Flatten nested attribute set"
,
106
lspserver::CodeAction::REFACTOR_REWRITE_KIND
, FileURI,
107
toLSPRange
(Src, Bind.range()), std::move(NewText)));
108
}
109
110
}
// namespace nixd
Attrs.h
Convert.h
Convert between LSP and nixf types.
FlattenAttrs.h
Code action for flattening nested attribute sets.
Utils.h
Shared utilities for code actions.
nixf::Binding
Definition
Attrs.h:115
nixf::Binding::path
const AttrPath & path() const
Definition
Attrs.h:131
nixf::Binds
Definition
Attrs.h:173
nixf::Binds::bindings
const std::vector< std::shared_ptr< Node > > & bindings() const
Definition
Attrs.h:180
nixf::ExprAttrs
Definition
Attrs.h:272
nixf::ExprAttrs::isRecursive
bool isRecursive() const
Definition
Attrs.h:287
nixf::ExprAttrs::binds
const Binds * binds() const
Definition
Attrs.h:284
nixf::Node
Definition
Basic.h:12
nixf::Node::src
std::string_view src(std::string_view Src) const
Definition
Basic.h:63
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
nixd
Definition
CommandLine/Configuration.h:9
nixd::addFlattenAttrsAction
void addFlattenAttrsAction(const nixf::Node &N, const nixf::ParentMapAnalysis &PM, const std::string &FileURI, llvm::StringRef Src, std::vector< lspserver::CodeAction > &Actions)
Add flatten action for nested attribute sets.
Definition
FlattenAttrs.cpp:44
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
lspserver::CodeAction::REFACTOR_REWRITE_KIND
static const llvm::StringLiteral REFACTOR_REWRITE_KIND
Definition
lspserver/include/lspserver/Protocol.h:1131
Generated by
1.17.0