Rename Reference members

This commit is contained in:
Fangrui Song 2018-02-09 09:42:10 -08:00
parent c5f08c5eb8
commit c4bd7ef44b
23 changed files with 305 additions and 307 deletions

View File

@ -695,13 +695,13 @@ void UniqueAdd(std::vector<T>& values, T value) {
values.push_back(value);
}
// FIXME Reference: set lex_parent_id in call sites and remove this
// FIXME Reference: set id in call sites and remove this
void AddUse(std::vector<Reference>& values, Range value) {
values.push_back(Reference{value, Id<void>(), SymbolKind::Invalid,
SymbolRole::Reference});
}
// FIXME Reference: set lex_parent_id in call sites and remove this
// FIXME Reference: set id in call sites and remove this
void UniqueAdd(std::vector<Reference>& values, Range value) {
if (std::find_if(values.begin(), values.end(), [&](const Reference& ref) {
return ref.range == value;
@ -2341,7 +2341,7 @@ void Reflect(Reader& visitor, IndexFuncRef& value) {
RawId id = atol(str_value);
const char* loc_string = strchr(str_value, '@') + 1;
value.lex_parent_id = Id<void>(id);
value.id = Id<void>(id);
value.range = Range(loc_string);
} else {
Reflect(visitor, static_cast<Reference&>(value));
@ -2354,8 +2354,8 @@ void Reflect(Writer& visitor, IndexFuncRef& value) {
s += "~";
// id.id is unsigned, special case -1 value
if (value.lex_parent_id.HasValue())
s += std::to_string(value.lex_parent_id.id);
if (value.id.HasValue())
s += std::to_string(value.id.id);
else
s += "-1";
@ -2377,13 +2377,13 @@ void Reflect(Reader& visitor, Reference& value) {
else {
char* p = const_cast<char*>(s.c_str()) + sep;
value.role = SymbolRole(strtol(p + 1, &p, 10));
value.lex_parent_kind = SymbolKind(strtol(p + 1, &p, 10));
value.lex_parent_id = Id<void>(strtol(p + 1, &p, 10));
value.kind = SymbolKind(strtol(p + 1, &p, 10));
value.id = Id<void>(strtol(p + 1, &p, 10));
}
} else {
Reflect(visitor, value.range);
Reflect(visitor, value.lex_parent_id);
Reflect(visitor, value.lex_parent_kind);
Reflect(visitor, value.id);
Reflect(visitor, value.kind);
Reflect(visitor, value.role);
}
}
@ -2391,16 +2391,16 @@ void Reflect(Writer& visitor, Reference& value) {
if (visitor.Format() == SerializeFormat::Json) {
std::string s = value.range.ToString();
if (value.role != SymbolRole::Reference ||
value.lex_parent_kind != SymbolKind::Invalid) {
value.kind != SymbolKind::Invalid) {
s += '|' + std::to_string(uint8_t(value.role));
s += '|' + std::to_string(uint8_t(value.lex_parent_kind));
s += '|' + std::to_string(RawId(value.lex_parent_id));
s += '|' + std::to_string(uint8_t(value.kind));
s += '|' + std::to_string(RawId(value.id));
}
visitor.String(s.c_str());
} else {
Reflect(visitor, value.range);
Reflect(visitor, value.lex_parent_id);
Reflect(visitor, value.lex_parent_kind);
Reflect(visitor, value.id);
Reflect(visitor, value.kind);
Reflect(visitor, value.role);
}
}

View File

@ -54,9 +54,9 @@ struct Id {
bool HasValue() const { return id != RawId(-1); }
bool operator==(const Id<T>& o) const { return id == o.id; }
bool operator!=(const Id<T>& o) const { return id != o.id; }
bool operator<(const Id<T>& o) const { return id < o.id; }
bool operator==(const Id& o) const { return id == o.id; }
bool operator!=(const Id& o) const { return id != o.id; }
bool operator<(const Id& o) const { return id < o.id; }
};
namespace std {
@ -80,13 +80,13 @@ struct IdCache;
struct Reference {
Range range;
Id<void> lex_parent_id;
SymbolKind lex_parent_kind;
Id<void> id;
SymbolKind kind;
SymbolRole role;
bool HasValue() const { return lex_parent_id.HasValue(); }
bool HasValue() const { return id.HasValue(); }
std::tuple<Range, Id<void>, SymbolKind, SymbolRole> ToTuple() const {
return std::make_tuple(range, lex_parent_id, lex_parent_kind, role);
return std::make_tuple(range, id, kind, role);
}
bool operator==(const Reference& o) const {
return ToTuple() == o.ToTuple();

View File

@ -115,18 +115,18 @@ void EmitSemanticHighlighting(QueryDatabase* db,
ClangSymbolKind kind = ClangSymbolKind::Unknown;
StorageClass storage = StorageClass::Invalid;
// This switch statement also filters out symbols that are not highlighted.
switch (sym.idx.kind) {
switch (sym.kind) {
case SymbolKind::Func: {
QueryFunc* func = &db->funcs[sym.idx.idx];
if (!func->def)
QueryFunc& func = sym.Func(db);
if (!func.def)
continue; // applies to for loop
// Don't highlight overloadable operators or implicit lambda ->
// std::function constructor.
std::string_view short_name = func->def->ShortName();
std::string_view short_name = func.def->ShortName();
if (short_name.compare(0, 8, "operator") == 0 ||
short_name.compare(0, 27, "function<type-parameter-0-0") == 0)
continue; // applies to for loop
kind = func->def->kind;
kind = func.def->kind;
detailed_name = short_name;
// Check whether the function name is actually there.
@ -135,54 +135,55 @@ void EmitSemanticHighlighting(QueryDatabase* db,
// but we still want to keep the range for jumping to definition.
std::string_view concise_name =
detailed_name.substr(0, detailed_name.find('<'));
int16_t start_line = sym.loc.range.start.line;
int16_t start_col = sym.loc.range.start.column;
int16_t start_line = sym.range.start.line;
int16_t start_col = sym.range.start.column;
if (start_line >= 0 && start_line < working_file->index_lines.size()) {
std::string_view line = working_file->index_lines[start_line];
sym.loc.range.end.line = start_line;
sym.range.end.line = start_line;
if (line.compare(start_col, concise_name.size(), concise_name) == 0)
sym.loc.range.end.column = start_col + concise_name.size();
sym.range.end.column = start_col + concise_name.size();
else
continue; // applies to for loop
}
break;
}
case SymbolKind::Var: {
QueryVar* var = &db->vars[sym.idx.idx];
if (!var->def)
QueryVar& var = sym.Var(db);
if (!var.def)
continue; // applies to for loop
parent_kind = var->def->parent_kind;
kind = var->def->kind;
storage = var->def->storage;
detailed_name = var->def->ShortName();
parent_kind = var.def->parent_kind;
kind = var.def->kind;
storage = var.def->storage;
detailed_name = var.def->ShortName();
break;
}
case SymbolKind::Type: {
QueryType* type = &db->types[sym.idx.idx];
if (!type->def)
QueryType& type = sym.Type(db);
if (!type.def)
continue; // applies to for loop
kind = type->def->kind;
detailed_name = type->def->detailed_name;
kind = type.def->kind;
detailed_name = type.def->detailed_name;
break;
}
default:
continue; // applies to for loop
}
optional<lsRange> loc = GetLsRange(working_file, sym.loc.range);
optional<lsRange> loc = GetLsRange(working_file, sym.range);
if (loc) {
auto it = grouped_symbols.find(sym.idx);
auto key = SymbolIdx(sym.kind, RawId(sym.id));
auto it = grouped_symbols.find(key);
if (it != grouped_symbols.end()) {
it->second.ranges.push_back(*loc);
} else {
Out_CqueryPublishSemanticHighlighting::Symbol symbol;
symbol.stableId = semantic_cache_for_file->GetStableId(
sym.idx.kind, std::string(detailed_name));
sym.kind, std::string(detailed_name));
symbol.parentKind = parent_kind;
symbol.kind = kind;
symbol.storage = storage;
symbol.ranges.push_back(*loc);
grouped_symbols[sym.idx] = symbol;
grouped_symbols[key] = symbol;
}
}
}

View File

@ -23,25 +23,25 @@ struct CqueryBaseHandler : BaseMessageHandler<Ipc_CqueryBase> {
Out_LocationList out;
out.id = request->id;
std::vector<SymbolRef> refs =
std::vector<SymbolRef> syms =
FindSymbolsAtLocation(working_file, file, request->params.position);
// A template definition may be a use of its primary template.
// We want to get the definition instead of the use.
// Order by |Definition| DESC, range size ASC.
std::stable_sort(refs.begin(), refs.end(),
std::stable_sort(syms.begin(), syms.end(),
[](const SymbolRef& a, const SymbolRef& b) {
return (a.role & SymbolRole::Definition) >
(b.role & SymbolRole::Definition);
});
for (const SymbolRef& ref : refs) {
if (ref.idx.kind == SymbolKind::Type) {
QueryType& type = db->types[ref.idx.idx];
for (const SymbolRef& sym : syms) {
if (sym.kind == SymbolKind::Type) {
QueryType& type = sym.Type(db);
if (type.def)
out.result = GetLsLocations(db, working_files,
ToReference(db, type.def->parents));
break;
} else if (ref.idx.kind == SymbolKind::Func) {
QueryFunc& func = db->funcs[ref.idx.idx];
} else if (sym.kind == SymbolKind::Func) {
QueryFunc& func = sym.Func(db);
if (func.def)
out.result =
GetLsLocations(db, working_files, ToReference(db, func.def->base));

View File

@ -171,11 +171,11 @@ struct CqueryCallTreeInitialHandler
Out_CqueryCallTree out;
out.id = request->id;
for (const SymbolRef& ref :
for (SymbolRef sym :
FindSymbolsAtLocation(working_file, file, request->params.position)) {
if (ref.idx.kind == SymbolKind::Func) {
if (sym.kind == SymbolKind::Func) {
out.result =
BuildInitialCallTree(db, working_files, QueryFuncId(ref.idx.idx));
BuildInitialCallTree(db, working_files, QueryFuncId(sym.Idx()));
break;
}
}

View File

@ -23,10 +23,10 @@ struct CqueryCallersHandler : BaseMessageHandler<Ipc_CqueryCallers> {
Out_LocationList out;
out.id = request->id;
for (const SymbolRef& ref :
for (const SymbolRef& sym :
FindSymbolsAtLocation(working_file, file, request->params.position)) {
if (ref.idx.kind == SymbolKind::Func) {
QueryFunc& func = db->funcs[ref.idx.idx];
if (sym.kind == SymbolKind::Func) {
QueryFunc& func = db->funcs[sym.Idx()];
std::vector<Reference> uses = ToReference(db, func.callers);
for (QueryFuncRef func_ref : GetCallersForAllBaseFunctions(db, func))
uses.push_back(func_ref);

View File

@ -23,24 +23,24 @@ struct CqueryDerivedHandler : BaseMessageHandler<Ipc_CqueryDerived> {
Out_LocationList out;
out.id = request->id;
std::vector<SymbolRef> refs =
std::vector<SymbolRef> syms =
FindSymbolsAtLocation(working_file, file, request->params.position);
// A template definition may be a use of its primary template.
// We want to get the definition instead of the use.
// Order by |Definition| DESC, range size ASC.
std::stable_sort(refs.begin(), refs.end(),
std::stable_sort(syms.begin(), syms.end(),
[](const SymbolRef& a, const SymbolRef& b) {
return (a.role & SymbolRole::Definition) >
(b.role & SymbolRole::Definition);
});
for (const SymbolRef& ref : refs) {
if (ref.idx.kind == SymbolKind::Type) {
QueryType& type = db->types[ref.idx.idx];
for (const SymbolRef& sym : syms) {
if (sym.kind == SymbolKind::Type) {
QueryType& type = sym.Type(db);
out.result =
GetLsLocations(db, working_files, ToReference(db, type.derived));
break;
} else if (ref.idx.kind == SymbolKind::Func) {
QueryFunc& func = db->funcs[ref.idx.idx];
} else if (sym.kind == SymbolKind::Func) {
QueryFunc& func = sym.Func(db);
out.result =
GetLsLocations(db, working_files, ToReference(db, func.derived));
break;

View File

@ -92,14 +92,14 @@ struct CqueryMemberHierarchyInitialHandler
Out_CqueryMemberHierarchy out;
out.id = request->id;
for (const SymbolRef& ref :
for (const SymbolRef& sym :
FindSymbolsAtLocation(working_file, file, request->params.position)) {
if (ref.idx.kind == SymbolKind::Type) {
out.result = BuildInitial(db, working_files, QueryTypeId(ref.idx.idx));
if (sym.kind == SymbolKind::Type) {
out.result = BuildInitial(db, working_files, QueryTypeId(sym.Idx()));
break;
}
if (ref.idx.kind == SymbolKind::Var) {
QueryVar& var = db->vars[ref.idx.idx];
if (sym.kind == SymbolKind::Var) {
QueryVar& var = sym.Var(db);
if (var.def && var.def->variable_type)
out.result = BuildInitial(db, working_files, *var.def->variable_type);
break;

View File

@ -165,18 +165,18 @@ struct CqueryTypeHierarchyTreeHandler
Out_CqueryTypeHierarchyTree out;
out.id = request->id;
for (const SymbolRef& ref :
for (const SymbolRef& sym :
FindSymbolsAtLocation(working_file, file, request->params.position)) {
if (ref.idx.kind == SymbolKind::Type) {
QueryType& type = db->types[ref.idx.idx];
if (sym.kind == SymbolKind::Type) {
QueryType& type = sym.Type(db);
if (type.def)
out.result =
BuildInheritanceHierarchyForType(db, working_files, type);
break;
}
if (ref.idx.kind == SymbolKind::Func) {
if (sym.kind == SymbolKind::Func) {
out.result = BuildInheritanceHierarchyForFunc(db, working_files,
QueryFuncId(ref.idx.idx));
QueryFuncId(sym.id));
break;
}
}

View File

@ -25,19 +25,19 @@ struct CqueryVarsHandler : BaseMessageHandler<Ipc_CqueryVars> {
out.id = request->id;
for (const SymbolRef& ref :
FindSymbolsAtLocation(working_file, file, request->params.position)) {
size_t id = ref.idx.idx;
switch (ref.idx.kind) {
RawId idx = ref.Idx();
switch (ref.kind) {
default:
break;
case SymbolKind::Var: {
QueryVar& var = db->vars[id];
QueryVar& var = db->vars[idx];
if (!var.def || !var.def->variable_type)
continue;
id = var.def->variable_type->id;
idx = var.def->variable_type->id;
}
// fallthrough
case SymbolKind::Type: {
QueryType& type = db->types[id];
QueryType& type = db->types[idx];
out.result = GetLsLocations(db, working_files,
ToReference(db, type.instances));
break;

View File

@ -67,9 +67,9 @@ optional<QueryFileId> GetImplementationFile(QueryDatabase* db,
QueryFileId file_id,
QueryFile* file) {
for (SymbolRef sym : file->def->outline) {
switch (sym.idx.kind) {
switch (sym.kind) {
case SymbolKind::Func: {
QueryFunc& func = db->funcs[sym.idx.idx];
QueryFunc& func = sym.Func(db);
// Note: we ignore the definition if it is in the same file (ie,
// possibly a header).
if (func.def && func.def->definition_extent &&
@ -79,12 +79,12 @@ optional<QueryFileId> GetImplementationFile(QueryDatabase* db,
break;
}
case SymbolKind::Var: {
QueryVar& var = db->vars[sym.idx.idx];
QueryVar& var = sym.Var(db);
// Note: we ignore the definition if it is in the same file (ie,
// possibly a header).
if (var.def && var.def->definition_extent &&
var.def->definition_extent->FileId() != file_id) {
return db->vars[sym.idx.idx].def->definition_extent->FileId();
return var.def->definition_extent->FileId();
}
break;
}
@ -196,9 +196,9 @@ optional<lsTextEdit> BuildAutoImplementForFunction(QueryDatabase* db,
QueryFile& file = db->files[impl_file_id.id];
assert(file.def);
for (SymbolRef sym : file.def->outline) {
switch (sym.idx.kind) {
switch (sym.kind) {
case SymbolKind::Func: {
QueryFunc& sym_func = db->funcs[sym.idx.idx];
QueryFunc& sym_func = sym.Func(db);
if (!sym_func.def || !sym_func.def->definition_extent)
break;
@ -231,7 +231,7 @@ optional<lsTextEdit> BuildAutoImplementForFunction(QueryDatabase* db,
case SymbolKind::File:
case SymbolKind::Type:
LOG_S(WARNING) << "Unexpected SymbolKind "
<< static_cast<int>(sym.idx.kind);
<< static_cast<int>(sym.kind);
break;
}
}
@ -342,9 +342,9 @@ struct TextDocumentCodeActionHandler
std::vector<SymbolRef> syms =
FindSymbolsAtLocation(working_file, file, request->params.range.start);
for (SymbolRef sym : syms) {
switch (sym.idx.kind) {
switch (sym.kind) {
case SymbolKind::Type: {
QueryType& type = db->types[sym.idx.idx];
QueryType& type = sym.Type(db);
if (!type.def)
break;
@ -395,7 +395,7 @@ struct TextDocumentCodeActionHandler
}
case SymbolKind::Func: {
QueryFunc& func = db->funcs[sym.idx.idx];
QueryFunc& func = sym.Func(db);
if (!func.def || func.def->definition_extent)
break;

View File

@ -143,32 +143,30 @@ struct TextDocumentCodeLensHandler
common.working_files = working_files;
common.working_file = working_files->GetFileByFilename(file->def->path);
for (SymbolRef ref : file->def->outline) {
for (SymbolRef sym : file->def->outline) {
// NOTE: We OffsetColumn so that the code lens always show up in a
// predictable order. Otherwise, the client may randomize it.
SymbolIdx symbol = ref.idx;
switch (symbol.kind) {
switch (sym.kind) {
case SymbolKind::Type: {
QueryType& type = db->types[symbol.idx];
QueryType& type = sym.Type(db);
if (!type.def)
continue;
if (type.def->kind == ClangSymbolKind::Namespace)
continue;
AddCodeLens("ref", "refs", &common, ref.loc.OffsetStartColumn(0),
AddCodeLens("ref", "refs", &common, sym.OffsetStartColumn(db, 0),
type.uses, type.def->definition_spelling,
true /*force_display*/);
AddCodeLens("derived", "derived", &common,
ref.loc.OffsetStartColumn(1),
ToReference(db, type.derived), nullopt,
false /*force_display*/);
AddCodeLens("var", "vars", &common, ref.loc.OffsetStartColumn(2),
AddCodeLens(
"derived", "derived", &common, sym.OffsetStartColumn(db, 1),
ToReference(db, type.derived), nullopt, false /*force_display*/);
AddCodeLens("var", "vars", &common, sym.OffsetStartColumn(db, 2),
ToReference(db, type.instances), nullopt,
false /*force_display*/);
break;
}
case SymbolKind::Func: {
QueryFunc& func = db->funcs[symbol.idx];
QueryFunc& func = sym.Func(db);
if (!func.def)
continue;
@ -179,12 +177,13 @@ struct TextDocumentCodeLensHandler
// extent location to the spelling location.
auto try_ensure_spelling = [&](SymbolRef sym) {
optional<QueryLocation> def =
GetDefinitionSpellingOfSymbol(db, sym.idx);
if (!def || def->FileId() != sym.loc.FileId() ||
def->range.start.line != sym.loc.range.start.line) {
return sym.loc;
GetDefinitionSpellingOfSymbol(db, sym);
if (!def || def->FileId() != GetFileId(db, sym) ||
def->range.start.line != sym.range.start.line) {
return sym;
}
return *def;
return SymbolRef(def->range, Id<void>(def->FileId()),
SymbolKind::File, SymbolRole::None);
};
std::vector<QueryFuncRef> base_callers =
@ -192,31 +191,31 @@ struct TextDocumentCodeLensHandler
std::vector<QueryFuncRef> derived_callers =
GetCallersForAllDerivedFunctions(db, func);
if (base_callers.empty() && derived_callers.empty()) {
QueryLocation loc = try_ensure_spelling(ref);
SymbolRef loc = try_ensure_spelling(sym);
AddCodeLens("call", "calls", &common,
loc.OffsetStartColumn(offset++),
loc.OffsetStartColumn(db, offset++),
ToReference(db, func.callers), nullopt,
true /*force_display*/);
} else {
QueryLocation loc = try_ensure_spelling(ref);
SymbolRef loc = try_ensure_spelling(sym);
AddCodeLens("direct call", "direct calls", &common,
loc.OffsetStartColumn(offset++),
loc.OffsetStartColumn(db, offset++),
ToReference(db, func.callers), nullopt,
false /*force_display*/);
if (!base_callers.empty())
AddCodeLens("base call", "base calls", &common,
loc.OffsetStartColumn(offset++),
loc.OffsetStartColumn(db, offset++),
ToReference(db, base_callers), nullopt,
false /*force_display*/);
if (!derived_callers.empty())
AddCodeLens("derived call", "derived calls", &common,
loc.OffsetStartColumn(offset++),
loc.OffsetStartColumn(db, offset++),
ToReference(db, derived_callers), nullopt,
false /*force_display*/);
}
AddCodeLens("derived", "derived", &common,
ref.loc.OffsetStartColumn(offset++),
sym.OffsetStartColumn(db, offset++),
ToReference(db, func.derived), nullopt,
false /*force_display*/);
@ -230,7 +229,7 @@ struct TextDocumentCodeLensHandler
GetLsLocation(db, working_files, *base_loc);
if (ls_base) {
optional<lsRange> range =
GetLsRange(common.working_file, ref.loc.range);
GetLsRange(common.working_file, sym.range);
if (range) {
TCodeLens code_lens;
code_lens.range = *range;
@ -245,7 +244,7 @@ struct TextDocumentCodeLensHandler
}
}
} else {
AddCodeLens("base", "base", &common, ref.loc.OffsetStartColumn(1),
AddCodeLens("base", "base", &common, sym.OffsetStartColumn(db, 1),
ToReference(db, func.def->base), nullopt,
false /*force_display*/);
}
@ -253,7 +252,7 @@ struct TextDocumentCodeLensHandler
break;
}
case SymbolKind::Var: {
QueryVar& var = db->vars[symbol.idx];
QueryVar& var = sym.Var(db);
if (!var.def)
continue;
@ -266,7 +265,7 @@ struct TextDocumentCodeLensHandler
if (var.def->is_macro())
force_display = false;
AddCodeLens("ref", "refs", &common, ref.loc.OffsetStartColumn(0),
AddCodeLens("ref", "refs", &common, sym.OffsetStartColumn(db, 0),
var.uses, var.def->definition_spelling, force_display);
break;
}

View File

@ -24,23 +24,24 @@ struct Out_TextDocumentDefinition
MAKE_REFLECT_STRUCT(Out_TextDocumentDefinition, jsonrpc, id, result);
std::vector<Reference> GetGotoDefinitionTargets(QueryDatabase* db,
const SymbolIdx& symbol) {
switch (symbol.kind) {
SymbolRef sym) {
switch (sym.kind) {
// Returns GetDeclarationsOfSymbolForGotoDefinition and
// variable type definition.
case SymbolKind::Var: {
std::vector<Reference> ret =
GetDeclarationsOfSymbolForGotoDefinition(db, symbol);
QueryVar& var = db->vars[symbol.idx];
GetDeclarationsOfSymbolForGotoDefinition(db, sym);
QueryVar& var = sym.Var(db);
if (var.def && var.def->variable_type) {
std::vector<Reference> types = GetDeclarationsOfSymbolForGotoDefinition(
db, SymbolIdx(SymbolKind::Type, var.def->variable_type->id));
db, SymbolRef(Range(), Id<void>(var.def->variable_type->id),
SymbolKind::Type, SymbolRole::None));
ret.insert(ret.end(), types.begin(), types.end());
}
return ret;
}
default:
return GetDeclarationsOfSymbolForGotoDefinition(db, symbol);
return GetDeclarationsOfSymbolForGotoDefinition(db, sym);
}
}
@ -64,7 +65,7 @@ struct TextDocumentDefinitionHandler
int target_line = request->params.position.line;
int target_column = request->params.position.character;
for (const SymbolRef& ref :
for (const SymbolRef& sym :
FindSymbolsAtLocation(working_file, file, request->params.position)) {
// Found symbol. Return definition.
@ -73,14 +74,12 @@ struct TextDocumentDefinitionHandler
// - start at spelling but end at extent for better mouse tooltip
// - goto declaration while in definition of recursive type
optional<QueryLocation> def_loc =
GetDefinitionSpellingOfSymbol(db, ref.idx);
optional<QueryLocation> def_loc = GetDefinitionSpellingOfSymbol(db, sym);
// We use spelling start and extent end because this causes vscode to
// highlight the entire definition when previewing / hoving with the
// mouse.
optional<QueryLocation> def_extent =
GetDefinitionExtentOfSymbol(db, ref.idx);
optional<QueryLocation> def_extent = GetDefinitionExtentOfSymbol(db, sym);
if (def_loc && def_extent)
def_loc->range.end = def_extent->range.end;
@ -92,7 +91,7 @@ struct TextDocumentDefinitionHandler
def_loc->range.Contains(target_line, target_column))) {
// Goto declaration.
std::vector<Reference> targets = GetGotoDefinitionTargets(db, ref.idx);
std::vector<Reference> targets = GetGotoDefinitionTargets(db, sym);
for (Reference target : targets) {
optional<lsLocation> ls_target =
GetLsLocation(db, working_files, target);

View File

@ -35,13 +35,13 @@ struct TextDocumentDocumentSymbolHandler
return;
}
for (SymbolRef ref : file->def->outline) {
for (SymbolRef sym : file->def->outline) {
optional<lsSymbolInformation> info =
GetSymbolInfo(db, working_files, ref.idx, true /*use_short_name*/);
GetSymbolInfo(db, working_files, sym, true /*use_short_name*/);
if (!info)
continue;
optional<lsLocation> location = GetLsLocation(db, working_files, ref.loc);
optional<lsLocation> location = GetLsLocation(db, working_files, sym);
if (!location)
continue;
info->location = *location;

View File

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

View File

@ -6,10 +6,10 @@ namespace {
std::pair<std::string_view, std::string_view> GetCommentsAndHover(
QueryDatabase* db,
const SymbolIdx& symbol) {
switch (symbol.kind) {
SymbolRef sym) {
switch (sym.kind) {
case SymbolKind::Type: {
QueryType& type = db->types[symbol.idx];
QueryType& type = db->types[sym.Idx()];
if (type.def)
return {type.def->comments, type.def->hover.size()
? type.def->hover
@ -17,7 +17,7 @@ std::pair<std::string_view, std::string_view> GetCommentsAndHover(
break;
}
case SymbolKind::Func: {
QueryFunc& func = db->funcs[symbol.idx];
QueryFunc& func = db->funcs[sym.Idx()];
if (func.def)
return {func.def->comments, func.def->hover.size()
? func.def->hover
@ -25,7 +25,7 @@ std::pair<std::string_view, std::string_view> GetCommentsAndHover(
break;
}
case SymbolKind::Var: {
QueryVar& var = db->vars[symbol.idx];
QueryVar& var = db->vars[sym.Idx()];
if (var.def)
return {var.def->comments, var.def->hover.size()
? var.def->hover
@ -87,16 +87,16 @@ struct TextDocumentHoverHandler : BaseMessageHandler<Ipc_TextDocumentHover> {
Out_TextDocumentHover out;
out.id = request->id;
for (const SymbolRef& ref :
for (const SymbolRef& sym :
FindSymbolsAtLocation(working_file, file, request->params.position)) {
// Found symbol. Return hover.
optional<lsRange> ls_range = GetLsRange(
working_files->GetFileByFilename(file->def->path), ref.loc.range);
working_files->GetFileByFilename(file->def->path), sym.range);
if (!ls_range)
continue;
std::pair<std::string_view, std::string_view> comments_hover =
GetCommentsAndHover(db, ref.idx);
GetCommentsAndHover(db, sym);
if (comments_hover.first.size() || comments_hover.second.size()) {
out.result = Out_TextDocumentHover::Result();
if (comments_hover.first.size()) {

View File

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

View File

@ -95,11 +95,11 @@ struct TextDocumentRenameHandler : BaseMessageHandler<Ipc_TextDocumentRename> {
Out_TextDocumentRename out;
out.id = request->id;
for (const SymbolRef& ref :
for (const SymbolRef& sym :
FindSymbolsAtLocation(working_file, file, request->params.position)) {
// Found symbol. Return references to rename.
out.result = BuildWorkspaceEdit(db, working_files,
GetUsesOfSymbol(db, ref.idx, true),
GetUsesOfSymbol(db, sym, true),
request->params.newName);
break;
}

View File

@ -237,36 +237,38 @@ QueryFile::DefUpdate BuildFileDefUpdate(const IdMap& id_map, const IndexFile& in
}
}();
auto add_outline = [&def, &id_map](SymbolIdx idx, Range range) {
def.outline.push_back(
SymbolRef(idx, SymbolRole::Declaration,
id_map.ToQuery(range, SymbolRole::Declaration)));
auto add_outline = [&](Range range, RawId id, SymbolKind kind,
SymbolRole role) {
def.outline.push_back(SymbolRef(range, Id<void>(id), kind, role));
};
auto add_all_symbols = [&def, &id_map](SymbolIdx idx, SymbolRole role,
Range range) {
def.all_symbols.push_back(
SymbolRef(idx, role, id_map.ToQuery(range, role)));
auto add_all_symbols = [&](Range range, RawId id, SymbolKind kind,
SymbolRole role) {
def.all_symbols.push_back(SymbolRef(range, Id<void>(id), kind, role));
};
for (const IndexType& type : indexed.types) {
RawId id = id_map.ToQuery(type.id).id;
if (type.def.definition_spelling.has_value())
add_all_symbols(id_map.ToSymbol(type.id), SymbolRole::Definition,
*type.def.definition_spelling);
if (type.def.definition_extent.has_value())
add_outline(id_map.ToSymbol(type.id), *type.def.definition_extent);
add_all_symbols(*type.def.definition_spelling, id, SymbolKind::Type,
SymbolRole::Definition);
if (type.def.definition_extent)
add_outline(*type.def.definition_extent, id, SymbolKind::Type,
SymbolRole::None);
for (const Reference& use : type.uses)
add_all_symbols(id_map.ToSymbol(type.id), use.role, use.range);
add_all_symbols(use.range, id, SymbolKind::Type, use.role);
}
for (const IndexFunc& func : indexed.funcs) {
RawId id = id_map.ToQuery(func.id).id;
if (func.def.definition_spelling.has_value())
add_all_symbols(id_map.ToSymbol(func.id), SymbolRole::Definition,
*func.def.definition_spelling);
add_all_symbols(*func.def.definition_spelling, id, SymbolKind::Func,
SymbolRole::Definition);
if (func.def.definition_extent.has_value())
add_outline(id_map.ToSymbol(func.id), *func.def.definition_extent);
add_outline(*func.def.definition_extent, id,
SymbolKind::Func, SymbolRole::None);
for (const IndexFunc::Declaration& decl : func.declarations) {
add_all_symbols(id_map.ToSymbol(func.id), SymbolRole::Declaration,
decl.spelling);
add_outline(id_map.ToSymbol(func.id), decl.spelling);
add_all_symbols(decl.spelling, id, SymbolKind::Func,
SymbolRole::Declaration);
add_outline(decl.spelling, id, SymbolKind::Func, SymbolRole::Declaration);
}
for (const IndexFuncRef& caller : func.callers) {
// Make ranges of implicit function calls larger (spanning one more column
@ -279,31 +281,35 @@ QueryFile::DefUpdate BuildFileDefUpdate(const IdMap& id_map, const IndexFile& in
range.start.column--;
range.end.column++;
}
add_all_symbols(id_map.ToSymbol(func.id),
caller.role | SymbolRole::CalledBy, range);
add_all_symbols(range, id, SymbolKind::Func,
caller.role | SymbolRole::CalledBy);
}
}
for (const IndexVar& var : indexed.vars) {
if (var.def.definition_spelling.has_value())
add_all_symbols(id_map.ToSymbol(var.id), SymbolRole::Definition,
*var.def.definition_spelling);
if (var.def.definition_spelling)
add_all_symbols(*var.def.definition_spelling, id_map.ToQuery(var.id).id,
SymbolKind::Var, SymbolRole::Definition);
if (var.def.definition_extent.has_value())
add_outline(id_map.ToSymbol(var.id), *var.def.definition_extent);
add_outline(*var.def.definition_extent, id_map.ToQuery(var.id).id,
SymbolKind::Var, SymbolRole::None);
for (const Range& decl : var.declarations) {
add_all_symbols(id_map.ToSymbol(var.id), SymbolRole::Declaration, decl);
add_outline(id_map.ToSymbol(var.id), decl);
add_all_symbols(decl, id_map.ToQuery(var.id).id, SymbolKind::Var,
SymbolRole::Definition);
add_outline(decl, id_map.ToQuery(var.id).id, SymbolKind::Var,
SymbolRole::Declaration);
}
for (auto& use : var.uses)
add_all_symbols(id_map.ToSymbol(var.id), use.role, use.range);
add_all_symbols(use.range, id_map.ToQuery(var.id).id, SymbolKind::Var,
use.role);
}
std::sort(def.outline.begin(), def.outline.end(),
[](const SymbolRef& a, const SymbolRef& b) {
return a.loc.range.start < b.loc.range.start;
return a.range.start < b.range.start;
});
std::sort(def.all_symbols.begin(), def.all_symbols.end(),
[](const SymbolRef& a, const SymbolRef& b) {
return a.loc.range.start < b.loc.range.start;
return a.range.start < b.range.start;
});
return QueryFile::DefUpdate(def, indexed.file_contents);
@ -372,6 +378,44 @@ Maybe<QueryVarId> GetQueryVarIdFromUsr(QueryDatabase* query_db,
} // namespace
QueryFileId GetFileId(QueryDatabase* db, Reference ref) {
switch (ref.kind) {
case SymbolKind::Invalid:
break;
case SymbolKind::File:
return QueryFileId(ref.id);
case SymbolKind::Func: {
QueryFunc& file = db->funcs[ref.id.id];
if (file.def)
return file.def->file;
break;
}
case SymbolKind::Type: {
QueryType& type = db->types[ref.id.id];
if (type.def)
return type.def->file;
break;
}
case SymbolKind::Var: {
QueryVar& var = db->vars[ref.id.id];
if (var.def)
return var.def->file;
break;
}
}
return QueryFileId();
}
QueryFunc& SymbolRef::Func(QueryDatabase* db) const {
return db->funcs[Idx()];
}
QueryType& SymbolRef::Type(QueryDatabase* db) const {
return db->types[Idx()];
}
QueryVar& SymbolRef::Var(QueryDatabase* db) const {
return db->vars[Idx()];
}
Maybe<QueryFileId> QueryDatabase::GetQueryFileIdFromPath(
const std::string& path) {
return ::GetQueryFileIdFromPath(this, path, false);
@ -415,23 +459,23 @@ QueryLocation IdMap::ToQuery(Range range, SymbolRole role) const {
return QueryLocation{range, primary_file, role};
}
Reference IdMap::ToQuery(Reference ref) const {
switch (ref.lex_parent_kind) {
switch (ref.kind) {
case SymbolKind::Invalid:
case SymbolKind::File:
ref.lex_parent_kind = SymbolKind::File;
ref.lex_parent_id = Id<void>(primary_file);
ref.kind = SymbolKind::File;
ref.id = Id<void>(primary_file);
break;
case SymbolKind::Func:
ref.lex_parent_id = Id<void>(
cached_func_ids_.find(IndexFuncId(ref.lex_parent_id))->second);
ref.id = Id<void>(
cached_func_ids_.find(IndexFuncId(ref.id))->second);
break;
case SymbolKind::Type:
ref.lex_parent_id = Id<void>(
cached_type_ids_.find(IndexTypeId(ref.lex_parent_id))->second);
ref.id = Id<void>(
cached_type_ids_.find(IndexTypeId(ref.id))->second);
break;
case SymbolKind::Var:
ref.lex_parent_id =
Id<void>(cached_var_ids_.find(IndexVarId(ref.lex_parent_id))->second);
ref.id =
Id<void>(cached_var_ids_.find(IndexVarId(ref.id))->second);
break;
}
return ref;
@ -451,18 +495,18 @@ QueryVarId IdMap::ToQuery(IndexVarId id) const {
return QueryVarId(cached_var_ids_.find(id)->second);
}
QueryFuncRef IdMap::ToQuery(IndexFuncRef ref) const {
QueryFuncRef ret(ref.range, ref.lex_parent_id, ref.lex_parent_kind, ref.role);
switch (ref.lex_parent_kind) {
QueryFuncRef ret(ref.range, ref.id, ref.kind, ref.role);
switch (ref.kind) {
default:
break;
case SymbolKind::File:
ret.lex_parent_id = Id<void>(primary_file);
ret.id = Id<void>(primary_file);
break;
case SymbolKind::Func:
ret.lex_parent_id = Id<void>(ToQuery(IndexFuncId(ref.lex_parent_id)));
ret.id = Id<void>(ToQuery(IndexFuncId(ref.id)));
break;
case SymbolKind::Type:
ret.lex_parent_id = Id<void>(ToQuery(IndexTypeId(ref.lex_parent_id)));
ret.id = Id<void>(ToQuery(IndexTypeId(ref.id)));
break;
}
return ret;

View File

@ -25,12 +25,6 @@ struct QueryLocation {
QueryFileId path;
SymbolRole role;
QueryLocation OffsetStartColumn(int16_t offset) const {
QueryLocation result = *this;
result.range.start.column += offset;
return result;
}
bool HasValue() const { return range.HasValue(); }
QueryFileId FileId() const { return path; }
@ -52,15 +46,6 @@ struct QueryLocation {
MAKE_REFLECT_STRUCT(QueryLocation, range, path, role);
MAKE_HASHABLE(QueryLocation, t.range, t.path, t.role);
namespace std {
template <>
struct hash<::SymbolKind> {
size_t operator()(const ::SymbolKind& instance) const {
return std::hash<int>()(static_cast<int>(instance));
}
};
} // namespace std
struct SymbolIdx {
SymbolKind kind;
RawId idx;
@ -83,23 +68,27 @@ struct SymbolIdx {
MAKE_REFLECT_STRUCT(SymbolIdx, kind, idx);
MAKE_HASHABLE(SymbolIdx, t.kind, t.idx);
struct SymbolRef {
SymbolIdx idx;
SymbolRole role;
QueryLocation loc;
QueryFileId GetFileId(QueryDatabase* db, Reference ref);
SymbolRef() {} // Do not use, needed for reflect.
SymbolRef(SymbolIdx idx, SymbolRole role, QueryLocation loc)
: idx(idx), role(role), loc(loc) {}
struct SymbolRef : Reference {
SymbolRef() = default;
SymbolRef(Range range, Id<void> id, SymbolKind kind, SymbolRole role)
: Reference{range, id, kind, role} {}
SymbolRef(SymbolIdx si)
: Reference{Range(), Id<void>(si.idx), si.kind, SymbolRole::None} {}
std::tuple<SymbolIdx, SymbolRole, QueryLocation> ToTuple() const {
return std::make_tuple(idx, role, loc);
RawId Idx() const { return RawId(id); }
operator SymbolIdx() const { return SymbolIdx(kind, Idx()); }
QueryFunc& Func(QueryDatabase* db) const;
QueryType& Type(QueryDatabase* db) const;
QueryVar& Var(QueryDatabase* db) const;
QueryLocation OffsetStartColumn(QueryDatabase* db, int16_t offset) const {
QueryLocation ret = {range, GetFileId(db, *this), role};
ret.range.start.column += offset;
return ret;
}
bool operator==(const SymbolRef& o) const { return ToTuple() == o.ToTuple(); }
bool operator!=(const SymbolRef& o) const { return !(*this == o); }
bool operator<(const SymbolRef& o) const { return ToTuple() < o.ToTuple(); }
};
MAKE_REFLECT_STRUCT(SymbolRef, idx, loc);
struct QueryFuncRef : Reference {
QueryFuncRef() = default;
@ -107,8 +96,8 @@ struct QueryFuncRef : Reference {
: Reference{range, id, kind, role} {}
QueryFuncId FuncId() const {
if (lex_parent_kind == SymbolKind::Func)
return QueryFuncId(lex_parent_id);
if (kind == SymbolKind::Func)
return QueryFuncId(id);
return QueryFuncId();
}
};
@ -448,5 +437,3 @@ struct IdMap {
spp::sparse_hash_map<IndexFuncId, QueryFuncId> cached_func_ids_;
spp::sparse_hash_map<IndexVarId, QueryVarId> cached_var_ids_;
};
QueryFileId GetFileId(const Reference& ref, QueryDatabase* db);

View File

@ -16,34 +16,6 @@ int ComputeRangeSize(const Range& range) {
} // namespace
QueryFileId GetFileId(QueryDatabase* db, Reference ref) {
switch (ref.lex_parent_kind) {
case SymbolKind::Invalid:
break;
case SymbolKind::File:
return QueryFileId(ref.lex_parent_id);
case SymbolKind::Func: {
QueryFunc& file = db->funcs[ref.lex_parent_id.id];
if (file.def)
return file.def->file;
break;
}
case SymbolKind::Type: {
QueryType& type = db->types[ref.lex_parent_id.id];
if (type.def)
return type.def->file;
break;
}
case SymbolKind::Var: {
QueryVar& var = db->vars[ref.lex_parent_id.id];
if (var.def)
return var.def->file;
break;
}
}
return QueryFileId();
}
optional<QueryLocation> GetDefinitionSpellingOfSymbol(QueryDatabase* db,
const QueryTypeId& id) {
QueryType& type = db->types[id.id];
@ -69,22 +41,22 @@ optional<QueryLocation> GetDefinitionSpellingOfSymbol(QueryDatabase* db,
}
optional<QueryLocation> GetDefinitionSpellingOfSymbol(QueryDatabase* db,
const SymbolIdx& symbol) {
switch (symbol.kind) {
SymbolRef sym) {
switch (sym.kind) {
case SymbolKind::Type: {
QueryType& type = db->types[symbol.idx];
QueryType& type = sym.Type(db);
if (type.def)
return *type.def->definition_spelling;
break;
}
case SymbolKind::Func: {
QueryFunc& func = db->funcs[symbol.idx];
QueryFunc& func = sym.Func(db);
if (func.def)
return func.def->definition_spelling;
break;
}
case SymbolKind::Var: {
QueryVar& var = db->vars[symbol.idx];
QueryVar& var = sym.Var(db);
if (var.def)
return var.def->definition_spelling;
break;
@ -99,29 +71,29 @@ optional<QueryLocation> GetDefinitionSpellingOfSymbol(QueryDatabase* db,
}
optional<QueryLocation> GetDefinitionExtentOfSymbol(QueryDatabase* db,
const SymbolIdx& symbol) {
switch (symbol.kind) {
SymbolRef sym) {
switch (sym.kind) {
case SymbolKind::Type: {
QueryType& type = db->types[symbol.idx];
QueryType& type = sym.Type(db);
if (type.def)
return type.def->definition_extent;
break;
}
case SymbolKind::Func: {
QueryFunc& func = db->funcs[symbol.idx];
QueryFunc& func = sym.Func(db);
if (func.def)
return func.def->definition_extent;
break;
}
case SymbolKind::Var: {
QueryVar& var = db->vars[symbol.idx];
QueryVar& var = sym.Var(db);
if (var.def)
return var.def->definition_extent;
break;
}
case SymbolKind::File: {
return QueryLocation{Range(Position(0, 0), Position(0, 0)),
QueryFileId(symbol.idx), SymbolRole::None};
QueryFileId(sym.Idx()), SymbolRole::None};
}
case SymbolKind::Invalid: {
assert(false && "unexpected");
@ -132,16 +104,16 @@ optional<QueryLocation> GetDefinitionExtentOfSymbol(QueryDatabase* db,
}
optional<QueryFileId> GetDeclarationFileForSymbol(QueryDatabase* db,
const SymbolIdx& symbol) {
switch (symbol.kind) {
SymbolRef sym) {
switch (sym.kind) {
case SymbolKind::Type: {
QueryType& type = db->types[symbol.idx];
QueryType& type = sym.Type(db);
if (type.def && type.def->definition_spelling)
return type.def->definition_spelling->FileId();
break;
}
case SymbolKind::Func: {
QueryFunc& func = db->funcs[symbol.idx];
QueryFunc& func = sym.Func(db);
if (!func.declarations.empty())
return GetFileId(db, func.declarations[0]);
if (func.def && func.def->definition_spelling)
@ -149,13 +121,13 @@ optional<QueryFileId> GetDeclarationFileForSymbol(QueryDatabase* db,
break;
}
case SymbolKind::Var: {
QueryVar& var = db->vars[symbol.idx];
QueryVar& var = sym.Var(db);
if (var.def && var.def->definition_spelling)
return var.def->definition_spelling->FileId();
break;
}
case SymbolKind::File: {
return QueryFileId(symbol.idx);
return QueryFileId(sym.Idx());
}
case SymbolKind::Invalid: {
assert(false && "unexpected");
@ -175,11 +147,11 @@ std::vector<Reference> ToReference(QueryDatabase* db,
}
std::vector<Reference> GetUsesOfSymbol(QueryDatabase* db,
const SymbolIdx& symbol,
SymbolRef sym,
bool include_decl) {
switch (symbol.kind) {
switch (sym.kind) {
case SymbolKind::Type: {
QueryType& type = db->types[symbol.idx];
QueryType& type = db->types[sym.Idx()];
std::vector<Reference> ret = type.uses;
if (include_decl && type.def && type.def->definition_spelling)
ret.push_back(*type.def->definition_spelling);
@ -187,7 +159,7 @@ std::vector<Reference> GetUsesOfSymbol(QueryDatabase* db,
}
case SymbolKind::Func: {
// TODO: the vector allocation could be avoided.
QueryFunc& func = db->funcs[symbol.idx];
QueryFunc& func = db->funcs[sym.Idx()];
std::vector<Reference> ret = ToReference(db, func.callers);
if (include_decl) {
AddRange(&ret, func.declarations);
@ -197,7 +169,7 @@ std::vector<Reference> GetUsesOfSymbol(QueryDatabase* db,
return ret;
}
case SymbolKind::Var: {
QueryVar& var = db->vars[symbol.idx];
QueryVar& var = db->vars[sym.Idx()];
std::vector<Reference> ret = var.uses;
if (include_decl) {
if (var.def && var.def->definition_spelling)
@ -216,14 +188,14 @@ std::vector<Reference> GetUsesOfSymbol(QueryDatabase* db,
std::vector<Reference> GetDeclarationsOfSymbolForGotoDefinition(
QueryDatabase* db,
SymbolIdx symbol) {
switch (symbol.kind) {
SymbolRef sym) {
switch (sym.kind) {
case SymbolKind::Type: {
// Returning the definition spelling of a type is a hack (and is why the
// function has the postfix `ForGotoDefintion`, but it lets the user
// jump to the start of a type if clicking goto-definition on the same
// type from within the type definition.
QueryType& type = db->types[symbol.idx];
QueryType& type = sym.Type(db);
if (type.def) {
optional<QueryLocation> declaration = type.def->definition_spelling;
if (declaration)
@ -232,9 +204,9 @@ std::vector<Reference> GetDeclarationsOfSymbolForGotoDefinition(
break;
}
case SymbolKind::Func:
return db->funcs[symbol.idx].declarations;
return sym.Func(db).declarations;
case SymbolKind::Var:
return db->vars[symbol.idx].declarations;
return sym.Var(db).declarations;
default:
break;
}
@ -425,13 +397,13 @@ std::vector<lsLocation> GetLsLocations(
// Returns a symbol. The symbol will have *NOT* have a location assigned.
optional<lsSymbolInformation> GetSymbolInfo(QueryDatabase* db,
WorkingFiles* working_files,
SymbolIdx symbol,
SymbolRef sym,
bool use_short_name) {
switch (symbol.kind) {
switch (sym.kind) {
case SymbolKind::File: {
QueryFile& file = db->files[symbol.idx];
QueryFile& file = db->files[sym.Idx()];
if (!file.def)
return nullopt;
break;
lsSymbolInformation info;
info.name = file.def->path;
@ -439,9 +411,9 @@ optional<lsSymbolInformation> GetSymbolInfo(QueryDatabase* db,
return info;
}
case SymbolKind::Type: {
QueryType& type = db->types[symbol.idx];
QueryType& type = sym.Type(db);
if (!type.def)
return nullopt;
break;
lsSymbolInformation info;
if (use_short_name)
@ -462,9 +434,9 @@ optional<lsSymbolInformation> GetSymbolInfo(QueryDatabase* db,
return info;
}
case SymbolKind::Func: {
QueryFunc& func = db->funcs[symbol.idx];
QueryFunc& func = sym.Func(db);
if (!func.def)
return nullopt;
break;
lsSymbolInformation info;
if (use_short_name)
@ -483,9 +455,9 @@ optional<lsSymbolInformation> GetSymbolInfo(QueryDatabase* db,
return info;
}
case SymbolKind::Var: {
QueryVar& var = db->vars[symbol.idx];
QueryVar& var = sym.Var(db);
if (!var.def)
return nullopt;
break;
lsSymbolInformation info;
if (use_short_name)
@ -496,10 +468,9 @@ optional<lsSymbolInformation> GetSymbolInfo(QueryDatabase* db,
info.kind = lsSymbolKind::Variable;
return info;
}
case SymbolKind::Invalid: {
return nullopt;
case SymbolKind::Invalid:
break;
}
};
return nullopt;
}
@ -520,9 +491,9 @@ std::vector<SymbolRef> FindSymbolsAtLocation(WorkingFile* working_file,
target_line = *index_line;
}
for (const SymbolRef& ref : file->def->all_symbols) {
if (ref.loc.range.Contains(target_line, target_column))
symbols.push_back(ref);
for (const SymbolRef& sym : file->def->all_symbols) {
if (sym.range.Contains(target_line, target_column))
symbols.push_back(sym);
}
// Order shorter ranges first, since they are more detailed/precise. This is
@ -538,17 +509,16 @@ std::vector<SymbolRef> FindSymbolsAtLocation(WorkingFile* working_file,
// better on constructors.
std::sort(symbols.begin(), symbols.end(),
[](const SymbolRef& a, const SymbolRef& b) {
int a_size = ComputeRangeSize(a.loc.range);
int b_size = ComputeRangeSize(b.loc.range);
int a_size = ComputeRangeSize(a.range);
int b_size = ComputeRangeSize(b.range);
if (a_size != b_size)
return a_size < b_size;
// operator> orders Var/Func before Type.
int t =
static_cast<int>(a.idx.kind) - static_cast<int>(b.idx.kind);
int t = static_cast<int>(a.kind) - static_cast<int>(b.kind);
if (t)
return t > 0;
return a.idx.idx < b.idx.idx;
return a.Idx() < b.Idx();
});
return symbols;

View File

@ -14,13 +14,11 @@ optional<QueryLocation> GetDefinitionSpellingOfSymbol(QueryDatabase* db,
optional<QueryLocation> GetDefinitionSpellingOfSymbol(QueryDatabase* db,
const QueryVarId& id);
optional<QueryLocation> GetDefinitionSpellingOfSymbol(QueryDatabase* db,
const SymbolIdx& symbol);
SymbolRef sym);
optional<QueryLocation> GetDefinitionExtentOfSymbol(QueryDatabase* db,
const SymbolIdx& symbol);
SymbolRef sym);
optional<QueryFileId> GetDeclarationFileForSymbol(QueryDatabase* db,
const SymbolIdx& symbol);
QueryFileId GetFileId(QueryDatabase* db, Reference ref);
SymbolRef sym);
std::vector<Reference> ToReference(QueryDatabase* db,
const std::vector<QueryFuncRef>& refs);
@ -39,11 +37,11 @@ std::vector<Reference> ToReference(QueryDatabase* db,
}
std::vector<Reference> GetUsesOfSymbol(QueryDatabase* db,
const SymbolIdx& symbol,
SymbolRef sym,
bool include_decl);
std::vector<Reference> GetDeclarationsOfSymbolForGotoDefinition(
QueryDatabase* db,
SymbolIdx symbol);
SymbolRef sym);
bool HasCallersOnSelfOrBaseOrDerived(QueryDatabase* db, QueryFunc& root);
std::vector<QueryFuncRef> GetCallersForAllBaseFunctions(QueryDatabase* db,
@ -68,7 +66,7 @@ std::vector<lsLocation> GetLsLocations(
// Returns a symbol. The symbol will have *NOT* have a location assigned.
optional<lsSymbolInformation> GetSymbolInfo(QueryDatabase* db,
WorkingFiles* working_files,
SymbolIdx symbol,
SymbolRef sym,
bool use_short_name);
std::vector<SymbolRef> FindSymbolsAtLocation(WorkingFile* working_file,

2
third_party/loguru vendored

@ -1 +1 @@
Subproject commit 2c35b5e7251ab5d364b1b3164eccef7b5d2293c5
Subproject commit bead38889d44d9fdb5c52916d1f26c4d6af09e66