mirror of
https://github.com/MaskRay/ccls.git
synced 2024-11-26 01:21:57 +00:00
Rename Reference members
This commit is contained in:
parent
c5f08c5eb8
commit
c4bd7ef44b
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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();
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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));
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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)
|
||||
|
@ -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()) {
|
||||
|
@ -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 =
|
||||
|
@ -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;
|
||||
}
|
||||
|
132
src/query.cc
132
src/query.cc
@ -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;
|
||||
|
51
src/query.h
51
src/query.h
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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
2
third_party/loguru
vendored
@ -1 +1 @@
|
||||
Subproject commit 2c35b5e7251ab5d364b1b3164eccef7b5d2293c5
|
||||
Subproject commit bead38889d44d9fdb5c52916d1f26c4d6af09e66
|
Loading…
Reference in New Issue
Block a user