mirror of
https://github.com/MaskRay/ccls.git
synced 2025-03-21 08:16:18 +00:00
Remove UniqueAdd* and uniquify uses
after libclang callbacks.
This removes some duplication in `uses`.
This commit is contained in:
parent
9f4b30ca8c
commit
b98c9a4575
106
src/indexer.cc
106
src/indexer.cc
@ -754,23 +754,30 @@ std::string IndexFile::ToString() {
|
||||
|
||||
IndexType::IndexType(IndexTypeId id, Usr usr) : usr(usr), id(id) {}
|
||||
|
||||
void RemoveItem(std::vector<Range>& ranges, Range to_remove) {
|
||||
auto it = std::find(ranges.begin(), ranges.end(), to_remove);
|
||||
if (it != ranges.end())
|
||||
ranges.erase(it);
|
||||
template <typename T>
|
||||
void Uniquify(std::vector<Id<T>>& ids) {
|
||||
std::unordered_set<Id<T>> seen;
|
||||
size_t n = 0;
|
||||
for (size_t i = 0; i < ids.size(); i++)
|
||||
if (seen.insert(ids[i]).second)
|
||||
ids[n++] = ids[i];
|
||||
ids.resize(n);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void UniqueAdd(std::vector<T>& values, T value) {
|
||||
if (std::find(values.begin(), values.end(), value) == values.end())
|
||||
values.push_back(value);
|
||||
void Uniquify(std::vector<Use>& uses) {
|
||||
std::unordered_set<Range> seen;
|
||||
size_t n = 0;
|
||||
for (size_t i = 0; i < uses.size(); i++)
|
||||
if (seen.insert(uses[i].range).second)
|
||||
uses[n++] = uses[i];
|
||||
uses.resize(n);
|
||||
}
|
||||
|
||||
// FIXME Reference: set id in call sites and remove this
|
||||
void AddUse(std::vector<Use>& values, Range value) {
|
||||
values.push_back(
|
||||
Use(value, Id<void>(), SymbolKind::File, Role::Reference, {}));
|
||||
}
|
||||
//void AddUse(std::vector<Use>& values, Range value) {
|
||||
// values.push_back(
|
||||
// Use(value, Id<void>(), SymbolKind::File, Role::Reference, {}));
|
||||
//}
|
||||
|
||||
void AddUse(IndexFile* db,
|
||||
std::vector<Use>& uses,
|
||||
@ -797,30 +804,7 @@ CXCursor fromContainer(const CXIdxContainerInfo* parent) {
|
||||
}
|
||||
|
||||
void AddUseSpell(IndexFile* db, std::vector<Use>& uses, ClangCursor cursor) {
|
||||
AddUse(db, uses, cursor.get_spell(), cursor.get_lexical_parent().cx_cursor,
|
||||
Role::Reference);
|
||||
}
|
||||
|
||||
template <typename... Args>
|
||||
void UniqueAddUse(IndexFile* db,
|
||||
std::vector<Use>& uses,
|
||||
Range range,
|
||||
Args&&... args) {
|
||||
if (std::find_if(uses.begin(), uses.end(),
|
||||
[&](Use use) { return use.range == range; }) == uses.end())
|
||||
AddUse(db, uses, range, std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
template <typename... Args>
|
||||
void UniqueAddUseSpell(IndexFile* db,
|
||||
std::vector<Use>& uses,
|
||||
ClangCursor cursor,
|
||||
Args&&... args) {
|
||||
Range range = cursor.get_spell();
|
||||
if (std::find_if(uses.begin(), uses.end(),
|
||||
[&](Use use) { return use.range == range; }) == uses.end())
|
||||
AddUse(db, uses, range, cursor.get_lexical_parent().cx_cursor,
|
||||
std::forward<Args>(args)...);
|
||||
AddUse(db, uses, cursor.get_spell(), cursor.get_lexical_parent().cx_cursor);
|
||||
}
|
||||
|
||||
IdCache::IdCache(const std::string& primary_file)
|
||||
@ -970,7 +954,7 @@ void VisitDeclForTypeUsageVisitorHandler(ClangCursor cursor,
|
||||
IndexType* ref_type = db->Resolve(*param->toplevel_type);
|
||||
std::string name = cursor.get_referenced().get_spell_name();
|
||||
if (name == ref_type->def.ShortName()) {
|
||||
UniqueAddUseSpell(db, ref_type->uses, cursor);
|
||||
AddUseSpell(db, ref_type->uses, cursor);
|
||||
param->toplevel_type = nullopt;
|
||||
return;
|
||||
}
|
||||
@ -992,7 +976,7 @@ void VisitDeclForTypeUsageVisitorHandler(ClangCursor cursor,
|
||||
IndexType* ref_type_def = db->Resolve(ref_type_id);
|
||||
// TODO: Should we even be visiting this if the file is not from the main
|
||||
// def? Try adding assert on |loc| later.
|
||||
UniqueAddUseSpell(db, ref_type_def->uses, cursor);
|
||||
AddUseSpell(db, ref_type_def->uses, cursor);
|
||||
}
|
||||
|
||||
ClangCursor::VisitResult VisitDeclForTypeUsageVisitor(
|
||||
@ -1212,7 +1196,7 @@ ClangCursor::VisitResult AddDeclInitializerUsagesVisitor(ClangCursor cursor,
|
||||
break;
|
||||
|
||||
IndexVar* ref_var = db->Resolve(db->ToVarId(HashUsr(ref_usr)));
|
||||
UniqueAddUseSpell(db, ref_var->uses, cursor);
|
||||
AddUseSpell(db, ref_var->uses, cursor);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -1266,7 +1250,7 @@ ClangCursor::VisitResult VisitMacroDefinitionAndExpansions(ClangCursor cursor,
|
||||
var_def->def.extent = SetUse(
|
||||
db, ResolveCXSourceRange(cx_extent, nullptr), parent, Role::None);
|
||||
} else
|
||||
UniqueAddUse(db, var_def->uses, decl_loc_spelling, parent);
|
||||
AddUse(db, var_def->uses, decl_loc_spelling, parent);
|
||||
|
||||
break;
|
||||
}
|
||||
@ -1323,11 +1307,11 @@ ClangCursor::VisitResult TemplateVisitor(ClangCursor cursor,
|
||||
// seems no way to extract the spelling range of `type` and we do
|
||||
// not want to do subtraction here.
|
||||
// See https://github.com/jacobdufault/cquery/issues/252
|
||||
UniqueAddUse(db, ref_type_index->uses, ref_cursor.get_extent(),
|
||||
ref_cursor.get_lexical_parent());
|
||||
AddUse(db, ref_type_index->uses, ref_cursor.get_extent(),
|
||||
ref_cursor.get_lexical_parent());
|
||||
}
|
||||
}
|
||||
UniqueAddUseSpell(db, ref_var->uses, cursor);
|
||||
AddUseSpell(db, ref_var->uses, cursor);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -1379,7 +1363,7 @@ ClangCursor::VisitResult TemplateVisitor(ClangCursor cursor,
|
||||
int16_t(strlen(ref_type->def.detailed_name.c_str()));
|
||||
ref_type->def.kind = lsSymbolKind::TypeParameter;
|
||||
}
|
||||
UniqueAddUseSpell(db, ref_type->uses, cursor);
|
||||
AddUseSpell(db, ref_type->uses, cursor);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -1414,7 +1398,7 @@ ClangCursor::VisitResult TemplateVisitor(ClangCursor cursor,
|
||||
int16_t(strlen(ref_type->def.detailed_name.c_str()));
|
||||
ref_type->def.kind = lsSymbolKind::TypeParameter;
|
||||
}
|
||||
UniqueAddUseSpell(db, ref_type->uses, cursor);
|
||||
AddUseSpell(db, ref_type->uses, cursor);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -1549,7 +1533,7 @@ void OnIndexDeclaration(CXClientData client_data, const CXIdxDeclInfo* decl) {
|
||||
ns->def.parents.push_back(parent_id);
|
||||
}
|
||||
}
|
||||
AddUse(ns->uses, spell);
|
||||
AddUse(db, ns->uses, spell, lex_parent);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -1737,11 +1721,11 @@ void OnIndexDeclaration(CXClientData client_data, const CXIdxDeclInfo* decl) {
|
||||
|
||||
// Mark a type reference at the ctor/dtor location.
|
||||
if (decl->entityInfo->kind == CXIdxEntity_CXXConstructor)
|
||||
UniqueAddUse(db, declaring_type_def->uses, spell,
|
||||
fromContainer(decl->lexicalContainer));
|
||||
AddUse(db, declaring_type_def->uses, spell,
|
||||
fromContainer(decl->lexicalContainer));
|
||||
|
||||
// Add function to declaring type.
|
||||
UniqueAdd(declaring_type_def->def.funcs, func_id);
|
||||
declaring_type_def->def.funcs.push_back(func_id);
|
||||
}
|
||||
|
||||
// Process inheritance.
|
||||
@ -1815,8 +1799,7 @@ void OnIndexDeclaration(CXClientData client_data, const CXIdxDeclInfo* decl) {
|
||||
}
|
||||
}
|
||||
|
||||
UniqueAddUse(db, type->uses, spell,
|
||||
fromContainer(decl->lexicalContainer));
|
||||
AddUse(db, type->uses, spell, fromContainer(decl->lexicalContainer));
|
||||
break;
|
||||
}
|
||||
|
||||
@ -1863,8 +1846,8 @@ void OnIndexDeclaration(CXClientData client_data, const CXIdxDeclInfo* decl) {
|
||||
}
|
||||
}
|
||||
} else
|
||||
UniqueAddUse(db, type->declarations, spell,
|
||||
fromContainer(decl->lexicalContainer));
|
||||
AddUse(db, type->declarations, spell,
|
||||
fromContainer(decl->lexicalContainer), Role::Declaration);
|
||||
|
||||
switch (decl->entityInfo->templateKind) {
|
||||
default:
|
||||
@ -2061,8 +2044,8 @@ void OnIndexReference(CXClientData client_data, const CXIdxEntityRefInfo* ref) {
|
||||
var->def.kind = lsSymbolKind::Parameter;
|
||||
}
|
||||
}
|
||||
UniqueAddUse(db, var->uses, loc, fromContainer(ref->container),
|
||||
GetRole(ref, Role::Reference));
|
||||
AddUse(db, var->uses, loc, fromContainer(ref->container),
|
||||
GetRole(ref, Role::Reference));
|
||||
break;
|
||||
}
|
||||
|
||||
@ -2199,9 +2182,9 @@ void OnIndexReference(CXClientData client_data, const CXIdxEntityRefInfo* ref) {
|
||||
// }
|
||||
//
|
||||
if (!ref->parentEntity || IsDeclContext(ref->parentEntity->kind))
|
||||
UniqueAddUseSpell(db, ref_type->declarations, ref->cursor);
|
||||
AddUseSpell(db, ref_type->declarations, ref->cursor);
|
||||
else
|
||||
UniqueAddUseSpell(db, ref_type->uses, ref->cursor);
|
||||
AddUseSpell(db, ref_type->uses, ref->cursor);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -2313,6 +2296,15 @@ optional<std::vector<std::unique_ptr<IndexFile>>> ParseWithTu(
|
||||
for (std::unique_ptr<IndexFile>& entry : result) {
|
||||
entry->import_file = file;
|
||||
entry->args = args;
|
||||
for (IndexFunc& func : entry->funcs)
|
||||
Uniquify(func.uses);
|
||||
for (IndexType& type : entry->types) {
|
||||
Uniquify(type.uses);
|
||||
// e.g. declaration + out-of-line definition
|
||||
Uniquify(type.def.funcs);
|
||||
}
|
||||
for (IndexVar& var : entry->vars)
|
||||
Uniquify(var.uses);
|
||||
|
||||
if (param.primary_file) {
|
||||
// If there are errors, show at least one at the include position.
|
||||
|
@ -131,6 +131,8 @@ struct Use : Reference {
|
||||
Use(Range range, Id<void> id, SymbolKind kind, Role role, Id<QueryFile> file)
|
||||
: Reference{range, id, kind, role}, file(file) {}
|
||||
};
|
||||
// Used by |HANDLE_MERGEABLE| so only |range| is needed.
|
||||
MAKE_HASHABLE(Use, t.range);
|
||||
|
||||
void Reflect(Reader& visitor, Reference& value);
|
||||
void Reflect(Writer& visitor, Reference& value);
|
||||
|
14
src/utils.h
14
src/utils.h
@ -8,6 +8,7 @@
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
#include <unordered_set>
|
||||
#include <vector>
|
||||
|
||||
// Trim from start (in place)
|
||||
@ -144,14 +145,11 @@ void AddRange(std::vector<T>* dest, std::vector<T>&& to_add) {
|
||||
|
||||
template <typename T>
|
||||
void RemoveRange(std::vector<T>* dest, const std::vector<T>& to_remove) {
|
||||
dest->erase(std::remove_if(dest->begin(), dest->end(),
|
||||
[&](const T& t) {
|
||||
// TODO: make to_remove a set?
|
||||
return std::find(to_remove.begin(),
|
||||
to_remove.end(),
|
||||
t) != to_remove.end();
|
||||
}),
|
||||
dest->end());
|
||||
std::unordered_set<T> to_remove_set(to_remove.begin(), to_remove.end());
|
||||
dest->erase(
|
||||
std::remove_if(dest->begin(), dest->end(),
|
||||
[&](const T& t) { return to_remove_set.count(t) > 0; }),
|
||||
dest->end());
|
||||
}
|
||||
|
||||
// http://stackoverflow.com/a/38140932
|
||||
|
Loading…
Reference in New Issue
Block a user