QueryLocation -> Reference

This commit is contained in:
Fangrui Song 2018-02-08 21:11:35 -08:00
parent 2d255da07b
commit 82b429bfbc
12 changed files with 126 additions and 109 deletions

View File

@ -452,7 +452,7 @@ struct IndexVar {
std::vector<Range> declarations; std::vector<Range> declarations;
// Usages. // Usages.
std::vector<Range> uses; std::vector<Reference> uses;
IndexVar() {} // For serialization. IndexVar() {} // For serialization.
IndexVar(IndexVarId id, Usr usr) : usr(usr), id(id) { IndexVar(IndexVarId id, Usr usr) : usr(usr), id(id) {

View File

@ -148,8 +148,8 @@ optional<lsTextEdit> BuildAutoImplementForFunction(QueryDatabase* db,
QueryFileId impl_file_id, QueryFileId impl_file_id,
QueryFunc& func) { QueryFunc& func) {
assert(func.def); assert(func.def);
for (const QueryLocation& decl : func.declarations) { for (const Reference& decl : func.declarations) {
if (decl.FileId() != decl_file_id) if (GetFileId(db, decl) != decl_file_id)
continue; continue;
optional<lsRange> ls_decl = GetLsRange(working_file, decl.range); optional<lsRange> ls_decl = GetLsRange(working_file, decl.range);
@ -202,8 +202,8 @@ optional<lsTextEdit> BuildAutoImplementForFunction(QueryDatabase* db,
if (!sym_func.def || !sym_func.def->definition_extent) if (!sym_func.def || !sym_func.def->definition_extent)
break; break;
for (QueryLocation& func_decl : sym_func.declarations) { for (const Reference& func_decl : sym_func.declarations) {
if (func_decl.FileId() == decl_file_id) { if (GetFileId(db, func_decl) == decl_file_id) {
int dist = func_decl.range.start.line - decl.range.start.line; int dist = func_decl.range.start.line - decl.range.start.line;
if (abs(dist) < abs(best_dist)) { if (abs(dist) < abs(best_dist)) {
optional<lsLocation> def_loc = GetLsLocation( optional<lsLocation> def_loc = GetLsLocation(

View File

@ -76,6 +76,7 @@ struct CommonCodeLensParams {
WorkingFile* working_file; WorkingFile* working_file;
}; };
// FIXME Reference
void AddCodeLens(const char* singular, void AddCodeLens(const char* singular,
const char* plural, const char* plural,
CommonCodeLensParams* common, CommonCodeLensParams* common,
@ -270,8 +271,13 @@ struct TextDocumentCodeLensHandler
if (var.def->is_macro()) if (var.def->is_macro())
force_display = false; force_display = false;
// FIXME Reference
std::vector<QueryLocation> uses;
for (auto x: var.uses)
uses.push_back(QueryLocation{x.range, GetFileId(db, x), x.role});
AddCodeLens("ref", "refs", &common, ref.loc.OffsetStartColumn(0), AddCodeLens("ref", "refs", &common, ref.loc.OffsetStartColumn(0),
var.uses, var.def->definition_spelling, force_display); uses, var.def->definition_spelling, force_display);
break; break;
} }
case SymbolKind::File: case SymbolKind::File:

View File

@ -23,20 +23,18 @@ struct Out_TextDocumentDefinition
}; };
MAKE_REFLECT_STRUCT(Out_TextDocumentDefinition, jsonrpc, id, result); MAKE_REFLECT_STRUCT(Out_TextDocumentDefinition, jsonrpc, id, result);
std::vector<QueryLocation> GetGotoDefinitionTargets(QueryDatabase* db, std::vector<Reference> GetGotoDefinitionTargets(QueryDatabase* db,
const SymbolIdx& symbol) { const SymbolIdx& symbol) {
switch (symbol.kind) { switch (symbol.kind) {
// Returns GetDeclarationsOfSymbolForGotoDefinition and // Returns GetDeclarationsOfSymbolForGotoDefinition and
// variable type definition. // variable type definition.
case SymbolKind::Var: { case SymbolKind::Var: {
std::vector<QueryLocation> ret = std::vector<Reference> ret =
GetDeclarationsOfSymbolForGotoDefinition(db, symbol); GetDeclarationsOfSymbolForGotoDefinition(db, symbol);
QueryVar& var = db->vars[symbol.idx]; QueryVar& var = db->vars[symbol.idx];
// FIXME WithGen
if (var.def && var.def->variable_type) { if (var.def && var.def->variable_type) {
std::vector<QueryLocation> types = std::vector<Reference> types = GetDeclarationsOfSymbolForGotoDefinition(
GetDeclarationsOfSymbolForGotoDefinition( db, SymbolIdx(SymbolKind::Type, var.def->variable_type->id));
db, SymbolIdx(SymbolKind::Type, var.def->variable_type->id));
ret.insert(ret.end(), types.begin(), types.end()); ret.insert(ret.end(), types.begin(), types.end());
} }
return ret; return ret;
@ -94,9 +92,8 @@ struct TextDocumentDefinitionHandler
def_loc->range.Contains(target_line, target_column))) { def_loc->range.Contains(target_line, target_column))) {
// Goto declaration. // Goto declaration.
std::vector<QueryLocation> targets = std::vector<Reference> targets = GetGotoDefinitionTargets(db, ref.idx);
GetGotoDefinitionTargets(db, ref.idx); for (Reference target : targets) {
for (QueryLocation target : targets) {
optional<lsLocation> ls_target = optional<lsLocation> ls_target =
GetLsLocation(db, working_files, target); GetLsLocation(db, working_files, target);
if (ls_target) if (ls_target)

View File

@ -38,10 +38,10 @@ struct TextDocumentDocumentHighlightHandler
for (const SymbolRef& ref : for (const SymbolRef& ref :
FindSymbolsAtLocation(working_file, file, request->params.position)) { FindSymbolsAtLocation(working_file, file, request->params.position)) {
// Found symbol. Return references to highlight. // Found symbol. Return references to highlight.
std::vector<QueryLocation> uses = GetUsesOfSymbol(db, ref.idx, true); std::vector<Reference> uses = GetUsesOfSymbol(db, ref.idx, true);
out.result.reserve(uses.size()); out.result.reserve(uses.size());
for (const QueryLocation& use : uses) { for (const Reference& use : uses) {
if (use.FileId() != file_id) if (GetFileId(db, use) != file_id)
continue; continue;
optional<lsLocation> ls_location = optional<lsLocation> ls_location =

View File

@ -54,10 +54,10 @@ struct TextDocumentReferencesHandler
for (const SymbolRef& ref : for (const SymbolRef& ref :
FindSymbolsAtLocation(working_file, file, request->params.position)) { FindSymbolsAtLocation(working_file, file, request->params.position)) {
// Found symbol. Return references. // Found symbol. Return references.
std::vector<QueryLocation> uses = GetUsesOfSymbol( std::vector<Reference> uses = GetUsesOfSymbol(
db, ref.idx, request->params.context.includeDeclaration); db, ref.idx, request->params.context.includeDeclaration);
out.result.reserve(uses.size()); out.result.reserve(uses.size());
for (const QueryLocation& use : uses) { for (const Reference& use : uses) {
optional<lsLocation> ls_location = optional<lsLocation> ls_location =
GetLsLocation(db, working_files, use); GetLsLocation(db, working_files, use);
if (ls_location) if (ls_location)

View File

@ -6,17 +6,17 @@ namespace {
lsWorkspaceEdit BuildWorkspaceEdit(QueryDatabase* db, lsWorkspaceEdit BuildWorkspaceEdit(QueryDatabase* db,
WorkingFiles* working_files, WorkingFiles* working_files,
const std::vector<QueryLocation>& locations, const std::vector<Reference>& refs,
const std::string& new_text) { const std::string& new_text) {
std::unordered_map<QueryFileId, lsTextDocumentEdit> path_to_edit; std::unordered_map<QueryFileId, lsTextDocumentEdit> path_to_edit;
for (auto& location : locations) { for (auto& ref : refs) {
optional<lsLocation> ls_location = optional<lsLocation> ls_location =
GetLsLocation(db, working_files, location); GetLsLocation(db, working_files, ref);
if (!ls_location) if (!ls_location)
continue; continue;
QueryFileId file_id = location.FileId(); QueryFileId file_id = GetFileId(db, ref);
if (path_to_edit.find(file_id) == path_to_edit.end()) { if (path_to_edit.find(file_id) == path_to_edit.end()) {
path_to_edit[file_id] = lsTextDocumentEdit(); path_to_edit[file_id] = lsTextDocumentEdit();
@ -98,9 +98,9 @@ struct TextDocumentRenameHandler : BaseMessageHandler<Ipc_TextDocumentRename> {
for (const SymbolRef& ref : for (const SymbolRef& ref :
FindSymbolsAtLocation(working_file, file, request->params.position)) { FindSymbolsAtLocation(working_file, file, request->params.position)) {
// Found symbol. Return references to rename. // Found symbol. Return references to rename.
std::vector<QueryLocation> uses = GetUsesOfSymbol(db, ref.idx, true); out.result = BuildWorkspaceEdit(db, working_files,
out.result = GetUsesOfSymbol(db, ref.idx, true),
BuildWorkspaceEdit(db, working_files, uses, request->params.newName); request->params.newName);
break; break;
} }

View File

@ -23,15 +23,17 @@ bool InsertSymbolIntoResult(QueryDatabase* db,
return false; return false;
optional<QueryLocation> location = GetDefinitionExtentOfSymbol(db, symbol); optional<QueryLocation> location = GetDefinitionExtentOfSymbol(db, symbol);
if (!location) { Reference loc;
if (location)
loc = *location;
else {
auto decls = GetDeclarationsOfSymbolForGotoDefinition(db, symbol); auto decls = GetDeclarationsOfSymbolForGotoDefinition(db, symbol);
if (decls.empty()) if (decls.empty())
return false; return false;
location = decls[0]; loc = decls[0];
} }
optional<lsLocation> ls_location = optional<lsLocation> ls_location = GetLsLocation(db, working_files, loc);
GetLsLocation(db, working_files, *location);
if (!ls_location) if (!ls_location)
return false; return false;
info->location = *ls_location; info->location = *ls_location;

View File

@ -293,8 +293,8 @@ QueryFile::DefUpdate BuildFileDefUpdate(const IdMap& id_map, const IndexFile& in
add_all_symbols(id_map.ToSymbol(var.id), SymbolRole::Declaration, decl); add_all_symbols(id_map.ToSymbol(var.id), SymbolRole::Declaration, decl);
add_outline(id_map.ToSymbol(var.id), decl); add_outline(id_map.ToSymbol(var.id), decl);
} }
for (const Range& use : var.uses) for (auto& use : var.uses)
add_all_symbols(id_map.ToSymbol(var.id), SymbolRole::Reference, use); add_all_symbols(id_map.ToSymbol(var.id), use.role, use.range);
} }
std::sort(def.outline.begin(), def.outline.end(), std::sort(def.outline.begin(), def.outline.end(),
@ -453,12 +453,12 @@ QueryVarId IdMap::ToQuery(IndexVarId id) const {
QueryFuncRef IdMap::ToQuery(IndexFuncRef ref) const { QueryFuncRef IdMap::ToQuery(IndexFuncRef ref) const {
return QueryFuncRef{ToQuery(ref.id), ToQuery(ref.loc, ref.role)}; return QueryFuncRef{ToQuery(ref.id), ToQuery(ref.loc, ref.role)};
} }
QueryLocation IdMap::ToQuery(IndexFunc::Declaration decl) const { Reference IdMap::ToQuery(IndexFunc::Declaration decl) const {
// TODO: expose more than just QueryLocation. // TODO: expose more than just QueryLocation.
return QueryLocation{decl.spelling, primary_file, SymbolRole::Declaration}; return Reference{decl.spelling, Id<void>(primary_file), SymbolKind::File, SymbolRole::Declaration};
} }
std::vector<QueryLocation> IdMap::ToQuery(const std::vector<Range>& a) const { std::vector<Reference> IdMap::ToQuery(const std::vector<Range>& a) const {
std::vector<QueryLocation> ret; std::vector<Reference> ret;
ret.reserve(a.size()); ret.reserve(a.size());
for (auto& x : a) for (auto& x : a)
ret.push_back(ToQuery(x, SymbolRole::Reference)); ret.push_back(ToQuery(x, SymbolRole::Reference));
@ -645,7 +645,7 @@ IndexUpdate::IndexUpdate(const IdMap& previous_id_map,
} }
PROCESS_UPDATE_DIFF(QueryFuncId, funcs_declarations, declarations, PROCESS_UPDATE_DIFF(QueryFuncId, funcs_declarations, declarations,
QueryLocation); Reference);
PROCESS_UPDATE_DIFF(QueryFuncId, funcs_derived, derived, QueryFuncId); PROCESS_UPDATE_DIFF(QueryFuncId, funcs_derived, derived, QueryFuncId);
PROCESS_UPDATE_DIFF(QueryFuncId, funcs_callers, callers, QueryFuncRef); PROCESS_UPDATE_DIFF(QueryFuncId, funcs_callers, callers, QueryFuncRef);
}); });
@ -697,8 +697,8 @@ IndexUpdate::IndexUpdate(const IdMap& previous_id_map,
current->usr, std::move(*current_remapped_def))); current->usr, std::move(*current_remapped_def)));
PROCESS_UPDATE_DIFF(QueryVarId, vars_declarations, declarations, PROCESS_UPDATE_DIFF(QueryVarId, vars_declarations, declarations,
QueryLocation); Reference);
PROCESS_UPDATE_DIFF(QueryVarId, vars_uses, uses, QueryLocation); PROCESS_UPDATE_DIFF(QueryVarId, vars_uses, uses, Reference);
}); });
#undef PROCESS_UPDATE_DIFF #undef PROCESS_UPDATE_DIFF
@ -1031,7 +1031,7 @@ TEST_SUITE("query") {
->callers.push_back(IndexFuncRef{Range(Position(2, 0)), IndexFuncId(0), ->callers.push_back(IndexFuncRef{Range(Position(2, 0)), IndexFuncId(0),
SymbolRole::None}); SymbolRole::None});
previous.Resolve(previous.ToVarId(HashUsr("usr3"))) previous.Resolve(previous.ToVarId(HashUsr("usr3")))
->uses.push_back(Range(Position(3, 0))); ->uses.push_back(Reference{Range(Position(3, 0))});
IndexUpdate update = GetDelta(previous, current); IndexUpdate update = GetDelta(previous, current);

View File

@ -34,6 +34,10 @@ struct QueryLocation {
bool HasValue() const { return range.HasValue(); } bool HasValue() const { return range.HasValue(); }
QueryFileId FileId() const { return path; } QueryFileId FileId() const { return path; }
operator Reference() const {
return Reference{range, Id<void>(path), SymbolKind::File, role};
}
std::tuple<Range, QueryFileId, SymbolRole> ToTuple() const { std::tuple<Range, QueryFileId, SymbolRole> ToTuple() const {
return std::make_tuple(range, path, role); return std::make_tuple(range, path, role);
} }
@ -246,14 +250,14 @@ struct QueryFunc {
QueryFuncRef, QueryFuncRef,
QueryLocation>; QueryLocation>;
using DefUpdate = WithUsr<Def>; using DefUpdate = WithUsr<Def>;
using DeclarationsUpdate = MergeableUpdate<QueryFuncId, QueryLocation>; using DeclarationsUpdate = MergeableUpdate<QueryFuncId, Reference>;
using DerivedUpdate = MergeableUpdate<QueryFuncId, QueryFuncId>; using DerivedUpdate = MergeableUpdate<QueryFuncId, QueryFuncId>;
using CallersUpdate = MergeableUpdate<QueryFuncId, QueryFuncRef>; using CallersUpdate = MergeableUpdate<QueryFuncId, QueryFuncRef>;
Usr usr; Usr usr;
Maybe<Id<void>> symbol_idx; Maybe<Id<void>> symbol_idx;
optional<Def> def; optional<Def> def;
std::vector<QueryLocation> declarations; std::vector<Reference> declarations;
std::vector<QueryFuncId> derived; std::vector<QueryFuncId> derived;
std::vector<QueryFuncRef> callers; std::vector<QueryFuncRef> callers;
@ -267,14 +271,14 @@ struct QueryVar {
QueryVarId, QueryVarId,
QueryLocation>; QueryLocation>;
using DefUpdate = WithUsr<Def>; using DefUpdate = WithUsr<Def>;
using DeclarationsUpdate = MergeableUpdate<QueryVarId, QueryLocation>; using DeclarationsUpdate = MergeableUpdate<QueryVarId, Reference>;
using UsesUpdate = MergeableUpdate<QueryVarId, QueryLocation>; using UsesUpdate = MergeableUpdate<QueryVarId, Reference>;
Usr usr; Usr usr;
Maybe<Id<void>> symbol_idx; Maybe<Id<void>> symbol_idx;
optional<Def> def; optional<Def> def;
std::vector<QueryLocation> declarations; std::vector<Reference> declarations;
std::vector<QueryLocation> uses; std::vector<Reference> uses;
explicit QueryVar(const Usr& usr) : usr(usr) {} explicit QueryVar(const Usr& usr) : usr(usr) {}
}; };
@ -400,9 +404,9 @@ template <> struct IndexToQuery<IndexFuncId> { using type = QueryFuncId; };
template <> struct IndexToQuery<IndexTypeId> { using type = QueryTypeId; }; template <> struct IndexToQuery<IndexTypeId> { using type = QueryTypeId; };
template <> struct IndexToQuery<IndexVarId> { using type = QueryVarId; }; template <> struct IndexToQuery<IndexVarId> { using type = QueryVarId; };
template <> struct IndexToQuery<IndexFuncRef> { using type = QueryFuncRef; }; template <> struct IndexToQuery<IndexFuncRef> { using type = QueryFuncRef; };
template <> struct IndexToQuery<Range> { using type = QueryLocation; }; template <> struct IndexToQuery<Range> { using type = Reference; };
template <> struct IndexToQuery<Reference> { using type = Reference; }; template <> struct IndexToQuery<Reference> { using type = Reference; };
template <> struct IndexToQuery<IndexFunc::Declaration> { using type = QueryLocation; }; template <> struct IndexToQuery<IndexFunc::Declaration> { using type = Reference; };
template <typename I> struct IndexToQuery<optional<I>> { template <typename I> struct IndexToQuery<optional<I>> {
using type = optional<typename IndexToQuery<I>::type>; using type = optional<typename IndexToQuery<I>::type>;
}; };
@ -425,7 +429,7 @@ struct IdMap {
QueryFuncId ToQuery(IndexFuncId id) const; QueryFuncId ToQuery(IndexFuncId id) const;
QueryVarId ToQuery(IndexVarId id) const; QueryVarId ToQuery(IndexVarId id) const;
QueryFuncRef ToQuery(IndexFuncRef ref) const; QueryFuncRef ToQuery(IndexFuncRef ref) const;
QueryLocation ToQuery(IndexFunc::Declaration decl) const; Reference ToQuery(IndexFunc::Declaration decl) const;
template <typename I> template <typename I>
Maybe<typename IndexToQuery<I>::type> ToQuery(Maybe<I> id) const { Maybe<typename IndexToQuery<I>::type> ToQuery(Maybe<I> id) const {
if (!id) if (!id)
@ -440,7 +444,7 @@ struct IdMap {
ret.push_back(ToQuery(x)); ret.push_back(ToQuery(x));
return ret; return ret;
} }
std::vector<QueryLocation> ToQuery(const std::vector<Range>& a) const; std::vector<Reference> ToQuery(const std::vector<Range>& a) const;
// clang-format on // clang-format on
SymbolIdx ToSymbol(IndexTypeId id) const; SymbolIdx ToSymbol(IndexTypeId id) const;

View File

@ -28,36 +28,36 @@ std::vector<QueryLocation> ToQueryLocationHelper(
return locs; return locs;
} }
} // namespace
QueryFileId GetFileId(QueryDatabase* db, Reference ref) { QueryFileId GetFileId(QueryDatabase* db, Reference ref) {
switch (ref.lex_parent_kind) { switch (ref.lex_parent_kind) {
case SymbolKind::Invalid: case SymbolKind::Invalid:
break; break;
case SymbolKind::File: case SymbolKind::File:
return QueryFileId(ref.lex_parent_id); return QueryFileId(ref.lex_parent_id);
case SymbolKind::Func: { case SymbolKind::Func: {
QueryFunc& file = db->funcs[ref.lex_parent_id.id]; QueryFunc& file = db->funcs[ref.lex_parent_id.id];
if (file.def) if (file.def)
return file.def->file; return file.def->file;
break; break;
} }
case SymbolKind::Type: { case SymbolKind::Type: {
QueryType& type = db->types[ref.lex_parent_id.id]; QueryType& type = db->types[ref.lex_parent_id.id];
if (type.def) if (type.def)
return type.def->file; return type.def->file;
break; break;
} }
case SymbolKind::Var: { case SymbolKind::Var: {
QueryVar& var = db->vars[ref.lex_parent_id.id]; QueryVar& var = db->vars[ref.lex_parent_id.id];
if (var.def) if (var.def)
return var.def->file; return var.def->file;
break; break;
} }
} }
return QueryFileId(); return QueryFileId();
} }
} // namespace
optional<QueryLocation> GetDefinitionSpellingOfSymbol(QueryDatabase* db, optional<QueryLocation> GetDefinitionSpellingOfSymbol(QueryDatabase* db,
const QueryTypeId& id) { const QueryTypeId& id) {
QueryType& type = db->types[id.id]; QueryType& type = db->types[id.id];
@ -157,7 +157,7 @@ optional<QueryFileId> GetDeclarationFileForSymbol(QueryDatabase* db,
case SymbolKind::Func: { case SymbolKind::Func: {
QueryFunc& func = db->funcs[symbol.idx]; QueryFunc& func = db->funcs[symbol.idx];
if (!func.declarations.empty()) if (!func.declarations.empty())
return func.declarations[0].FileId(); return GetFileId(db, func.declarations[0]);
if (func.def && func.def->definition_spelling) if (func.def && func.def->definition_spelling)
return func.def->definition_spelling->FileId(); return func.def->definition_spelling->FileId();
break; break;
@ -183,6 +183,16 @@ QueryLocation ToQueryLocation(QueryDatabase* db, Reference ref) {
return QueryLocation{ref.range, GetFileId(db, ref), ref.role}; return QueryLocation{ref.range, GetFileId(db, ref), ref.role};
} }
std::vector<Reference> ToReference(QueryDatabase* db,
const std::vector<QueryFuncRef>& refs) {
std::vector<Reference> ret;
ret.reserve(refs.size());
for (auto& ref : refs)
ret.push_back(Reference{ref.loc.range, Id<void>(ref.id_), SymbolKind::Func,
ref.loc.role});
return ret;
}
std::vector<QueryLocation> ToQueryLocation( std::vector<QueryLocation> ToQueryLocation(
QueryDatabase* db, QueryDatabase* db,
const std::vector<QueryFuncRef>& refs) { const std::vector<QueryFuncRef>& refs) {
@ -208,16 +218,13 @@ std::vector<QueryLocation> ToQueryLocation(
return ToQueryLocationHelper(db, ids); return ToQueryLocationHelper(db, ids);
} }
std::vector<QueryLocation> GetUsesOfSymbol(QueryDatabase* db, std::vector<Reference> GetUsesOfSymbol(QueryDatabase* db,
const SymbolIdx& symbol, const SymbolIdx& symbol,
bool include_decl) { bool include_decl) {
switch (symbol.kind) { switch (symbol.kind) {
case SymbolKind::Type: { case SymbolKind::Type: {
QueryType& type = db->types[symbol.idx]; QueryType& type = db->types[symbol.idx];
std::vector<QueryLocation> ret; std::vector<Reference> ret = type.uses;
ret.reserve(type.uses.size());
for (auto& x : type.uses)
ret.push_back(ToQueryLocation(db, x));
if (include_decl && type.def && type.def->definition_spelling) if (include_decl && type.def && type.def->definition_spelling)
ret.push_back(*type.def->definition_spelling); ret.push_back(*type.def->definition_spelling);
return ret; return ret;
@ -225,17 +232,17 @@ std::vector<QueryLocation> GetUsesOfSymbol(QueryDatabase* db,
case SymbolKind::Func: { case SymbolKind::Func: {
// TODO: the vector allocation could be avoided. // TODO: the vector allocation could be avoided.
QueryFunc& func = db->funcs[symbol.idx]; QueryFunc& func = db->funcs[symbol.idx];
std::vector<QueryLocation> result = ToQueryLocation(db, func.callers); std::vector<Reference> ret = ToReference(db, func.callers);
if (include_decl) { if (include_decl) {
AddRange(&result, func.declarations); AddRange(&ret, func.declarations);
if (func.def && func.def->definition_spelling) if (func.def && func.def->definition_spelling)
result.push_back(*func.def->definition_spelling); ret.push_back(*func.def->definition_spelling);
} }
return result; return ret;
} }
case SymbolKind::Var: { case SymbolKind::Var: {
QueryVar& var = db->vars[symbol.idx]; QueryVar& var = db->vars[symbol.idx];
std::vector<QueryLocation> ret = var.uses; std::vector<Reference> ret = var.uses;
if (include_decl) { if (include_decl) {
if (var.def && var.def->definition_spelling) if (var.def && var.def->definition_spelling)
ret.push_back(*var.def->definition_spelling); ret.push_back(*var.def->definition_spelling);
@ -246,15 +253,14 @@ std::vector<QueryLocation> GetUsesOfSymbol(QueryDatabase* db,
case SymbolKind::File: case SymbolKind::File:
case SymbolKind::Invalid: { case SymbolKind::Invalid: {
assert(false && "unexpected"); assert(false && "unexpected");
break; return {};
} }
} }
return {};
} }
std::vector<QueryLocation> GetDeclarationsOfSymbolForGotoDefinition( std::vector<Reference> GetDeclarationsOfSymbolForGotoDefinition(
QueryDatabase* db, QueryDatabase* db,
const SymbolIdx& symbol) { SymbolIdx symbol) {
switch (symbol.kind) { switch (symbol.kind) {
case SymbolKind::Type: { case SymbolKind::Type: {
// Returning the definition spelling of a type is a hack (and is why the // Returning the definition spelling of a type is a hack (and is why the
@ -265,17 +271,14 @@ std::vector<QueryLocation> GetDeclarationsOfSymbolForGotoDefinition(
if (type.def) { if (type.def) {
optional<QueryLocation> declaration = type.def->definition_spelling; optional<QueryLocation> declaration = type.def->definition_spelling;
if (declaration) if (declaration)
return {*declaration}; return {Reference(*declaration)};
} }
break; break;
} }
case SymbolKind::Func: { case SymbolKind::Func:
QueryFunc& func = db->funcs[symbol.idx]; return db->funcs[symbol.idx].declarations;
return func.declarations; case SymbolKind::Var:
}
case SymbolKind::Var: {
return db->vars[symbol.idx].declarations; return db->vars[symbol.idx].declarations;
}
default: default:
break; break;
} }
@ -434,11 +437,11 @@ lsDocumentUri GetLsDocumentUri(QueryDatabase* db, QueryFileId file_id) {
optional<lsLocation> GetLsLocation(QueryDatabase* db, optional<lsLocation> GetLsLocation(QueryDatabase* db,
WorkingFiles* working_files, WorkingFiles* working_files,
const QueryLocation& location) { Reference ref) {
std::string path; std::string path;
lsDocumentUri uri = GetLsDocumentUri(db, location.FileId(), &path); lsDocumentUri uri = GetLsDocumentUri(db, GetFileId(db, ref), &path);
optional<lsRange> range = optional<lsRange> range =
GetLsRange(working_files->GetFileByFilename(path), location.range); GetLsRange(working_files->GetFileByFilename(path), ref.range);
if (!range) if (!range)
return nullopt; return nullopt;
return lsLocation(uri, *range); return lsLocation(uri, *range);

View File

@ -21,6 +21,10 @@ optional<QueryFileId> GetDeclarationFileForSymbol(QueryDatabase* db,
const SymbolIdx& symbol); const SymbolIdx& symbol);
QueryLocation ToQueryLocation(QueryDatabase* db, Reference ref); QueryLocation ToQueryLocation(QueryDatabase* db, Reference ref);
QueryFileId GetFileId(QueryDatabase* db, Reference ref);
std::vector<Reference> ToReference(QueryDatabase* db,
const std::vector<QueryFuncRef>& refs);
std::vector<QueryLocation> ToQueryLocation( std::vector<QueryLocation> ToQueryLocation(
QueryDatabase* db, QueryDatabase* db,
const std::vector<QueryFuncRef>& refs); const std::vector<QueryFuncRef>& refs);
@ -32,12 +36,12 @@ std::vector<QueryLocation> ToQueryLocation(
const std::vector<QueryVarId>& refs); const std::vector<QueryVarId>& refs);
std::vector<QueryLocation> ToQueryLocation(QueryDatabase* db, std::vector<QueryLocation> ToQueryLocation(QueryDatabase* db,
const std::vector<QueryFuncId>& ids); const std::vector<QueryFuncId>& ids);
std::vector<QueryLocation> GetUsesOfSymbol(QueryDatabase* db, std::vector<Reference> GetUsesOfSymbol(QueryDatabase* db,
const SymbolIdx& symbol, const SymbolIdx& symbol,
bool include_decl); bool include_decl);
std::vector<QueryLocation> GetDeclarationsOfSymbolForGotoDefinition( std::vector<Reference> GetDeclarationsOfSymbolForGotoDefinition(
QueryDatabase* db, QueryDatabase* db,
const SymbolIdx& symbol); SymbolIdx symbol);
bool HasCallersOnSelfOrBaseOrDerived(QueryDatabase* db, QueryFunc& root); bool HasCallersOnSelfOrBaseOrDerived(QueryDatabase* db, QueryFunc& root);
std::vector<QueryFuncRef> GetCallersForAllBaseFunctions(QueryDatabase* db, std::vector<QueryFuncRef> GetCallersForAllBaseFunctions(QueryDatabase* db,
@ -51,9 +55,10 @@ lsDocumentUri GetLsDocumentUri(QueryDatabase* db,
QueryFileId file_id, QueryFileId file_id,
std::string* path); std::string* path);
lsDocumentUri GetLsDocumentUri(QueryDatabase* db, QueryFileId file_id); lsDocumentUri GetLsDocumentUri(QueryDatabase* db, QueryFileId file_id);
optional<lsLocation> GetLsLocation(QueryDatabase* db, optional<lsLocation> GetLsLocation(QueryDatabase* db,
WorkingFiles* working_files, WorkingFiles* working_files,
const QueryLocation& location); Reference location);
std::vector<lsLocation> GetLsLocations( std::vector<lsLocation> GetLsLocations(
QueryDatabase* db, QueryDatabase* db,
WorkingFiles* working_files, WorkingFiles* working_files,