diff --git a/src/messages/ccls_vars.cc b/src/messages/ccls_vars.cc index 95d8ff91..70616845 100644 --- a/src/messages/ccls_vars.cc +++ b/src/messages/ccls_vars.cc @@ -8,9 +8,17 @@ MethodType kMethodType = "$ccls/vars"; struct In_CclsVars : public RequestInMessage { MethodType GetMethodType() const override { return kMethodType; } - - lsTextDocumentPositionParams params; + struct Params : lsTextDocumentPositionParams { + // 1: field + // 2: local + // 4: parameter + unsigned kind = ~0u; + } params; }; +MAKE_REFLECT_STRUCT(In_CclsVars::Params, + textDocument, + position, + kind); MAKE_REFLECT_STRUCT(In_CclsVars, id, params); REGISTER_IN_MESSAGE(In_CclsVars); @@ -18,11 +26,11 @@ struct Handler_CclsVars : BaseMessageHandler { MethodType GetMethodType() const override { return kMethodType; } void Run(In_CclsVars* request) override { + auto& params = request->params; QueryFile* file; if (!FindFileOrFail(db, project, request->id, - request->params.textDocument.uri.GetPath(), &file)) { + params.textDocument.uri.GetPath(), &file)) return; - } WorkingFile* working_file = working_files->GetFileByFilename(file->def->path); @@ -30,7 +38,7 @@ struct Handler_CclsVars : BaseMessageHandler { Out_LocationList out; out.id = request->id; for (SymbolRef sym : - FindSymbolsAtLocation(working_file, file, request->params.position)) { + FindSymbolsAtLocation(working_file, file, params.position)) { Usr usr = sym.usr; switch (sym.kind) { default: @@ -43,9 +51,9 @@ struct Handler_CclsVars : BaseMessageHandler { [[fallthrough]]; } case SymbolKind::Type: - out.result = - GetLsLocationExs(db, working_files, - GetVarDeclarations(db, db->Type(usr).instances)); + out.result = GetLsLocationExs( + db, working_files, + GetVarDeclarations(db, db->Type(usr).instances, params.kind)); break; } } diff --git a/src/messages/text_document_code_lens.cc b/src/messages/text_document_code_lens.cc index 0691ac30..bd6704fd 100644 --- a/src/messages/text_document_code_lens.cc +++ b/src/messages/text_document_code_lens.cc @@ -121,7 +121,7 @@ struct Handler_TextDocumentCodeLens GetTypeDeclarations(db, type.derived), false /*force_display*/); AddCodeLens("var", "vars", &common, OffsetStartColumn(use, 2), - GetVarDeclarations(db, type.instances), + GetVarDeclarations(db, type.instances, true), false /*force_display*/); break; } diff --git a/src/query_utils.cc b/src/query_utils.cc index 6ffdb4af..0ced17ba 100644 --- a/src/query_utils.cc +++ b/src/query_utils.cc @@ -59,8 +59,35 @@ std::vector GetFuncDeclarations(DB* db, const std::vector& usrs) { std::vector GetTypeDeclarations(DB* db, const std::vector& usrs) { return GetDeclarations(db->type_usr, db->types, usrs); } -std::vector GetVarDeclarations(DB* db, const std::vector& usrs) { - return GetDeclarations(db->var_usr, db->vars, usrs); +std::vector GetVarDeclarations(DB* db, + const std::vector& usrs, + unsigned kind) { + std::vector ret; + ret.reserve(usrs.size()); + for (Usr usr : usrs) { + QueryVar& var = db->Var(usr); + bool has_def = false; + for (auto& def : var.def) + if (def.spell) { + has_def = true; + // See messages/ccls_vars.cc + if (def.kind == lsSymbolKind::Field) { + if (!(kind & 1)) + break; + } else if (def.kind == lsSymbolKind::Variable) { + if (!(kind & 2)) + break; + } else if (def.kind == lsSymbolKind::Parameter) { + if (!(kind & 4)) + break; + } + ret.push_back(*def.spell); + break; + } + if (!has_def && var.declarations.size()) + ret.push_back(var.declarations[0]); + } + return ret; } std::vector GetNonDefDeclarations(DB* db, SymbolIdx sym) { diff --git a/src/query_utils.h b/src/query_utils.h index 239738cb..52397000 100644 --- a/src/query_utils.h +++ b/src/query_utils.h @@ -12,7 +12,7 @@ Maybe GetDefinitionExtent(DB* db, SymbolIdx sym); // for each id. std::vector GetFuncDeclarations(DB*, const std::vector&); std::vector GetTypeDeclarations(DB*, const std::vector&); -std::vector GetVarDeclarations(DB*, const std::vector&); +std::vector GetVarDeclarations(DB*, const std::vector&, unsigned); // Get non-defining declarations. std::vector GetNonDefDeclarations(DB* db, SymbolIdx sym);