mirror of
https://github.com/MaskRay/ccls.git
synced 2024-11-25 09:05:10 +00:00
Small code cleanups/renames
This commit is contained in:
parent
ce4c2232d7
commit
d867d962d8
@ -13,7 +13,6 @@ std::vector<CompilationEntry> LoadCompilationEntriesFromDirectory(const std::str
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
||||
CXCompileCommands cx_commands = clang_CompilationDatabase_getAllCompileCommands(cx_db);
|
||||
|
||||
unsigned int num_commands = clang_CompileCommands_getSize(cx_commands);
|
||||
|
92
indexer.cpp
92
indexer.cpp
@ -1,59 +1,59 @@
|
||||
#include "indexer.h"
|
||||
|
||||
ParsingDatabase::ParsingDatabase() {}
|
||||
IndexedFile::IndexedFile() {}
|
||||
|
||||
// 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);
|
||||
if (it != usr_to_type_id.end())
|
||||
return it->second;
|
||||
|
||||
TypeId id(types.size());
|
||||
types.push_back(TypeDef(id, usr));
|
||||
types.push_back(IndexedTypeDef(id, usr));
|
||||
usr_to_type_id[usr] = 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);
|
||||
if (it != usr_to_func_id.end())
|
||||
return it->second;
|
||||
|
||||
FuncId id(funcs.size());
|
||||
funcs.push_back(FuncDef(id, usr));
|
||||
funcs.push_back(IndexedFuncDef(id, usr));
|
||||
usr_to_func_id[usr] = 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);
|
||||
if (it != usr_to_var_id.end())
|
||||
return it->second;
|
||||
|
||||
VarId id(vars.size());
|
||||
vars.push_back(VarDef(id, usr));
|
||||
vars.push_back(IndexedVarDef(id, usr));
|
||||
usr_to_var_id[usr] = id;
|
||||
return id;
|
||||
}
|
||||
|
||||
TypeId ParsingDatabase::ToTypeId(const CXCursor& cursor) {
|
||||
TypeId IndexedFile::ToTypeId(const CXCursor& cursor) {
|
||||
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());
|
||||
}
|
||||
|
||||
VarId ParsingDatabase::ToVarId(const CXCursor& cursor) {
|
||||
VarId IndexedFile::ToVarId(const CXCursor& cursor) {
|
||||
return ToVarId(clang::Cursor(cursor).get_usr());
|
||||
}
|
||||
|
||||
|
||||
TypeDef* ParsingDatabase::Resolve(TypeId id) {
|
||||
IndexedTypeDef* IndexedFile::Resolve(TypeId id) {
|
||||
return &types[id.local_id];
|
||||
}
|
||||
FuncDef* ParsingDatabase::Resolve(FuncId id) {
|
||||
IndexedFuncDef* IndexedFile::Resolve(FuncId id) {
|
||||
return &funcs[id.local_id];
|
||||
}
|
||||
VarDef* ParsingDatabase::Resolve(VarId id) {
|
||||
IndexedVarDef* IndexedFile::Resolve(VarId id) {
|
||||
return &vars[id.local_id];
|
||||
}
|
||||
|
||||
@ -148,7 +148,7 @@ void Write(Writer& writer, const char* key, uint64_t value) {
|
||||
writer.Uint64(value);
|
||||
}
|
||||
|
||||
std::string ParsingDatabase::ToString() {
|
||||
std::string IndexedFile::ToString() {
|
||||
auto it = usr_to_type_id.find("");
|
||||
if (it != usr_to_type_id.end()) {
|
||||
Resolve(it->second)->short_name = "<fundamental>";
|
||||
@ -168,7 +168,7 @@ std::string ParsingDatabase::ToString() {
|
||||
// Types
|
||||
writer.Key("types");
|
||||
writer.StartArray();
|
||||
for (TypeDef& def : types) {
|
||||
for (IndexedTypeDef& def : types) {
|
||||
if (def.is_system_def) continue;
|
||||
|
||||
writer.StartObject();
|
||||
@ -191,7 +191,7 @@ std::string ParsingDatabase::ToString() {
|
||||
// Functions
|
||||
writer.Key("functions");
|
||||
writer.StartArray();
|
||||
for (FuncDef& def : funcs) {
|
||||
for (IndexedFuncDef& def : funcs) {
|
||||
if (def.is_system_def) continue;
|
||||
|
||||
writer.StartObject();
|
||||
@ -215,7 +215,7 @@ std::string ParsingDatabase::ToString() {
|
||||
// Variables
|
||||
writer.Key("variables");
|
||||
writer.StartArray();
|
||||
for (VarDef& def : vars) {
|
||||
for (IndexedVarDef& def : vars) {
|
||||
if (def.is_system_def) continue;
|
||||
|
||||
writer.StartObject();
|
||||
@ -404,7 +404,7 @@ struct NamespaceHelper {
|
||||
};
|
||||
|
||||
struct IndexParam {
|
||||
ParsingDatabase* db;
|
||||
IndexedFile* db;
|
||||
NamespaceHelper* ns;
|
||||
|
||||
// Record the last type usage location we recorded. Clang will sometimes
|
||||
@ -413,7 +413,7 @@ struct IndexParam {
|
||||
Location last_type_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 {
|
||||
ParsingDatabase* db;
|
||||
IndexedFile* db;
|
||||
bool is_interesting;
|
||||
int has_processed_any = false;
|
||||
optional<clang::Cursor> previous_cursor;
|
||||
optional<TypeId> initial_type;
|
||||
|
||||
VisitDeclForTypeUsageParam(ParsingDatabase* db, bool is_interesting)
|
||||
VisitDeclForTypeUsageParam(IndexedFile* db, bool is_interesting)
|
||||
: db(db), is_interesting(is_interesting) {}
|
||||
};
|
||||
|
||||
void VisitDeclForTypeUsageVisitorHandler(clang::Cursor cursor, VisitDeclForTypeUsageParam* param) {
|
||||
param->has_processed_any = true;
|
||||
ParsingDatabase* db = param->db;
|
||||
IndexedFile* db = param->db;
|
||||
|
||||
// TODO: Something in STL (type_traits)? reports an empty 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;
|
||||
|
||||
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*/);
|
||||
ref_type_def->AddUsage(loc);
|
||||
}
|
||||
@ -496,7 +496,7 @@ clang::VisiterResult VisitDeclForTypeUsageVisitor(clang::Cursor cursor, clang::C
|
||||
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,
|
||||
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));
|
||||
|
||||
IndexParam* param = static_cast<IndexParam*>(client_data);
|
||||
ParsingDatabase* db = param->db;
|
||||
IndexedFile* db = param->db;
|
||||
NamespaceHelper* ns = param->ns;
|
||||
|
||||
switch (decl->entityInfo->kind) {
|
||||
@ -580,7 +580,7 @@ void indexDeclaration(CXClientData client_data, const CXIdxDeclInfo* decl) {
|
||||
{
|
||||
clang::Cursor decl_cursor = decl->cursor;
|
||||
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;
|
||||
|
||||
@ -610,7 +610,7 @@ void indexDeclaration(CXClientData client_data, const CXIdxDeclInfo* decl) {
|
||||
|
||||
if (decl->isDefinition && IsTypeDefinition(decl->semanticContainer)) {
|
||||
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;
|
||||
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;
|
||||
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;
|
||||
|
||||
@ -653,7 +653,7 @@ void indexDeclaration(CXClientData client_data, const CXIdxDeclInfo* decl) {
|
||||
// be one of those in the entire program.
|
||||
if (IsTypeDefinition(decl->semanticContainer)) {
|
||||
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;
|
||||
|
||||
// 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) {
|
||||
clang::Cursor parent = overridden[i];
|
||||
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->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);
|
||||
|
||||
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;
|
||||
|
||||
@ -766,7 +766,7 @@ void indexDeclaration(CXClientData client_data, const CXIdxDeclInfo* decl) {
|
||||
case CXIdxEntity_CXXClass:
|
||||
{
|
||||
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;
|
||||
|
||||
@ -805,9 +805,9 @@ void indexDeclaration(CXClientData client_data, const CXIdxDeclInfo* decl) {
|
||||
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);
|
||||
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) {
|
||||
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);
|
||||
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) {
|
||||
IndexParam* param = static_cast<IndexParam*>(client_data);
|
||||
ParsingDatabase* db = param->db;
|
||||
IndexedFile* db = param->db;
|
||||
clang::Cursor cursor(ref->cursor);
|
||||
|
||||
switch (ref->referencedEntity->kind) {
|
||||
@ -852,7 +852,7 @@ void indexEntityReference(CXClientData client_data, const CXIdxEntityRefInfo* re
|
||||
case CXIdxEntity_Field:
|
||||
{
|
||||
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*/));
|
||||
break;
|
||||
}
|
||||
@ -883,15 +883,15 @@ void indexEntityReference(CXClientData client_data, const CXIdxEntityRefInfo* re
|
||||
FuncId called_id = db->ToFuncId(ref->referencedEntity->USR);
|
||||
if (IsFunction(ref->container->cursor.kind)) {
|
||||
FuncId caller_id = db->ToFuncId(ref->container->cursor);
|
||||
FuncDef* caller_def = db->Resolve(caller_id);
|
||||
FuncDef* called_def = db->Resolve(called_id);
|
||||
IndexedFuncDef* caller_def = db->Resolve(caller_id);
|
||||
IndexedFuncDef* called_def = db->Resolve(called_id);
|
||||
|
||||
caller_def->callees.push_back(FuncRef(called_id, loc));
|
||||
called_def->callers.push_back(FuncRef(caller_id, loc));
|
||||
called_def->uses.push_back(loc);
|
||||
}
|
||||
else {
|
||||
FuncDef* called_def = db->Resolve(called_id);
|
||||
IndexedFuncDef* called_def = db->Resolve(called_id);
|
||||
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 our_loc = db->file_db.Resolve(ref->loc, true /*is_interesting*/);
|
||||
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());
|
||||
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);
|
||||
}
|
||||
}
|
||||
@ -923,7 +923,7 @@ void indexEntityReference(CXClientData client_data, const CXIdxEntityRefInfo* re
|
||||
case CXIdxEntity_CXXClass:
|
||||
{
|
||||
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
|
||||
@ -964,7 +964,7 @@ void indexEntityReference(CXClientData client_data, const CXIdxEntityRefInfo* re
|
||||
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::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;
|
||||
IndexParam param(&db, &ns);
|
||||
clang_indexTranslationUnit(index_action, ¶m, callbacks, sizeof(callbacks),
|
||||
@ -1089,7 +1089,7 @@ void WriteToFile(const std::string& filename, const std::string& 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
|
||||
|
||||
/*
|
||||
@ -1128,7 +1128,7 @@ int mai2n(int argc, char** argv) {
|
||||
|
||||
// Run test.
|
||||
std::cout << "[START] " << path << std::endl;
|
||||
ParsingDatabase db = Parse(path, {});
|
||||
IndexedFile db = Parse(path, {});
|
||||
std::string actual_output = db.ToString();
|
||||
|
||||
//WriteToFile("output.json", actual_output);
|
||||
|
36
indexer.h
36
indexer.h
@ -80,11 +80,11 @@ Location WithInteresting(bool interesting) {
|
||||
|
||||
END_BITFIELD_TYPE()
|
||||
|
||||
struct FileDb {
|
||||
struct IndexedFileDb {
|
||||
std::unordered_map<std::string, FileId> file_path_to_file_id;
|
||||
std::unordered_map<FileId, std::string> file_id_to_file_path;
|
||||
|
||||
FileDb() {
|
||||
IndexedFileDb() {
|
||||
// Reserve id 0 for unfound.
|
||||
file_path_to_file_id[""] = 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,
|
||||
// or do not emit things we don't have definitions for.
|
||||
|
||||
struct TypeDef {
|
||||
struct IndexedTypeDef {
|
||||
bool is_system_def = false;
|
||||
|
||||
// General metadata.
|
||||
@ -204,7 +204,7 @@ struct TypeDef {
|
||||
// NOTE: Do not insert directly! Use AddUsage instead.
|
||||
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);
|
||||
//std::cout << "Creating type with usr " << usr << std::endl;
|
||||
}
|
||||
@ -226,7 +226,7 @@ struct TypeDef {
|
||||
}
|
||||
};
|
||||
|
||||
struct FuncDef {
|
||||
struct IndexedFuncDef {
|
||||
bool is_system_def = false;
|
||||
|
||||
// General metadata.
|
||||
@ -260,12 +260,12 @@ struct FuncDef {
|
||||
// All usages. For interesting usages, see callees.
|
||||
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);
|
||||
}
|
||||
};
|
||||
|
||||
struct VarDef {
|
||||
struct IndexedVarDef {
|
||||
bool is_system_def = false;
|
||||
|
||||
// General metadata.
|
||||
@ -287,26 +287,26 @@ struct VarDef {
|
||||
// Usages.
|
||||
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);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
struct ParsingDatabase {
|
||||
struct IndexedFile {
|
||||
// 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.
|
||||
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, VarId> usr_to_var_id;
|
||||
|
||||
std::vector<TypeDef> types;
|
||||
std::vector<FuncDef> funcs;
|
||||
std::vector<VarDef> vars;
|
||||
std::vector<IndexedTypeDef> types;
|
||||
std::vector<IndexedFuncDef> funcs;
|
||||
std::vector<IndexedVarDef> vars;
|
||||
|
||||
FileDb file_db;
|
||||
IndexedFileDb file_db;
|
||||
|
||||
ParsingDatabase();
|
||||
IndexedFile();
|
||||
|
||||
TypeId ToTypeId(const std::string& usr);
|
||||
FuncId ToFuncId(const std::string& usr);
|
||||
@ -315,11 +315,11 @@ struct ParsingDatabase {
|
||||
FuncId ToFuncId(const CXCursor& usr);
|
||||
VarId ToVarId(const CXCursor& usr);
|
||||
|
||||
TypeDef* Resolve(TypeId id);
|
||||
FuncDef* Resolve(FuncId id);
|
||||
VarDef* Resolve(VarId id);
|
||||
IndexedTypeDef* Resolve(TypeId id);
|
||||
IndexedFuncDef* Resolve(FuncId id);
|
||||
IndexedVarDef* Resolve(VarId id);
|
||||
|
||||
std::string ToString();
|
||||
};
|
||||
|
||||
ParsingDatabase Parse(std::string filename, std::vector<std::string> args);
|
||||
IndexedFile Parse(std::string filename, std::vector<std::string> args);
|
107
query_db.cc
107
query_db.cc
@ -24,7 +24,7 @@ struct SymbolIdx {
|
||||
};
|
||||
};
|
||||
|
||||
struct File {
|
||||
struct QueryableFile {
|
||||
// Symbols declared in the file.
|
||||
std::vector<SymbolIdx> declared_symbols;
|
||||
// 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
|
||||
// in-memory.
|
||||
struct QueryDatabase {
|
||||
struct QueryableDatabase {
|
||||
// Indicies between lookup vectors are related to symbols, ie, index 5 in
|
||||
// |qualified_names| matches index 5 in |symbols|.
|
||||
std::vector<QueryableEntry> qualified_names;
|
||||
@ -51,7 +51,7 @@ struct QueryDatabase {
|
||||
// |files| is indexed by FileId. Retrieve a FileId from a path using
|
||||
// |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 {
|
||||
Declaration,
|
||||
Definition
|
||||
};
|
||||
std::istream& operator >> (std::istream& is, PreferredSymbolLocation& obj) {
|
||||
std::string content;
|
||||
is >> content;
|
||||
|
||||
if (content == "declaration")
|
||||
obj = PreferredSymbolLocation::Declaration;
|
||||
else if (content == "definition")
|
||||
obj = PreferredSymbolLocation::Definition;
|
||||
else
|
||||
is.setstate(std::ios::failbit);
|
||||
bool ParsePreferredSymbolLocation(const std::string& content, PreferredSymbolLocation* obj) {
|
||||
#define PARSE_AS(name, string) \
|
||||
if (content == #string) { \
|
||||
*obj = name; \
|
||||
return true; \
|
||||
}
|
||||
|
||||
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
|
||||
@ -127,34 +145,24 @@ enum class Command {
|
||||
Search
|
||||
};
|
||||
|
||||
//std::ostream& operator<<(std::ostream& os, const Command& obj) {
|
||||
// write obj to stream
|
||||
// return os;
|
||||
//}
|
||||
std::istream& operator >> (std::istream& is, Command& obj) {
|
||||
std::string content;
|
||||
is >> content;
|
||||
bool ParseCommand(const std::string& content, Command* obj) {
|
||||
#define PARSE_AS(name, string) \
|
||||
if (content == #string) { \
|
||||
*obj = name; \
|
||||
return true; \
|
||||
}
|
||||
|
||||
if (content == "callees")
|
||||
obj = Command::Callees;
|
||||
else if (content == "callers")
|
||||
obj = Command::Callers;
|
||||
else if (content == "find-all-usages")
|
||||
obj = Command::FindAllUsages;
|
||||
else if (content == "find-interesting-usages")
|
||||
obj = Command::FindInterestingUsages;
|
||||
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);
|
||||
PARSE_AS(Command::Callees, "callees");
|
||||
PARSE_AS(Command::Callers, "callers");
|
||||
PARSE_AS(Command::FindAllUsages, "find-all-usages");
|
||||
PARSE_AS(Command::FindInterestingUsages, "find-interesting-usages");
|
||||
PARSE_AS(Command::GotoReferenced, "goto-referenced");
|
||||
PARSE_AS(Command::Hierarchy, "hierarchy");
|
||||
PARSE_AS(Command::Outline, "outline");
|
||||
PARSE_AS(Command::Search, "search");
|
||||
|
||||
return is;
|
||||
return false;
|
||||
#undef PARSE_AS
|
||||
}
|
||||
|
||||
// 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();
|
||||
}
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
int main2(int argc, char** argv) {
|
||||
std::unordered_map<std::string, std::string> options = ParseOptions(argc, argv);
|
||||
|
||||
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<ParsingDatabase> dbs;
|
||||
std::vector<IndexedFile> dbs;
|
||||
for (const CompilationEntry& entry : entries) {
|
||||
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);
|
||||
std::cout << db.ToString() << std::endl << std::endl;
|
||||
@ -296,6 +304,13 @@ int main(int argc, char** argv) {
|
||||
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.";
|
||||
exit(1);
|
||||
|
7
utils.cc
7
utils.cc
@ -1,5 +1,6 @@
|
||||
#include "utils.h"
|
||||
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
|
||||
#include "tinydir.h"
|
||||
@ -66,3 +67,9 @@ void ParseTestExpectation(std::string filename, std::string* expected_output) {
|
||||
in_output = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Fail(const std::string& message) {
|
||||
std::cerr << "Fatal error: " << message << std::endl;
|
||||
std::exit(1);
|
||||
}
|
4
utils.h
4
utils.h
@ -5,4 +5,6 @@
|
||||
|
||||
std::vector<std::string> GetFilesInFolder(std::string folder);
|
||||
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);
|
Loading…
Reference in New Issue
Block a user