19#include <boost/asio/post.hpp>
45 SM_Deprecated = 1 << 1,
49struct RawSemanticToken {
51 bool operator<(
const RawSemanticToken &Other)
const {
52 return Pos < Other.Pos;
56 unsigned TokenModifiers;
59class SemanticTokenBuilder {
65 std::vector<RawSemanticToken> Raw;
71 : VLA(VLA), Src(Src) {}
73 unsigned TokenModifiers) {
75 Raw.emplace_back(RawSemanticToken{P, Length, TokenType, TokenModifiers});
78 void add(
const Node &N,
unsigned TokenType,
unsigned TokenModifiers) {
81 addImpl(N.
lCur(), len(N), TokenType, TokenModifiers);
84 static bool skip(
const Node &N) {
89 static unsigned len(
const Node &N) {
94 unsigned Modifers = 0;
97 add(Str, ST_String, Modifers);
101 if (Var.
id().
name() ==
"true" || Var.
id().
name() ==
"false") {
102 add(Var, ST_Bool, SM_Builtin);
106 if (Var.
id().
name() ==
"null") {
107 add(Var, ST_Null, 0);
111 auto Result = VLA.
query(Var);
113 if (Result.Def && Result.Def->isBuiltin()) {
114 add(Var, ST_Builtin, SM_Builtin);
117 if (Result.Kind == ResultKind::Defined) {
118 add(Var, ST_Defined, 0);
121 if (Result.Kind == ResultKind::FromWith) {
122 add(Var, ST_FromWith, SM_Dynamic);
126 add(Var, ST_Defined, SM_Deprecated);
134 for (
const std::shared_ptr<nixf::AttrName> &Name : Select.
path()->
names()) {
140 add(AN, ST_Select, 0);
147 for (
const auto &[Name, Attr] : SA.
staticAttrs()) {
153 if (Attr.fromInherit())
155 add(Attr.key(), ST_AttrName, 0);
165 add(*Arg.
id(), ST_LambdaArg, 0);
170 add(*
Formal->
id(), ST_LambdaFormal, 0);
182 void dfs(
const Node *AST) {
185 switch (AST->
kind()) {
186 case Node::NK_ExprLambda: {
187 const auto &Lambda =
static_cast<const ExprLambda &
>(*AST);
191 case Node::NK_ExprString: {
192 const auto &Str =
static_cast<const ExprString &
>(*AST);
196 case Node::NK_ExprVar: {
197 const auto &Var =
static_cast<const ExprVar &
>(*AST);
201 case Node::NK_ExprSelect: {
202 const auto &Select =
static_cast<const ExprSelect &
>(*AST);
206 case Node::NK_ExprAttrs: {
218 std::vector<SemanticToken> finish() {
219 std::vector<SemanticToken> Tokens;
220 std::sort(Raw.begin(), Raw.end());
222 for (
auto Elm : Raw) {
223 assert(Elm.Pos.line - Prev.line >= 0);
224 unsigned DeltaLine = Elm.Pos.line - Prev.line;
226 DeltaLine ? Elm.Pos.character : Elm.Pos.character - Prev.character;
228 Tokens.emplace_back(DeltaLine, DeltaCol, Elm.Length, Elm.TokenType,
243 return Reply([&]() -> llvm::Expected<CheckTy> {
246 SemanticTokenBuilder Builder(*TU->variableLookup(), TU->src());
247 Builder.dfs(AST.get());
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.
AttrNameKind kind() const
const std::vector< std::shared_ptr< AttrName > > & names() const
const SemaAttrs & sema() const
Expr * defaultExpr() const
const Identifier & id() const
const std::string & name() const
Formals * formals() const
A point in the source file.
std::size_t offset() const
Offset in the source file, starting from 0.
int64_t line() const
Line number, starting from 0.
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
bool operator<(const CompletionItem &, const CompletionItem &)
lspserver::Position toLSPPosition(llvm::StringRef Code, const nixf::LexerCursor &P)
Body of textDocument/semanticTokens/full request.
TextDocumentIdentifier textDocument
The text document.
A versioned set of tokens.
URIForFile uri
The text document's URI.