Add Id<QueryFile> file; to Use and simplify query.cc

This commit is contained in:
Fangrui Song 2018-02-11 20:22:47 -08:00
parent 2d6fd4e240
commit afd38cbce9
12 changed files with 76 additions and 97 deletions

View File

@ -657,8 +657,8 @@ void OnIndexReference_Function(IndexFile* db,
} // namespace } // namespace
// static // static
const int IndexFile::kMajorVersion = 12; const int IndexFile::kMajorVersion = 13;
const int IndexFile::kMinorVersion = 1; const int IndexFile::kMinorVersion = 0;
IndexFile::IndexFile(const std::string& path, const std::string& contents) IndexFile::IndexFile(const std::string& path, const std::string& contents)
: id_cache(path), path(path), file_contents(contents) {} : id_cache(path), path(path), file_contents(contents) {}
@ -1542,7 +1542,9 @@ void OnIndexDeclaration(CXClientData client_data, const CXIdxDeclInfo* decl) {
SetUse(db, &var->def.spell, decl_spell, lex_parent, Role::Definition); SetUse(db, &var->def.spell, decl_spell, lex_parent, Role::Definition);
SetUse(db, &var->def.extent, decl_cursor.get_extent(), lex_parent, Role::None); SetUse(db, &var->def.extent, decl_cursor.get_extent(), lex_parent, Role::None);
} else { } else {
var->declarations.push_back(decl_spell); Maybe<Use> use;
SetUse(db, &use, decl_spell, lex_parent, Role::Declaration);
var->declarations.push_back(*use);
} }
AddDeclInitializerUsages(db, decl_cursor); AddDeclInitializerUsages(db, decl_cursor);
@ -2374,6 +2376,9 @@ std::string GetClangVersion() {
return ToString(clang_getClangVersion()); return ToString(clang_getClangVersion());
} }
// |SymbolRef| is serialized this way.
// |Use| also uses this though it has an extra field |file|,
// which is not used by Index* so it does not need to be serialized.
void Reflect(Reader& visitor, Reference& value) { void Reflect(Reader& visitor, Reference& value) {
if (visitor.Format() == SerializeFormat::Json) { if (visitor.Format() == SerializeFormat::Json) {
std::string t = visitor.GetString(); std::string t = visitor.GetString();

View File

@ -136,13 +136,19 @@ struct SymbolRef : Reference {
: Reference{Range(), si.id, si.kind, Role::None} {} : Reference{Range(), si.id, si.kind, Role::None} {}
}; };
struct QueryFile;
// Represents an occurrence of a variable/type, |id,kind| refer to the lexical // Represents an occurrence of a variable/type, |id,kind| refer to the lexical
// parent. // parent.
struct Use : Reference { struct Use : Reference {
// |file| is used in Query* but not in Index*
Id<QueryFile> file;
Use() = default; Use() = default;
Use(Reference ref) : Reference(ref) {} Use(Reference ref) : Reference(ref) {}
Use(Range range, Id<void> id, SymbolKind kind, Role role) Use(Range range, Id<void> id, SymbolKind kind, Role role)
: Reference{range, id, kind, role} {} : Reference{range, id, kind, role} {}
Use(Range range, Id<void> id, SymbolKind kind, Role role, Id<QueryFile> file)
: Reference{range, id, kind, role}, file(file) {}
}; };
void Reflect(Reader& visitor, Reference& value); void Reflect(Reader& visitor, Reference& value);
@ -433,7 +439,7 @@ struct IndexVar {
Def def; Def def;
std::vector<Range> declarations; std::vector<Use> declarations;
// Usages. // Usages.
std::vector<Use> uses; std::vector<Use> uses;

View File

@ -80,7 +80,7 @@ std::vector<Out_CqueryCallTree::CallEntry> BuildExpandCallTree(
std::vector<Out_CqueryCallTree::CallEntry> result; std::vector<Out_CqueryCallTree::CallEntry> result;
auto handle_caller = [&](QueryFuncRef caller, auto handle_caller = [&](Use caller,
Out_CqueryCallTree::CallType call_type) { Out_CqueryCallTree::CallType call_type) {
optional<lsLocation> call_location = optional<lsLocation> call_location =
GetLsLocation(db, working_files, caller); GetLsLocation(db, working_files, caller);
@ -130,21 +130,21 @@ std::vector<Out_CqueryCallTree::CallEntry> BuildExpandCallTree(
} }
}; };
std::vector<QueryFuncRef> base_callers = std::vector<Use> base_callers =
GetCallersForAllBaseFunctions(db, root_func); GetCallersForAllBaseFunctions(db, root_func);
std::vector<QueryFuncRef> derived_callers = std::vector<Use> derived_callers =
GetCallersForAllDerivedFunctions(db, root_func); GetCallersForAllDerivedFunctions(db, root_func);
result.reserve(root_func.uses.size() + base_callers.size() + result.reserve(root_func.uses.size() + base_callers.size() +
derived_callers.size()); derived_callers.size());
for (QueryFuncRef caller : root_func.uses) for (Use caller : root_func.uses)
handle_caller(caller, Out_CqueryCallTree::CallType::Direct); handle_caller(caller, Out_CqueryCallTree::CallType::Direct);
for (QueryFuncRef caller : base_callers) for (Use caller : base_callers)
if (caller.kind == SymbolKind::Func && caller.id != Id<void>(root)) { if (caller.kind == SymbolKind::Func && caller.id != Id<void>(root)) {
// Do not show calls to the base function coming from this function. // Do not show calls to the base function coming from this function.
handle_caller(caller, Out_CqueryCallTree::CallType::Base); handle_caller(caller, Out_CqueryCallTree::CallType::Base);
} }
for (QueryFuncRef caller : derived_callers) for (Use caller : derived_callers)
handle_caller(caller, Out_CqueryCallTree::CallType::Derived); handle_caller(caller, Out_CqueryCallTree::CallType::Derived);
return result; return result;

View File

@ -73,7 +73,7 @@ optional<QueryFileId> GetImplementationFile(QueryDatabase* db,
// Note: we ignore the definition if it is in the same file (ie, // Note: we ignore the definition if it is in the same file (ie,
// possibly a header). // possibly a header).
if (func.def && func.def->extent) { if (func.def && func.def->extent) {
Maybe<QueryFileId> t = db->GetFileId(*func.def->extent); QueryFileId t = func.def->extent->file;
if (t != file_id) if (t != file_id)
return t; return t;
} }
@ -84,7 +84,7 @@ optional<QueryFileId> GetImplementationFile(QueryDatabase* db,
// Note: we ignore the definition if it is in the same file (ie, // Note: we ignore the definition if it is in the same file (ie,
// possibly a header). // possibly a header).
if (var.def && var.def->extent) { if (var.def && var.def->extent) {
Maybe<QueryFileId> t = db->GetFileId(*var.def->extent); QueryFileId t = var.def->extent->file;
if (t != file_id) if (t != file_id)
return t; return t;
} }
@ -150,8 +150,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 Reference& decl : func.declarations) { for (Use decl : func.declarations) {
if (db->GetFileId(decl) != decl_file_id) if (decl.file != decl_file_id)
continue; continue;
optional<lsRange> ls_decl = GetLsRange(working_file, decl.range); optional<lsRange> ls_decl = GetLsRange(working_file, decl.range);
@ -204,8 +204,8 @@ optional<lsTextEdit> BuildAutoImplementForFunction(QueryDatabase* db,
if (!sym_func.def || !sym_func.def->extent) if (!sym_func.def || !sym_func.def->extent)
break; break;
for (const Reference& func_decl : sym_func.declarations) { for (Use func_decl : sym_func.declarations) {
if (db->GetFileId(func_decl) == decl_file_id) { if (func_decl.file == 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

@ -91,6 +91,7 @@ void AddCodeLens(const char* singular,
optional<lsRange> range = GetLsRange(common->working_file, loc.range); optional<lsRange> range = GetLsRange(common->working_file, loc.range);
if (!range) if (!range)
return; return;
// FIXME SymbolRef loc -> Use loc
Maybe<QueryFileId> file_id = common->db->GetFileId(loc); Maybe<QueryFileId> file_id = common->db->GetFileId(loc);
if (!file_id) if (!file_id)
return; return;
@ -178,7 +179,7 @@ struct TextDocumentCodeLensHandler
// extent location to the spelling location. // extent location to the spelling location.
auto try_ensure_spelling = [&](SymbolRef sym) { auto try_ensure_spelling = [&](SymbolRef sym) {
Maybe<Use> def = GetDefinitionSpellingOfSymbol(db, sym); Maybe<Use> def = GetDefinitionSpellingOfSymbol(db, sym);
if (!def || db->GetFileId(*def) != db->GetFileId(sym) || if (!def || def->file != *db->GetFileId(sym) ||
def->range.start.line != sym.range.start.line) { def->range.start.line != sym.range.start.line) {
return sym; return sym;
} }

View File

@ -86,7 +86,7 @@ struct TextDocumentDefinitionHandler
// the declaration if possible. We also want to use declarations if // the declaration if possible. We also want to use declarations if
// we're pointing to, ie, a pure virtual function which has no // we're pointing to, ie, a pure virtual function which has no
// definition. // definition.
if (!def_loc || (db->GetFileId(*def_loc) == file_id && if (!def_loc || (def_loc->file == file_id &&
def_loc->range.Contains(target_line, target_column))) { def_loc->range.Contains(target_line, target_column))) {
// Goto declaration. // Goto declaration.

View File

@ -41,7 +41,7 @@ struct TextDocumentDocumentHighlightHandler
std::vector<Use> uses = GetUsesOfSymbol(db, sym, true); std::vector<Use> uses = GetUsesOfSymbol(db, sym, true);
out.result.reserve(uses.size()); out.result.reserve(uses.size());
for (Use use : uses) { for (Use use : uses) {
if (db->GetFileId(use) != file_id) if (use.file != file_id)
continue; continue;
optional<lsLocation> ls_location = optional<lsLocation> ls_location =

View File

@ -16,23 +16,21 @@ lsWorkspaceEdit BuildWorkspaceEdit(QueryDatabase* db,
if (!ls_location) if (!ls_location)
continue; continue;
Maybe<QueryFileId> file_id = db->GetFileId(use); QueryFileId file_id = use.file;
if (!file_id) if (path_to_edit.find(file_id) == path_to_edit.end()) {
continue; path_to_edit[file_id] = lsTextDocumentEdit();
if (path_to_edit.find(*file_id) == path_to_edit.end()) {
path_to_edit[*file_id] = lsTextDocumentEdit();
QueryFile& file = db->files[file_id->id]; QueryFile& file = db->files[file_id.id];
if (!file.def) if (!file.def)
continue; continue;
const std::string& path = file.def->path; const std::string& path = file.def->path;
path_to_edit[*file_id].textDocument.uri = path_to_edit[file_id].textDocument.uri =
lsDocumentUri::FromPath(path); lsDocumentUri::FromPath(path);
WorkingFile* working_file = working_files->GetFileByFilename(path); WorkingFile* working_file = working_files->GetFileByFilename(path);
if (working_file) if (working_file)
path_to_edit[*file_id].textDocument.version = path_to_edit[file_id].textDocument.version =
working_file->version; working_file->version;
} }
@ -41,7 +39,7 @@ lsWorkspaceEdit BuildWorkspaceEdit(QueryDatabase* db,
edit.newText = new_text; edit.newText = new_text;
// vscode complains if we submit overlapping text edits. // vscode complains if we submit overlapping text edits.
auto& edits = path_to_edit[*file_id].edits; auto& edits = path_to_edit[file_id].edits;
if (std::find(edits.begin(), edits.end(), edit) == edits.end()) if (std::find(edits.begin(), edits.end(), edit) == edits.end())
edits.push_back(edit); edits.push_back(edit);
} }

View File

@ -233,10 +233,6 @@ QueryFile::DefUpdate BuildFileDefUpdate(const IdMap& id_map, const IndexFile& in
Role role) { Role role) {
def.outline.push_back(SymbolRef(range, id, kind, role)); def.outline.push_back(SymbolRef(range, id, kind, role));
}; };
auto add_all_symbols = [&](Range range, Id<void> id, SymbolKind kind,
Role role) {
def.all_symbols.push_back(SymbolRef(range, id, kind, role));
};
auto add_all_symbols_use = [&](Use use, Id<void> id, SymbolKind kind) { auto add_all_symbols_use = [&](Use use, Id<void> id, SymbolKind kind) {
def.all_symbols.push_back( def.all_symbols.push_back(
SymbolRef(use.range, id, kind, use.role)); SymbolRef(use.range, id, kind, use.role));
@ -252,7 +248,7 @@ QueryFile::DefUpdate BuildFileDefUpdate(const IdMap& id_map, const IndexFile& in
if (type.def.extent) if (type.def.extent)
add_outline_use(*type.def.extent, id, SymbolKind::Type); add_outline_use(*type.def.extent, id, SymbolKind::Type);
for (Use use : type.uses) for (Use use : type.uses)
add_all_symbols(use.range, id, SymbolKind::Type, use.role); add_all_symbols_use(use, id, SymbolKind::Type);
} }
for (const IndexFunc& func : indexed.funcs) { for (const IndexFunc& func : indexed.funcs) {
QueryFuncId id = id_map.ToQuery(func.id); QueryFuncId id = id_map.ToQuery(func.id);
@ -261,23 +257,21 @@ QueryFile::DefUpdate BuildFileDefUpdate(const IdMap& id_map, const IndexFile& in
if (func.def.extent) if (func.def.extent)
add_outline_use(*func.def.extent, id, SymbolKind::Func); add_outline_use(*func.def.extent, id, SymbolKind::Func);
for (const IndexFunc::Declaration& decl : func.declarations) { for (const IndexFunc::Declaration& decl : func.declarations) {
add_all_symbols(decl.spelling, id, SymbolKind::Func, def.all_symbols.push_back(
Role::Declaration); SymbolRef(decl.spelling, id, SymbolKind::Func, Role::Declaration));
add_outline(decl.spelling, id, SymbolKind::Func, Role::Declaration); add_outline(decl.spelling, id, SymbolKind::Func, Role::Declaration);
} }
for (Use caller : func.uses) { for (Use use : func.uses) {
// Make ranges of implicit function calls larger (spanning one more column // Make ranges of implicit function calls larger (spanning one more column
// to the left/right). This is hacky but useful. e.g. // to the left/right). This is hacky but useful. e.g.
// textDocument/definition on the space/semicolon in `A a;` or `return // textDocument/definition on the space/semicolon in `A a;` or `return
// 42;` will take you to the constructor. // 42;` will take you to the constructor.
Range range = caller.range; if (use.role & Role::Implicit) {
if (caller.role & Role::Implicit) { if (use.range.start.column > 0)
if (range.start.column > 0) use.range.start.column--;
range.start.column--; use.range.end.column++;
range.end.column++;
} }
add_all_symbols(range, id, SymbolKind::Func, add_all_symbols_use(use, id, SymbolKind::Func);
caller.role | Role::Call);
} }
} }
for (const IndexVar& var : indexed.vars) { for (const IndexVar& var : indexed.vars) {
@ -286,15 +280,12 @@ QueryFile::DefUpdate BuildFileDefUpdate(const IdMap& id_map, const IndexFile& in
add_all_symbols_use(*var.def.spell, id, SymbolKind::Var); add_all_symbols_use(*var.def.spell, id, SymbolKind::Var);
if (var.def.extent) if (var.def.extent)
add_outline_use(*var.def.extent, id, SymbolKind::Var); add_outline_use(*var.def.extent, id, SymbolKind::Var);
for (const Range& decl : var.declarations) { for (Use decl : var.declarations) {
add_all_symbols(decl, id_map.ToQuery(var.id), SymbolKind::Var, add_all_symbols_use(decl, id, SymbolKind::Var);
Role::Definition); add_outline_use(decl, id, SymbolKind::Var);
add_outline(decl, id_map.ToQuery(var.id), SymbolKind::Var,
Role::Declaration);
} }
for (Use use : var.uses) for (Use use : var.uses)
add_all_symbols(use.range, id_map.ToQuery(var.id), SymbolKind::Var, add_all_symbols_use(use, id, SymbolKind::Var);
use.role);
} }
std::sort(def.outline.begin(), def.outline.end(), std::sort(def.outline.begin(), def.outline.end(),
@ -411,14 +402,12 @@ IdMap::IdMap(QueryDatabase* query_db, const IdCache& local_ids)
*GetQueryVarIdFromUsr(query_db, entry.second, true); *GetQueryVarIdFromUsr(query_db, entry.second, true);
} }
Use IdMap::ToQuery(Range range, Role role) const {
return Use(range, primary_file, SymbolKind:: File, role);
}
QueryTypeId IdMap::ToQuery(IndexTypeId id) const { QueryTypeId IdMap::ToQuery(IndexTypeId id) const {
assert(cached_type_ids_.find(id) != cached_type_ids_.end()); assert(cached_type_ids_.find(id) != cached_type_ids_.end());
return QueryTypeId(cached_type_ids_.find(id)->second); return QueryTypeId(cached_type_ids_.find(id)->second);
} }
QueryFuncId IdMap::ToQuery(IndexFuncId id) const { QueryFuncId IdMap::ToQuery(IndexFuncId id) const {
// FIXME id shouldn't be invalid
if (id == IndexFuncId()) if (id == IndexFuncId())
return QueryFuncId(); return QueryFuncId();
assert(cached_func_ids_.find(id) != cached_func_ids_.end()); assert(cached_func_ids_.find(id) != cached_func_ids_.end());
@ -430,44 +419,38 @@ QueryVarId IdMap::ToQuery(IndexVarId id) const {
} }
Use IdMap::ToQuery(Reference ref) const { Use IdMap::ToQuery(Reference ref) const {
Use ret(ref);
ret.file = primary_file;
switch (ref.kind) { switch (ref.kind) {
case SymbolKind::Invalid: case SymbolKind::Invalid:
break; break;
case SymbolKind::File: case SymbolKind::File:
ref.id = primary_file; ret.id = primary_file;
break; break;
case SymbolKind::Func: case SymbolKind::Func:
ref.id = ToQuery(IndexFuncId(ref.id)); ret.id = ToQuery(IndexFuncId(ref.id));
break; break;
case SymbolKind::Type: case SymbolKind::Type:
ref.id = ToQuery(IndexTypeId(ref.id)); ret.id = ToQuery(IndexTypeId(ref.id));
break; break;
case SymbolKind::Var: case SymbolKind::Var:
ref.id = ToQuery(IndexVarId(ref.id)); ret.id = ToQuery(IndexVarId(ref.id));
break; break;
} }
return ref; return ret;
} }
SymbolRef IdMap::ToQuery(SymbolRef ref) const { SymbolRef IdMap::ToQuery(SymbolRef ref) const {
ref.Reference::operator=(ToQuery(static_cast<Reference>(ref))); ref.Reference::operator=(ToQuery(static_cast<Reference>(ref)));
return ref; return ref;
} }
Use IdMap::ToQuery(Use use) const { Use IdMap::ToQuery(Use use) const {
use.Reference::operator=(ToQuery(static_cast<Reference>(use))); return ToQuery(static_cast<Reference>(use));
return use;
} }
Use IdMap::ToQuery(IndexFunc::Declaration decl) const { Use IdMap::ToQuery(IndexFunc::Declaration decl) const {
// TODO: expose more than just QueryLocation. // TODO: expose more than just QueryLocation.
return Use(decl.spelling, primary_file, SymbolKind::File, return {decl.spelling, primary_file, SymbolKind::File, Role::Declaration,
Role::Declaration); primary_file};
}
std::vector<Use> IdMap::ToQuery(const std::vector<Range>& a) const {
std::vector<Use> ret;
ret.reserve(a.size());
for (auto& x : a)
ret.push_back(ToQuery(x, Role::Reference));
return ret;
} }
// ---------------------- // ----------------------

View File

@ -20,8 +20,6 @@ using QueryVarId = Id<QueryVar>;
struct IdMap; struct IdMap;
using QueryFuncRef = Use;
// 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.
// //
@ -341,7 +339,6 @@ template <> struct IndexToQuery<IndexTypeId> { using type = QueryTypeId; };
template <> struct IndexToQuery<IndexVarId> { using type = QueryVarId; }; template <> struct IndexToQuery<IndexVarId> { using type = QueryVarId; };
template <> struct IndexToQuery<Use> { using type = Use; }; template <> struct IndexToQuery<Use> { using type = Use; };
template <> struct IndexToQuery<SymbolRef> { using type = SymbolRef; }; template <> struct IndexToQuery<SymbolRef> { using type = SymbolRef; };
template <> struct IndexToQuery<Range> { using type = Use; };
template <> struct IndexToQuery<IndexFunc::Declaration> { using type = Use; }; template <> struct IndexToQuery<IndexFunc::Declaration> { using type = Use; };
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>;
@ -363,7 +360,6 @@ struct IdMap {
QueryFuncId ToQuery(IndexFuncId id) const; QueryFuncId ToQuery(IndexFuncId id) const;
QueryVarId ToQuery(IndexVarId id) const; QueryVarId ToQuery(IndexVarId id) const;
SymbolRef ToQuery(SymbolRef ref) const; SymbolRef ToQuery(SymbolRef ref) const;
Use ToQuery(Range range, Role role) const;
Use ToQuery(Reference ref) const; Use ToQuery(Reference ref) const;
Use ToQuery(Use ref) const; Use ToQuery(Use ref) const;
Use ToQuery(IndexFunc::Declaration decl) const; Use ToQuery(IndexFunc::Declaration decl) const;
@ -381,7 +377,6 @@ struct IdMap {
ret.push_back(ToQuery(x)); ret.push_back(ToQuery(x));
return ret; return ret;
} }
std::vector<Use> ToQuery(const std::vector<Range>& a) const;
// clang-format on // clang-format on

View File

@ -16,19 +16,13 @@ int ComputeRangeSize(const Range& range) {
return range.end.column - range.start.column; return range.end.column - range.start.column;
} }
Maybe<Use> UseWithFileId(Maybe<Use> use, QueryFileId file_id) {
if (!use)
return nullopt;
return Use(use->range, file_id, SymbolKind::File, use->role);
}
} // namespace } // namespace
Maybe<Use> GetDefinitionSpellingOfSymbol(QueryDatabase* db, Maybe<Use> GetDefinitionSpellingOfSymbol(QueryDatabase* db,
QueryFuncId id) { QueryFuncId id) {
QueryFunc& func = db->funcs[id.id]; QueryFunc& func = db->funcs[id.id];
if (func.def) if (func.def)
return UseWithFileId(func.def->spell, func.def->file); return func.def->spell;
return nullopt; return nullopt;
} }
@ -38,19 +32,19 @@ Maybe<Use> GetDefinitionSpellingOfSymbol(QueryDatabase* db,
case SymbolKind::Type: { case SymbolKind::Type: {
QueryType& type = db->GetType(sym); QueryType& type = db->GetType(sym);
if (type.def) if (type.def)
return UseWithFileId(type.def->spell, type.def->file); return type.def->spell;
break; break;
} }
case SymbolKind::Func: { case SymbolKind::Func: {
QueryFunc& func = db->GetFunc(sym); QueryFunc& func = db->GetFunc(sym);
if (func.def) if (func.def)
return UseWithFileId(func.def->spell, func.def->file); return func.def->spell;
break; break;
} }
case SymbolKind::Var: { case SymbolKind::Var: {
QueryVar& var = db->GetVar(sym); QueryVar& var = db->GetVar(sym);
if (var.def) if (var.def)
return UseWithFileId(var.def->spell, var.def->file); return var.def->spell;
break; break;
} }
case SymbolKind::File: case SymbolKind::File:
@ -67,24 +61,24 @@ Maybe<Use> GetDefinitionExtentOfSymbol(QueryDatabase* db, SymbolIdx sym) {
case SymbolKind::Type: { case SymbolKind::Type: {
QueryType& type = db->GetType(sym); QueryType& type = db->GetType(sym);
if (type.def) if (type.def)
return UseWithFileId(type.def->extent, type.def->file); return type.def->extent;
break; break;
} }
case SymbolKind::Func: { case SymbolKind::Func: {
QueryFunc& func = db->GetFunc(sym); QueryFunc& func = db->GetFunc(sym);
if (func.def) if (func.def)
return UseWithFileId(func.def->extent, func.def->file); return func.def->extent;
break; break;
} }
case SymbolKind::Var: { case SymbolKind::Var: {
QueryVar& var = db->GetVar(sym); QueryVar& var = db->GetVar(sym);
if (var.def) if (var.def)
return UseWithFileId(var.def->extent, var.def->file); return var.def->extent;
break; break;
} }
case SymbolKind::File: case SymbolKind::File:
return Use(Range(Position(0, 0), Position(0, 0)), sym.id, sym.kind, return Use(Range(Position(0, 0), Position(0, 0)), sym.id, sym.kind,
Role::None); Role::None, QueryFileId(sym.id));
case SymbolKind::Invalid: { case SymbolKind::Invalid: {
assert(false && "unexpected"); assert(false && "unexpected");
break; break;
@ -105,7 +99,7 @@ Maybe<QueryFileId> GetDeclarationFileForSymbol(QueryDatabase* db,
case SymbolKind::Func: { case SymbolKind::Func: {
QueryFunc& func = db->GetFunc(sym); QueryFunc& func = db->GetFunc(sym);
if (!func.declarations.empty()) if (!func.declarations.empty())
return db->GetFileId(func.declarations[0]); return func.declarations[0].file;
if (func.def) if (func.def)
return func.def->file; return func.def->file;
break; break;
@ -383,14 +377,11 @@ lsDocumentUri GetLsDocumentUri(QueryDatabase* db, QueryFileId file_id) {
optional<lsLocation> GetLsLocation(QueryDatabase* db, optional<lsLocation> GetLsLocation(QueryDatabase* db,
WorkingFiles* working_files, WorkingFiles* working_files,
Reference ref) { Use use) {
std::string path; std::string path;
Maybe<QueryFileId> file_id = db->GetFileId(ref); lsDocumentUri uri = GetLsDocumentUri(db, use.file, &path);
if (!file_id)
return nullopt;
lsDocumentUri uri = GetLsDocumentUri(db, *file_id, &path);
optional<lsRange> range = optional<lsRange> range =
GetLsRange(working_files->GetFileByFilename(path), ref.range); GetLsRange(working_files->GetFileByFilename(path), use.range);
if (!range) if (!range)
return nullopt; return nullopt;
return lsLocation(uri, *range); return lsLocation(uri, *range);

View File

@ -44,7 +44,7 @@ lsDocumentUri GetLsDocumentUri(QueryDatabase* db, QueryFileId file_id);
optional<lsLocation> GetLsLocation(QueryDatabase* db, optional<lsLocation> GetLsLocation(QueryDatabase* db,
WorkingFiles* working_files, WorkingFiles* working_files,
Reference location); Use use);
optional<lsLocationEx> GetLsLocationEx(QueryDatabase* db, optional<lsLocationEx> GetLsLocationEx(QueryDatabase* db,
WorkingFiles* working_files, WorkingFiles* working_files,
Use use, Use use,