From 475afc77a5b2053caf961267fb1849d266931c23 Mon Sep 17 00:00:00 2001 From: Jacob Dufault Date: Thu, 20 Jul 2017 19:53:08 -0700 Subject: [PATCH] Support functions in type hierarchy. --- src/command_line.cc | 6 ++++- src/query_utils.cc | 64 +++++++++++++++++++++++++++++++++++++++++---- src/query_utils.h | 6 +++-- 3 files changed, 68 insertions(+), 8 deletions(-) diff --git a/src/command_line.cc b/src/command_line.cc index bf872070..e99ced04 100644 --- a/src/command_line.cc +++ b/src/command_line.cc @@ -1356,7 +1356,11 @@ bool QueryDbMainLoop( for (const SymbolRef& ref : FindSymbolsAtLocation(working_file, file, msg->params.position)) { if (ref.idx.kind == SymbolKind::Type) { - response.result = BuildTypeHierarchy(db, working_files, QueryTypeId(ref.idx.idx)); + response.result = BuildInheritanceHierarchyForType(db, working_files, QueryTypeId(ref.idx.idx)); + break; + } + if (ref.idx.kind == SymbolKind::Func) { + response.result = BuildInheritanceHierarchyForFunc(db, working_files, QueryFuncId(ref.idx.idx)); break; } } diff --git a/src/query_utils.cc b/src/query_utils.cc index 363a7fd1..29b159a6 100644 --- a/src/query_utils.cc +++ b/src/query_utils.cc @@ -615,7 +615,7 @@ std::vector FindSymbolsAtLocation(WorkingFile* working_file, QueryFil return symbols; } -NonElidedVector BuildParentTypeHierarchy(QueryDatabase* db, WorkingFiles* working_files, QueryTypeId root) { +NonElidedVector BuildParentInheritanceHierarchyForType(QueryDatabase* db, WorkingFiles* working_files, QueryTypeId root) { optional& root_type = db->types[root.id]; if (!root_type) return {}; @@ -632,7 +632,7 @@ NonElidedVector BuildParentTypeHierarchy parent_entry.name = parent_type->def.detailed_name; if (parent_type->def.definition_spelling) parent_entry.location = GetLsLocation(db, working_files, *parent_type->def.definition_spelling); - parent_entry.children = BuildParentTypeHierarchy(db, working_files, parent_id); + parent_entry.children = BuildParentInheritanceHierarchyForType(db, working_files, parent_id); parent_entries.push_back(parent_entry); } @@ -641,7 +641,7 @@ NonElidedVector BuildParentTypeHierarchy } -optional BuildTypeHierarchy(QueryDatabase* db, WorkingFiles* working_files, QueryTypeId root_id) { +optional BuildInheritanceHierarchyForType(QueryDatabase* db, WorkingFiles* working_files, QueryTypeId root_id) { optional& root_type = db->types[root_id.id]; if (!root_type) return nullopt; @@ -659,13 +659,67 @@ optional BuildTypeHierarchy(QueryDatabas Out_CqueryTypeHierarchyTree::TypeEntry base; base.name = "[[Base]]"; base.location = entry.location; - base.children = BuildParentTypeHierarchy(db, working_files, root_id); + base.children = BuildParentInheritanceHierarchyForType(db, working_files, root_id); if (!base.children.empty()) entry.children.push_back(base); // Add derived. for (QueryTypeId derived : root_type->derived) { - auto derived_entry = BuildTypeHierarchy(db, working_files, derived); + auto derived_entry = BuildInheritanceHierarchyForType(db, working_files, derived); + if (derived_entry) + entry.children.push_back(*derived_entry); + } + + return entry; +} + + +NonElidedVector BuildParentInheritanceHierarchyForFunc(QueryDatabase* db, WorkingFiles* working_files, QueryFuncId root) { + optional& root_func = db->funcs[root.id]; + if (!root_func || !root_func->def.base) + return {}; + + optional& parent_func = db->funcs[root_func->def.base->id]; + if (!parent_func) + return {}; + + Out_CqueryTypeHierarchyTree::TypeEntry parent_entry; + parent_entry.name = parent_func->def.detailed_name; + if (parent_func->def.definition_spelling) + parent_entry.location = GetLsLocation(db, working_files, *parent_func->def.definition_spelling); + parent_entry.children = BuildParentInheritanceHierarchyForFunc(db, working_files, *root_func->def.base); + + NonElidedVector entries; + entries.push_back(parent_entry); + return entries; +} + + +optional BuildInheritanceHierarchyForFunc(QueryDatabase* db, WorkingFiles* working_files, QueryFuncId root_id) { + optional& root_func = db->funcs[root_id.id]; + if (!root_func) + return nullopt; + + Out_CqueryTypeHierarchyTree::TypeEntry entry; + + // Name and location. + entry.name = root_func->def.detailed_name; + if (root_func->def.definition_spelling) + entry.location = GetLsLocation(db, working_files, *root_func->def.definition_spelling); + + entry.children.reserve(root_func->derived.size()); + + // Base types. + Out_CqueryTypeHierarchyTree::TypeEntry base; + base.name = "[[Base]]"; + base.location = entry.location; + base.children = BuildParentInheritanceHierarchyForFunc(db, working_files, root_id); + if (!base.children.empty()) + entry.children.push_back(base); + + // Add derived. + for (QueryFuncId derived : root_func->derived) { + auto derived_entry = BuildInheritanceHierarchyForFunc(db, working_files, derived); if (derived_entry) entry.children.push_back(*derived_entry); } diff --git a/src/query_utils.h b/src/query_utils.h index 4feade09..f4a6011f 100644 --- a/src/query_utils.h +++ b/src/query_utils.h @@ -52,7 +52,9 @@ void AddCodeLens( lsWorkspaceEdit BuildWorkspaceEdit(QueryDatabase* db, WorkingFiles* working_files, const std::vector& locations, const std::string& new_text); std::vector FindSymbolsAtLocation(WorkingFile* working_file, QueryFile* file, lsPosition position); -NonElidedVector BuildParentTypeHierarchy(QueryDatabase* db, WorkingFiles* working_files, QueryTypeId root); -optional BuildTypeHierarchy(QueryDatabase* db, WorkingFiles* working_files, QueryTypeId root_id); +NonElidedVector BuildParentInheritanceHierarchyForType(QueryDatabase* db, WorkingFiles* working_files, QueryTypeId root); +optional BuildInheritanceHierarchyForType(QueryDatabase* db, WorkingFiles* working_files, QueryTypeId root_id); +NonElidedVector BuildParentInheritanceHierarchyForFunc(QueryDatabase* db, WorkingFiles* working_files, QueryFuncId root); +optional BuildInheritanceHierarchyForFunc(QueryDatabase* db, WorkingFiles* working_files, QueryFuncId root_id); NonElidedVector BuildInitialCallTree(QueryDatabase* db, WorkingFiles* working_files, QueryFuncId root); NonElidedVector BuildExpandCallTree(QueryDatabase* db, WorkingFiles* working_files, QueryFuncId root); \ No newline at end of file