Remove some duplicated code in workspace / document symbol creation

This commit is contained in:
Jacob Dufault 2017-04-08 19:48:50 -07:00
parent 96d5815641
commit 3cd9ae4d16
3 changed files with 102 additions and 106 deletions

View File

@ -43,17 +43,27 @@ QueryableFile* FindFile(QueryableDatabase* db, const std::string& filename) {
return nullptr; return nullptr;
} }
QueryableFile* GetQueryable(QueryableDatabase* db, const QueryFileId& id) {
return &db->files[id.id];
}
QueryableTypeDef* GetQueryable(QueryableDatabase* db, const QueryTypeId& id) {
return &db->types[id.id];
}
QueryableFuncDef* GetQueryable(QueryableDatabase* db, const QueryFuncId& id) {
return &db->funcs[id.id];
}
QueryableVarDef* GetQueryable(QueryableDatabase* db, const QueryVarId& id) {
return &db->vars[id.id];
}
optional<QueryableLocation> GetDefinitionSpellingOfSymbol(QueryableDatabase* db, const QueryTypeId& id) { optional<QueryableLocation> GetDefinitionSpellingOfSymbol(QueryableDatabase* db, const QueryTypeId& id) {
QueryableTypeDef* def = &db->types[id.id]; return GetQueryable(db, id)->def.definition_spelling;
return def->def.definition_spelling;
} }
optional<QueryableLocation> GetDefinitionSpellingOfSymbol(QueryableDatabase* db, const QueryFuncId& id) { optional<QueryableLocation> GetDefinitionSpellingOfSymbol(QueryableDatabase* db, const QueryFuncId& id) {
QueryableFuncDef* def = &db->funcs[id.id]; return GetQueryable(db, id)->def.definition_spelling;
return def->def.definition_spelling;
} }
optional<QueryableLocation> GetDefinitionSpellingOfSymbol(QueryableDatabase* db, const QueryVarId& id) { optional<QueryableLocation> GetDefinitionSpellingOfSymbol(QueryableDatabase* db, const QueryVarId& id) {
QueryableVarDef* def = &db->vars[id.id]; return GetQueryable(db, id)->def.definition_spelling;
return def->def.definition_spelling;
} }
optional<QueryableLocation> GetDefinitionSpellingOfSymbol(QueryableDatabase* db, const SymbolIdx& symbol) { optional<QueryableLocation> GetDefinitionSpellingOfSymbol(QueryableDatabase* db, const SymbolIdx& symbol) {
switch (symbol.kind) { switch (symbol.kind) {
@ -89,6 +99,62 @@ lsLocation GetLsLocation(QueryableDatabase* db, const QueryableLocation& locatio
GetLsRange(location.range)); GetLsRange(location.range));
} }
// Returns a symbol. The symbol will have the location pointing to the
// definition.
lsSymbolInformation GetSymbolInfo(QueryableDatabase* db, SymbolIdx symbol) {
lsSymbolInformation info;
switch (symbol.kind) {
case SymbolKind::File: {
QueryableFile* def = symbol.ResolveFile(db);
info.name = def->def.usr;
info.kind = lsSymbolKind::File;
info.location.uri.SetPath(def->def.usr);
break;
}
case SymbolKind::Type: {
QueryableTypeDef* def = symbol.ResolveType(db);
info.name = def->def.qualified_name;
info.kind = lsSymbolKind::Class;
if (def->def.definition_extent.has_value())
info.location = GetLsLocation(db, def->def.definition_extent.value());
break;
}
case SymbolKind::Func: {
QueryableFuncDef* def = symbol.ResolveFunc(db);
info.name = def->def.qualified_name;
if (def->def.declaring_type.has_value()) {
info.kind = lsSymbolKind::Method;
info.containerName = db->types[def->def.declaring_type->id].def.qualified_name;
}
else {
info.kind = lsSymbolKind::Function;
}
if (def->def.definition_extent.has_value()) {
info.location = GetLsLocation(db, def->def.definition_extent.value());
}
break;
}
case SymbolKind::Var: {
QueryableVarDef* def = symbol.ResolveVar(db);
info.name = def->def.qualified_name;
info.kind = lsSymbolKind::Variable;
if (def->def.definition_extent.has_value()) {
info.location = GetLsLocation(db, def->def.definition_extent.value());
}
break;
}
case SymbolKind::Invalid: {
assert(false && "unexpected");
break;
}
};
return info;
}
void AddCodeLens( void AddCodeLens(
QueryableDatabase* db, QueryableDatabase* db,
@ -543,43 +609,8 @@ void QueryDbMainLoop(
std::cerr << "File outline size is " << file->def.outline.size() << std::endl; std::cerr << "File outline size is " << file->def.outline.size() << std::endl;
for (SymbolRef ref : file->def.outline) { for (SymbolRef ref : file->def.outline) {
SymbolIdx symbol = ref.idx; lsSymbolInformation info = GetSymbolInfo(db, ref.idx);
lsSymbolInformation info;
info.location = GetLsLocation(db, ref.loc); info.location = GetLsLocation(db, ref.loc);
switch (symbol.kind) {
case SymbolKind::Type: {
QueryableTypeDef& def = db->types[symbol.idx];
info.name = def.def.qualified_name;
info.kind = lsSymbolKind::Class;
break;
}
case SymbolKind::Func: {
QueryableFuncDef& def = db->funcs[symbol.idx];
info.name = def.def.qualified_name;
if (def.def.declaring_type.has_value()) {
info.kind = lsSymbolKind::Method;
info.containerName = db->types[def.def.declaring_type->id].def.qualified_name;
}
else {
info.kind = lsSymbolKind::Function;
}
break;
}
case SymbolKind::Var: {
QueryableVarDef& def = db->vars[symbol.idx];
info.name = def.def.qualified_name;
info.kind = lsSymbolKind::Variable;
break;
}
case SymbolKind::File:
case SymbolKind::Invalid: {
assert(false && "unexpected");
break;
}
};
response.result.push_back(info); response.result.push_back(info);
} }
@ -670,69 +701,8 @@ void QueryDbMainLoop(
break; break;
} }
const std::string& name = db->qualified_names[i]; if (db->qualified_names[i].find(query) != std::string::npos)
// std::cerr << "- Considering " << name << std::endl; response.result.push_back(GetSymbolInfo(db, db->symbols[i]));
if (name.find(query) != std::string::npos) {
lsSymbolInformation info;
info.name = name;
SymbolIdx symbol = db->symbols[i];
// TODO: dedup this code w/ above (ie, add ctor to convert symbol to
// SymbolInformation)
switch (symbol.kind) {
case SymbolKind::File: {
QueryableFile& def = db->files[symbol.idx];
info.name = def.def.usr;
info.kind = lsSymbolKind::File;
info.location.uri.SetPath(def.def.usr);
break;
}
// TODO: file
case SymbolKind::Type: {
QueryableTypeDef& def = db->types[symbol.idx];
info.name = def.def.qualified_name;
info.kind = lsSymbolKind::Class;
if (def.def.definition_extent.has_value())
info.location = GetLsLocation(db, def.def.definition_extent.value());
break;
}
case SymbolKind::Func: {
QueryableFuncDef& def = db->funcs[symbol.idx];
info.name = def.def.qualified_name;
if (def.def.declaring_type.has_value()) {
info.kind = lsSymbolKind::Method;
info.containerName = db->types[def.def.declaring_type->id].def.qualified_name;
}
else {
info.kind = lsSymbolKind::Function;
}
if (def.def.definition_extent.has_value()) {
info.location = GetLsLocation(db, def.def.definition_extent.value());
}
break;
}
case SymbolKind::Var: {
QueryableVarDef& def = db->vars[symbol.idx];
info.name = def.def.qualified_name;
info.kind = lsSymbolKind::Variable;
if (def.def.definition_extent.has_value()) {
info.location = GetLsLocation(db, def.def.definition_extent.value());
}
break;
}
case SymbolKind::Invalid: {
assert(false && "unexpected");
break;
}
};
response.result.push_back(info);
}
} }
SendOutMessageToClient(language_client, response); SendOutMessageToClient(language_client, response);

View File

@ -171,7 +171,22 @@ void RemoveRange(std::vector<T>* dest, const std::vector<T>& to_remove) {
QueryableFile* SymbolIdx::ResolveFile(QueryableDatabase* db) const {
assert(kind == SymbolKind::File);
return &db->files[idx];
}
QueryableTypeDef* SymbolIdx::ResolveType(QueryableDatabase* db) const {
assert(kind == SymbolKind::Type);
return &db->types[idx];
}
QueryableFuncDef* SymbolIdx::ResolveFunc(QueryableDatabase* db) const {
assert(kind == SymbolKind::Func);
return &db->funcs[idx];
}
QueryableVarDef* SymbolIdx::ResolveVar(QueryableDatabase* db) const {
assert(kind == SymbolKind::Var);
return &db->vars[idx];
}

View File

@ -56,6 +56,12 @@ struct QueryableLocation {
} }
}; };
class QueryableFile;
class QueryableTypeDef;
class QueryableFuncDef;
class QueryableVarDef;
class QueryableDatabase;
enum class SymbolKind { Invalid, File, Type, Func, Var }; enum class SymbolKind { Invalid, File, Type, Func, Var };
struct SymbolIdx { struct SymbolIdx {
SymbolKind kind; SymbolKind kind;
@ -71,6 +77,11 @@ struct SymbolIdx {
bool operator<(const SymbolIdx& that) const { bool operator<(const SymbolIdx& that) const {
return kind < that.kind || idx < that.idx; return kind < that.kind || idx < that.idx;
} }
QueryableFile* ResolveFile(QueryableDatabase* db) const;
QueryableTypeDef* ResolveType(QueryableDatabase* db) const;
QueryableFuncDef* ResolveFunc(QueryableDatabase* db) const;
QueryableVarDef* ResolveVar(QueryableDatabase* db) const;
}; };
struct SymbolRef { struct SymbolRef {