mirror of
https://github.com/MaskRay/ccls.git
synced 2024-11-22 07:35:08 +00:00
building
This commit is contained in:
parent
bc8daee065
commit
18aa28bdea
3
.gitignore
vendored
3
.gitignore
vendored
@ -1,6 +1,9 @@
|
|||||||
.vs
|
.vs
|
||||||
Debug
|
Debug
|
||||||
x64
|
x64
|
||||||
|
build
|
||||||
|
waf-*
|
||||||
|
.lock-waf*
|
||||||
*.swp
|
*.swp
|
||||||
*.sln
|
*.sln
|
||||||
*.vcxproj
|
*.vcxproj
|
||||||
|
41
indexer.cpp
41
indexer.cpp
@ -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, ¶m, callbacks, sizeof(callbacks),
|
clang_indexTranslationUnit(index_action, ¶m, 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
105
indexer.h
@ -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);
|
46
query.cc
46
query.cc
@ -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
72
query.h
@ -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;
|
||||||
|
1
wscript
1
wscript
@ -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'],
|
||||||
|
Loading…
Reference in New Issue
Block a user