Support functions in type hierarchy.

This commit is contained in:
Jacob Dufault 2017-07-20 19:53:08 -07:00
parent a046f89650
commit 475afc77a5
3 changed files with 68 additions and 8 deletions

View File

@ -1356,7 +1356,11 @@ bool QueryDbMainLoop(
for (const SymbolRef& ref : FindSymbolsAtLocation(working_file, file, msg->params.position)) { for (const SymbolRef& ref : FindSymbolsAtLocation(working_file, file, msg->params.position)) {
if (ref.idx.kind == SymbolKind::Type) { 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; break;
} }
} }

View File

@ -615,7 +615,7 @@ std::vector<SymbolRef> FindSymbolsAtLocation(WorkingFile* working_file, QueryFil
return symbols; return symbols;
} }
NonElidedVector<Out_CqueryTypeHierarchyTree::TypeEntry> BuildParentTypeHierarchy(QueryDatabase* db, WorkingFiles* working_files, QueryTypeId root) { NonElidedVector<Out_CqueryTypeHierarchyTree::TypeEntry> BuildParentInheritanceHierarchyForType(QueryDatabase* db, WorkingFiles* working_files, QueryTypeId root) {
optional<QueryType>& root_type = db->types[root.id]; optional<QueryType>& root_type = db->types[root.id];
if (!root_type) if (!root_type)
return {}; return {};
@ -632,7 +632,7 @@ NonElidedVector<Out_CqueryTypeHierarchyTree::TypeEntry> BuildParentTypeHierarchy
parent_entry.name = parent_type->def.detailed_name; parent_entry.name = parent_type->def.detailed_name;
if (parent_type->def.definition_spelling) if (parent_type->def.definition_spelling)
parent_entry.location = GetLsLocation(db, working_files, *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); parent_entries.push_back(parent_entry);
} }
@ -641,7 +641,7 @@ NonElidedVector<Out_CqueryTypeHierarchyTree::TypeEntry> BuildParentTypeHierarchy
} }
optional<Out_CqueryTypeHierarchyTree::TypeEntry> BuildTypeHierarchy(QueryDatabase* db, WorkingFiles* working_files, QueryTypeId root_id) { optional<Out_CqueryTypeHierarchyTree::TypeEntry> BuildInheritanceHierarchyForType(QueryDatabase* db, WorkingFiles* working_files, QueryTypeId root_id) {
optional<QueryType>& root_type = db->types[root_id.id]; optional<QueryType>& root_type = db->types[root_id.id];
if (!root_type) if (!root_type)
return nullopt; return nullopt;
@ -659,13 +659,67 @@ optional<Out_CqueryTypeHierarchyTree::TypeEntry> BuildTypeHierarchy(QueryDatabas
Out_CqueryTypeHierarchyTree::TypeEntry base; Out_CqueryTypeHierarchyTree::TypeEntry base;
base.name = "[[Base]]"; base.name = "[[Base]]";
base.location = entry.location; base.location = entry.location;
base.children = BuildParentTypeHierarchy(db, working_files, root_id); base.children = BuildParentInheritanceHierarchyForType(db, working_files, root_id);
if (!base.children.empty()) if (!base.children.empty())
entry.children.push_back(base); entry.children.push_back(base);
// Add derived. // Add derived.
for (QueryTypeId derived : root_type->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<Out_CqueryTypeHierarchyTree::TypeEntry> BuildParentInheritanceHierarchyForFunc(QueryDatabase* db, WorkingFiles* working_files, QueryFuncId root) {
optional<QueryFunc>& root_func = db->funcs[root.id];
if (!root_func || !root_func->def.base)
return {};
optional<QueryFunc>& 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<Out_CqueryTypeHierarchyTree::TypeEntry> entries;
entries.push_back(parent_entry);
return entries;
}
optional<Out_CqueryTypeHierarchyTree::TypeEntry> BuildInheritanceHierarchyForFunc(QueryDatabase* db, WorkingFiles* working_files, QueryFuncId root_id) {
optional<QueryFunc>& 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) if (derived_entry)
entry.children.push_back(*derived_entry); entry.children.push_back(*derived_entry);
} }

View File

@ -52,7 +52,9 @@ void AddCodeLens(
lsWorkspaceEdit BuildWorkspaceEdit(QueryDatabase* db, WorkingFiles* working_files, const std::vector<QueryLocation>& locations, const std::string& new_text); lsWorkspaceEdit BuildWorkspaceEdit(QueryDatabase* db, WorkingFiles* working_files, const std::vector<QueryLocation>& locations, const std::string& new_text);
std::vector<SymbolRef> FindSymbolsAtLocation(WorkingFile* working_file, QueryFile* file, lsPosition position); std::vector<SymbolRef> FindSymbolsAtLocation(WorkingFile* working_file, QueryFile* file, lsPosition position);
NonElidedVector<Out_CqueryTypeHierarchyTree::TypeEntry> BuildParentTypeHierarchy(QueryDatabase* db, WorkingFiles* working_files, QueryTypeId root); NonElidedVector<Out_CqueryTypeHierarchyTree::TypeEntry> BuildParentInheritanceHierarchyForType(QueryDatabase* db, WorkingFiles* working_files, QueryTypeId root);
optional<Out_CqueryTypeHierarchyTree::TypeEntry> BuildTypeHierarchy(QueryDatabase* db, WorkingFiles* working_files, QueryTypeId root_id); optional<Out_CqueryTypeHierarchyTree::TypeEntry> BuildInheritanceHierarchyForType(QueryDatabase* db, WorkingFiles* working_files, QueryTypeId root_id);
NonElidedVector<Out_CqueryTypeHierarchyTree::TypeEntry> BuildParentInheritanceHierarchyForFunc(QueryDatabase* db, WorkingFiles* working_files, QueryFuncId root);
optional<Out_CqueryTypeHierarchyTree::TypeEntry> BuildInheritanceHierarchyForFunc(QueryDatabase* db, WorkingFiles* working_files, QueryFuncId root_id);
NonElidedVector<Out_CqueryCallTree::CallEntry> BuildInitialCallTree(QueryDatabase* db, WorkingFiles* working_files, QueryFuncId root); NonElidedVector<Out_CqueryCallTree::CallEntry> BuildInitialCallTree(QueryDatabase* db, WorkingFiles* working_files, QueryFuncId root);
NonElidedVector<Out_CqueryCallTree::CallEntry> BuildExpandCallTree(QueryDatabase* db, WorkingFiles* working_files, QueryFuncId root); NonElidedVector<Out_CqueryCallTree::CallEntry> BuildExpandCallTree(QueryDatabase* db, WorkingFiles* working_files, QueryFuncId root);