7#include <llvm/Support/JSON.h>
22std::string jsonToNix(
const llvm::json::Value &V,
size_t Indent = 0,
27 std::string IndentStr(Indent * 2,
' ');
28 std::string NextIndent((Indent + 1) * 2,
' ');
31 if (V.kind() == llvm::json::Value::Null) {
33 }
else if (
auto B = V.getAsBoolean()) {
34 Out = *B ?
"true" :
"false";
35 }
else if (
auto I = V.getAsInteger()) {
36 Out = std::to_string(*I);
37 }
else if (
auto D = V.getAsNumber()) {
39 std::ostringstream SS;
40 SS << std::setprecision(17) << *D;
42 }
else if (
auto S = V.getAsString()) {
44 }
else if (
const auto *A = V.getAsArray()) {
53 size_t EstimatedSize = 4 + A->size() * ((Indent + 1) * 2 + 20);
54 Out.reserve(EstimatedSize);
56 for (
size_t I = 0; I < A->size(); ++I) {
57 std::string Elem = jsonToNix((*A)[I], Indent + 1, Depth + 1);
60 Out += NextIndent + Elem;
61 if (I + 1 < A->size())
64 Out +=
"\n" + IndentStr +
"]";
66 }
else if (
const auto *O = V.getAsObject()) {
75 size_t EstimatedSize = 4 + O->size() * ((Indent + 1) * 2 + 30);
76 Out.reserve(EstimatedSize);
79 for (
const auto &KV : *O) {
81 std::string Val = jsonToNix(KV.second, Indent + 1, Depth + 1);
84 Out += NextIndent +
Key +
" = " + Val +
";";
85 if (I + 1 < O->size())
89 Out +=
"\n" + IndentStr +
"}";
98 const std::string &FileURI,
99 std::vector<lspserver::CodeAction> &Actions) {
101 llvm::Expected<size_t> StartOffset =
103 llvm::Expected<size_t> EndOffset =
106 if (!StartOffset || !EndOffset) {
108 llvm::consumeError(StartOffset.takeError());
110 llvm::consumeError(EndOffset.takeError());
115 if (*StartOffset >= *EndOffset || *EndOffset > Src.size())
119 llvm::StringRef SelectedText =
120 Src.substr(*StartOffset, *EndOffset - *StartOffset);
123 if (SelectedText.size() < 2)
127 char First = SelectedText.front();
128 if (First !=
'{' && First !=
'[')
132 llvm::Expected<llvm::json::Value> JsonVal = llvm::json::parse(SelectedText);
134 llvm::consumeError(JsonVal.takeError());
139 if (
const auto *A = JsonVal->getAsArray()) {
142 }
else if (
const auto *O = JsonVal->getAsObject()) {
148 std::string NixText = jsonToNix(*JsonVal);
154 FileURI,
Range, std::move(NixText)));
Code action for converting JSON to Nix expressions.
Shared utilities for code actions.
llvm::Expected< size_t > positionToOffset(llvm::StringRef Code, Position P, bool AllowColumnsBeyondLineLength=true)
void addJsonToNixAction(llvm::StringRef Src, const lspserver::Range &Range, const std::string &FileURI, std::vector< lspserver::CodeAction > &Actions)
Add JSON to Nix conversion action for selected JSON text.
constexpr size_t MaxJsonDepth
Maximum recursion depth for JSON to Nix conversion.
constexpr size_t MaxJsonWidth
Maximum array/object width for JSON to Nix conversion.
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.
std::string escapeNixString(llvm::StringRef S)
Escape special characters for Nix double-quoted string literals.
std::string quoteNixAttrKey(const std::string &Key)
Quote and escape a Nix attribute key if necessary.
static const llvm::StringLiteral REFACTOR_REWRITE_KIND
Position start
The range's start position.
Position end
The range's end position.