Make $ccls/inheritanceHierarchy and textDocument/typeDefinition find declarations if definitions do not exist; spelling ranges of operator=

This commit is contained in:
Fangrui Song 2018-09-12 13:46:20 -07:00
parent e2f29d7b1b
commit 6bca153ee3
4 changed files with 26 additions and 14 deletions

View File

@ -45,7 +45,7 @@ OUTPUT:
"kind": 6,
"storage": 0,
"declarations": [],
"spell": "2:8-2:16|15041163540773201510|2|1026|-1",
"spell": "2:8-2:18|15041163540773201510|2|1026|-1",
"extent": "2:3-2:27|15041163540773201510|2|0|-1",
"bases": [],
"derived": [],

View File

@ -679,6 +679,7 @@ public:
switch (OrigD->getKind()) {
case Decl::CXXConversion: // *operator* int => *operator int*
case Decl::CXXDestructor: // *~*A => *~A*
case Decl::CXXMethod: // *operator*= => *operator=*
if (Loc.isFileID()) {
SourceRange R =
cast<FunctionDecl>(OrigD)->getNameInfo().getSourceRange();

View File

@ -83,6 +83,9 @@ bool ExpandHelper(MessageHandler *m, Out_CclsInheritanceHierarchy::Entry *entry,
if (def->spell) {
if (auto loc = GetLsLocation(m->db, m->working_files, *def->spell))
entry->location = *loc;
} else if (entity.declarations.size()) {
if (auto loc = GetLsLocation(m->db, m->working_files, entity.declarations[0]))
entry->location = *loc;
}
} else if (!derived) {
entry->numChildren = 0;

View File

@ -42,33 +42,41 @@ struct Handler_TextDocumentTypeDefinition
QueryFile *file;
if (!FindFileOrFail(db, project, request->id,
request->params.textDocument.uri.GetPath(), &file,
nullptr)) {
nullptr))
return;
}
WorkingFile *working_file =
working_files->GetFileByFilename(file->def->path);
Out_TextDocumentTypeDefinition out;
out.id = request->id;
for (SymbolRef sym :
FindSymbolsAtLocation(working_file, file, request->params.position)) {
Usr usr = sym.usr;
switch (sym.kind) {
case SymbolKind::Var: {
const QueryVar::Def *def = db->GetVar(sym).AnyDef();
if (!def || !def->type)
continue;
usr = def->type;
[[fallthrough]];
}
case SymbolKind::Type: {
QueryType &type = db->Type(usr);
auto Add = [&](const QueryType &type) {
for (const auto &def : type.def)
if (def.spell) {
if (auto ls_loc = GetLsLocationEx(db, working_files, *def.spell,
g_config->xref.container))
out.result.push_back(*ls_loc);
}
if (out.result.empty())
for (const DeclRef &dr : type.declarations)
if (auto ls_loc = GetLsLocationEx(db, working_files, dr,
g_config->xref.container))
out.result.push_back(*ls_loc);
};
for (SymbolRef sym :
FindSymbolsAtLocation(working_file, file, request->params.position)) {
switch (sym.kind) {
case SymbolKind::Var: {
const QueryVar::Def *def = db->GetVar(sym).AnyDef();
if (def && def->type)
Add(db->Type(def->type));
break;
}
case SymbolKind::Type: {
for (auto &def : db->GetType(sym).def)
if (def.alias_of) {
Add(db->Type(def.alias_of));
break;
}
break;
}
default: