This commit is contained in:
Jacob Dufault 2017-02-26 18:03:14 -08:00
parent bc8daee065
commit 18aa28bdea
6 changed files with 137 additions and 131 deletions

3
.gitignore vendored
View File

@ -1,6 +1,9 @@
.vs .vs
Debug Debug
x64 x64
build
waf-*
.lock-waf*
*.swp *.swp
*.sln *.sln
*.vcxproj *.vcxproj

View File

@ -2,8 +2,8 @@
#include "serializer.h" #include "serializer.h"
IndexedFile::IndexedFile(IdCache* id_cache, FileDb* file_db) IndexedFile::IndexedFile(IdCache* id_cache)
: id_cache(id_cache), file_db(file_db) { : id_cache(id_cache) {
// TODO: Reconsider if we should still be reusing the same id_cache. // TODO: Reconsider if we should still be reusing the same id_cache.
// Preallocate any existing resolved ids. // Preallocate any existing resolved ids.
@ -322,7 +322,7 @@ void VisitDeclForTypeUsageVisitorHandler(clang::Cursor cursor, VisitDeclForTypeU
if (param->is_interesting) { if (param->is_interesting) {
IndexedTypeDef* ref_type_def = db->Resolve(ref_type_id); IndexedTypeDef* ref_type_def = db->Resolve(ref_type_id);
Location loc = db->file_db->Resolve(cursor, true /*interesting*/); Location loc = db->id_cache->Resolve(cursor, true /*interesting*/);
ref_type_def->AddUsage(loc); ref_type_def->AddUsage(loc);
} }
} }
@ -445,7 +445,7 @@ void indexDeclaration(CXClientData client_data, const CXIdxDeclInfo* decl) {
var_def->def.qualified_name = ns->QualifiedName(decl->semanticContainer, var_def->def.short_name); var_def->def.qualified_name = ns->QualifiedName(decl->semanticContainer, var_def->def.short_name);
//} //}
Location decl_loc = db->file_db->Resolve(decl->loc, false /*interesting*/); Location decl_loc = db->id_cache->Resolve(decl->loc, false /*interesting*/);
if (decl->isDefinition) if (decl->isDefinition)
var_def->def.definition = decl_loc; var_def->def.definition = decl_loc;
else else
@ -491,7 +491,7 @@ void indexDeclaration(CXClientData client_data, const CXIdxDeclInfo* decl) {
func_def->def.qualified_name = ns->QualifiedName(decl->semanticContainer, func_def->def.short_name); func_def->def.qualified_name = ns->QualifiedName(decl->semanticContainer, func_def->def.short_name);
//} //}
Location decl_loc = db->file_db->Resolve(decl->loc, false /*interesting*/); Location decl_loc = db->id_cache->Resolve(decl->loc, false /*interesting*/);
if (decl->isDefinition) if (decl->isDefinition)
func_def->def.definition = decl_loc; func_def->def.definition = decl_loc;
else else
@ -608,7 +608,7 @@ void indexDeclaration(CXClientData client_data, const CXIdxDeclInfo* decl) {
type_def->def.short_name = decl->entityInfo->name; type_def->def.short_name = decl->entityInfo->name;
type_def->def.qualified_name = ns->QualifiedName(decl->semanticContainer, type_def->def.short_name); type_def->def.qualified_name = ns->QualifiedName(decl->semanticContainer, type_def->def.short_name);
Location decl_loc = db->file_db->Resolve(decl->loc, true /*interesting*/); Location decl_loc = db->id_cache->Resolve(decl->loc, true /*interesting*/);
type_def->def.definition = decl_loc.WithInteresting(false); type_def->def.definition = decl_loc.WithInteresting(false);
type_def->AddUsage(decl_loc); type_def->AddUsage(decl_loc);
break; break;
@ -642,7 +642,7 @@ void indexDeclaration(CXClientData client_data, const CXIdxDeclInfo* decl) {
// } // }
assert(decl->isDefinition); assert(decl->isDefinition);
Location decl_loc = db->file_db->Resolve(decl->loc, true /*interesting*/); Location decl_loc = db->id_cache->Resolve(decl->loc, true /*interesting*/);
type_def->def.definition = decl_loc.WithInteresting(false); type_def->def.definition = decl_loc.WithInteresting(false);
type_def->AddUsage(decl_loc); type_def->AddUsage(decl_loc);
@ -671,7 +671,7 @@ void indexDeclaration(CXClientData client_data, const CXIdxDeclInfo* decl) {
} }
default: default:
std::cout << "!! Unhandled indexDeclaration: " << clang::Cursor(decl->cursor).ToString() << " at " << db->file_db->Resolve(decl->loc, false /*interesting*/).ToString() << std::endl; std::cout << "!! Unhandled indexDeclaration: " << clang::Cursor(decl->cursor).ToString() << " at " << db->id_cache->Resolve(decl->loc, false /*interesting*/).ToString() << std::endl;
std::cout << " entityInfo->kind = " << decl->entityInfo->kind << std::endl; std::cout << " entityInfo->kind = " << decl->entityInfo->kind << std::endl;
std::cout << " entityInfo->USR = " << decl->entityInfo->USR << std::endl; std::cout << " entityInfo->USR = " << decl->entityInfo->USR << std::endl;
if (decl->declAsContainer) if (decl->declAsContainer)
@ -707,7 +707,7 @@ void indexEntityReference(CXClientData client_data, const CXIdxEntityRefInfo* re
{ {
VarId var_id = db->ToVarId(ref->referencedEntity->cursor); VarId var_id = db->ToVarId(ref->referencedEntity->cursor);
IndexedVarDef* var_def = db->Resolve(var_id); IndexedVarDef* var_def = db->Resolve(var_id);
var_def->uses.push_back(db->file_db->Resolve(ref->loc, false /*interesting*/)); var_def->uses.push_back(db->id_cache->Resolve(ref->loc, false /*interesting*/));
break; break;
} }
@ -729,7 +729,7 @@ void indexEntityReference(CXClientData client_data, const CXIdxEntityRefInfo* re
// Don't report duplicate usages. // Don't report duplicate usages.
// TODO: search full history? // TODO: search full history?
Location loc = db->file_db->Resolve(ref->loc, false /*interesting*/); Location loc = db->id_cache->Resolve(ref->loc, false /*interesting*/);
if (param->last_func_usage_location == loc) break; if (param->last_func_usage_location == loc) break;
param->last_func_usage_location = loc; param->last_func_usage_location = loc;
@ -757,8 +757,8 @@ void indexEntityReference(CXClientData client_data, const CXIdxEntityRefInfo* re
if (ref->referencedEntity->kind == CXIdxEntity_CXXConstructor || if (ref->referencedEntity->kind == CXIdxEntity_CXXConstructor ||
ref->referencedEntity->kind == CXIdxEntity_CXXDestructor) { ref->referencedEntity->kind == CXIdxEntity_CXXDestructor) {
Location parent_loc = db->file_db->Resolve(ref->parentEntity->cursor, true /*interesting*/); Location parent_loc = db->id_cache->Resolve(ref->parentEntity->cursor, true /*interesting*/);
Location our_loc = db->file_db->Resolve(ref->loc, true /*is_interesting*/); Location our_loc = db->id_cache->Resolve(ref->loc, true /*is_interesting*/);
if (!parent_loc.IsEqualTo(our_loc)) { if (!parent_loc.IsEqualTo(our_loc)) {
IndexedFuncDef* called_def = db->Resolve(called_id); IndexedFuncDef* called_def = db->Resolve(called_id);
assert(called_def->def.declaring_type.has_value()); assert(called_def->def.declaring_type.has_value());
@ -778,12 +778,12 @@ void indexEntityReference(CXClientData client_data, const CXIdxEntityRefInfo* re
{ {
TypeId referenced_id = db->ToTypeId(ref->referencedEntity->USR); TypeId referenced_id = db->ToTypeId(ref->referencedEntity->USR);
IndexedTypeDef* referenced_def = db->Resolve(referenced_id); IndexedTypeDef* referenced_def = db->Resolve(referenced_id);
// We will not get a declaration visit for forward declared types. Try to mark them as non-bad // We will not get a declaration visit for forward declared types. Try to mark them as non-bad
// defs here so we will output usages/etc. // defs here so we will output usages/etc.
if (referenced_def->is_bad_def) { if (referenced_def->is_bad_def) {
bool is_system_def = clang_Location_isInSystemHeader(clang_getCursorLocation(ref->referencedEntity->cursor)); bool is_system_def = clang_Location_isInSystemHeader(clang_getCursorLocation(ref->referencedEntity->cursor));
Location loc = db->file_db->Resolve(ref->referencedEntity->cursor, false /*interesting*/); Location loc = db->id_cache->Resolve(ref->referencedEntity->cursor, false /*interesting*/);
if (!is_system_def && loc.raw_file_id != -1) if (!is_system_def && loc.raw_file_id != -1)
referenced_def->is_bad_def = false; referenced_def->is_bad_def = false;
} }
@ -802,16 +802,16 @@ void indexEntityReference(CXClientData client_data, const CXIdxEntityRefInfo* re
// Foo f; // Foo f;
// } // }
// //
referenced_def->AddUsage(db->file_db->Resolve(ref->loc, false /*interesting*/)); referenced_def->AddUsage(db->id_cache->Resolve(ref->loc, false /*interesting*/));
break; break;
} }
default: default:
std::cout << "!! Unhandled indexEntityReference: " << cursor.ToString() << " at " << db->file_db->Resolve(ref->loc, false /*interesting*/).ToString() << std::endl; std::cout << "!! Unhandled indexEntityReference: " << cursor.ToString() << " at " << db->id_cache->Resolve(ref->loc, false /*interesting*/).ToString() << std::endl;
std::cout << " ref->referencedEntity->kind = " << ref->referencedEntity->kind << std::endl; std::cout << " ref->referencedEntity->kind = " << ref->referencedEntity->kind << std::endl;
if (ref->parentEntity) if (ref->parentEntity)
std::cout << " ref->parentEntity->kind = " << ref->parentEntity->kind << std::endl; std::cout << " ref->parentEntity->kind = " << ref->parentEntity->kind << std::endl;
std::cout << " ref->loc = " << db->file_db->Resolve(ref->loc, false /*interesting*/).ToString() << std::endl; std::cout << " ref->loc = " << db->id_cache->Resolve(ref->loc, false /*interesting*/).ToString() << std::endl;
std::cout << " ref->kind = " << ref->kind << std::endl; std::cout << " ref->kind = " << ref->kind << std::endl;
if (ref->parentEntity) if (ref->parentEntity)
std::cout << " parentEntity = " << clang::Cursor(ref->parentEntity->cursor).ToString() << std::endl; std::cout << " parentEntity = " << clang::Cursor(ref->parentEntity->cursor).ToString() << std::endl;
@ -826,7 +826,7 @@ void indexEntityReference(CXClientData client_data, const CXIdxEntityRefInfo* re
static bool DUMP_AST = true; static bool DUMP_AST = true;
IndexedFile Parse(IdCache* id_cache, FileDb* file_db, std::string filename, std::vector<std::string> args) { IndexedFile Parse(IdCache* id_cache, std::string filename, std::vector<std::string> args) {
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);
@ -849,7 +849,7 @@ IndexedFile Parse(IdCache* id_cache, FileDb* file_db, std::string filename, std:
*/ */
}; };
IndexedFile db(id_cache, file_db); IndexedFile db(id_cache);
NamespaceHelper ns; NamespaceHelper ns;
IndexParam param(&db, &ns); IndexParam param(&db, &ns);
clang_indexTranslationUnit(index_action, &param, callbacks, sizeof(callbacks), clang_indexTranslationUnit(index_action, &param, callbacks, sizeof(callbacks),
@ -991,8 +991,7 @@ int main55555(int argc, char** argv) {
// Run test. // Run test.
std::cout << "[START] " << path << std::endl; std::cout << "[START] " << path << std::endl;
IdCache id_cache(1); IdCache id_cache(1);
FileDb file_db(1); IndexedFile db = Parse(&id_cache, path, {});
IndexedFile db = Parse(&id_cache, &file_db, path, {});
std::string actual_output = db.ToString(); std::string actual_output = db.ToString();
//WriteToFile("output.json", actual_output); //WriteToFile("output.json", actual_output);

105
indexer.h
View File

@ -209,55 +209,6 @@ Location WithInteresting(bool interesting) {
END_BITFIELD_TYPE() END_BITFIELD_TYPE()
#endif #endif
struct FileDb {
GroupId group;
std::unordered_map<std::string, FileId> file_path_to_file_id;
std::unordered_map<FileId, std::string> file_id_to_file_path;
FileDb(GroupId group) : group(group) {
// Reserve id 0 for unfound.
file_path_to_file_id[""] = FileId(group, 0);
file_id_to_file_path[FileId(group, 0)] = "";
}
Location Resolve(const CXSourceLocation& cx_loc, bool interesting) {
CXFile file;
unsigned int line, column, offset;
clang_getSpellingLocation(cx_loc, &file, &line, &column, &offset);
FileId file_id(-1, -1);
if (file != nullptr) {
std::string path = clang::ToString(clang_getFileName(file));
auto it = file_path_to_file_id.find(path);
if (it != file_path_to_file_id.end()) {
file_id = it->second;
}
else {
file_id = FileId(group, file_path_to_file_id.size());
file_path_to_file_id[path] = file_id;
file_id_to_file_path[file_id] = path;
}
}
return Location(interesting, file_id, line, column);
}
Location Resolve(const CXIdxLoc& cx_idx_loc, bool interesting) {
CXSourceLocation cx_loc = clang_indexLoc_getCXSourceLocation(cx_idx_loc);
return Resolve(cx_loc, interesting);
}
Location Resolve(const CXCursor& cx_cursor, bool interesting) {
return Resolve(clang_getCursorLocation(cx_cursor), interesting);
}
Location Resolve(const clang::Cursor& cursor, bool interesting) {
return Resolve(cursor.cx_cursor, interesting);
}
};
template<typename T> template<typename T>
struct Ref { struct Ref {
Id<T> id; Id<T> id;
@ -295,7 +246,7 @@ using VarRef = Ref<IndexedVarDef>;
// TODO: Either eliminate the defs created as a by-product of cross-referencing, // TODO: Either eliminate the defs created as a by-product of cross-referencing,
// or do not emit things we don't have definitions for. // or do not emit things we don't have definitions for.
template<typename TypeId = TypeId, typename FuncId = FuncId, typename VarId = VarId> template<typename TypeId = TypeId, typename FuncId = FuncId, typename VarId = VarId, typename Location = Location>
struct TypeDefDefinitionData { struct TypeDefDefinitionData {
// General metadata. // General metadata.
TypeId id; TypeId id;
@ -376,7 +327,7 @@ namespace std {
}; };
} }
template<typename TypeId = TypeId, typename FuncId = FuncId, typename VarId = VarId, typename FuncRef = FuncRef> template<typename TypeId = TypeId, typename FuncId = FuncId, typename VarId = VarId, typename FuncRef = FuncRef, typename Location = Location>
struct FuncDefDefinitionData { struct FuncDefDefinitionData {
// General metadata. // General metadata.
FuncId id; FuncId id;
@ -459,7 +410,7 @@ namespace std {
}; };
} }
template<typename TypeId = TypeId, typename FuncId = FuncId, typename VarId = VarId> template<typename TypeId = TypeId, typename FuncId = FuncId, typename VarId = VarId, typename Location = Location>
struct VarDefDefinitionData { struct VarDefDefinitionData {
// General metadata. // General metadata.
VarId id; VarId id;
@ -526,25 +477,67 @@ struct IdCache {
// NOTE: Every Id is resolved to a file_id of 0. The correct file_id needs // NOTE: Every Id is resolved to a file_id of 0. The correct file_id needs
// to get fixed up when inserting into the real db. // to get fixed up when inserting into the real db.
GroupId group; GroupId group;
std::unordered_map<std::string, FileId> file_path_to_file_id;
std::unordered_map<std::string, TypeId> usr_to_type_id; std::unordered_map<std::string, TypeId> usr_to_type_id;
std::unordered_map<std::string, FuncId> usr_to_func_id; std::unordered_map<std::string, FuncId> usr_to_func_id;
std::unordered_map<std::string, VarId> usr_to_var_id; std::unordered_map<std::string, VarId> usr_to_var_id;
std::unordered_map<FileId, std::string> file_id_to_file_path;
std::unordered_map<TypeId, std::string> type_id_to_usr; std::unordered_map<TypeId, std::string> type_id_to_usr;
std::unordered_map<FuncId, std::string> func_id_to_usr; std::unordered_map<FuncId, std::string> func_id_to_usr;
std::unordered_map<VarId, std::string> var_id_to_usr; std::unordered_map<VarId, std::string> var_id_to_usr;
IdCache(GroupId group) : group(group) {} IdCache(GroupId group) : group(group) {
// Reserve id 0 for unfound.
file_path_to_file_id[""] = FileId(group, 0);
file_id_to_file_path[FileId(group, 0)] = "";
}
Location Resolve(const CXSourceLocation& cx_loc, bool interesting) {
CXFile file;
unsigned int line, column, offset;
clang_getSpellingLocation(cx_loc, &file, &line, &column, &offset);
FileId file_id(-1, -1);
if (file != nullptr) {
std::string path = clang::ToString(clang_getFileName(file));
auto it = file_path_to_file_id.find(path);
if (it != file_path_to_file_id.end()) {
file_id = it->second;
}
else {
file_id = FileId(group, file_path_to_file_id.size());
file_path_to_file_id[path] = file_id;
file_id_to_file_path[file_id] = path;
}
}
return Location(interesting, file_id, line, column);
}
Location Resolve(const CXIdxLoc& cx_idx_loc, bool interesting) {
CXSourceLocation cx_loc = clang_indexLoc_getCXSourceLocation(cx_idx_loc);
return Resolve(cx_loc, interesting);
}
Location Resolve(const CXCursor& cx_cursor, bool interesting) {
return Resolve(clang_getCursorLocation(cx_cursor), interesting);
}
Location Resolve(const clang::Cursor& cursor, bool interesting) {
return Resolve(cursor.cx_cursor, interesting);
}
}; };
struct IndexedFile { struct IndexedFile {
FileDb* file_db;
IdCache* id_cache; IdCache* id_cache;
std::vector<IndexedTypeDef> types; std::vector<IndexedTypeDef> types;
std::vector<IndexedFuncDef> funcs; std::vector<IndexedFuncDef> funcs;
std::vector<IndexedVarDef> vars; std::vector<IndexedVarDef> vars;
IndexedFile(IdCache* id_cache, FileDb* file_db); IndexedFile(IdCache* id_cache);
TypeId ToTypeId(const std::string& usr); TypeId ToTypeId(const std::string& usr);
FuncId ToFuncId(const std::string& usr); FuncId ToFuncId(const std::string& usr);
@ -562,4 +555,4 @@ struct IndexedFile {
IndexedFile Parse(IdCache* id_cache, FileDb* file_db, std::string filename, std::vector<std::string> args); IndexedFile Parse(IdCache* id_cache, std::string filename, std::vector<std::string> args);

View File

@ -290,23 +290,6 @@ struct IdMap {
// TODO: Switch over to QueryableLocation. Figure out if there is
// a good way to get the indexer using it. I don't think so
// since we may discover more files while indexing a file.
//
// We could also reuse planned USR caching system for file
// paths.
struct CachedFileDb {
using Id = int64_t;
std::vector<std::string> file_names;
};
struct QueryableLocation {
CachedFileDb::Id id;
int line;
int column;
bool is_interesting;
};
@ -337,7 +320,9 @@ Usr MapIdToUsr(IdCache& id_cache, FuncId& id) {
Usr MapIdToUsr(IdCache& id_cache, VarId& id) { Usr MapIdToUsr(IdCache& id_cache, VarId& id) {
return id_cache.var_id_to_usr[id]; return id_cache.var_id_to_usr[id];
} }
Location MapIdToUsr(IdCache& id_cache, Location& ids); // FIXME: We will need additional data to map locations. QueryableLocation MapIdToUsr(IdCache& id_cache, Location& id) {
return QueryableLocation(id_cache.file_id_to_file_path[id.file_id()], id.line, id.column, id.interesting);
}
std::vector<Usr> MapIdToUsr(IdCache& id_cache, std::vector<TypeId>& ids) { std::vector<Usr> MapIdToUsr(IdCache& id_cache, std::vector<TypeId>& ids) {
return Transform<TypeId, Usr>(ids, [&](TypeId id) { return id_cache.type_id_to_usr[id]; }); return Transform<TypeId, Usr>(ids, [&](TypeId id) { return id_cache.type_id_to_usr[id]; });
@ -351,12 +336,16 @@ std::vector<Usr> MapIdToUsr(IdCache& id_cache, std::vector<VarId>& ids) {
std::vector<UsrRef> MapIdToUsr(IdCache& id_cache, std::vector<FuncRef>& ids) { std::vector<UsrRef> MapIdToUsr(IdCache& id_cache, std::vector<FuncRef>& ids) {
return Transform<FuncRef, UsrRef>(ids, [&](FuncRef ref) { return Transform<FuncRef, UsrRef>(ids, [&](FuncRef ref) {
UsrRef result; UsrRef result;
result.loc = ref.loc; // FIXME: Patch proper location. Fix when fixing MapIdToUsr(Location). I'm thinking we will have a GlobalLocation type. result.loc = MapIdToUsr(id_cache, ref.loc);
result.usr = id_cache.func_id_to_usr[ref.id]; result.usr = id_cache.func_id_to_usr[ref.id];
return result; return result;
}); });
} }
std::vector<Location> MapIdToUsr(IdCache& id_cache, std::vector<Location>& ids); // FIXME: We will need additional data to map locations. std::vector<QueryableLocation> MapIdToUsr(IdCache& id_cache, std::vector<Location>& ids) {
return Transform<Location, QueryableLocation>(ids, [&](Location id) {
return QueryableLocation(id_cache.file_id_to_file_path[id.file_id()], id.line, id.column, id.interesting);
});
}
QueryableTypeDef::DefUpdate MapIdToUsr(IdCache& id_cache, TypeDefDefinitionData<>& def) { QueryableTypeDef::DefUpdate MapIdToUsr(IdCache& id_cache, TypeDefDefinitionData<>& def) {
QueryableTypeDef::DefUpdate result(def.usr, def.usr); QueryableTypeDef::DefUpdate result(def.usr, def.usr);
if (result.definition) if (result.definition)
@ -788,6 +777,7 @@ struct QueryableDatabase {
std::vector<SymbolIdx> symbols; std::vector<SymbolIdx> symbols;
// Raw data storage. // Raw data storage.
std::vector<QueryableFile> files; // File path is stored as a Usr.
std::vector<QueryableTypeDef> types; std::vector<QueryableTypeDef> types;
std::vector<QueryableFuncDef> funcs; std::vector<QueryableFuncDef> funcs;
std::vector<QueryableVarDef> vars; std::vector<QueryableVarDef> vars;
@ -795,13 +785,6 @@ struct QueryableDatabase {
// Lookup symbol based on a usr. // Lookup symbol based on a usr.
std::unordered_map<Usr, SymbolIdx> usr_to_symbol; std::unordered_map<Usr, SymbolIdx> usr_to_symbol;
// |files| is indexed by FileId. Retrieve a FileId from a path using
// |file_db|.
FileDb file_db;
std::vector<QueryableFile> files;
QueryableDatabase(GroupId group);
// Insert the contents of |update| into |db|. // Insert the contents of |update| into |db|.
void ApplyIndexUpdate(IndexUpdate* update); void ApplyIndexUpdate(IndexUpdate* update);
@ -909,8 +892,6 @@ void ApplyUpdates(std::unordered_map<TId, int>* id_map, std::vector<TDef>* defs,
} }
} }
QueryableDatabase::QueryableDatabase(GroupId group) : file_db(group) {}
void QueryableDatabase::ApplyIndexUpdate(IndexUpdate* update) { void QueryableDatabase::ApplyIndexUpdate(IndexUpdate* update) {
#define JOIN(a, b) a##b #define JOIN(a, b) a##b
#define HANDLE_MERGEABLE(update_var_name, def_var_name, storage_name) \ #define HANDLE_MERGEABLE(update_var_name, def_var_name, storage_name) \
@ -956,13 +937,12 @@ void QueryableDatabase::ApplyIndexUpdate(IndexUpdate* update) {
int main(int argc, char** argv) { int main(int argc, char** argv) {
// TODO: Unify UserToIdResolver and FileDb // TODO: Unify UserToIdResolver and FileDb
IdCache id_cache(1); IdCache id_cache(1);
FileDb file_db(1);
IndexedFile indexed_file_a = Parse(&id_cache, &file_db, "full_tests/index_delta/a_v0.cc", {}); IndexedFile indexed_file_a = Parse(&id_cache, "full_tests/index_delta/a_v0.cc", {});
std::cout << indexed_file_a.ToString() << std::endl; std::cout << indexed_file_a.ToString() << std::endl;
std::cout << std::endl; std::cout << std::endl;
IndexedFile indexed_file_b = Parse(&id_cache, &file_db, "full_tests/index_delta/a_v1.cc", {}); IndexedFile indexed_file_b = Parse(&id_cache, "full_tests/index_delta/a_v1.cc", {});
std::cout << indexed_file_b.ToString() << std::endl; std::cout << indexed_file_b.ToString() << std::endl;
// TODO: We don't need to do ID remapping when computting a diff. Well, we need to do it for the IndexUpdate. // TODO: We don't need to do ID remapping when computting a diff. Well, we need to do it for the IndexUpdate.
IndexUpdate import(indexed_file_a); IndexUpdate import(indexed_file_a);
@ -970,7 +950,7 @@ int main(int argc, char** argv) {
dest_ids.Import(indexed_file_b.file_db, indexed_file_b.id_cache); dest_ids.Import(indexed_file_b.file_db, indexed_file_b.id_cache);
IndexUpdate update = ComputeDiff(indexed_file_a, indexed_file_b); IndexUpdate update = ComputeDiff(indexed_file_a, indexed_file_b);
*/ */
QueryableDatabase db(5); QueryableDatabase db;
db.ApplyIndexUpdate(&import); db.ApplyIndexUpdate(&import);
//db.ApplyIndexUpdate(&update); //db.ApplyIndexUpdate(&update);

72
query.h
View File

@ -23,15 +23,45 @@ enum class PreferredSymbolLocation {
}; };
using Usr = std::string; using Usr = std::string;
// TODO: Switch over to QueryableLocation. Figure out if there is
// a good way to get the indexer using it. I don't think so
// since we may discover more files while indexing a file.
//
// We could also reuse planned USR caching system for file
// paths.
struct QueryableLocation {
Usr path;
int line;
int column;
bool interesting;
QueryableLocation()
: path(""), line(-1), column(-1), interesting(false) {}
QueryableLocation(Usr path, int line, int column, bool interesting)
: path(path), line(line), column(column), interesting(interesting) {}
bool operator==(const QueryableLocation& other) const {
// Note: We ignore |is_interesting|.
return
path == other.path &&
line == other.line &&
column == other.column;
}
};
struct UsrRef { struct UsrRef {
Usr usr; Usr usr;
Location loc; QueryableLocation loc;
bool operator==(const UsrRef& other) const { bool operator==(const UsrRef& other) const {
return usr == other.usr && loc == other.loc; return usr == other.usr && loc == other.loc;
} }
}; };
// There are two sources of reindex updates: the (single) definition of a // There are two sources of reindex updates: the (single) definition of a
// symbol has changed, or one of many users of the symbol has changed. // symbol has changed, or one of many users of the symbol has changed.
// //
@ -52,45 +82,45 @@ struct MergeableUpdate {
}; };
struct QueryableTypeDef { struct QueryableTypeDef {
TypeDefDefinitionData<Usr, Usr, Usr> def; using DefUpdate = TypeDefDefinitionData<Usr, Usr, Usr, QueryableLocation>;
std::vector<Usr> derived;
std::vector<Location> uses;
using DefUpdate = TypeDefDefinitionData<Usr, Usr, Usr>;
using DerivedUpdate = MergeableUpdate<Usr>; using DerivedUpdate = MergeableUpdate<Usr>;
using UsesUpdate = MergeableUpdate<Location>; using UsesUpdate = MergeableUpdate<QueryableLocation>;
DefUpdate def;
std::vector<Usr> derived;
std::vector<QueryableLocation> uses;
QueryableTypeDef(IdCache& id_cache, IndexedTypeDef& indexed); QueryableTypeDef(IdCache& id_cache, IndexedTypeDef& indexed);
}; };
struct QueryableFuncDef { struct QueryableFuncDef {
FuncDefDefinitionData<Usr, Usr, Usr, UsrRef> def; using DefUpdate = FuncDefDefinitionData<Usr, Usr, Usr, UsrRef, QueryableLocation>;
std::vector<Location> declarations; using DeclarationsUpdate = MergeableUpdate<QueryableLocation>;
std::vector<Usr> derived;
std::vector<UsrRef> callers;
std::vector<Location> uses;
using DefUpdate = FuncDefDefinitionData<Usr, Usr, Usr, UsrRef>;
using DeclarationsUpdate = MergeableUpdate<Location>;
using DerivedUpdate = MergeableUpdate<Usr>; using DerivedUpdate = MergeableUpdate<Usr>;
using CallersUpdate = MergeableUpdate<UsrRef>; using CallersUpdate = MergeableUpdate<UsrRef>;
using UsesUpdate = MergeableUpdate<Location>; using UsesUpdate = MergeableUpdate<QueryableLocation>;
DefUpdate def;
std::vector<QueryableLocation> declarations;
std::vector<Usr> derived;
std::vector<UsrRef> callers;
std::vector<QueryableLocation> uses;
QueryableFuncDef(IdCache& id_cache, IndexedFuncDef& indexed); QueryableFuncDef(IdCache& id_cache, IndexedFuncDef& indexed);
}; };
struct QueryableVarDef { struct QueryableVarDef {
VarDefDefinitionData<Usr, Usr, Usr> def; using DefUpdate = VarDefDefinitionData<Usr, Usr, Usr, QueryableLocation>;
std::vector<Location> uses; using UsesUpdate = MergeableUpdate<QueryableLocation>;
using DefUpdate = VarDefDefinitionData<Usr, Usr, Usr>; DefUpdate def;
using UsesUpdate = MergeableUpdate<Location>; std::vector<QueryableLocation> uses;
QueryableVarDef(IdCache& id_cache, IndexedVarDef& indexed); QueryableVarDef(IdCache& id_cache, IndexedVarDef& indexed);
}; };
enum class SymbolKind { Invalid, Type, Func, Var }; enum class SymbolKind { Invalid, File, Type, Func, Var };
struct SymbolIdx { struct SymbolIdx {
SymbolKind kind; SymbolKind kind;
uint64_t idx; uint64_t idx;

View File

@ -17,6 +17,7 @@ def configure(conf):
# https://github.com/Andersbakken/rtags/blob/master/scripts/getclang.sh # https://github.com/Andersbakken/rtags/blob/master/scripts/getclang.sh
def download_clang(): def download_clang():
#'http://releases.llvm.org/3.9.0/clang+llvm-3.9.0-x86_64-apple-darwin.tar.xz' #'http://releases.llvm.org/3.9.0/clang+llvm-3.9.0-x86_64-apple-darwin.tar.xz'
pass
def build(bld): def build(bld):
cc_files = bld.path.ant_glob(['**/*.cpp', '**/*.cc'], cc_files = bld.path.ant_glob(['**/*.cpp', '**/*.cc'],