11#include <boost/asio/post.hpp>
26constexpr size_t MaxRecursionDepth = 256;
45void addFoldingRange(
const Node &N, std::vector<FoldingRange> &Ranges,
46 llvm::StringRef Src) {
49 Ranges.emplace_back(toFoldingRange(R));
57void collectFoldingRanges(
const Node *AST, std::vector<FoldingRange> &Ranges,
58 llvm::StringRef Src,
size_t Depth = 0) {
59 if (!AST || Depth >= MaxRecursionDepth)
62 switch (AST->
kind()) {
63 case Node::NK_ExprAttrs: {
64 addFoldingRange(*AST, Ranges, Src);
65 const auto &Attrs =
static_cast<const ExprAttrs &
>(*AST);
68 collectFoldingRanges(Ch, Ranges, Src, Depth + 1);
72 case Node::NK_ExprList: {
73 addFoldingRange(*AST, Ranges, Src);
75 collectFoldingRanges(Ch, Ranges, Src, Depth + 1);
78 case Node::NK_ExprLambda: {
79 addFoldingRange(*AST, Ranges, Src);
80 const auto &Lambda =
static_cast<const ExprLambda &
>(*AST);
81 if (
const auto *Body = Lambda.body())
82 collectFoldingRanges(Body, Ranges, Src, Depth + 1);
85 case Node::NK_ExprLet: {
86 addFoldingRange(*AST, Ranges, Src);
87 const auto &Let =
static_cast<const ExprLet &
>(*AST);
88 if (
const auto *Attrs = Let.attrs())
89 collectFoldingRanges(Attrs, Ranges, Src, Depth + 1);
90 if (
const auto *E = Let.expr())
91 collectFoldingRanges(E, Ranges, Src, Depth + 1);
94 case Node::NK_ExprWith: {
95 addFoldingRange(*AST, Ranges, Src);
96 const auto &With =
static_cast<const ExprWith &
>(*AST);
97 if (
const auto *W = With.with())
98 collectFoldingRanges(W, Ranges, Src, Depth + 1);
99 if (
const auto *E = With.expr())
100 collectFoldingRanges(E, Ranges, Src, Depth + 1);
103 case Node::NK_ExprIf: {
104 addFoldingRange(*AST, Ranges, Src);
105 const auto &If =
static_cast<const ExprIf &
>(*AST);
106 if (
const auto *Cond = If.cond())
107 collectFoldingRanges(Cond, Ranges, Src, Depth + 1);
108 if (
const auto *Then = If.then())
109 collectFoldingRanges(Then, Ranges, Src, Depth + 1);
110 if (
const auto *Else = If.elseExpr())
111 collectFoldingRanges(Else, Ranges, Src, Depth + 1);
114 case Node::NK_ExprString:
116 addFoldingRange(*AST, Ranges, Src);
121 collectFoldingRanges(Ch, Ranges, Src, Depth + 1);
136 Callback<std::vector<FoldingRange>> Reply) {
137 using CheckTy = std::vector<FoldingRange>;
138 auto Action = [Reply = std::move(Reply), URI = Params.
textDocument.
uri,
140 return Reply([&]() -> llvm::Expected<CheckTy> {
144 auto Ranges = std::vector<FoldingRange>();
145 collectFoldingRanges(AST.get(), Ranges, TU->
src());
147 }
catch (std::exception &E) {
148 elog(
"textDocument/foldingRange failed: {0}", E.what());
153 boost::asio::post(Pool, std::move(Action));
#define CheckDefault(x)
Variant of CheckReturn, but returns default constructed CheckTy.
Convert between LSP and nixf types.
std::string_view src(std::string_view Src) const
LexerCursorRange range() const
virtual ChildVector children() const =0
Whether current platform treats paths case insensitively.
llvm::unique_function< void(llvm::Expected< T >)> Callback
void elog(const char *Fmt, Ts &&...Vals)
lspserver::Range toLSPRange(llvm::StringRef Code, const nixf::LexerCursorRange &R)
TextDocumentIdentifier textDocument
Stores information about a region of code that can be folded.
static const llvm::StringLiteral REGION_KIND
int64_t line
Line position in a document (zero-based).
Position start
The range's start position.
Position end
The range's end position.
URIForFile uri
The text document's URI.