$ccls/vars: differentiate local/field/parameter

This commit is contained in:
Fangrui Song 2018-05-31 16:28:47 -07:00
parent bb08fdfa02
commit da545f1139
4 changed files with 47 additions and 12 deletions

View File

@ -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<In_CclsVars> {
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<In_CclsVars> {
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<In_CclsVars> {
[[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;
}
}

View File

@ -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;
}

View File

@ -59,8 +59,35 @@ std::vector<Use> GetFuncDeclarations(DB* db, const std::vector<Usr>& usrs) {
std::vector<Use> GetTypeDeclarations(DB* db, const std::vector<Usr>& usrs) {
return GetDeclarations(db->type_usr, db->types, usrs);
}
std::vector<Use> GetVarDeclarations(DB* db, const std::vector<Usr>& usrs) {
return GetDeclarations(db->var_usr, db->vars, usrs);
std::vector<Use> GetVarDeclarations(DB* db,
const std::vector<Usr>& usrs,
unsigned kind) {
std::vector<Use> 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<Use> GetNonDefDeclarations(DB* db, SymbolIdx sym) {

View File

@ -12,7 +12,7 @@ Maybe<Use> GetDefinitionExtent(DB* db, SymbolIdx sym);
// for each id.
std::vector<Use> GetFuncDeclarations(DB*, const std::vector<Usr>&);
std::vector<Use> GetTypeDeclarations(DB*, const std::vector<Usr>&);
std::vector<Use> GetVarDeclarations(DB*, const std::vector<Usr>&);
std::vector<Use> GetVarDeclarations(DB*, const std::vector<Usr>&, unsigned);
// Get non-defining declarations.
std::vector<Use> GetNonDefDeclarations(DB* db, SymbolIdx sym);