mirror of
https://github.com/MaskRay/ccls.git
synced 2025-02-16 21:58:08 +00:00
prep to drop separate interesting_uses entry
This commit is contained in:
parent
7c70d7fafd
commit
f067f6dcc4
105
main.cpp
105
main.cpp
@ -48,8 +48,8 @@ using FileId = int64_t;
|
|||||||
|
|
||||||
|
|
||||||
BEGIN_BITFIELD_TYPE(Location, uint64_t)
|
BEGIN_BITFIELD_TYPE(Location, uint64_t)
|
||||||
Location(FileId file_id, uint32_t line, uint32_t column) {
|
Location(bool interesting, FileId file_id, uint32_t line, uint32_t column) {
|
||||||
interesting = true;
|
this->interesting = false;
|
||||||
this->file_id = file_id;
|
this->file_id = file_id;
|
||||||
this->line = line;
|
this->line = line;
|
||||||
this->column = column;
|
this->column = column;
|
||||||
@ -66,7 +66,7 @@ std::string ToString() {
|
|||||||
// 3 => column
|
// 3 => column
|
||||||
|
|
||||||
std::string result;
|
std::string result;
|
||||||
if (interesting)
|
//if (interesting)
|
||||||
result += '*';
|
result += '*';
|
||||||
result += std::to_string(file_id);
|
result += std::to_string(file_id);
|
||||||
result += ':';
|
result += ':';
|
||||||
@ -92,7 +92,7 @@ struct FileDb {
|
|||||||
file_id_to_file_path[0] = "";
|
file_id_to_file_path[0] = "";
|
||||||
}
|
}
|
||||||
|
|
||||||
Location Resolve(const CXSourceLocation& cx_loc) {
|
Location Resolve(const CXSourceLocation& cx_loc, bool is_interesting = false) {
|
||||||
CXFile file;
|
CXFile file;
|
||||||
unsigned int line, column, offset;
|
unsigned int line, column, offset;
|
||||||
clang_getSpellingLocation(cx_loc, &file, &line, &column, &offset);
|
clang_getSpellingLocation(cx_loc, &file, &line, &column, &offset);
|
||||||
@ -112,20 +112,20 @@ struct FileDb {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return Location(file_id, line, column);
|
return Location(is_interesting, file_id, line, column);
|
||||||
}
|
}
|
||||||
|
|
||||||
Location Resolve(const CXIdxLoc& cx_idx_loc) {
|
Location Resolve(const CXIdxLoc& cx_idx_loc, bool is_interesting = false) {
|
||||||
CXSourceLocation cx_loc = clang_indexLoc_getCXSourceLocation(cx_idx_loc);
|
CXSourceLocation cx_loc = clang_indexLoc_getCXSourceLocation(cx_idx_loc);
|
||||||
return Resolve(cx_loc);
|
return Resolve(cx_loc, is_interesting);
|
||||||
}
|
}
|
||||||
|
|
||||||
Location Resolve(const CXCursor& cx_cursor) {
|
Location Resolve(const CXCursor& cx_cursor, bool is_interesting = false) {
|
||||||
return Resolve(clang_getCursorLocation(cx_cursor));
|
return Resolve(clang_getCursorLocation(cx_cursor), is_interesting);
|
||||||
}
|
}
|
||||||
|
|
||||||
Location Resolve(const clang::Cursor& cursor) {
|
Location Resolve(const clang::Cursor& cursor, bool is_interesting = false) {
|
||||||
return Resolve(cursor.cx_cursor);
|
return Resolve(cursor.cx_cursor, is_interesting);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -188,14 +188,30 @@ struct TypeDef {
|
|||||||
std::vector<VarId> vars;
|
std::vector<VarId> vars;
|
||||||
|
|
||||||
// Every usage, useful for things like renames.
|
// Every usage, useful for things like renames.
|
||||||
|
// NOTE: Do not insert directly! Use AddUsage instead.
|
||||||
std::vector<Location> all_uses;
|
std::vector<Location> all_uses;
|
||||||
// Usages that a user is probably interested in.
|
|
||||||
std::vector<Location> interesting_uses;
|
|
||||||
|
|
||||||
TypeDef(TypeId id, const std::string& usr) : id(id), usr(usr) {
|
TypeDef(TypeId id, const std::string& usr) : id(id), usr(usr) {
|
||||||
assert(usr.size() > 0);
|
assert(usr.size() > 0);
|
||||||
//std::cout << "Creating type with usr " << usr << std::endl;
|
//std::cout << "Creating type with usr " << usr << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AddUsage(Location loc) {
|
||||||
|
Location interesting = loc;
|
||||||
|
interesting.interesting = true;
|
||||||
|
Location uninteresting = loc;
|
||||||
|
uninteresting.interesting = false;
|
||||||
|
|
||||||
|
for (int i = all_uses.size() - 1; i >= 0; --i) {
|
||||||
|
if (all_uses[i] == interesting || all_uses[i] == uninteresting) {
|
||||||
|
if (loc.interesting)
|
||||||
|
all_uses[i].interesting = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
all_uses.push_back(loc);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct FuncDef {
|
struct FuncDef {
|
||||||
@ -443,7 +459,6 @@ std::string ParsingDatabase::ToString() {
|
|||||||
if (it != usr_to_type_id.end()) {
|
if (it != usr_to_type_id.end()) {
|
||||||
Resolve(it->second)->short_name = "<fundamental>";
|
Resolve(it->second)->short_name = "<fundamental>";
|
||||||
assert(Resolve(it->second)->all_uses.size() == 0);
|
assert(Resolve(it->second)->all_uses.size() == 0);
|
||||||
assert(Resolve(it->second)->interesting_uses.size() == 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#define WRITE(name) Write(writer, #name, def.name)
|
#define WRITE(name) Write(writer, #name, def.name)
|
||||||
@ -473,7 +488,22 @@ std::string ParsingDatabase::ToString() {
|
|||||||
WRITE(funcs);
|
WRITE(funcs);
|
||||||
WRITE(vars);
|
WRITE(vars);
|
||||||
WRITE(all_uses);
|
WRITE(all_uses);
|
||||||
WRITE(interesting_uses);
|
|
||||||
|
bool wrote_key = false;
|
||||||
|
for (Location usage : def.all_uses) {
|
||||||
|
if (usage.interesting) {
|
||||||
|
if (!wrote_key) {
|
||||||
|
writer.Key("interesting_uses");
|
||||||
|
wrote_key = true;
|
||||||
|
writer.StartArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
Write(writer, nullptr, usage);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (wrote_key)
|
||||||
|
writer.EndArray();
|
||||||
|
|
||||||
writer.EndObject();
|
writer.EndObject();
|
||||||
}
|
}
|
||||||
writer.EndArray();
|
writer.EndArray();
|
||||||
@ -756,15 +786,6 @@ std::string GetNamespacePrefx(const CXIdxDeclInfo* decl) {
|
|||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
bool HasUsage(const std::vector<Location>& usages, const Location& usage) {
|
|
||||||
for (int i = usages.size() - 1; i >= 0; --i) {
|
|
||||||
if (usages[i] == usage)
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool IsTypeDefinition(const CXIdxContainerInfo* container) {
|
bool IsTypeDefinition(const CXIdxContainerInfo* container) {
|
||||||
if (!container)
|
if (!container)
|
||||||
return false;
|
return false;
|
||||||
@ -801,7 +822,9 @@ void VisitDeclForTypeUsageVisitorHandler(clang::Cursor cursor, VisitDeclForTypeU
|
|||||||
|
|
||||||
if (param->is_interesting) {
|
if (param->is_interesting) {
|
||||||
TypeDef* ref_type_def = db->Resolve(ref_type_id);
|
TypeDef* ref_type_def = db->Resolve(ref_type_id);
|
||||||
ref_type_def->interesting_uses.push_back(db->file_db.Resolve(cursor));
|
Location loc = db->file_db.Resolve(cursor);
|
||||||
|
loc.interesting = true;
|
||||||
|
ref_type_def->AddUsage(loc);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1079,7 +1102,7 @@ void indexDeclaration(CXClientData client_data, const CXIdxDeclInfo* decl) {
|
|||||||
|
|
||||||
Location decl_loc = db->file_db.Resolve(decl->loc);
|
Location decl_loc = db->file_db.Resolve(decl->loc);
|
||||||
type_def->definition = decl_loc;
|
type_def->definition = decl_loc;
|
||||||
type_def->all_uses.push_back(decl_loc);
|
type_def->AddUsage(decl_loc);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1101,7 +1124,7 @@ void indexDeclaration(CXClientData client_data, const CXIdxDeclInfo* decl) {
|
|||||||
assert(decl->isDefinition);
|
assert(decl->isDefinition);
|
||||||
Location decl_loc = db->file_db.Resolve(decl->loc);
|
Location decl_loc = db->file_db.Resolve(decl->loc);
|
||||||
type_def->definition = decl_loc;
|
type_def->definition = decl_loc;
|
||||||
type_def->all_uses.push_back(decl_loc);
|
type_def->AddUsage(decl_loc);
|
||||||
|
|
||||||
//type_def->alias_of
|
//type_def->alias_of
|
||||||
//type_def->funcs
|
//type_def->funcs
|
||||||
@ -1171,6 +1194,7 @@ void indexEntityReference(CXClientData client_data, const CXIdxEntityRefInfo* re
|
|||||||
case CXIdxEntity_CXXInstanceMethod:
|
case CXIdxEntity_CXXInstanceMethod:
|
||||||
case CXIdxEntity_Function:
|
case CXIdxEntity_Function:
|
||||||
case CXIdxEntity_CXXConstructor:
|
case CXIdxEntity_CXXConstructor:
|
||||||
|
case CXIdxEntity_CXXDestructor:
|
||||||
{
|
{
|
||||||
// TODO: Redirect container to constructor for
|
// TODO: Redirect container to constructor for
|
||||||
// int Gen() { return 5; }
|
// int Gen() { return 5; }
|
||||||
@ -1199,6 +1223,21 @@ void indexEntityReference(CXClientData client_data, const CXIdxEntityRefInfo* re
|
|||||||
FuncDef* called_def = db->Resolve(called_id);
|
FuncDef* called_def = db->Resolve(called_id);
|
||||||
called_def->all_uses.push_back(loc);
|
called_def->all_uses.push_back(loc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#if false
|
||||||
|
// For constructor/destructor, also add a usage against the type.
|
||||||
|
// TODO: This will also process implicit constructors which we do not want.
|
||||||
|
clang::Cursor ref_cursor = ref->cursor;
|
||||||
|
if (ref->referencedEntity->kind == CXIdxEntity_CXXConstructor ||
|
||||||
|
ref->referencedEntity->kind == CXIdxEntity_CXXDestructor &&
|
||||||
|
ref_cursor.get_spelling() != "") {
|
||||||
|
FuncDef* called_def = db->Resolve(called_id);
|
||||||
|
assert(called_def->declaring_type.has_value());
|
||||||
|
TypeDef* type_def = db->Resolve(called_def->declaring_type.value());
|
||||||
|
type_def->AddUsage(db->file_db.Resolve(ref->loc, true /*is_interesting*/));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1225,10 +1264,7 @@ void indexEntityReference(CXClientData client_data, const CXIdxEntityRefInfo* re
|
|||||||
// Foo f;
|
// Foo f;
|
||||||
// }
|
// }
|
||||||
//
|
//
|
||||||
Location loc = db->file_db.Resolve(ref->loc);
|
referenced_def->AddUsage(db->file_db.Resolve(ref->loc));
|
||||||
if (!HasUsage(referenced_def->all_uses, loc))
|
|
||||||
referenced_def->all_uses.push_back(loc);
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1257,7 +1293,7 @@ ParsingDatabase Parse(std::string filename) {
|
|||||||
clang::Index index(0 /*excludeDeclarationsFromPCH*/, 0 /*displayDiagnostics*/);
|
clang::Index index(0 /*excludeDeclarationsFromPCH*/, 0 /*displayDiagnostics*/);
|
||||||
clang::TranslationUnit tu(index, filename, args);
|
clang::TranslationUnit tu(index, filename, args);
|
||||||
|
|
||||||
//Dump(tu.document_cursor());
|
Dump(tu.document_cursor());
|
||||||
|
|
||||||
CXIndexAction index_action = clang_IndexAction_create(index.cx_index);
|
CXIndexAction index_action = clang_IndexAction_create(index.cx_index);
|
||||||
|
|
||||||
@ -1384,7 +1420,7 @@ int main(int argc, char** argv) {
|
|||||||
for (std::string path : GetFilesInFolder("tests")) {
|
for (std::string path : GetFilesInFolder("tests")) {
|
||||||
//if (path != "tests/declaration_vs_definition/class_member_static.cc") continue;
|
//if (path != "tests/declaration_vs_definition/class_member_static.cc") continue;
|
||||||
//if (path != "tests/usage/type_usage_typedef_and_using_template.cc") continue;
|
//if (path != "tests/usage/type_usage_typedef_and_using_template.cc") continue;
|
||||||
//if (path == "tests/constructors/constructor.cc") continue;
|
//if (path != "tests/constructors/constructor.cc") continue;
|
||||||
//if (path == "tests/constructors/destructor.cc") continue;
|
//if (path == "tests/constructors/destructor.cc") continue;
|
||||||
//if (path == "tests/usage/func_usage_call_method.cc") continue;
|
//if (path == "tests/usage/func_usage_call_method.cc") continue;
|
||||||
//if (path != "tests/usage/type_usage_as_template_parameter.cc") continue;
|
//if (path != "tests/usage/type_usage_as_template_parameter.cc") continue;
|
||||||
@ -1392,8 +1428,9 @@ int main(int argc, char** argv) {
|
|||||||
//if (path != "tests/usage/type_usage_as_template_parameter_simple.cc") continue;
|
//if (path != "tests/usage/type_usage_as_template_parameter_simple.cc") continue;
|
||||||
//if (path != "tests/usage/type_usage_typedef_and_using.cc") continue;
|
//if (path != "tests/usage/type_usage_typedef_and_using.cc") continue;
|
||||||
//if (path != "tests/usage/type_usage_declare_local.cc") continue;
|
//if (path != "tests/usage/type_usage_declare_local.cc") continue;
|
||||||
|
//if (path == "tests/usage/type_usage_typedef_and_using_template.cc") continue;
|
||||||
//if (path != "tests/usage/func_usage_addr_method.cc") continue;
|
//if (path != "tests/usage/func_usage_addr_method.cc") continue;
|
||||||
//if (path != "tests/usage/func_usage_template_func.cc") continue;
|
//if (path != "tests/usage/type_usage_typedef_and_using.cc") continue;
|
||||||
//if (path != "tests/usage/usage_inside_of_call.cc") continue;
|
//if (path != "tests/usage/usage_inside_of_call.cc") continue;
|
||||||
//if (path != "tests/foobar.cc") continue;
|
//if (path != "tests/foobar.cc") continue;
|
||||||
//if (path != "tests/inheritance/class_inherit_templated_parent.cc") continue;
|
//if (path != "tests/inheritance/class_inherit_templated_parent.cc") continue;
|
||||||
|
@ -9,7 +9,13 @@ void foo() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
// TODO: We should mark the constructor location inside of all_usages for the type, so renames work.
|
// TODO: We should mark the constructor location inside of all_usages for the
|
||||||
|
// type, so renames work. There's some code that sort of does this, but
|
||||||
|
// it also includes implicit constructors. Maybe that's ok?
|
||||||
|
// TODO: check for implicit by comparing location to parent decl?
|
||||||
|
// TODO: At the moment, type rename is broken because we do not capture the
|
||||||
|
// `new Foo()` as a reference to the Foo type.
|
||||||
|
//
|
||||||
OUTPUT:
|
OUTPUT:
|
||||||
{
|
{
|
||||||
"types": [{
|
"types": [{
|
||||||
|
@ -56,6 +56,7 @@ OUTPUT:
|
|||||||
}, {
|
}, {
|
||||||
"id": 4,
|
"id": 4,
|
||||||
"usr": "c:class_inherit_templated_parent.cc@154",
|
"usr": "c:class_inherit_templated_parent.cc@154",
|
||||||
|
"all_uses": ["*1:11:24"],
|
||||||
"interesting_uses": ["*1:11:24"]
|
"interesting_uses": ["*1:11:24"]
|
||||||
}, {
|
}, {
|
||||||
"id": 5,
|
"id": 5,
|
||||||
|
@ -10,6 +10,11 @@ void accept2(Foo2*) {}
|
|||||||
void accept3(Foo3*) {}
|
void accept3(Foo3*) {}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
||||||
|
// TODO: I think we should mark using Foo1 = foo as an interesting usage on
|
||||||
|
// Foo1.
|
||||||
|
// TODO: Also mark class Foo {} as an interesting usage of Foo.
|
||||||
|
|
||||||
OUTPUT:
|
OUTPUT:
|
||||||
{
|
{
|
||||||
"types": [{
|
"types": [{
|
||||||
|
Loading…
Reference in New Issue
Block a user