mirror of
https://github.com/MaskRay/ccls.git
synced 2024-11-29 11:01:57 +00:00
Add TypeDefDefinitionData::declarations
Constructors and destructors are also included in declarations. But this is not necessarily bad, as textDocument/definition on class spelling names can jump to constructors as well as declarations.
This commit is contained in:
parent
9f3e0ce0dc
commit
40ab5900de
@ -39,6 +39,23 @@ void AddFuncUse(std::vector<Use>* result, Use ref) {
|
|||||||
result->push_back(ref);
|
result->push_back(ref);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO How to check if a reference to type is a declaration?
|
||||||
|
// This currently also includes constructors/destructors.
|
||||||
|
// It seems declarations in functions are not indexed.
|
||||||
|
bool IsDeclContext(CXIdxEntityKind kind) {
|
||||||
|
switch (kind) {
|
||||||
|
case CXIdxEntity_CXXClass:
|
||||||
|
case CXIdxEntity_CXXNamespace:
|
||||||
|
case CXIdxEntity_ObjCCategory:
|
||||||
|
case CXIdxEntity_ObjCClass:
|
||||||
|
case CXIdxEntity_ObjCProtocol:
|
||||||
|
case CXIdxEntity_Struct:
|
||||||
|
return true;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool IsScopeSemanticContainer(CXCursorKind kind) {
|
bool IsScopeSemanticContainer(CXCursorKind kind) {
|
||||||
switch (kind) {
|
switch (kind) {
|
||||||
case CXCursor_Namespace:
|
case CXCursor_Namespace:
|
||||||
@ -1820,7 +1837,8 @@ void OnIndexDeclaration(CXClientData client_data, const CXIdxDeclInfo* decl) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else
|
} else
|
||||||
UniqueAddUse(db, type->uses, spell, fromContainer(decl->lexicalContainer));
|
UniqueAddUse(db, type->declarations, spell,
|
||||||
|
fromContainer(decl->lexicalContainer));
|
||||||
|
|
||||||
switch (decl->entityInfo->templateKind) {
|
switch (decl->entityInfo->templateKind) {
|
||||||
default:
|
default:
|
||||||
@ -2152,6 +2170,9 @@ void OnIndexReference(CXClientData client_data, const CXIdxEntityRefInfo* ref) {
|
|||||||
// Foo f;
|
// Foo f;
|
||||||
// }
|
// }
|
||||||
//
|
//
|
||||||
|
if (!ref->parentEntity || IsDeclContext(ref->parentEntity->kind))
|
||||||
|
UniqueAddUseSpell(db, ref_type->declarations, ref->cursor);
|
||||||
|
else
|
||||||
UniqueAddUseSpell(db, ref_type->uses, ref->cursor);
|
UniqueAddUseSpell(db, ref_type->uses, ref->cursor);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -231,6 +231,7 @@ struct IndexType {
|
|||||||
IndexTypeId id;
|
IndexTypeId id;
|
||||||
|
|
||||||
Def def;
|
Def def;
|
||||||
|
std::vector<Use> declarations;
|
||||||
|
|
||||||
// Immediate derived types.
|
// Immediate derived types.
|
||||||
std::vector<IndexTypeId> derived;
|
std::vector<IndexTypeId> derived;
|
||||||
|
@ -37,11 +37,15 @@ std::vector<Use> GetGotoDefinitionTargets(QueryDatabase* db,
|
|||||||
case SymbolKind::Var: {
|
case SymbolKind::Var: {
|
||||||
std::vector<Use> ret =
|
std::vector<Use> ret =
|
||||||
GetDeclarationsOfSymbolForGotoDefinition(db, sym);
|
GetDeclarationsOfSymbolForGotoDefinition(db, sym);
|
||||||
QueryVar::Def* def = db->GetVar(sym).AnyDef();
|
if (ret.empty()) {
|
||||||
if (def && def->type) {
|
for (auto& def : db->GetVar(sym).def)
|
||||||
std::vector<Use> types = GetDeclarationsOfSymbolForGotoDefinition(
|
if (def.type) {
|
||||||
db, SymbolIdx{*def->type, SymbolKind::Type});
|
if (Maybe<Use> use = GetDefinitionSpellingOfSymbol(
|
||||||
ret.insert(ret.end(), types.begin(), types.end());
|
db, SymbolIdx{*def.type, SymbolKind::Type})) {
|
||||||
|
ret.push_back(*use);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
14
src/query.cc
14
src/query.cc
@ -247,6 +247,10 @@ QueryFile::DefUpdate BuildFileDefUpdate(const IdMap& id_map, const IndexFile& in
|
|||||||
add_all_symbols(*type.def.spell, id, SymbolKind::Type);
|
add_all_symbols(*type.def.spell, id, SymbolKind::Type);
|
||||||
if (type.def.extent)
|
if (type.def.extent)
|
||||||
add_outline(*type.def.extent, id, SymbolKind::Type);
|
add_outline(*type.def.extent, id, SymbolKind::Type);
|
||||||
|
for (Use decl : type.declarations) {
|
||||||
|
add_all_symbols(decl, id, SymbolKind::Type);
|
||||||
|
add_outline(decl, id, SymbolKind::Type);
|
||||||
|
}
|
||||||
for (Use use : type.uses)
|
for (Use use : type.uses)
|
||||||
add_all_symbols(use, id, SymbolKind::Type);
|
add_all_symbols(use, id, SymbolKind::Type);
|
||||||
}
|
}
|
||||||
@ -523,6 +527,10 @@ IndexUpdate::IndexUpdate(const IdMap& previous_id_map,
|
|||||||
[this, &previous_id_map](IndexType* type) {
|
[this, &previous_id_map](IndexType* type) {
|
||||||
if (type->def.spell)
|
if (type->def.spell)
|
||||||
types_removed.push_back(type->usr);
|
types_removed.push_back(type->usr);
|
||||||
|
if (!type->declarations.empty())
|
||||||
|
types_declarations.push_back(QueryType::DeclarationsUpdate(
|
||||||
|
previous_id_map.ToQuery(type->id), {},
|
||||||
|
previous_id_map.ToQuery(type->declarations)));
|
||||||
if (!type->derived.empty())
|
if (!type->derived.empty())
|
||||||
types_derived.push_back(QueryType::DerivedUpdate(
|
types_derived.push_back(QueryType::DerivedUpdate(
|
||||||
previous_id_map.ToQuery(type->id), {},
|
previous_id_map.ToQuery(type->id), {},
|
||||||
@ -543,6 +551,10 @@ IndexUpdate::IndexUpdate(const IdMap& previous_id_map,
|
|||||||
if (def_update)
|
if (def_update)
|
||||||
types_def_update.push_back(
|
types_def_update.push_back(
|
||||||
QueryType::DefUpdate(type->usr, std::move(*def_update)));
|
QueryType::DefUpdate(type->usr, std::move(*def_update)));
|
||||||
|
if (!type->declarations.empty())
|
||||||
|
types_declarations.push_back(QueryType::DeclarationsUpdate(
|
||||||
|
current_id_map.ToQuery(type->id),
|
||||||
|
current_id_map.ToQuery(type->declarations)));
|
||||||
if (!type->derived.empty())
|
if (!type->derived.empty())
|
||||||
types_derived.push_back(
|
types_derived.push_back(
|
||||||
QueryType::DerivedUpdate(current_id_map.ToQuery(type->id),
|
QueryType::DerivedUpdate(current_id_map.ToQuery(type->id),
|
||||||
@ -570,6 +582,7 @@ IndexUpdate::IndexUpdate(const IdMap& previous_id_map,
|
|||||||
current->usr, std::move(*current_remapped_def)));
|
current->usr, std::move(*current_remapped_def)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PROCESS_UPDATE_DIFF(QueryTypeId, types_declarations, declarations, Use);
|
||||||
PROCESS_UPDATE_DIFF(QueryTypeId, types_derived, derived, QueryTypeId);
|
PROCESS_UPDATE_DIFF(QueryTypeId, types_derived, derived, QueryTypeId);
|
||||||
PROCESS_UPDATE_DIFF(QueryTypeId, types_instances, instances,
|
PROCESS_UPDATE_DIFF(QueryTypeId, types_instances, instances,
|
||||||
QueryVarId);
|
QueryVarId);
|
||||||
@ -820,6 +833,7 @@ void QueryDatabase::ApplyIndexUpdate(IndexUpdate* update) {
|
|||||||
|
|
||||||
RemoveUsrs(SymbolKind::Type, update->types_removed);
|
RemoveUsrs(SymbolKind::Type, update->types_removed);
|
||||||
ImportOrUpdate(std::move(update->types_def_update));
|
ImportOrUpdate(std::move(update->types_def_update));
|
||||||
|
HANDLE_MERGEABLE(types_declarations, declarations, types);
|
||||||
HANDLE_MERGEABLE(types_derived, derived, types);
|
HANDLE_MERGEABLE(types_derived, derived, types);
|
||||||
HANDLE_MERGEABLE(types_instances, instances, types);
|
HANDLE_MERGEABLE(types_instances, instances, types);
|
||||||
HANDLE_MERGEABLE(types_uses, uses, types);
|
HANDLE_MERGEABLE(types_uses, uses, types);
|
||||||
|
@ -136,6 +136,7 @@ MAKE_REFLECT_STRUCT(QueryFile::Def,
|
|||||||
struct QueryType {
|
struct QueryType {
|
||||||
using Def = TypeDefDefinitionData<QueryFamily>;
|
using Def = TypeDefDefinitionData<QueryFamily>;
|
||||||
using DefUpdate = WithUsr<Def>;
|
using DefUpdate = WithUsr<Def>;
|
||||||
|
using DeclarationsUpdate = MergeableUpdate<QueryTypeId, Use>;
|
||||||
using DerivedUpdate = MergeableUpdate<QueryTypeId, QueryTypeId>;
|
using DerivedUpdate = MergeableUpdate<QueryTypeId, QueryTypeId>;
|
||||||
using InstancesUpdate = MergeableUpdate<QueryTypeId, QueryVarId>;
|
using InstancesUpdate = MergeableUpdate<QueryTypeId, QueryVarId>;
|
||||||
using UsesUpdate = MergeableUpdate<QueryTypeId, Use>;
|
using UsesUpdate = MergeableUpdate<QueryTypeId, Use>;
|
||||||
@ -143,6 +144,7 @@ struct QueryType {
|
|||||||
Usr usr;
|
Usr usr;
|
||||||
Maybe<Id<void>> symbol_idx;
|
Maybe<Id<void>> symbol_idx;
|
||||||
std::forward_list<Def> def;
|
std::forward_list<Def> def;
|
||||||
|
std::vector<Use> declarations;
|
||||||
std::vector<QueryTypeId> derived;
|
std::vector<QueryTypeId> derived;
|
||||||
std::vector<QueryVarId> instances;
|
std::vector<QueryVarId> instances;
|
||||||
std::vector<Use> uses;
|
std::vector<Use> uses;
|
||||||
@ -228,6 +230,7 @@ struct IndexUpdate {
|
|||||||
// Type updates.
|
// Type updates.
|
||||||
std::vector<Usr> types_removed;
|
std::vector<Usr> types_removed;
|
||||||
std::vector<QueryType::DefUpdate> types_def_update;
|
std::vector<QueryType::DefUpdate> types_def_update;
|
||||||
|
std::vector<QueryType::DeclarationsUpdate> types_declarations;
|
||||||
std::vector<QueryType::DerivedUpdate> types_derived;
|
std::vector<QueryType::DerivedUpdate> types_derived;
|
||||||
std::vector<QueryType::InstancesUpdate> types_instances;
|
std::vector<QueryType::InstancesUpdate> types_instances;
|
||||||
std::vector<QueryType::UsesUpdate> types_uses;
|
std::vector<QueryType::UsesUpdate> types_uses;
|
||||||
|
@ -16,6 +16,26 @@ int ComputeRangeSize(const Range& range) {
|
|||||||
return range.end.column - range.start.column;
|
return range.end.column - range.start.column;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename Q>
|
||||||
|
std::vector<Use> ToUsesHelper(std::vector<Q>& entities,
|
||||||
|
const std::vector<Id<Q>>& ids) {
|
||||||
|
std::vector<Use> ret;
|
||||||
|
ret.reserve(ids.size());
|
||||||
|
for (auto id : ids) {
|
||||||
|
Q& entity = entities[id.id];
|
||||||
|
bool has_def = false;
|
||||||
|
for (auto& def : entity.def)
|
||||||
|
if (def.spell) {
|
||||||
|
ret.push_back(*def.spell);
|
||||||
|
has_def = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (!has_def && entity.declarations.size())
|
||||||
|
ret.push_back(entity.declarations[0]);
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
Maybe<Use> GetDefinitionSpellingOfSymbol(QueryDatabase* db,
|
Maybe<Use> GetDefinitionSpellingOfSymbol(QueryDatabase* db,
|
||||||
@ -112,54 +132,16 @@ Maybe<QueryFileId> GetDeclarationFileForSymbol(QueryDatabase* db,
|
|||||||
|
|
||||||
std::vector<Use> ToUses(QueryDatabase* db,
|
std::vector<Use> ToUses(QueryDatabase* db,
|
||||||
const std::vector<QueryFuncId>& ids) {
|
const std::vector<QueryFuncId>& ids) {
|
||||||
std::vector<Use> ret;
|
return ToUsesHelper(db->funcs, ids);
|
||||||
ret.reserve(ids.size());
|
|
||||||
for (auto id : ids) {
|
|
||||||
QueryFunc& func = db->funcs[id.id];
|
|
||||||
bool has_def = false;
|
|
||||||
for (auto& def : func.def)
|
|
||||||
if (def.spell) {
|
|
||||||
ret.push_back(*def.spell);
|
|
||||||
has_def = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (!has_def && func.declarations.size())
|
|
||||||
ret.push_back(func.declarations[0]);
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<Use> ToUses(QueryDatabase* db,
|
std::vector<Use> ToUses(QueryDatabase* db,
|
||||||
const std::vector<QueryTypeId>& ids) {
|
const std::vector<QueryTypeId>& ids) {
|
||||||
std::vector<Use> ret;
|
return ToUsesHelper(db->types, ids);
|
||||||
ret.reserve(ids.size());
|
|
||||||
for (auto id : ids) {
|
|
||||||
QueryType& type = db->types[id.id];
|
|
||||||
for (auto& def : type.def)
|
|
||||||
if (def.spell) {
|
|
||||||
ret.push_back(*def.spell);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<Use> ToUses(QueryDatabase* db, const std::vector<QueryVarId>& ids) {
|
std::vector<Use> ToUses(QueryDatabase* db, const std::vector<QueryVarId>& ids) {
|
||||||
std::vector<Use> ret;
|
return ToUsesHelper(db->vars, ids);
|
||||||
ret.reserve(ids.size());
|
|
||||||
for (auto id : ids) {
|
|
||||||
QueryVar& var = db->vars[id.id];
|
|
||||||
bool has_def = false;
|
|
||||||
for (auto& def : var.def)
|
|
||||||
if (def.spell) {
|
|
||||||
ret.push_back(*def.spell);
|
|
||||||
has_def = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (!has_def && var.declarations.size())
|
|
||||||
ret.push_back(var.declarations[0]);
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<Use> GetUsesOfSymbol(QueryDatabase* db,
|
std::vector<Use> GetUsesOfSymbol(QueryDatabase* db,
|
||||||
@ -173,6 +155,7 @@ std::vector<Use> GetUsesOfSymbol(QueryDatabase* db,
|
|||||||
for (auto& def : type.def)
|
for (auto& def : type.def)
|
||||||
if (def.spell)
|
if (def.spell)
|
||||||
ret.push_back(*def.spell);
|
ret.push_back(*def.spell);
|
||||||
|
AddRange(&ret, type.declarations);
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@ -210,27 +193,15 @@ std::vector<Use> GetDeclarationsOfSymbolForGotoDefinition(
|
|||||||
QueryDatabase* db,
|
QueryDatabase* db,
|
||||||
SymbolIdx sym) {
|
SymbolIdx sym) {
|
||||||
switch (sym.kind) {
|
switch (sym.kind) {
|
||||||
case SymbolKind::Type: {
|
|
||||||
// Returning the definition spelling of a type is a hack (and is why the
|
|
||||||
// function has the postfix `ForGotoDefintion`, but it lets the user
|
|
||||||
// jump to the start of a type if clicking goto-definition on the same
|
|
||||||
// type from within the type definition.
|
|
||||||
if (const auto* def = db->GetType(sym).AnyDef()) {
|
|
||||||
Maybe<Use> spell = def->spell;
|
|
||||||
if (spell)
|
|
||||||
return {*spell};
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case SymbolKind::Func:
|
case SymbolKind::Func:
|
||||||
return db->GetFunc(sym).declarations;
|
return db->GetFunc(sym).declarations;
|
||||||
|
case SymbolKind::Type:
|
||||||
|
return db->GetType(sym).declarations;
|
||||||
case SymbolKind::Var:
|
case SymbolKind::Var:
|
||||||
return db->GetVar(sym).declarations;
|
return db->GetVar(sym).declarations;
|
||||||
default:
|
default:
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return {};
|
return {};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool HasCallersOnSelfOrBaseOrDerived(QueryDatabase* db, QueryFunc& root) {
|
bool HasCallersOnSelfOrBaseOrDerived(QueryDatabase* db, QueryFunc& root) {
|
||||||
|
@ -215,6 +215,7 @@ void Reflect(TVisitor& visitor, IndexType& value) {
|
|||||||
ReflectShortName(visitor, value.def);
|
ReflectShortName(visitor, value.def);
|
||||||
REFLECT_MEMBER2("kind", value.def.kind);
|
REFLECT_MEMBER2("kind", value.def.kind);
|
||||||
ReflectHoverAndComments(visitor, value.def);
|
ReflectHoverAndComments(visitor, value.def);
|
||||||
|
REFLECT_MEMBER2("declarations", value.declarations);
|
||||||
REFLECT_MEMBER2("spell", value.def.spell);
|
REFLECT_MEMBER2("spell", value.def.spell);
|
||||||
REFLECT_MEMBER2("extent", value.def.extent);
|
REFLECT_MEMBER2("extent", value.def.extent);
|
||||||
REFLECT_MEMBER2("alias_of", value.def.alias_of);
|
REFLECT_MEMBER2("alias_of", value.def.alias_of);
|
||||||
|
Loading…
Reference in New Issue
Block a user