From d758b786357572f0cb230cc606b459e5a2e992e5 Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Wed, 12 Sep 2018 13:46:20 -0700 Subject: [PATCH] Make $ccls/inheritanceHierarchy and textDocument/typeDefinition find declarations if definitions do not exist; spelling ranges of operator= --- index_tests/operators/operator.cc | 2 +- src/indexer.cc | 1 + src/messages/ccls_inheritanceHierarchy.cc | 3 ++ src/messages/textDocument_typeDefinition.cc | 34 +++++++++++++-------- 4 files changed, 26 insertions(+), 14 deletions(-) diff --git a/index_tests/operators/operator.cc b/index_tests/operators/operator.cc index 3a569983..009db1c0 100644 --- a/index_tests/operators/operator.cc +++ b/index_tests/operators/operator.cc @@ -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": [], diff --git a/src/indexer.cc b/src/indexer.cc index 421d4488..4d8a5584 100644 --- a/src/indexer.cc +++ b/src/indexer.cc @@ -664,6 +664,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(OrigD)->getNameInfo().getSourceRange(); diff --git a/src/messages/ccls_inheritanceHierarchy.cc b/src/messages/ccls_inheritanceHierarchy.cc index dd087c2e..c4a0696d 100644 --- a/src/messages/ccls_inheritanceHierarchy.cc +++ b/src/messages/ccls_inheritanceHierarchy.cc @@ -71,6 +71,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; diff --git a/src/messages/textDocument_typeDefinition.cc b/src/messages/textDocument_typeDefinition.cc index acba3cca..cc91e6ba 100644 --- a/src/messages/textDocument_typeDefinition.cc +++ b/src/messages/textDocument_typeDefinition.cc @@ -30,32 +30,40 @@ 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; + 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)) { - 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]]; + if (def && def->type) + Add(db->Type(def->type)); + break; } case SymbolKind::Type: { - QueryType &type = db->Type(usr); - 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); + for (auto &def : db->GetType(sym).def) + if (def.alias_of) { + Add(db->Type(def.alias_of)); + break; } break; }