11#include <boost/asio/post.hpp>
12#include <llvm/ADT/StringRef.h>
26std::string getLambdaName(
const ExprLambda &Lambda) {
27 if (!Lambda.
arg() || !Lambda.
arg()->
id())
28 return "(anonymous lambda)";
38 if (!Lambda.
arg()->
id()) {
55 if (Var.
id().
name() ==
"true" || Var.
id().
name() ==
"false") {
56 Sym.
kind = SymbolKind::Boolean;
57 Sym.
detail =
"builtin boolean";
61 if (Var.
id().
name() ==
"null") {
62 Sym.
kind = SymbolKind::Null;
67 auto Result = VLA.
query(Var);
69 if (Result.Kind == ResultKind::Defined)
70 Sym.
kind = SymbolKind::Constant;
71 else if (Result.Kind == ResultKind::FromWith)
72 Sym.
kind = SymbolKind::Variable;
78 if (Result.Def->isBuiltin())
79 Sym.
kind = SymbolKind::Event;
83void collect(
const Node *AST, std::vector<DocumentSymbol> &Symbols,
87 switch (AST->
kind()) {
89 case Node::NK_ExprString: {
90 const auto &Str =
static_cast<const ExprString &
>(*AST);
92 .name = Str.isLiteral() ? Str.literal() :
"(dynamic string)",
94 .kind = SymbolKind::String,
97 .selectionRange =
toLSPRange(Src, Str.range()),
100 Symbols.emplace_back(std::move(Sym));
103 case Node::NK_ExprInt: {
104 const auto &Int =
static_cast<const ExprInt &
>(*AST);
106 .name = std::to_string(Int.value()),
108 .kind = SymbolKind::Number,
111 .selectionRange =
toLSPRange(Src, Int.range()),
114 Symbols.emplace_back(std::move(Sym));
117 case Node::NK_ExprFloat: {
118 const auto &Float =
static_cast<const ExprFloat &
>(*AST);
120 .name = std::to_string(Float.value()),
122 .kind = SymbolKind::Number,
125 .selectionRange =
toLSPRange(Src, Float.range()),
128 Symbols.emplace_back(std::move(Sym));
131 case Node::NK_AttrName: {
132 const auto &AN =
static_cast<const AttrName &
>(*AST);
134 .name = AN.isStatic() ? AN.staticName() :
"(dynamic attribute name)",
135 .detail =
"attribute name",
136 .kind = SymbolKind::Property,
139 .selectionRange =
toLSPRange(Src, AN.range()),
142 Symbols.emplace_back(std::move(Sym));
145 case Node::NK_ExprVar: {
146 const auto &Var =
static_cast<const ExprVar &
>(*AST);
149 .detail =
"identifier",
150 .kind = SymbolKind::Variable,
156 richVar(Var, Sym, VLA);
157 Symbols.emplace_back(std::move(Sym));
160 case Node::NK_ExprLambda: {
161 std::vector<DocumentSymbol>
Children;
162 const auto &Lambda =
static_cast<const ExprLambda &
>(*AST);
165 .name = getLambdaName(Lambda),
167 .kind = SymbolKind::Function,
170 .selectionRange = getLambdaSelectionRage(Src, Lambda),
173 Symbols.emplace_back(std::move(Sym));
176 case Node::NK_ExprList: {
177 std::vector<DocumentSymbol>
Children;
178 const auto &List =
static_cast<const ExprList &
>(*AST);
183 .name =
"{anonymous}",
185 .kind = SymbolKind::Array,
188 .selectionRange =
toLSPRange(Src, List.range()),
191 Symbols.emplace_back(std::move(Sym));
194 case Node::NK_ExprAttrs: {
196 for (
const auto &[Name, Attr] : SA.
staticAttrs()) {
199 std::vector<DocumentSymbol>
Children;
203 .detail =
"attribute",
204 .kind = SymbolKind::Field,
206 .range = getAttrRange(Src, Attr),
210 Symbols.emplace_back(std::move(Sym));
213 std::vector<DocumentSymbol>
Children;
216 .name =
"${dynamic attribute}",
217 .detail =
"attribute",
218 .kind = SymbolKind::Field,
220 .range = getAttrRange(Src, Attr),
224 Symbols.emplace_back(std::move(Sym));
231 collect(Ch, Symbols, VLA, Src);
239 Callback<std::vector<DocumentSymbol>> Reply) {
240 using CheckTy = std::vector<DocumentSymbol>;
243 return Reply([&]() -> llvm::Expected<CheckTy> {
246 auto Symbols = std::vector<DocumentSymbol>();
247 collect(AST.get(), Symbols, *TU->variableLookup(), TU->
src());
251 boost::asio::post(Pool, std::move(Action));
#define CheckDefault(x)
Variant of CheckReturn, but returns default constructed CheckTy
Convert between LSP and nixf types.
Lookup variable names, from it's parent scope.
const SemaAttrs & sema() const
const Identifier & id() const
const std::string & name() const
Formals * formals() const
std::string_view src(std::string_view Src) const
LexerCursorRange range() const
virtual ChildVector children() const =0
Attribute set after deduplication.
const std::vector< Attribute > & dynamicAttrs() const
Dynamic attributes, require evaluation to get the key.
const std::map< std::string, Attribute > & staticAttrs() const
Static attributes, do not require evaluation to get the key.
LookupResult query(const ExprVar &Var) const
Query the which name/with binds to specific varaible.
Whether current platform treats paths case insensitively.
llvm::unique_function< void(llvm::Expected< T >)> Callback
lspserver::Position toLSPPosition(llvm::StringRef Code, const nixf::LexerCursor &P)
lspserver::Range toLSPRange(llvm::StringRef Code, const nixf::LexerCursorRange &R)
TextDocumentIdentifier textDocument
SymbolKind kind
The kind of this symbol.
bool deprecated
Indicates if this symbol is deprecated.
std::string detail
More detail for this symbol, e.g the signature of a function.
URIForFile uri
The text document's URI.