Small code cleanups/renames

This commit is contained in:
Jacob Dufault 2017-02-23 00:18:54 -08:00
parent ce4c2232d7
commit d867d962d8
6 changed files with 135 additions and 112 deletions

View File

@ -13,7 +13,6 @@ std::vector<CompilationEntry> LoadCompilationEntriesFromDirectory(const std::str
exit(1); exit(1);
} }
CXCompileCommands cx_commands = clang_CompilationDatabase_getAllCompileCommands(cx_db); CXCompileCommands cx_commands = clang_CompilationDatabase_getAllCompileCommands(cx_db);
unsigned int num_commands = clang_CompileCommands_getSize(cx_commands); unsigned int num_commands = clang_CompileCommands_getSize(cx_commands);

View File

@ -1,59 +1,59 @@
#include "indexer.h" #include "indexer.h"
ParsingDatabase::ParsingDatabase() {} IndexedFile::IndexedFile() {}
// TODO: Optimize for const char*? // TODO: Optimize for const char*?
TypeId ParsingDatabase::ToTypeId(const std::string& usr) { TypeId IndexedFile::ToTypeId(const std::string& usr) {
auto it = usr_to_type_id.find(usr); auto it = usr_to_type_id.find(usr);
if (it != usr_to_type_id.end()) if (it != usr_to_type_id.end())
return it->second; return it->second;
TypeId id(types.size()); TypeId id(types.size());
types.push_back(TypeDef(id, usr)); types.push_back(IndexedTypeDef(id, usr));
usr_to_type_id[usr] = id; usr_to_type_id[usr] = id;
return id; return id;
} }
FuncId ParsingDatabase::ToFuncId(const std::string& usr) { FuncId IndexedFile::ToFuncId(const std::string& usr) {
auto it = usr_to_func_id.find(usr); auto it = usr_to_func_id.find(usr);
if (it != usr_to_func_id.end()) if (it != usr_to_func_id.end())
return it->second; return it->second;
FuncId id(funcs.size()); FuncId id(funcs.size());
funcs.push_back(FuncDef(id, usr)); funcs.push_back(IndexedFuncDef(id, usr));
usr_to_func_id[usr] = id; usr_to_func_id[usr] = id;
return id; return id;
} }
VarId ParsingDatabase::ToVarId(const std::string& usr) { VarId IndexedFile::ToVarId(const std::string& usr) {
auto it = usr_to_var_id.find(usr); auto it = usr_to_var_id.find(usr);
if (it != usr_to_var_id.end()) if (it != usr_to_var_id.end())
return it->second; return it->second;
VarId id(vars.size()); VarId id(vars.size());
vars.push_back(VarDef(id, usr)); vars.push_back(IndexedVarDef(id, usr));
usr_to_var_id[usr] = id; usr_to_var_id[usr] = id;
return id; return id;
} }
TypeId ParsingDatabase::ToTypeId(const CXCursor& cursor) { TypeId IndexedFile::ToTypeId(const CXCursor& cursor) {
return ToTypeId(clang::Cursor(cursor).get_usr()); return ToTypeId(clang::Cursor(cursor).get_usr());
} }
FuncId ParsingDatabase::ToFuncId(const CXCursor& cursor) { FuncId IndexedFile::ToFuncId(const CXCursor& cursor) {
return ToFuncId(clang::Cursor(cursor).get_usr()); return ToFuncId(clang::Cursor(cursor).get_usr());
} }
VarId ParsingDatabase::ToVarId(const CXCursor& cursor) { VarId IndexedFile::ToVarId(const CXCursor& cursor) {
return ToVarId(clang::Cursor(cursor).get_usr()); return ToVarId(clang::Cursor(cursor).get_usr());
} }
TypeDef* ParsingDatabase::Resolve(TypeId id) { IndexedTypeDef* IndexedFile::Resolve(TypeId id) {
return &types[id.local_id]; return &types[id.local_id];
} }
FuncDef* ParsingDatabase::Resolve(FuncId id) { IndexedFuncDef* IndexedFile::Resolve(FuncId id) {
return &funcs[id.local_id]; return &funcs[id.local_id];
} }
VarDef* ParsingDatabase::Resolve(VarId id) { IndexedVarDef* IndexedFile::Resolve(VarId id) {
return &vars[id.local_id]; return &vars[id.local_id];
} }
@ -148,7 +148,7 @@ void Write(Writer& writer, const char* key, uint64_t value) {
writer.Uint64(value); writer.Uint64(value);
} }
std::string ParsingDatabase::ToString() { std::string IndexedFile::ToString() {
auto it = usr_to_type_id.find(""); auto it = usr_to_type_id.find("");
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>";
@ -168,7 +168,7 @@ std::string ParsingDatabase::ToString() {
// Types // Types
writer.Key("types"); writer.Key("types");
writer.StartArray(); writer.StartArray();
for (TypeDef& def : types) { for (IndexedTypeDef& def : types) {
if (def.is_system_def) continue; if (def.is_system_def) continue;
writer.StartObject(); writer.StartObject();
@ -191,7 +191,7 @@ std::string ParsingDatabase::ToString() {
// Functions // Functions
writer.Key("functions"); writer.Key("functions");
writer.StartArray(); writer.StartArray();
for (FuncDef& def : funcs) { for (IndexedFuncDef& def : funcs) {
if (def.is_system_def) continue; if (def.is_system_def) continue;
writer.StartObject(); writer.StartObject();
@ -215,7 +215,7 @@ std::string ParsingDatabase::ToString() {
// Variables // Variables
writer.Key("variables"); writer.Key("variables");
writer.StartArray(); writer.StartArray();
for (VarDef& def : vars) { for (IndexedVarDef& def : vars) {
if (def.is_system_def) continue; if (def.is_system_def) continue;
writer.StartObject(); writer.StartObject();
@ -404,7 +404,7 @@ struct NamespaceHelper {
}; };
struct IndexParam { struct IndexParam {
ParsingDatabase* db; IndexedFile* db;
NamespaceHelper* ns; NamespaceHelper* ns;
// Record the last type usage location we recorded. Clang will sometimes // Record the last type usage location we recorded. Clang will sometimes
@ -413,7 +413,7 @@ struct IndexParam {
Location last_type_usage_location; Location last_type_usage_location;
Location last_func_usage_location; Location last_func_usage_location;
IndexParam(ParsingDatabase* db, NamespaceHelper* ns) : db(db), ns(ns) {} IndexParam(IndexedFile* db, NamespaceHelper* ns) : db(db), ns(ns) {}
}; };
/* /*
@ -443,19 +443,19 @@ bool IsTypeDefinition(const CXIdxContainerInfo* container) {
struct VisitDeclForTypeUsageParam { struct VisitDeclForTypeUsageParam {
ParsingDatabase* db; IndexedFile* db;
bool is_interesting; bool is_interesting;
int has_processed_any = false; int has_processed_any = false;
optional<clang::Cursor> previous_cursor; optional<clang::Cursor> previous_cursor;
optional<TypeId> initial_type; optional<TypeId> initial_type;
VisitDeclForTypeUsageParam(ParsingDatabase* db, bool is_interesting) VisitDeclForTypeUsageParam(IndexedFile* db, bool is_interesting)
: db(db), is_interesting(is_interesting) {} : db(db), is_interesting(is_interesting) {}
}; };
void VisitDeclForTypeUsageVisitorHandler(clang::Cursor cursor, VisitDeclForTypeUsageParam* param) { void VisitDeclForTypeUsageVisitorHandler(clang::Cursor cursor, VisitDeclForTypeUsageParam* param) {
param->has_processed_any = true; param->has_processed_any = true;
ParsingDatabase* db = param->db; IndexedFile* db = param->db;
// TODO: Something in STL (type_traits)? reports an empty USR. // TODO: Something in STL (type_traits)? reports an empty USR.
std::string referenced_usr = cursor.get_referenced().get_usr(); std::string referenced_usr = cursor.get_referenced().get_usr();
@ -467,7 +467,7 @@ void VisitDeclForTypeUsageVisitorHandler(clang::Cursor cursor, VisitDeclForTypeU
param->initial_type = ref_type_id; param->initial_type = ref_type_id;
if (param->is_interesting) { if (param->is_interesting) {
TypeDef* 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->file_db.Resolve(cursor, true /*interesting*/);
ref_type_def->AddUsage(loc); ref_type_def->AddUsage(loc);
} }
@ -496,7 +496,7 @@ clang::VisiterResult VisitDeclForTypeUsageVisitor(clang::Cursor cursor, clang::C
return clang::VisiterResult::Continue; return clang::VisiterResult::Continue;
} }
optional<TypeId> ResolveDeclToType(ParsingDatabase* db, clang::Cursor decl_cursor, optional<TypeId> ResolveDeclToType(IndexedFile* db, clang::Cursor decl_cursor,
bool is_interesting, const CXIdxContainerInfo* semantic_container, bool is_interesting, const CXIdxContainerInfo* semantic_container,
const CXIdxContainerInfo* lexical_container) { const CXIdxContainerInfo* lexical_container) {
// //
@ -563,7 +563,7 @@ void indexDeclaration(CXClientData client_data, const CXIdxDeclInfo* decl) {
bool is_system_def = clang_Location_isInSystemHeader(clang_getCursorLocation(decl->cursor)); bool is_system_def = clang_Location_isInSystemHeader(clang_getCursorLocation(decl->cursor));
IndexParam* param = static_cast<IndexParam*>(client_data); IndexParam* param = static_cast<IndexParam*>(client_data);
ParsingDatabase* db = param->db; IndexedFile* db = param->db;
NamespaceHelper* ns = param->ns; NamespaceHelper* ns = param->ns;
switch (decl->entityInfo->kind) { switch (decl->entityInfo->kind) {
@ -580,7 +580,7 @@ void indexDeclaration(CXClientData client_data, const CXIdxDeclInfo* decl) {
{ {
clang::Cursor decl_cursor = decl->cursor; clang::Cursor decl_cursor = decl->cursor;
VarId var_id = db->ToVarId(decl->entityInfo->USR); VarId var_id = db->ToVarId(decl->entityInfo->USR);
VarDef* var_def = db->Resolve(var_id); IndexedVarDef* var_def = db->Resolve(var_id);
var_def->is_system_def = is_system_def; var_def->is_system_def = is_system_def;
@ -610,7 +610,7 @@ void indexDeclaration(CXClientData client_data, const CXIdxDeclInfo* decl) {
if (decl->isDefinition && IsTypeDefinition(decl->semanticContainer)) { if (decl->isDefinition && IsTypeDefinition(decl->semanticContainer)) {
TypeId declaring_type_id = db->ToTypeId(decl->semanticContainer->cursor); TypeId declaring_type_id = db->ToTypeId(decl->semanticContainer->cursor);
TypeDef* declaring_type_def = db->Resolve(declaring_type_id); IndexedTypeDef* declaring_type_def = db->Resolve(declaring_type_id);
var_def->declaring_type = declaring_type_id; var_def->declaring_type = declaring_type_id;
declaring_type_def->vars.push_back(var_id); declaring_type_def->vars.push_back(var_id);
} }
@ -627,7 +627,7 @@ void indexDeclaration(CXClientData client_data, const CXIdxDeclInfo* decl) {
{ {
clang::Cursor decl_cursor = decl->cursor; clang::Cursor decl_cursor = decl->cursor;
FuncId func_id = db->ToFuncId(decl->entityInfo->USR); FuncId func_id = db->ToFuncId(decl->entityInfo->USR);
FuncDef* func_def = db->Resolve(func_id); IndexedFuncDef* func_def = db->Resolve(func_id);
func_def->is_system_def = is_system_def; func_def->is_system_def = is_system_def;
@ -653,7 +653,7 @@ void indexDeclaration(CXClientData client_data, const CXIdxDeclInfo* decl) {
// be one of those in the entire program. // be one of those in the entire program.
if (IsTypeDefinition(decl->semanticContainer)) { if (IsTypeDefinition(decl->semanticContainer)) {
TypeId declaring_type_id = db->ToTypeId(decl->semanticContainer->cursor); TypeId declaring_type_id = db->ToTypeId(decl->semanticContainer->cursor);
TypeDef* declaring_type_def = db->Resolve(declaring_type_id); IndexedTypeDef* declaring_type_def = db->Resolve(declaring_type_id);
func_def->declaring_type = declaring_type_id; func_def->declaring_type = declaring_type_id;
// Mark a type reference at the ctor/dtor location. // Mark a type reference at the ctor/dtor location.
@ -716,7 +716,7 @@ void indexDeclaration(CXClientData client_data, const CXIdxDeclInfo* decl) {
for (unsigned int i = 0; i < num_overridden; ++i) { for (unsigned int i = 0; i < num_overridden; ++i) {
clang::Cursor parent = overridden[i]; clang::Cursor parent = overridden[i];
FuncId parent_id = db->ToFuncId(parent.get_usr()); FuncId parent_id = db->ToFuncId(parent.get_usr());
FuncDef* parent_def = db->Resolve(parent_id); IndexedFuncDef* parent_def = db->Resolve(parent_id);
func_def = db->Resolve(func_id); // ToFuncId invalidated func_def func_def = db->Resolve(func_id); // ToFuncId invalidated func_def
func_def->base = parent_id; func_def->base = parent_id;
@ -744,7 +744,7 @@ void indexDeclaration(CXClientData client_data, const CXIdxDeclInfo* decl) {
optional<TypeId> alias_of = ResolveDeclToType(db, decl->cursor, true /*is_interesting*/, decl->semanticContainer, decl->lexicalContainer); optional<TypeId> alias_of = ResolveDeclToType(db, decl->cursor, true /*is_interesting*/, decl->semanticContainer, decl->lexicalContainer);
TypeId type_id = db->ToTypeId(decl->entityInfo->USR); TypeId type_id = db->ToTypeId(decl->entityInfo->USR);
TypeDef* type_def = db->Resolve(type_id); IndexedTypeDef* type_def = db->Resolve(type_id);
type_def->is_system_def = is_system_def; type_def->is_system_def = is_system_def;
@ -766,7 +766,7 @@ void indexDeclaration(CXClientData client_data, const CXIdxDeclInfo* decl) {
case CXIdxEntity_CXXClass: case CXIdxEntity_CXXClass:
{ {
TypeId type_id = db->ToTypeId(decl->entityInfo->USR); TypeId type_id = db->ToTypeId(decl->entityInfo->USR);
TypeDef* type_def = db->Resolve(type_id); IndexedTypeDef* type_def = db->Resolve(type_id);
type_def->is_system_def = is_system_def; type_def->is_system_def = is_system_def;
@ -805,9 +805,9 @@ void indexDeclaration(CXClientData client_data, const CXIdxDeclInfo* decl) {
const CXIdxBaseClassInfo* base_class = class_info->bases[i]; const CXIdxBaseClassInfo* base_class = class_info->bases[i];
optional<TypeId> parent_type_id = ResolveDeclToType(db, base_class->cursor, true /*is_interesting*/, decl->semanticContainer, decl->lexicalContainer); optional<TypeId> parent_type_id = ResolveDeclToType(db, base_class->cursor, true /*is_interesting*/, decl->semanticContainer, decl->lexicalContainer);
TypeDef* type_def = db->Resolve(type_id); // type_def ptr could be invalidated by ResolveDeclToType. IndexedTypeDef* type_def = db->Resolve(type_id); // type_def ptr could be invalidated by ResolveDeclToType.
if (parent_type_id) { if (parent_type_id) {
TypeDef* parent_type_def = db->Resolve(parent_type_id.value()); IndexedTypeDef* parent_type_def = db->Resolve(parent_type_id.value());
parent_type_def->derived.push_back(type_id); parent_type_def->derived.push_back(type_id);
type_def->parents.push_back(parent_type_id.value()); type_def->parents.push_back(parent_type_id.value());
} }
@ -842,7 +842,7 @@ bool IsFunction(CXCursorKind kind) {
void indexEntityReference(CXClientData client_data, const CXIdxEntityRefInfo* ref) { void indexEntityReference(CXClientData client_data, const CXIdxEntityRefInfo* ref) {
IndexParam* param = static_cast<IndexParam*>(client_data); IndexParam* param = static_cast<IndexParam*>(client_data);
ParsingDatabase* db = param->db; IndexedFile* db = param->db;
clang::Cursor cursor(ref->cursor); clang::Cursor cursor(ref->cursor);
switch (ref->referencedEntity->kind) { switch (ref->referencedEntity->kind) {
@ -852,7 +852,7 @@ void indexEntityReference(CXClientData client_data, const CXIdxEntityRefInfo* re
case CXIdxEntity_Field: case CXIdxEntity_Field:
{ {
VarId var_id = db->ToVarId(ref->referencedEntity->cursor); VarId var_id = db->ToVarId(ref->referencedEntity->cursor);
VarDef* 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->file_db.Resolve(ref->loc, false /*interesting*/));
break; break;
} }
@ -883,15 +883,15 @@ void indexEntityReference(CXClientData client_data, const CXIdxEntityRefInfo* re
FuncId called_id = db->ToFuncId(ref->referencedEntity->USR); FuncId called_id = db->ToFuncId(ref->referencedEntity->USR);
if (IsFunction(ref->container->cursor.kind)) { if (IsFunction(ref->container->cursor.kind)) {
FuncId caller_id = db->ToFuncId(ref->container->cursor); FuncId caller_id = db->ToFuncId(ref->container->cursor);
FuncDef* caller_def = db->Resolve(caller_id); IndexedFuncDef* caller_def = db->Resolve(caller_id);
FuncDef* called_def = db->Resolve(called_id); IndexedFuncDef* called_def = db->Resolve(called_id);
caller_def->callees.push_back(FuncRef(called_id, loc)); caller_def->callees.push_back(FuncRef(called_id, loc));
called_def->callers.push_back(FuncRef(caller_id, loc)); called_def->callers.push_back(FuncRef(caller_id, loc));
called_def->uses.push_back(loc); called_def->uses.push_back(loc);
} }
else { else {
FuncDef* called_def = db->Resolve(called_id); IndexedFuncDef* called_def = db->Resolve(called_id);
called_def->uses.push_back(loc); called_def->uses.push_back(loc);
} }
@ -906,9 +906,9 @@ void indexEntityReference(CXClientData client_data, const CXIdxEntityRefInfo* re
Location parent_loc = db->file_db.Resolve(ref->parentEntity->cursor, true /*interesting*/); Location parent_loc = db->file_db.Resolve(ref->parentEntity->cursor, true /*interesting*/);
Location our_loc = db->file_db.Resolve(ref->loc, true /*is_interesting*/); Location our_loc = db->file_db.Resolve(ref->loc, true /*is_interesting*/);
if (!parent_loc.IsEqualTo(our_loc)) { if (!parent_loc.IsEqualTo(our_loc)) {
FuncDef* called_def = db->Resolve(called_id); IndexedFuncDef* called_def = db->Resolve(called_id);
assert(called_def->declaring_type.has_value()); assert(called_def->declaring_type.has_value());
TypeDef* type_def = db->Resolve(called_def->declaring_type.value()); IndexedTypeDef* type_def = db->Resolve(called_def->declaring_type.value());
type_def->AddUsage(our_loc); type_def->AddUsage(our_loc);
} }
} }
@ -923,7 +923,7 @@ void indexEntityReference(CXClientData client_data, const CXIdxEntityRefInfo* re
case CXIdxEntity_CXXClass: case CXIdxEntity_CXXClass:
{ {
TypeId referenced_id = db->ToTypeId(ref->referencedEntity->USR); TypeId referenced_id = db->ToTypeId(ref->referencedEntity->USR);
TypeDef* referenced_def = db->Resolve(referenced_id); IndexedTypeDef* referenced_def = db->Resolve(referenced_id);
// //
// The following will generate two TypeRefs to Foo, both located at the // The following will generate two TypeRefs to Foo, both located at the
@ -964,7 +964,7 @@ void indexEntityReference(CXClientData client_data, const CXIdxEntityRefInfo* re
static bool DUMP_AST = true; static bool DUMP_AST = true;
ParsingDatabase Parse(std::string filename, std::vector<std::string> args) { IndexedFile Parse(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);
@ -987,7 +987,7 @@ ParsingDatabase Parse(std::string filename, std::vector<std::string> args) {
*/ */
}; };
ParsingDatabase db; IndexedFile db;
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),
@ -1089,7 +1089,7 @@ void WriteToFile(const std::string& filename, const std::string& content) {
file << content; file << content;
} }
int mai2n(int argc, char** argv) { int main(int argc, char** argv) {
// TODO: Assert that we need to be on clang >= 3.9.1 // TODO: Assert that we need to be on clang >= 3.9.1
/* /*
@ -1128,7 +1128,7 @@ int mai2n(int argc, char** argv) {
// Run test. // Run test.
std::cout << "[START] " << path << std::endl; std::cout << "[START] " << path << std::endl;
ParsingDatabase db = Parse(path, {}); IndexedFile db = Parse(path, {});
std::string actual_output = db.ToString(); std::string actual_output = db.ToString();
//WriteToFile("output.json", actual_output); //WriteToFile("output.json", actual_output);

View File

@ -80,11 +80,11 @@ Location WithInteresting(bool interesting) {
END_BITFIELD_TYPE() END_BITFIELD_TYPE()
struct FileDb { struct IndexedFileDb {
std::unordered_map<std::string, FileId> file_path_to_file_id; std::unordered_map<std::string, FileId> file_path_to_file_id;
std::unordered_map<FileId, std::string> file_id_to_file_path; std::unordered_map<FileId, std::string> file_id_to_file_path;
FileDb() { IndexedFileDb() {
// Reserve id 0 for unfound. // Reserve id 0 for unfound.
file_path_to_file_id[""] = 0; file_path_to_file_id[""] = 0;
file_id_to_file_path[0] = ""; file_id_to_file_path[0] = "";
@ -167,7 +167,7 @@ using VarRef = Ref<VarDef>;
// 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.
struct TypeDef { struct IndexedTypeDef {
bool is_system_def = false; bool is_system_def = false;
// General metadata. // General metadata.
@ -204,7 +204,7 @@ struct TypeDef {
// NOTE: Do not insert directly! Use AddUsage instead. // NOTE: Do not insert directly! Use AddUsage instead.
std::vector<Location> uses; std::vector<Location> uses;
TypeDef(TypeId id, const std::string& usr) : id(id), usr(usr) { IndexedTypeDef(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;
} }
@ -226,7 +226,7 @@ struct TypeDef {
} }
}; };
struct FuncDef { struct IndexedFuncDef {
bool is_system_def = false; bool is_system_def = false;
// General metadata. // General metadata.
@ -260,12 +260,12 @@ struct FuncDef {
// All usages. For interesting usages, see callees. // All usages. For interesting usages, see callees.
std::vector<Location> uses; std::vector<Location> uses;
FuncDef(FuncId id, const std::string& usr) : id(id), usr(usr) { IndexedFuncDef(FuncId id, const std::string& usr) : id(id), usr(usr) {
assert(usr.size() > 0); assert(usr.size() > 0);
} }
}; };
struct VarDef { struct IndexedVarDef {
bool is_system_def = false; bool is_system_def = false;
// General metadata. // General metadata.
@ -287,26 +287,26 @@ struct VarDef {
// Usages. // Usages.
std::vector<Location> uses; std::vector<Location> uses;
VarDef(VarId id, const std::string& usr) : id(id), usr(usr) { IndexedVarDef(VarId id, const std::string& usr) : id(id), usr(usr) {
assert(usr.size() > 0); assert(usr.size() > 0);
} }
}; };
struct ParsingDatabase { struct IndexedFile {
// 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.
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::vector<TypeDef> types; std::vector<IndexedTypeDef> types;
std::vector<FuncDef> funcs; std::vector<IndexedFuncDef> funcs;
std::vector<VarDef> vars; std::vector<IndexedVarDef> vars;
FileDb file_db; IndexedFileDb file_db;
ParsingDatabase(); IndexedFile();
TypeId ToTypeId(const std::string& usr); TypeId ToTypeId(const std::string& usr);
FuncId ToFuncId(const std::string& usr); FuncId ToFuncId(const std::string& usr);
@ -315,11 +315,11 @@ struct ParsingDatabase {
FuncId ToFuncId(const CXCursor& usr); FuncId ToFuncId(const CXCursor& usr);
VarId ToVarId(const CXCursor& usr); VarId ToVarId(const CXCursor& usr);
TypeDef* Resolve(TypeId id); IndexedTypeDef* Resolve(TypeId id);
FuncDef* Resolve(FuncId id); IndexedFuncDef* Resolve(FuncId id);
VarDef* Resolve(VarId id); IndexedVarDef* Resolve(VarId id);
std::string ToString(); std::string ToString();
}; };
ParsingDatabase Parse(std::string filename, std::vector<std::string> args); IndexedFile Parse(std::string filename, std::vector<std::string> args);

View File

@ -24,7 +24,7 @@ struct SymbolIdx {
}; };
}; };
struct File { struct QueryableFile {
// Symbols declared in the file. // Symbols declared in the file.
std::vector<SymbolIdx> declared_symbols; std::vector<SymbolIdx> declared_symbols;
// Symbols which have definitions in the file. // Symbols which have definitions in the file.
@ -37,7 +37,7 @@ struct QueryableEntry {
// The query database is heavily optimized for fast queries. It is stored // The query database is heavily optimized for fast queries. It is stored
// in-memory. // in-memory.
struct QueryDatabase { struct QueryableDatabase {
// Indicies between lookup vectors are related to symbols, ie, index 5 in // Indicies between lookup vectors are related to symbols, ie, index 5 in
// |qualified_names| matches index 5 in |symbols|. // |qualified_names| matches index 5 in |symbols|.
std::vector<QueryableEntry> qualified_names; std::vector<QueryableEntry> qualified_names;
@ -51,7 +51,7 @@ struct QueryDatabase {
// |files| is indexed by FileId. Retrieve a FileId from a path using // |files| is indexed by FileId. Retrieve a FileId from a path using
// |file_locator|. // |file_locator|.
FileDatabase file_locator; FileDatabase file_locator;
std::vector<File> files; std::vector<QueryableFile> files;
}; };
@ -91,27 +91,45 @@ struct Query {
}; };
void fail(const std::string& message) {
std::cerr << "Fatal error: " << message << std::endl;
std::exit(1);
}
struct CachedIndexedFile {
// Path to the file indexed.
std::string path;
// Full in-memory storage for the index. Empty if not loaded into memory.
// |path| can be used to fetch the index from disk.
optional<rapidjson::Document> index;
};
struct DocumentDiff {
};
// Compute a diff between |original| and |updated|.
//rapidjson::Document DiffIndex(rapidjson::Document original, rapidjson::Document updated) {
//}
// NOTE: If updating this enum, make sure to also update the parser and the
// help text.
enum class PreferredSymbolLocation { enum class PreferredSymbolLocation {
Declaration, Declaration,
Definition Definition
}; };
std::istream& operator >> (std::istream& is, PreferredSymbolLocation& obj) {
std::string content;
is >> content;
if (content == "declaration") bool ParsePreferredSymbolLocation(const std::string& content, PreferredSymbolLocation* obj) {
obj = PreferredSymbolLocation::Declaration; #define PARSE_AS(name, string) \
else if (content == "definition") if (content == #string) { \
obj = PreferredSymbolLocation::Definition; *obj = name; \
else return true; \
is.setstate(std::ios::failbit); }
return is; PARSE_AS(PreferredSymbolLocation::Declaration, "declaration");
PARSE_AS(PreferredSymbolLocation::Definition, "definition");
return false;
#undef PARSE_AS
} }
// NOTE: If updating this enum, make sure to also update the parser and the // NOTE: If updating this enum, make sure to also update the parser and the
@ -127,34 +145,24 @@ enum class Command {
Search Search
}; };
//std::ostream& operator<<(std::ostream& os, const Command& obj) { bool ParseCommand(const std::string& content, Command* obj) {
// write obj to stream #define PARSE_AS(name, string) \
// return os; if (content == #string) { \
//} *obj = name; \
std::istream& operator >> (std::istream& is, Command& obj) { return true; \
std::string content; }
is >> content;
if (content == "callees") PARSE_AS(Command::Callees, "callees");
obj = Command::Callees; PARSE_AS(Command::Callers, "callers");
else if (content == "callers") PARSE_AS(Command::FindAllUsages, "find-all-usages");
obj = Command::Callers; PARSE_AS(Command::FindInterestingUsages, "find-interesting-usages");
else if (content == "find-all-usages") PARSE_AS(Command::GotoReferenced, "goto-referenced");
obj = Command::FindAllUsages; PARSE_AS(Command::Hierarchy, "hierarchy");
else if (content == "find-interesting-usages") PARSE_AS(Command::Outline, "outline");
obj = Command::FindInterestingUsages; PARSE_AS(Command::Search, "search");
else if (content == "goto-referenced")
obj = Command::GotoReferenced;
else if (content == "hierarchy")
obj = Command::Hierarchy;
else if (content == "outline")
obj = Command::Outline;
else if (content == "search")
obj = Command::Search;
else
is.setstate(std::ios::failbit);
return is; return false;
#undef PARSE_AS
} }
// TODO: I think we can run libclang multiple times in one process. So we might // TODO: I think we can run libclang multiple times in one process. So we might
@ -196,7 +204,7 @@ bool HasOption(const std::unordered_map<std::string, std::string>& options, cons
return options.find(option) != options.end(); return options.find(option) != options.end();
} }
int main(int argc, char** argv) { int main2(int argc, char** argv) {
std::unordered_map<std::string, std::string> options = ParseOptions(argc, argv); std::unordered_map<std::string, std::string> options = ParseOptions(argc, argv);
if (argc == 1 || options.find("--help") != options.end()) { if (argc == 1 || options.find("--help") != options.end()) {
@ -283,10 +291,10 @@ int main(int argc, char** argv) {
std::vector<CompilationEntry> entries = LoadCompilationEntriesFromDirectory(options["--project"]); std::vector<CompilationEntry> entries = LoadCompilationEntriesFromDirectory(options["--project"]);
std::vector<ParsingDatabase> dbs; std::vector<IndexedFile> dbs;
for (const CompilationEntry& entry : entries) { for (const CompilationEntry& entry : entries) {
std::cout << "Parsing " << entry.filename << std::endl; std::cout << "Parsing " << entry.filename << std::endl;
ParsingDatabase db = Parse(entry.filename, entry.args); IndexedFile db = Parse(entry.filename, entry.args);
dbs.emplace_back(db); dbs.emplace_back(db);
std::cout << db.ToString() << std::endl << std::endl; std::cout << db.ToString() << std::endl << std::endl;
@ -296,6 +304,13 @@ int main(int argc, char** argv) {
exit(0); exit(0);
} }
if (HasOption(options, "--command")) {
Command command;
if (!ParseCommand(options["--command"], &command))
Fail("Unknown command \"" + options["--command"] + "\"; see --help-commands");
}
std::cout << "Invalid arguments. Try --help."; std::cout << "Invalid arguments. Try --help.";
exit(1); exit(1);

View File

@ -1,5 +1,6 @@
#include "utils.h" #include "utils.h"
#include <iostream>
#include <fstream> #include <fstream>
#include "tinydir.h" #include "tinydir.h"
@ -66,3 +67,9 @@ void ParseTestExpectation(std::string filename, std::string* expected_output) {
in_output = true; in_output = true;
} }
} }
void Fail(const std::string& message) {
std::cerr << "Fatal error: " << message << std::endl;
std::exit(1);
}

View File

@ -5,4 +5,6 @@
std::vector<std::string> GetFilesInFolder(std::string folder); std::vector<std::string> GetFilesInFolder(std::string folder);
std::vector<std::string> ReadLines(std::string filename); std::vector<std::string> ReadLines(std::string filename);
void ParseTestExpectation(std::string filename, std::string* expected_output); void ParseTestExpectation(std::string filename, std::string* expected_output);
void Fail(const std::string& message);