mirror of
https://github.com/MaskRay/ccls.git
synced 2025-02-18 06:31:15 +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);
|
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) {
|
void AddUse(std::vector<Reference>& values, Range value) {
|
||||||
values.push_back(Reference{value, Id<void>(), SymbolKind::Invalid,
|
values.push_back(Reference{value, Id<void>(), SymbolKind::Invalid,
|
||||||
SymbolRole::Reference});
|
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) {
|
void UniqueAdd(std::vector<Reference>& values, Range value) {
|
||||||
if (std::find_if(values.begin(), values.end(), [&](const Reference& ref) {
|
if (std::find_if(values.begin(), values.end(), [&](const Reference& ref) {
|
||||||
return ref.range == value;
|
return ref.range == value;
|
||||||
@ -2341,7 +2341,7 @@ void Reflect(Reader& visitor, IndexFuncRef& value) {
|
|||||||
RawId id = atol(str_value);
|
RawId id = atol(str_value);
|
||||||
const char* loc_string = strchr(str_value, '@') + 1;
|
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);
|
value.range = Range(loc_string);
|
||||||
} else {
|
} else {
|
||||||
Reflect(visitor, static_cast<Reference&>(value));
|
Reflect(visitor, static_cast<Reference&>(value));
|
||||||
@ -2354,8 +2354,8 @@ void Reflect(Writer& visitor, IndexFuncRef& value) {
|
|||||||
s += "~";
|
s += "~";
|
||||||
|
|
||||||
// id.id is unsigned, special case -1 value
|
// id.id is unsigned, special case -1 value
|
||||||
if (value.lex_parent_id.HasValue())
|
if (value.id.HasValue())
|
||||||
s += std::to_string(value.lex_parent_id.id);
|
s += std::to_string(value.id.id);
|
||||||
else
|
else
|
||||||
s += "-1";
|
s += "-1";
|
||||||
|
|
||||||
@ -2377,13 +2377,13 @@ void Reflect(Reader& visitor, Reference& value) {
|
|||||||
else {
|
else {
|
||||||
char* p = const_cast<char*>(s.c_str()) + sep;
|
char* p = const_cast<char*>(s.c_str()) + sep;
|
||||||
value.role = SymbolRole(strtol(p + 1, &p, 10));
|
value.role = SymbolRole(strtol(p + 1, &p, 10));
|
||||||
value.lex_parent_kind = SymbolKind(strtol(p + 1, &p, 10));
|
value.kind = SymbolKind(strtol(p + 1, &p, 10));
|
||||||
value.lex_parent_id = Id<void>(strtol(p + 1, &p, 10));
|
value.id = Id<void>(strtol(p + 1, &p, 10));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Reflect(visitor, value.range);
|
Reflect(visitor, value.range);
|
||||||
Reflect(visitor, value.lex_parent_id);
|
Reflect(visitor, value.id);
|
||||||
Reflect(visitor, value.lex_parent_kind);
|
Reflect(visitor, value.kind);
|
||||||
Reflect(visitor, value.role);
|
Reflect(visitor, value.role);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2391,16 +2391,16 @@ void Reflect(Writer& visitor, Reference& value) {
|
|||||||
if (visitor.Format() == SerializeFormat::Json) {
|
if (visitor.Format() == SerializeFormat::Json) {
|
||||||
std::string s = value.range.ToString();
|
std::string s = value.range.ToString();
|
||||||
if (value.role != SymbolRole::Reference ||
|
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.role));
|
||||||
s += '|' + std::to_string(uint8_t(value.lex_parent_kind));
|
s += '|' + std::to_string(uint8_t(value.kind));
|
||||||
s += '|' + std::to_string(RawId(value.lex_parent_id));
|
s += '|' + std::to_string(RawId(value.id));
|
||||||
}
|
}
|
||||||
visitor.String(s.c_str());
|
visitor.String(s.c_str());
|
||||||
} else {
|
} else {
|
||||||
Reflect(visitor, value.range);
|
Reflect(visitor, value.range);
|
||||||
Reflect(visitor, value.lex_parent_id);
|
Reflect(visitor, value.id);
|
||||||
Reflect(visitor, value.lex_parent_kind);
|
Reflect(visitor, value.kind);
|
||||||
Reflect(visitor, value.role);
|
Reflect(visitor, value.role);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -54,9 +54,9 @@ struct Id {
|
|||||||
|
|
||||||
bool HasValue() const { return id != RawId(-1); }
|
bool HasValue() const { return id != RawId(-1); }
|
||||||
|
|
||||||
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<T>& o) const { return id != o.id; }
|
bool operator!=(const Id& 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; }
|
||||||
};
|
};
|
||||||
|
|
||||||
namespace std {
|
namespace std {
|
||||||
@ -80,13 +80,13 @@ struct IdCache;
|
|||||||
|
|
||||||
struct Reference {
|
struct Reference {
|
||||||
Range range;
|
Range range;
|
||||||
Id<void> lex_parent_id;
|
Id<void> id;
|
||||||
SymbolKind lex_parent_kind;
|
SymbolKind kind;
|
||||||
SymbolRole role;
|
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 {
|
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 {
|
bool operator==(const Reference& o) const {
|
||||||
return ToTuple() == o.ToTuple();
|
return ToTuple() == o.ToTuple();
|
||||||
|
@ -115,18 +115,18 @@ void EmitSemanticHighlighting(QueryDatabase* db,
|
|||||||
ClangSymbolKind kind = ClangSymbolKind::Unknown;
|
ClangSymbolKind kind = ClangSymbolKind::Unknown;
|
||||||
StorageClass storage = StorageClass::Invalid;
|
StorageClass storage = StorageClass::Invalid;
|
||||||
// This switch statement also filters out symbols that are not highlighted.
|
// This switch statement also filters out symbols that are not highlighted.
|
||||||
switch (sym.idx.kind) {
|
switch (sym.kind) {
|
||||||
case SymbolKind::Func: {
|
case SymbolKind::Func: {
|
||||||
QueryFunc* func = &db->funcs[sym.idx.idx];
|
QueryFunc& func = sym.Func(db);
|
||||||
if (!func->def)
|
if (!func.def)
|
||||||
continue; // applies to for loop
|
continue; // applies to for loop
|
||||||
// Don't highlight overloadable operators or implicit lambda ->
|
// Don't highlight overloadable operators or implicit lambda ->
|
||||||
// std::function constructor.
|
// 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 ||
|
if (short_name.compare(0, 8, "operator") == 0 ||
|
||||||
short_name.compare(0, 27, "function<type-parameter-0-0") == 0)
|
short_name.compare(0, 27, "function<type-parameter-0-0") == 0)
|
||||||
continue; // applies to for loop
|
continue; // applies to for loop
|
||||||
kind = func->def->kind;
|
kind = func.def->kind;
|
||||||
detailed_name = short_name;
|
detailed_name = short_name;
|
||||||
|
|
||||||
// Check whether the function name is actually there.
|
// 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.
|
// but we still want to keep the range for jumping to definition.
|
||||||
std::string_view concise_name =
|
std::string_view concise_name =
|
||||||
detailed_name.substr(0, detailed_name.find('<'));
|
detailed_name.substr(0, detailed_name.find('<'));
|
||||||
int16_t start_line = sym.loc.range.start.line;
|
int16_t start_line = sym.range.start.line;
|
||||||
int16_t start_col = sym.loc.range.start.column;
|
int16_t start_col = sym.range.start.column;
|
||||||
if (start_line >= 0 && start_line < working_file->index_lines.size()) {
|
if (start_line >= 0 && start_line < working_file->index_lines.size()) {
|
||||||
std::string_view line = working_file->index_lines[start_line];
|
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)
|
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
|
else
|
||||||
continue; // applies to for loop
|
continue; // applies to for loop
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case SymbolKind::Var: {
|
case SymbolKind::Var: {
|
||||||
QueryVar* var = &db->vars[sym.idx.idx];
|
QueryVar& var = sym.Var(db);
|
||||||
if (!var->def)
|
if (!var.def)
|
||||||
continue; // applies to for loop
|
continue; // applies to for loop
|
||||||
parent_kind = var->def->parent_kind;
|
parent_kind = var.def->parent_kind;
|
||||||
kind = var->def->kind;
|
kind = var.def->kind;
|
||||||
storage = var->def->storage;
|
storage = var.def->storage;
|
||||||
detailed_name = var->def->ShortName();
|
detailed_name = var.def->ShortName();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case SymbolKind::Type: {
|
case SymbolKind::Type: {
|
||||||
QueryType* type = &db->types[sym.idx.idx];
|
QueryType& type = sym.Type(db);
|
||||||
if (!type->def)
|
if (!type.def)
|
||||||
continue; // applies to for loop
|
continue; // applies to for loop
|
||||||
kind = type->def->kind;
|
kind = type.def->kind;
|
||||||
detailed_name = type->def->detailed_name;
|
detailed_name = type.def->detailed_name;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
continue; // applies to for loop
|
continue; // applies to for loop
|
||||||
}
|
}
|
||||||
|
|
||||||
optional<lsRange> loc = GetLsRange(working_file, sym.loc.range);
|
optional<lsRange> loc = GetLsRange(working_file, sym.range);
|
||||||
if (loc) {
|
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()) {
|
if (it != grouped_symbols.end()) {
|
||||||
it->second.ranges.push_back(*loc);
|
it->second.ranges.push_back(*loc);
|
||||||
} else {
|
} else {
|
||||||
Out_CqueryPublishSemanticHighlighting::Symbol symbol;
|
Out_CqueryPublishSemanticHighlighting::Symbol symbol;
|
||||||
symbol.stableId = semantic_cache_for_file->GetStableId(
|
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.parentKind = parent_kind;
|
||||||
symbol.kind = kind;
|
symbol.kind = kind;
|
||||||
symbol.storage = storage;
|
symbol.storage = storage;
|
||||||
symbol.ranges.push_back(*loc);
|
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_LocationList out;
|
||||||
out.id = request->id;
|
out.id = request->id;
|
||||||
std::vector<SymbolRef> refs =
|
std::vector<SymbolRef> syms =
|
||||||
FindSymbolsAtLocation(working_file, file, request->params.position);
|
FindSymbolsAtLocation(working_file, file, request->params.position);
|
||||||
// A template definition may be a use of its primary template.
|
// A template definition may be a use of its primary template.
|
||||||
// We want to get the definition instead of the use.
|
// We want to get the definition instead of the use.
|
||||||
// Order by |Definition| DESC, range size ASC.
|
// 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) {
|
[](const SymbolRef& a, const SymbolRef& b) {
|
||||||
return (a.role & SymbolRole::Definition) >
|
return (a.role & SymbolRole::Definition) >
|
||||||
(b.role & SymbolRole::Definition);
|
(b.role & SymbolRole::Definition);
|
||||||
});
|
});
|
||||||
for (const SymbolRef& ref : refs) {
|
for (const SymbolRef& sym : syms) {
|
||||||
if (ref.idx.kind == SymbolKind::Type) {
|
if (sym.kind == SymbolKind::Type) {
|
||||||
QueryType& type = db->types[ref.idx.idx];
|
QueryType& type = sym.Type(db);
|
||||||
if (type.def)
|
if (type.def)
|
||||||
out.result = GetLsLocations(db, working_files,
|
out.result = GetLsLocations(db, working_files,
|
||||||
ToReference(db, type.def->parents));
|
ToReference(db, type.def->parents));
|
||||||
break;
|
break;
|
||||||
} else if (ref.idx.kind == SymbolKind::Func) {
|
} else if (sym.kind == SymbolKind::Func) {
|
||||||
QueryFunc& func = db->funcs[ref.idx.idx];
|
QueryFunc& func = sym.Func(db);
|
||||||
if (func.def)
|
if (func.def)
|
||||||
out.result =
|
out.result =
|
||||||
GetLsLocations(db, working_files, ToReference(db, func.def->base));
|
GetLsLocations(db, working_files, ToReference(db, func.def->base));
|
||||||
|
@ -171,11 +171,11 @@ struct CqueryCallTreeInitialHandler
|
|||||||
Out_CqueryCallTree out;
|
Out_CqueryCallTree out;
|
||||||
out.id = request->id;
|
out.id = request->id;
|
||||||
|
|
||||||
for (const SymbolRef& ref :
|
for (SymbolRef sym :
|
||||||
FindSymbolsAtLocation(working_file, file, request->params.position)) {
|
FindSymbolsAtLocation(working_file, file, request->params.position)) {
|
||||||
if (ref.idx.kind == SymbolKind::Func) {
|
if (sym.kind == SymbolKind::Func) {
|
||||||
out.result =
|
out.result =
|
||||||
BuildInitialCallTree(db, working_files, QueryFuncId(ref.idx.idx));
|
BuildInitialCallTree(db, working_files, QueryFuncId(sym.Idx()));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -23,10 +23,10 @@ struct CqueryCallersHandler : BaseMessageHandler<Ipc_CqueryCallers> {
|
|||||||
|
|
||||||
Out_LocationList out;
|
Out_LocationList out;
|
||||||
out.id = request->id;
|
out.id = request->id;
|
||||||
for (const SymbolRef& ref :
|
for (const SymbolRef& sym :
|
||||||
FindSymbolsAtLocation(working_file, file, request->params.position)) {
|
FindSymbolsAtLocation(working_file, file, request->params.position)) {
|
||||||
if (ref.idx.kind == SymbolKind::Func) {
|
if (sym.kind == SymbolKind::Func) {
|
||||||
QueryFunc& func = db->funcs[ref.idx.idx];
|
QueryFunc& func = db->funcs[sym.Idx()];
|
||||||
std::vector<Reference> uses = ToReference(db, func.callers);
|
std::vector<Reference> uses = ToReference(db, func.callers);
|
||||||
for (QueryFuncRef func_ref : GetCallersForAllBaseFunctions(db, func))
|
for (QueryFuncRef func_ref : GetCallersForAllBaseFunctions(db, func))
|
||||||
uses.push_back(func_ref);
|
uses.push_back(func_ref);
|
||||||
|
@ -23,24 +23,24 @@ struct CqueryDerivedHandler : BaseMessageHandler<Ipc_CqueryDerived> {
|
|||||||
|
|
||||||
Out_LocationList out;
|
Out_LocationList out;
|
||||||
out.id = request->id;
|
out.id = request->id;
|
||||||
std::vector<SymbolRef> refs =
|
std::vector<SymbolRef> syms =
|
||||||
FindSymbolsAtLocation(working_file, file, request->params.position);
|
FindSymbolsAtLocation(working_file, file, request->params.position);
|
||||||
// A template definition may be a use of its primary template.
|
// A template definition may be a use of its primary template.
|
||||||
// We want to get the definition instead of the use.
|
// We want to get the definition instead of the use.
|
||||||
// Order by |Definition| DESC, range size ASC.
|
// 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) {
|
[](const SymbolRef& a, const SymbolRef& b) {
|
||||||
return (a.role & SymbolRole::Definition) >
|
return (a.role & SymbolRole::Definition) >
|
||||||
(b.role & SymbolRole::Definition);
|
(b.role & SymbolRole::Definition);
|
||||||
});
|
});
|
||||||
for (const SymbolRef& ref : refs) {
|
for (const SymbolRef& sym : syms) {
|
||||||
if (ref.idx.kind == SymbolKind::Type) {
|
if (sym.kind == SymbolKind::Type) {
|
||||||
QueryType& type = db->types[ref.idx.idx];
|
QueryType& type = sym.Type(db);
|
||||||
out.result =
|
out.result =
|
||||||
GetLsLocations(db, working_files, ToReference(db, type.derived));
|
GetLsLocations(db, working_files, ToReference(db, type.derived));
|
||||||
break;
|
break;
|
||||||
} else if (ref.idx.kind == SymbolKind::Func) {
|
} else if (sym.kind == SymbolKind::Func) {
|
||||||
QueryFunc& func = db->funcs[ref.idx.idx];
|
QueryFunc& func = sym.Func(db);
|
||||||
out.result =
|
out.result =
|
||||||
GetLsLocations(db, working_files, ToReference(db, func.derived));
|
GetLsLocations(db, working_files, ToReference(db, func.derived));
|
||||||
break;
|
break;
|
||||||
|
@ -92,14 +92,14 @@ struct CqueryMemberHierarchyInitialHandler
|
|||||||
Out_CqueryMemberHierarchy out;
|
Out_CqueryMemberHierarchy out;
|
||||||
out.id = request->id;
|
out.id = request->id;
|
||||||
|
|
||||||
for (const SymbolRef& ref :
|
for (const SymbolRef& sym :
|
||||||
FindSymbolsAtLocation(working_file, file, request->params.position)) {
|
FindSymbolsAtLocation(working_file, file, request->params.position)) {
|
||||||
if (ref.idx.kind == SymbolKind::Type) {
|
if (sym.kind == SymbolKind::Type) {
|
||||||
out.result = BuildInitial(db, working_files, QueryTypeId(ref.idx.idx));
|
out.result = BuildInitial(db, working_files, QueryTypeId(sym.Idx()));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (ref.idx.kind == SymbolKind::Var) {
|
if (sym.kind == SymbolKind::Var) {
|
||||||
QueryVar& var = db->vars[ref.idx.idx];
|
QueryVar& var = sym.Var(db);
|
||||||
if (var.def && var.def->variable_type)
|
if (var.def && var.def->variable_type)
|
||||||
out.result = BuildInitial(db, working_files, *var.def->variable_type);
|
out.result = BuildInitial(db, working_files, *var.def->variable_type);
|
||||||
break;
|
break;
|
||||||
|
@ -165,18 +165,18 @@ struct CqueryTypeHierarchyTreeHandler
|
|||||||
Out_CqueryTypeHierarchyTree out;
|
Out_CqueryTypeHierarchyTree out;
|
||||||
out.id = request->id;
|
out.id = request->id;
|
||||||
|
|
||||||
for (const SymbolRef& ref :
|
for (const SymbolRef& sym :
|
||||||
FindSymbolsAtLocation(working_file, file, request->params.position)) {
|
FindSymbolsAtLocation(working_file, file, request->params.position)) {
|
||||||
if (ref.idx.kind == SymbolKind::Type) {
|
if (sym.kind == SymbolKind::Type) {
|
||||||
QueryType& type = db->types[ref.idx.idx];
|
QueryType& type = sym.Type(db);
|
||||||
if (type.def)
|
if (type.def)
|
||||||
out.result =
|
out.result =
|
||||||
BuildInheritanceHierarchyForType(db, working_files, type);
|
BuildInheritanceHierarchyForType(db, working_files, type);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (ref.idx.kind == SymbolKind::Func) {
|
if (sym.kind == SymbolKind::Func) {
|
||||||
out.result = BuildInheritanceHierarchyForFunc(db, working_files,
|
out.result = BuildInheritanceHierarchyForFunc(db, working_files,
|
||||||
QueryFuncId(ref.idx.idx));
|
QueryFuncId(sym.id));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -25,19 +25,19 @@ struct CqueryVarsHandler : BaseMessageHandler<Ipc_CqueryVars> {
|
|||||||
out.id = request->id;
|
out.id = request->id;
|
||||||
for (const SymbolRef& ref :
|
for (const SymbolRef& ref :
|
||||||
FindSymbolsAtLocation(working_file, file, request->params.position)) {
|
FindSymbolsAtLocation(working_file, file, request->params.position)) {
|
||||||
size_t id = ref.idx.idx;
|
RawId idx = ref.Idx();
|
||||||
switch (ref.idx.kind) {
|
switch (ref.kind) {
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
case SymbolKind::Var: {
|
case SymbolKind::Var: {
|
||||||
QueryVar& var = db->vars[id];
|
QueryVar& var = db->vars[idx];
|
||||||
if (!var.def || !var.def->variable_type)
|
if (!var.def || !var.def->variable_type)
|
||||||
continue;
|
continue;
|
||||||
id = var.def->variable_type->id;
|
idx = var.def->variable_type->id;
|
||||||
}
|
}
|
||||||
// fallthrough
|
// fallthrough
|
||||||
case SymbolKind::Type: {
|
case SymbolKind::Type: {
|
||||||
QueryType& type = db->types[id];
|
QueryType& type = db->types[idx];
|
||||||
out.result = GetLsLocations(db, working_files,
|
out.result = GetLsLocations(db, working_files,
|
||||||
ToReference(db, type.instances));
|
ToReference(db, type.instances));
|
||||||
break;
|
break;
|
||||||
|
@ -67,9 +67,9 @@ optional<QueryFileId> GetImplementationFile(QueryDatabase* db,
|
|||||||
QueryFileId file_id,
|
QueryFileId file_id,
|
||||||
QueryFile* file) {
|
QueryFile* file) {
|
||||||
for (SymbolRef sym : file->def->outline) {
|
for (SymbolRef sym : file->def->outline) {
|
||||||
switch (sym.idx.kind) {
|
switch (sym.kind) {
|
||||||
case SymbolKind::Func: {
|
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,
|
// Note: we ignore the definition if it is in the same file (ie,
|
||||||
// possibly a header).
|
// possibly a header).
|
||||||
if (func.def && func.def->definition_extent &&
|
if (func.def && func.def->definition_extent &&
|
||||||
@ -79,12 +79,12 @@ optional<QueryFileId> GetImplementationFile(QueryDatabase* db,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case SymbolKind::Var: {
|
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,
|
// Note: we ignore the definition if it is in the same file (ie,
|
||||||
// possibly a header).
|
// possibly a header).
|
||||||
if (var.def && var.def->definition_extent &&
|
if (var.def && var.def->definition_extent &&
|
||||||
var.def->definition_extent->FileId() != file_id) {
|
var.def->definition_extent->FileId() != file_id) {
|
||||||
return db->vars[sym.idx.idx].def->definition_extent->FileId();
|
return var.def->definition_extent->FileId();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -196,9 +196,9 @@ optional<lsTextEdit> BuildAutoImplementForFunction(QueryDatabase* db,
|
|||||||
QueryFile& file = db->files[impl_file_id.id];
|
QueryFile& file = db->files[impl_file_id.id];
|
||||||
assert(file.def);
|
assert(file.def);
|
||||||
for (SymbolRef sym : file.def->outline) {
|
for (SymbolRef sym : file.def->outline) {
|
||||||
switch (sym.idx.kind) {
|
switch (sym.kind) {
|
||||||
case SymbolKind::Func: {
|
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)
|
if (!sym_func.def || !sym_func.def->definition_extent)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -231,7 +231,7 @@ optional<lsTextEdit> BuildAutoImplementForFunction(QueryDatabase* db,
|
|||||||
case SymbolKind::File:
|
case SymbolKind::File:
|
||||||
case SymbolKind::Type:
|
case SymbolKind::Type:
|
||||||
LOG_S(WARNING) << "Unexpected SymbolKind "
|
LOG_S(WARNING) << "Unexpected SymbolKind "
|
||||||
<< static_cast<int>(sym.idx.kind);
|
<< static_cast<int>(sym.kind);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -342,9 +342,9 @@ struct TextDocumentCodeActionHandler
|
|||||||
std::vector<SymbolRef> syms =
|
std::vector<SymbolRef> syms =
|
||||||
FindSymbolsAtLocation(working_file, file, request->params.range.start);
|
FindSymbolsAtLocation(working_file, file, request->params.range.start);
|
||||||
for (SymbolRef sym : syms) {
|
for (SymbolRef sym : syms) {
|
||||||
switch (sym.idx.kind) {
|
switch (sym.kind) {
|
||||||
case SymbolKind::Type: {
|
case SymbolKind::Type: {
|
||||||
QueryType& type = db->types[sym.idx.idx];
|
QueryType& type = sym.Type(db);
|
||||||
if (!type.def)
|
if (!type.def)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -395,7 +395,7 @@ struct TextDocumentCodeActionHandler
|
|||||||
}
|
}
|
||||||
|
|
||||||
case SymbolKind::Func: {
|
case SymbolKind::Func: {
|
||||||
QueryFunc& func = db->funcs[sym.idx.idx];
|
QueryFunc& func = sym.Func(db);
|
||||||
if (!func.def || func.def->definition_extent)
|
if (!func.def || func.def->definition_extent)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -143,32 +143,30 @@ struct TextDocumentCodeLensHandler
|
|||||||
common.working_files = working_files;
|
common.working_files = working_files;
|
||||||
common.working_file = working_files->GetFileByFilename(file->def->path);
|
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
|
// NOTE: We OffsetColumn so that the code lens always show up in a
|
||||||
// predictable order. Otherwise, the client may randomize it.
|
// predictable order. Otherwise, the client may randomize it.
|
||||||
|
|
||||||
SymbolIdx symbol = ref.idx;
|
switch (sym.kind) {
|
||||||
switch (symbol.kind) {
|
|
||||||
case SymbolKind::Type: {
|
case SymbolKind::Type: {
|
||||||
QueryType& type = db->types[symbol.idx];
|
QueryType& type = sym.Type(db);
|
||||||
if (!type.def)
|
if (!type.def)
|
||||||
continue;
|
continue;
|
||||||
if (type.def->kind == ClangSymbolKind::Namespace)
|
if (type.def->kind == ClangSymbolKind::Namespace)
|
||||||
continue;
|
continue;
|
||||||
AddCodeLens("ref", "refs", &common, ref.loc.OffsetStartColumn(0),
|
AddCodeLens("ref", "refs", &common, sym.OffsetStartColumn(db, 0),
|
||||||
type.uses, type.def->definition_spelling,
|
type.uses, type.def->definition_spelling,
|
||||||
true /*force_display*/);
|
true /*force_display*/);
|
||||||
AddCodeLens("derived", "derived", &common,
|
AddCodeLens(
|
||||||
ref.loc.OffsetStartColumn(1),
|
"derived", "derived", &common, sym.OffsetStartColumn(db, 1),
|
||||||
ToReference(db, type.derived), nullopt,
|
ToReference(db, type.derived), nullopt, false /*force_display*/);
|
||||||
false /*force_display*/);
|
AddCodeLens("var", "vars", &common, sym.OffsetStartColumn(db, 2),
|
||||||
AddCodeLens("var", "vars", &common, ref.loc.OffsetStartColumn(2),
|
|
||||||
ToReference(db, type.instances), nullopt,
|
ToReference(db, type.instances), nullopt,
|
||||||
false /*force_display*/);
|
false /*force_display*/);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case SymbolKind::Func: {
|
case SymbolKind::Func: {
|
||||||
QueryFunc& func = db->funcs[symbol.idx];
|
QueryFunc& func = sym.Func(db);
|
||||||
if (!func.def)
|
if (!func.def)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
@ -179,12 +177,13 @@ struct TextDocumentCodeLensHandler
|
|||||||
// extent location to the spelling location.
|
// extent location to the spelling location.
|
||||||
auto try_ensure_spelling = [&](SymbolRef sym) {
|
auto try_ensure_spelling = [&](SymbolRef sym) {
|
||||||
optional<QueryLocation> def =
|
optional<QueryLocation> def =
|
||||||
GetDefinitionSpellingOfSymbol(db, sym.idx);
|
GetDefinitionSpellingOfSymbol(db, sym);
|
||||||
if (!def || def->FileId() != sym.loc.FileId() ||
|
if (!def || def->FileId() != GetFileId(db, sym) ||
|
||||||
def->range.start.line != sym.loc.range.start.line) {
|
def->range.start.line != sym.range.start.line) {
|
||||||
return sym.loc;
|
return sym;
|
||||||
}
|
}
|
||||||
return *def;
|
return SymbolRef(def->range, Id<void>(def->FileId()),
|
||||||
|
SymbolKind::File, SymbolRole::None);
|
||||||
};
|
};
|
||||||
|
|
||||||
std::vector<QueryFuncRef> base_callers =
|
std::vector<QueryFuncRef> base_callers =
|
||||||
@ -192,31 +191,31 @@ struct TextDocumentCodeLensHandler
|
|||||||
std::vector<QueryFuncRef> derived_callers =
|
std::vector<QueryFuncRef> derived_callers =
|
||||||
GetCallersForAllDerivedFunctions(db, func);
|
GetCallersForAllDerivedFunctions(db, func);
|
||||||
if (base_callers.empty() && derived_callers.empty()) {
|
if (base_callers.empty() && derived_callers.empty()) {
|
||||||
QueryLocation loc = try_ensure_spelling(ref);
|
SymbolRef loc = try_ensure_spelling(sym);
|
||||||
AddCodeLens("call", "calls", &common,
|
AddCodeLens("call", "calls", &common,
|
||||||
loc.OffsetStartColumn(offset++),
|
loc.OffsetStartColumn(db, offset++),
|
||||||
ToReference(db, func.callers), nullopt,
|
ToReference(db, func.callers), nullopt,
|
||||||
true /*force_display*/);
|
true /*force_display*/);
|
||||||
} else {
|
} else {
|
||||||
QueryLocation loc = try_ensure_spelling(ref);
|
SymbolRef loc = try_ensure_spelling(sym);
|
||||||
AddCodeLens("direct call", "direct calls", &common,
|
AddCodeLens("direct call", "direct calls", &common,
|
||||||
loc.OffsetStartColumn(offset++),
|
loc.OffsetStartColumn(db, offset++),
|
||||||
ToReference(db, func.callers), nullopt,
|
ToReference(db, func.callers), nullopt,
|
||||||
false /*force_display*/);
|
false /*force_display*/);
|
||||||
if (!base_callers.empty())
|
if (!base_callers.empty())
|
||||||
AddCodeLens("base call", "base calls", &common,
|
AddCodeLens("base call", "base calls", &common,
|
||||||
loc.OffsetStartColumn(offset++),
|
loc.OffsetStartColumn(db, offset++),
|
||||||
ToReference(db, base_callers), nullopt,
|
ToReference(db, base_callers), nullopt,
|
||||||
false /*force_display*/);
|
false /*force_display*/);
|
||||||
if (!derived_callers.empty())
|
if (!derived_callers.empty())
|
||||||
AddCodeLens("derived call", "derived calls", &common,
|
AddCodeLens("derived call", "derived calls", &common,
|
||||||
loc.OffsetStartColumn(offset++),
|
loc.OffsetStartColumn(db, offset++),
|
||||||
ToReference(db, derived_callers), nullopt,
|
ToReference(db, derived_callers), nullopt,
|
||||||
false /*force_display*/);
|
false /*force_display*/);
|
||||||
}
|
}
|
||||||
|
|
||||||
AddCodeLens("derived", "derived", &common,
|
AddCodeLens("derived", "derived", &common,
|
||||||
ref.loc.OffsetStartColumn(offset++),
|
sym.OffsetStartColumn(db, offset++),
|
||||||
ToReference(db, func.derived), nullopt,
|
ToReference(db, func.derived), nullopt,
|
||||||
false /*force_display*/);
|
false /*force_display*/);
|
||||||
|
|
||||||
@ -230,7 +229,7 @@ struct TextDocumentCodeLensHandler
|
|||||||
GetLsLocation(db, working_files, *base_loc);
|
GetLsLocation(db, working_files, *base_loc);
|
||||||
if (ls_base) {
|
if (ls_base) {
|
||||||
optional<lsRange> range =
|
optional<lsRange> range =
|
||||||
GetLsRange(common.working_file, ref.loc.range);
|
GetLsRange(common.working_file, sym.range);
|
||||||
if (range) {
|
if (range) {
|
||||||
TCodeLens code_lens;
|
TCodeLens code_lens;
|
||||||
code_lens.range = *range;
|
code_lens.range = *range;
|
||||||
@ -245,7 +244,7 @@ struct TextDocumentCodeLensHandler
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
AddCodeLens("base", "base", &common, ref.loc.OffsetStartColumn(1),
|
AddCodeLens("base", "base", &common, sym.OffsetStartColumn(db, 1),
|
||||||
ToReference(db, func.def->base), nullopt,
|
ToReference(db, func.def->base), nullopt,
|
||||||
false /*force_display*/);
|
false /*force_display*/);
|
||||||
}
|
}
|
||||||
@ -253,7 +252,7 @@ struct TextDocumentCodeLensHandler
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case SymbolKind::Var: {
|
case SymbolKind::Var: {
|
||||||
QueryVar& var = db->vars[symbol.idx];
|
QueryVar& var = sym.Var(db);
|
||||||
if (!var.def)
|
if (!var.def)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
@ -266,7 +265,7 @@ struct TextDocumentCodeLensHandler
|
|||||||
if (var.def->is_macro())
|
if (var.def->is_macro())
|
||||||
force_display = false;
|
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);
|
var.uses, var.def->definition_spelling, force_display);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -24,23 +24,24 @@ struct Out_TextDocumentDefinition
|
|||||||
MAKE_REFLECT_STRUCT(Out_TextDocumentDefinition, jsonrpc, id, result);
|
MAKE_REFLECT_STRUCT(Out_TextDocumentDefinition, jsonrpc, id, result);
|
||||||
|
|
||||||
std::vector<Reference> GetGotoDefinitionTargets(QueryDatabase* db,
|
std::vector<Reference> GetGotoDefinitionTargets(QueryDatabase* db,
|
||||||
const SymbolIdx& symbol) {
|
SymbolRef sym) {
|
||||||
switch (symbol.kind) {
|
switch (sym.kind) {
|
||||||
// Returns GetDeclarationsOfSymbolForGotoDefinition and
|
// Returns GetDeclarationsOfSymbolForGotoDefinition and
|
||||||
// variable type definition.
|
// variable type definition.
|
||||||
case SymbolKind::Var: {
|
case SymbolKind::Var: {
|
||||||
std::vector<Reference> ret =
|
std::vector<Reference> ret =
|
||||||
GetDeclarationsOfSymbolForGotoDefinition(db, symbol);
|
GetDeclarationsOfSymbolForGotoDefinition(db, sym);
|
||||||
QueryVar& var = db->vars[symbol.idx];
|
QueryVar& var = sym.Var(db);
|
||||||
if (var.def && var.def->variable_type) {
|
if (var.def && var.def->variable_type) {
|
||||||
std::vector<Reference> types = GetDeclarationsOfSymbolForGotoDefinition(
|
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());
|
ret.insert(ret.end(), types.begin(), types.end());
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
return GetDeclarationsOfSymbolForGotoDefinition(db, symbol);
|
return GetDeclarationsOfSymbolForGotoDefinition(db, sym);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -64,7 +65,7 @@ struct TextDocumentDefinitionHandler
|
|||||||
int target_line = request->params.position.line;
|
int target_line = request->params.position.line;
|
||||||
int target_column = request->params.position.character;
|
int target_column = request->params.position.character;
|
||||||
|
|
||||||
for (const SymbolRef& ref :
|
for (const SymbolRef& sym :
|
||||||
FindSymbolsAtLocation(working_file, file, request->params.position)) {
|
FindSymbolsAtLocation(working_file, file, request->params.position)) {
|
||||||
// Found symbol. Return definition.
|
// Found symbol. Return definition.
|
||||||
|
|
||||||
@ -73,14 +74,12 @@ struct TextDocumentDefinitionHandler
|
|||||||
// - start at spelling but end at extent for better mouse tooltip
|
// - start at spelling but end at extent for better mouse tooltip
|
||||||
// - goto declaration while in definition of recursive type
|
// - goto declaration while in definition of recursive type
|
||||||
|
|
||||||
optional<QueryLocation> def_loc =
|
optional<QueryLocation> def_loc = GetDefinitionSpellingOfSymbol(db, sym);
|
||||||
GetDefinitionSpellingOfSymbol(db, ref.idx);
|
|
||||||
|
|
||||||
// We use spelling start and extent end because this causes vscode to
|
// We use spelling start and extent end because this causes vscode to
|
||||||
// highlight the entire definition when previewing / hoving with the
|
// highlight the entire definition when previewing / hoving with the
|
||||||
// mouse.
|
// mouse.
|
||||||
optional<QueryLocation> def_extent =
|
optional<QueryLocation> def_extent = GetDefinitionExtentOfSymbol(db, sym);
|
||||||
GetDefinitionExtentOfSymbol(db, ref.idx);
|
|
||||||
if (def_loc && def_extent)
|
if (def_loc && def_extent)
|
||||||
def_loc->range.end = def_extent->range.end;
|
def_loc->range.end = def_extent->range.end;
|
||||||
|
|
||||||
@ -92,7 +91,7 @@ struct TextDocumentDefinitionHandler
|
|||||||
def_loc->range.Contains(target_line, target_column))) {
|
def_loc->range.Contains(target_line, target_column))) {
|
||||||
// Goto declaration.
|
// Goto declaration.
|
||||||
|
|
||||||
std::vector<Reference> targets = GetGotoDefinitionTargets(db, ref.idx);
|
std::vector<Reference> targets = GetGotoDefinitionTargets(db, sym);
|
||||||
for (Reference target : targets) {
|
for (Reference target : targets) {
|
||||||
optional<lsLocation> ls_target =
|
optional<lsLocation> ls_target =
|
||||||
GetLsLocation(db, working_files, target);
|
GetLsLocation(db, working_files, target);
|
||||||
|
@ -35,13 +35,13 @@ struct TextDocumentDocumentSymbolHandler
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (SymbolRef ref : file->def->outline) {
|
for (SymbolRef sym : file->def->outline) {
|
||||||
optional<lsSymbolInformation> info =
|
optional<lsSymbolInformation> info =
|
||||||
GetSymbolInfo(db, working_files, ref.idx, true /*use_short_name*/);
|
GetSymbolInfo(db, working_files, sym, true /*use_short_name*/);
|
||||||
if (!info)
|
if (!info)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
optional<lsLocation> location = GetLsLocation(db, working_files, ref.loc);
|
optional<lsLocation> location = GetLsLocation(db, working_files, sym);
|
||||||
if (!location)
|
if (!location)
|
||||||
continue;
|
continue;
|
||||||
info->location = *location;
|
info->location = *location;
|
||||||
|
@ -35,10 +35,10 @@ struct TextDocumentDocumentHighlightHandler
|
|||||||
Out_TextDocumentDocumentHighlight out;
|
Out_TextDocumentDocumentHighlight out;
|
||||||
out.id = request->id;
|
out.id = request->id;
|
||||||
|
|
||||||
for (const SymbolRef& ref :
|
for (const SymbolRef& sym :
|
||||||
FindSymbolsAtLocation(working_file, file, request->params.position)) {
|
FindSymbolsAtLocation(working_file, file, request->params.position)) {
|
||||||
// Found symbol. Return references to highlight.
|
// Found symbol. Return references to highlight.
|
||||||
std::vector<Reference> uses = GetUsesOfSymbol(db, ref.idx, true);
|
std::vector<Reference> uses = GetUsesOfSymbol(db, sym, true);
|
||||||
out.result.reserve(uses.size());
|
out.result.reserve(uses.size());
|
||||||
for (const Reference& use : uses) {
|
for (const Reference& use : uses) {
|
||||||
if (GetFileId(db, use) != file_id)
|
if (GetFileId(db, use) != file_id)
|
||||||
|
@ -6,10 +6,10 @@ namespace {
|
|||||||
|
|
||||||
std::pair<std::string_view, std::string_view> GetCommentsAndHover(
|
std::pair<std::string_view, std::string_view> GetCommentsAndHover(
|
||||||
QueryDatabase* db,
|
QueryDatabase* db,
|
||||||
const SymbolIdx& symbol) {
|
SymbolRef sym) {
|
||||||
switch (symbol.kind) {
|
switch (sym.kind) {
|
||||||
case SymbolKind::Type: {
|
case SymbolKind::Type: {
|
||||||
QueryType& type = db->types[symbol.idx];
|
QueryType& type = db->types[sym.Idx()];
|
||||||
if (type.def)
|
if (type.def)
|
||||||
return {type.def->comments, type.def->hover.size()
|
return {type.def->comments, type.def->hover.size()
|
||||||
? type.def->hover
|
? type.def->hover
|
||||||
@ -17,7 +17,7 @@ std::pair<std::string_view, std::string_view> GetCommentsAndHover(
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case SymbolKind::Func: {
|
case SymbolKind::Func: {
|
||||||
QueryFunc& func = db->funcs[symbol.idx];
|
QueryFunc& func = db->funcs[sym.Idx()];
|
||||||
if (func.def)
|
if (func.def)
|
||||||
return {func.def->comments, func.def->hover.size()
|
return {func.def->comments, func.def->hover.size()
|
||||||
? func.def->hover
|
? func.def->hover
|
||||||
@ -25,7 +25,7 @@ std::pair<std::string_view, std::string_view> GetCommentsAndHover(
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case SymbolKind::Var: {
|
case SymbolKind::Var: {
|
||||||
QueryVar& var = db->vars[symbol.idx];
|
QueryVar& var = db->vars[sym.Idx()];
|
||||||
if (var.def)
|
if (var.def)
|
||||||
return {var.def->comments, var.def->hover.size()
|
return {var.def->comments, var.def->hover.size()
|
||||||
? var.def->hover
|
? var.def->hover
|
||||||
@ -87,16 +87,16 @@ struct TextDocumentHoverHandler : BaseMessageHandler<Ipc_TextDocumentHover> {
|
|||||||
Out_TextDocumentHover out;
|
Out_TextDocumentHover out;
|
||||||
out.id = request->id;
|
out.id = request->id;
|
||||||
|
|
||||||
for (const SymbolRef& ref :
|
for (const SymbolRef& sym :
|
||||||
FindSymbolsAtLocation(working_file, file, request->params.position)) {
|
FindSymbolsAtLocation(working_file, file, request->params.position)) {
|
||||||
// Found symbol. Return hover.
|
// Found symbol. Return hover.
|
||||||
optional<lsRange> ls_range = GetLsRange(
|
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)
|
if (!ls_range)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
std::pair<std::string_view, std::string_view> comments_hover =
|
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()) {
|
if (comments_hover.first.size() || comments_hover.second.size()) {
|
||||||
out.result = Out_TextDocumentHover::Result();
|
out.result = Out_TextDocumentHover::Result();
|
||||||
if (comments_hover.first.size()) {
|
if (comments_hover.first.size()) {
|
||||||
|
@ -51,11 +51,11 @@ struct TextDocumentReferencesHandler
|
|||||||
Out_TextDocumentReferences out;
|
Out_TextDocumentReferences out;
|
||||||
out.id = request->id;
|
out.id = request->id;
|
||||||
|
|
||||||
for (const SymbolRef& ref :
|
for (const SymbolRef& sym :
|
||||||
FindSymbolsAtLocation(working_file, file, request->params.position)) {
|
FindSymbolsAtLocation(working_file, file, request->params.position)) {
|
||||||
// Found symbol. Return references.
|
// Found symbol. Return references.
|
||||||
std::vector<Reference> uses = GetUsesOfSymbol(
|
std::vector<Reference> uses = GetUsesOfSymbol(
|
||||||
db, ref.idx, request->params.context.includeDeclaration);
|
db, sym, request->params.context.includeDeclaration);
|
||||||
out.result.reserve(uses.size());
|
out.result.reserve(uses.size());
|
||||||
for (const Reference& use : uses) {
|
for (const Reference& use : uses) {
|
||||||
optional<lsLocation> ls_location =
|
optional<lsLocation> ls_location =
|
||||||
|
@ -95,11 +95,11 @@ struct TextDocumentRenameHandler : BaseMessageHandler<Ipc_TextDocumentRename> {
|
|||||||
Out_TextDocumentRename out;
|
Out_TextDocumentRename out;
|
||||||
out.id = request->id;
|
out.id = request->id;
|
||||||
|
|
||||||
for (const SymbolRef& ref :
|
for (const SymbolRef& sym :
|
||||||
FindSymbolsAtLocation(working_file, file, request->params.position)) {
|
FindSymbolsAtLocation(working_file, file, request->params.position)) {
|
||||||
// Found symbol. Return references to rename.
|
// Found symbol. Return references to rename.
|
||||||
out.result = BuildWorkspaceEdit(db, working_files,
|
out.result = BuildWorkspaceEdit(db, working_files,
|
||||||
GetUsesOfSymbol(db, ref.idx, true),
|
GetUsesOfSymbol(db, sym, true),
|
||||||
request->params.newName);
|
request->params.newName);
|
||||||
break;
|
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) {
|
auto add_outline = [&](Range range, RawId id, SymbolKind kind,
|
||||||
def.outline.push_back(
|
SymbolRole role) {
|
||||||
SymbolRef(idx, SymbolRole::Declaration,
|
def.outline.push_back(SymbolRef(range, Id<void>(id), kind, role));
|
||||||
id_map.ToQuery(range, SymbolRole::Declaration)));
|
|
||||||
};
|
};
|
||||||
auto add_all_symbols = [&def, &id_map](SymbolIdx idx, SymbolRole role,
|
auto add_all_symbols = [&](Range range, RawId id, SymbolKind kind,
|
||||||
Range range) {
|
SymbolRole role) {
|
||||||
def.all_symbols.push_back(
|
def.all_symbols.push_back(SymbolRef(range, Id<void>(id), kind, role));
|
||||||
SymbolRef(idx, role, id_map.ToQuery(range, role)));
|
|
||||||
};
|
};
|
||||||
|
|
||||||
for (const IndexType& type : indexed.types) {
|
for (const IndexType& type : indexed.types) {
|
||||||
|
RawId id = id_map.ToQuery(type.id).id;
|
||||||
if (type.def.definition_spelling.has_value())
|
if (type.def.definition_spelling.has_value())
|
||||||
add_all_symbols(id_map.ToSymbol(type.id), SymbolRole::Definition,
|
add_all_symbols(*type.def.definition_spelling, id, SymbolKind::Type,
|
||||||
*type.def.definition_spelling);
|
SymbolRole::Definition);
|
||||||
if (type.def.definition_extent.has_value())
|
if (type.def.definition_extent)
|
||||||
add_outline(id_map.ToSymbol(type.id), *type.def.definition_extent);
|
add_outline(*type.def.definition_extent, id, SymbolKind::Type,
|
||||||
|
SymbolRole::None);
|
||||||
for (const Reference& use : type.uses)
|
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) {
|
for (const IndexFunc& func : indexed.funcs) {
|
||||||
|
RawId id = id_map.ToQuery(func.id).id;
|
||||||
if (func.def.definition_spelling.has_value())
|
if (func.def.definition_spelling.has_value())
|
||||||
add_all_symbols(id_map.ToSymbol(func.id), SymbolRole::Definition,
|
add_all_symbols(*func.def.definition_spelling, id, SymbolKind::Func,
|
||||||
*func.def.definition_spelling);
|
SymbolRole::Definition);
|
||||||
if (func.def.definition_extent.has_value())
|
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) {
|
for (const IndexFunc::Declaration& decl : func.declarations) {
|
||||||
add_all_symbols(id_map.ToSymbol(func.id), SymbolRole::Declaration,
|
add_all_symbols(decl.spelling, id, SymbolKind::Func,
|
||||||
decl.spelling);
|
SymbolRole::Declaration);
|
||||||
add_outline(id_map.ToSymbol(func.id), decl.spelling);
|
add_outline(decl.spelling, id, SymbolKind::Func, SymbolRole::Declaration);
|
||||||
}
|
}
|
||||||
for (const IndexFuncRef& caller : func.callers) {
|
for (const IndexFuncRef& caller : func.callers) {
|
||||||
// Make ranges of implicit function calls larger (spanning one more column
|
// 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.start.column--;
|
||||||
range.end.column++;
|
range.end.column++;
|
||||||
}
|
}
|
||||||
add_all_symbols(id_map.ToSymbol(func.id),
|
add_all_symbols(range, id, SymbolKind::Func,
|
||||||
caller.role | SymbolRole::CalledBy, range);
|
caller.role | SymbolRole::CalledBy);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (const IndexVar& var : indexed.vars) {
|
for (const IndexVar& var : indexed.vars) {
|
||||||
if (var.def.definition_spelling.has_value())
|
if (var.def.definition_spelling)
|
||||||
add_all_symbols(id_map.ToSymbol(var.id), SymbolRole::Definition,
|
add_all_symbols(*var.def.definition_spelling, id_map.ToQuery(var.id).id,
|
||||||
*var.def.definition_spelling);
|
SymbolKind::Var, SymbolRole::Definition);
|
||||||
if (var.def.definition_extent.has_value())
|
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) {
|
for (const Range& decl : var.declarations) {
|
||||||
add_all_symbols(id_map.ToSymbol(var.id), SymbolRole::Declaration, decl);
|
add_all_symbols(decl, id_map.ToQuery(var.id).id, SymbolKind::Var,
|
||||||
add_outline(id_map.ToSymbol(var.id), decl);
|
SymbolRole::Definition);
|
||||||
|
add_outline(decl, id_map.ToQuery(var.id).id, SymbolKind::Var,
|
||||||
|
SymbolRole::Declaration);
|
||||||
}
|
}
|
||||||
for (auto& use : var.uses)
|
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(),
|
std::sort(def.outline.begin(), def.outline.end(),
|
||||||
[](const SymbolRef& a, const SymbolRef& b) {
|
[](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(),
|
std::sort(def.all_symbols.begin(), def.all_symbols.end(),
|
||||||
[](const SymbolRef& a, const SymbolRef& b) {
|
[](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);
|
return QueryFile::DefUpdate(def, indexed.file_contents);
|
||||||
@ -372,6 +378,44 @@ Maybe<QueryVarId> GetQueryVarIdFromUsr(QueryDatabase* query_db,
|
|||||||
|
|
||||||
} // namespace
|
} // 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(
|
Maybe<QueryFileId> QueryDatabase::GetQueryFileIdFromPath(
|
||||||
const std::string& path) {
|
const std::string& path) {
|
||||||
return ::GetQueryFileIdFromPath(this, path, false);
|
return ::GetQueryFileIdFromPath(this, path, false);
|
||||||
@ -415,23 +459,23 @@ QueryLocation IdMap::ToQuery(Range range, SymbolRole role) const {
|
|||||||
return QueryLocation{range, primary_file, role};
|
return QueryLocation{range, primary_file, role};
|
||||||
}
|
}
|
||||||
Reference IdMap::ToQuery(Reference ref) const {
|
Reference IdMap::ToQuery(Reference ref) const {
|
||||||
switch (ref.lex_parent_kind) {
|
switch (ref.kind) {
|
||||||
case SymbolKind::Invalid:
|
case SymbolKind::Invalid:
|
||||||
case SymbolKind::File:
|
case SymbolKind::File:
|
||||||
ref.lex_parent_kind = SymbolKind::File;
|
ref.kind = SymbolKind::File;
|
||||||
ref.lex_parent_id = Id<void>(primary_file);
|
ref.id = Id<void>(primary_file);
|
||||||
break;
|
break;
|
||||||
case SymbolKind::Func:
|
case SymbolKind::Func:
|
||||||
ref.lex_parent_id = Id<void>(
|
ref.id = Id<void>(
|
||||||
cached_func_ids_.find(IndexFuncId(ref.lex_parent_id))->second);
|
cached_func_ids_.find(IndexFuncId(ref.id))->second);
|
||||||
break;
|
break;
|
||||||
case SymbolKind::Type:
|
case SymbolKind::Type:
|
||||||
ref.lex_parent_id = Id<void>(
|
ref.id = Id<void>(
|
||||||
cached_type_ids_.find(IndexTypeId(ref.lex_parent_id))->second);
|
cached_type_ids_.find(IndexTypeId(ref.id))->second);
|
||||||
break;
|
break;
|
||||||
case SymbolKind::Var:
|
case SymbolKind::Var:
|
||||||
ref.lex_parent_id =
|
ref.id =
|
||||||
Id<void>(cached_var_ids_.find(IndexVarId(ref.lex_parent_id))->second);
|
Id<void>(cached_var_ids_.find(IndexVarId(ref.id))->second);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return ref;
|
return ref;
|
||||||
@ -451,18 +495,18 @@ QueryVarId IdMap::ToQuery(IndexVarId id) const {
|
|||||||
return QueryVarId(cached_var_ids_.find(id)->second);
|
return QueryVarId(cached_var_ids_.find(id)->second);
|
||||||
}
|
}
|
||||||
QueryFuncRef IdMap::ToQuery(IndexFuncRef ref) const {
|
QueryFuncRef IdMap::ToQuery(IndexFuncRef ref) const {
|
||||||
QueryFuncRef ret(ref.range, ref.lex_parent_id, ref.lex_parent_kind, ref.role);
|
QueryFuncRef ret(ref.range, ref.id, ref.kind, ref.role);
|
||||||
switch (ref.lex_parent_kind) {
|
switch (ref.kind) {
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
case SymbolKind::File:
|
case SymbolKind::File:
|
||||||
ret.lex_parent_id = Id<void>(primary_file);
|
ret.id = Id<void>(primary_file);
|
||||||
break;
|
break;
|
||||||
case SymbolKind::Func:
|
case SymbolKind::Func:
|
||||||
ret.lex_parent_id = Id<void>(ToQuery(IndexFuncId(ref.lex_parent_id)));
|
ret.id = Id<void>(ToQuery(IndexFuncId(ref.id)));
|
||||||
break;
|
break;
|
||||||
case SymbolKind::Type:
|
case SymbolKind::Type:
|
||||||
ret.lex_parent_id = Id<void>(ToQuery(IndexTypeId(ref.lex_parent_id)));
|
ret.id = Id<void>(ToQuery(IndexTypeId(ref.id)));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
|
51
src/query.h
51
src/query.h
@ -25,12 +25,6 @@ struct QueryLocation {
|
|||||||
QueryFileId path;
|
QueryFileId path;
|
||||||
SymbolRole role;
|
SymbolRole role;
|
||||||
|
|
||||||
QueryLocation OffsetStartColumn(int16_t offset) const {
|
|
||||||
QueryLocation result = *this;
|
|
||||||
result.range.start.column += offset;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool HasValue() const { return range.HasValue(); }
|
bool HasValue() const { return range.HasValue(); }
|
||||||
QueryFileId FileId() const { return path; }
|
QueryFileId FileId() const { return path; }
|
||||||
|
|
||||||
@ -52,15 +46,6 @@ struct QueryLocation {
|
|||||||
MAKE_REFLECT_STRUCT(QueryLocation, range, path, role);
|
MAKE_REFLECT_STRUCT(QueryLocation, range, path, role);
|
||||||
MAKE_HASHABLE(QueryLocation, t.range, t.path, t.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 {
|
struct SymbolIdx {
|
||||||
SymbolKind kind;
|
SymbolKind kind;
|
||||||
RawId idx;
|
RawId idx;
|
||||||
@ -83,23 +68,27 @@ struct SymbolIdx {
|
|||||||
MAKE_REFLECT_STRUCT(SymbolIdx, kind, idx);
|
MAKE_REFLECT_STRUCT(SymbolIdx, kind, idx);
|
||||||
MAKE_HASHABLE(SymbolIdx, t.kind, t.idx);
|
MAKE_HASHABLE(SymbolIdx, t.kind, t.idx);
|
||||||
|
|
||||||
struct SymbolRef {
|
QueryFileId GetFileId(QueryDatabase* db, Reference ref);
|
||||||
SymbolIdx idx;
|
|
||||||
SymbolRole role;
|
|
||||||
QueryLocation loc;
|
|
||||||
|
|
||||||
SymbolRef() {} // Do not use, needed for reflect.
|
struct SymbolRef : Reference {
|
||||||
SymbolRef(SymbolIdx idx, SymbolRole role, QueryLocation loc)
|
SymbolRef() = default;
|
||||||
: idx(idx), role(role), loc(loc) {}
|
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 {
|
RawId Idx() const { return RawId(id); }
|
||||||
return std::make_tuple(idx, role, loc);
|
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 {
|
struct QueryFuncRef : Reference {
|
||||||
QueryFuncRef() = default;
|
QueryFuncRef() = default;
|
||||||
@ -107,8 +96,8 @@ struct QueryFuncRef : Reference {
|
|||||||
: Reference{range, id, kind, role} {}
|
: Reference{range, id, kind, role} {}
|
||||||
|
|
||||||
QueryFuncId FuncId() const {
|
QueryFuncId FuncId() const {
|
||||||
if (lex_parent_kind == SymbolKind::Func)
|
if (kind == SymbolKind::Func)
|
||||||
return QueryFuncId(lex_parent_id);
|
return QueryFuncId(id);
|
||||||
return QueryFuncId();
|
return QueryFuncId();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -448,5 +437,3 @@ struct IdMap {
|
|||||||
spp::sparse_hash_map<IndexFuncId, QueryFuncId> cached_func_ids_;
|
spp::sparse_hash_map<IndexFuncId, QueryFuncId> cached_func_ids_;
|
||||||
spp::sparse_hash_map<IndexVarId, QueryVarId> cached_var_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
|
} // 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,
|
optional<QueryLocation> GetDefinitionSpellingOfSymbol(QueryDatabase* db,
|
||||||
const QueryTypeId& id) {
|
const QueryTypeId& id) {
|
||||||
QueryType& type = db->types[id.id];
|
QueryType& type = db->types[id.id];
|
||||||
@ -69,22 +41,22 @@ optional<QueryLocation> GetDefinitionSpellingOfSymbol(QueryDatabase* db,
|
|||||||
}
|
}
|
||||||
|
|
||||||
optional<QueryLocation> GetDefinitionSpellingOfSymbol(QueryDatabase* db,
|
optional<QueryLocation> GetDefinitionSpellingOfSymbol(QueryDatabase* db,
|
||||||
const SymbolIdx& symbol) {
|
SymbolRef sym) {
|
||||||
switch (symbol.kind) {
|
switch (sym.kind) {
|
||||||
case SymbolKind::Type: {
|
case SymbolKind::Type: {
|
||||||
QueryType& type = db->types[symbol.idx];
|
QueryType& type = sym.Type(db);
|
||||||
if (type.def)
|
if (type.def)
|
||||||
return *type.def->definition_spelling;
|
return *type.def->definition_spelling;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case SymbolKind::Func: {
|
case SymbolKind::Func: {
|
||||||
QueryFunc& func = db->funcs[symbol.idx];
|
QueryFunc& func = sym.Func(db);
|
||||||
if (func.def)
|
if (func.def)
|
||||||
return func.def->definition_spelling;
|
return func.def->definition_spelling;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case SymbolKind::Var: {
|
case SymbolKind::Var: {
|
||||||
QueryVar& var = db->vars[symbol.idx];
|
QueryVar& var = sym.Var(db);
|
||||||
if (var.def)
|
if (var.def)
|
||||||
return var.def->definition_spelling;
|
return var.def->definition_spelling;
|
||||||
break;
|
break;
|
||||||
@ -99,29 +71,29 @@ optional<QueryLocation> GetDefinitionSpellingOfSymbol(QueryDatabase* db,
|
|||||||
}
|
}
|
||||||
|
|
||||||
optional<QueryLocation> GetDefinitionExtentOfSymbol(QueryDatabase* db,
|
optional<QueryLocation> GetDefinitionExtentOfSymbol(QueryDatabase* db,
|
||||||
const SymbolIdx& symbol) {
|
SymbolRef sym) {
|
||||||
switch (symbol.kind) {
|
switch (sym.kind) {
|
||||||
case SymbolKind::Type: {
|
case SymbolKind::Type: {
|
||||||
QueryType& type = db->types[symbol.idx];
|
QueryType& type = sym.Type(db);
|
||||||
if (type.def)
|
if (type.def)
|
||||||
return type.def->definition_extent;
|
return type.def->definition_extent;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case SymbolKind::Func: {
|
case SymbolKind::Func: {
|
||||||
QueryFunc& func = db->funcs[symbol.idx];
|
QueryFunc& func = sym.Func(db);
|
||||||
if (func.def)
|
if (func.def)
|
||||||
return func.def->definition_extent;
|
return func.def->definition_extent;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case SymbolKind::Var: {
|
case SymbolKind::Var: {
|
||||||
QueryVar& var = db->vars[symbol.idx];
|
QueryVar& var = sym.Var(db);
|
||||||
if (var.def)
|
if (var.def)
|
||||||
return var.def->definition_extent;
|
return var.def->definition_extent;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case SymbolKind::File: {
|
case SymbolKind::File: {
|
||||||
return QueryLocation{Range(Position(0, 0), Position(0, 0)),
|
return QueryLocation{Range(Position(0, 0), Position(0, 0)),
|
||||||
QueryFileId(symbol.idx), SymbolRole::None};
|
QueryFileId(sym.Idx()), SymbolRole::None};
|
||||||
}
|
}
|
||||||
case SymbolKind::Invalid: {
|
case SymbolKind::Invalid: {
|
||||||
assert(false && "unexpected");
|
assert(false && "unexpected");
|
||||||
@ -132,16 +104,16 @@ optional<QueryLocation> GetDefinitionExtentOfSymbol(QueryDatabase* db,
|
|||||||
}
|
}
|
||||||
|
|
||||||
optional<QueryFileId> GetDeclarationFileForSymbol(QueryDatabase* db,
|
optional<QueryFileId> GetDeclarationFileForSymbol(QueryDatabase* db,
|
||||||
const SymbolIdx& symbol) {
|
SymbolRef sym) {
|
||||||
switch (symbol.kind) {
|
switch (sym.kind) {
|
||||||
case SymbolKind::Type: {
|
case SymbolKind::Type: {
|
||||||
QueryType& type = db->types[symbol.idx];
|
QueryType& type = sym.Type(db);
|
||||||
if (type.def && type.def->definition_spelling)
|
if (type.def && type.def->definition_spelling)
|
||||||
return type.def->definition_spelling->FileId();
|
return type.def->definition_spelling->FileId();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case SymbolKind::Func: {
|
case SymbolKind::Func: {
|
||||||
QueryFunc& func = db->funcs[symbol.idx];
|
QueryFunc& func = sym.Func(db);
|
||||||
if (!func.declarations.empty())
|
if (!func.declarations.empty())
|
||||||
return GetFileId(db, func.declarations[0]);
|
return GetFileId(db, func.declarations[0]);
|
||||||
if (func.def && func.def->definition_spelling)
|
if (func.def && func.def->definition_spelling)
|
||||||
@ -149,13 +121,13 @@ optional<QueryFileId> GetDeclarationFileForSymbol(QueryDatabase* db,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case SymbolKind::Var: {
|
case SymbolKind::Var: {
|
||||||
QueryVar& var = db->vars[symbol.idx];
|
QueryVar& var = sym.Var(db);
|
||||||
if (var.def && var.def->definition_spelling)
|
if (var.def && var.def->definition_spelling)
|
||||||
return var.def->definition_spelling->FileId();
|
return var.def->definition_spelling->FileId();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case SymbolKind::File: {
|
case SymbolKind::File: {
|
||||||
return QueryFileId(symbol.idx);
|
return QueryFileId(sym.Idx());
|
||||||
}
|
}
|
||||||
case SymbolKind::Invalid: {
|
case SymbolKind::Invalid: {
|
||||||
assert(false && "unexpected");
|
assert(false && "unexpected");
|
||||||
@ -175,11 +147,11 @@ std::vector<Reference> ToReference(QueryDatabase* db,
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::vector<Reference> GetUsesOfSymbol(QueryDatabase* db,
|
std::vector<Reference> GetUsesOfSymbol(QueryDatabase* db,
|
||||||
const SymbolIdx& symbol,
|
SymbolRef sym,
|
||||||
bool include_decl) {
|
bool include_decl) {
|
||||||
switch (symbol.kind) {
|
switch (sym.kind) {
|
||||||
case SymbolKind::Type: {
|
case SymbolKind::Type: {
|
||||||
QueryType& type = db->types[symbol.idx];
|
QueryType& type = db->types[sym.Idx()];
|
||||||
std::vector<Reference> ret = type.uses;
|
std::vector<Reference> ret = type.uses;
|
||||||
if (include_decl && type.def && type.def->definition_spelling)
|
if (include_decl && type.def && type.def->definition_spelling)
|
||||||
ret.push_back(*type.def->definition_spelling);
|
ret.push_back(*type.def->definition_spelling);
|
||||||
@ -187,7 +159,7 @@ std::vector<Reference> GetUsesOfSymbol(QueryDatabase* db,
|
|||||||
}
|
}
|
||||||
case SymbolKind::Func: {
|
case SymbolKind::Func: {
|
||||||
// TODO: the vector allocation could be avoided.
|
// TODO: the vector allocation could be avoided.
|
||||||
QueryFunc& func = db->funcs[symbol.idx];
|
QueryFunc& func = db->funcs[sym.Idx()];
|
||||||
std::vector<Reference> ret = ToReference(db, func.callers);
|
std::vector<Reference> ret = ToReference(db, func.callers);
|
||||||
if (include_decl) {
|
if (include_decl) {
|
||||||
AddRange(&ret, func.declarations);
|
AddRange(&ret, func.declarations);
|
||||||
@ -197,7 +169,7 @@ std::vector<Reference> GetUsesOfSymbol(QueryDatabase* db,
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
case SymbolKind::Var: {
|
case SymbolKind::Var: {
|
||||||
QueryVar& var = db->vars[symbol.idx];
|
QueryVar& var = db->vars[sym.Idx()];
|
||||||
std::vector<Reference> ret = var.uses;
|
std::vector<Reference> ret = var.uses;
|
||||||
if (include_decl) {
|
if (include_decl) {
|
||||||
if (var.def && var.def->definition_spelling)
|
if (var.def && var.def->definition_spelling)
|
||||||
@ -216,14 +188,14 @@ std::vector<Reference> GetUsesOfSymbol(QueryDatabase* db,
|
|||||||
|
|
||||||
std::vector<Reference> GetDeclarationsOfSymbolForGotoDefinition(
|
std::vector<Reference> GetDeclarationsOfSymbolForGotoDefinition(
|
||||||
QueryDatabase* db,
|
QueryDatabase* db,
|
||||||
SymbolIdx symbol) {
|
SymbolRef sym) {
|
||||||
switch (symbol.kind) {
|
switch (sym.kind) {
|
||||||
case SymbolKind::Type: {
|
case SymbolKind::Type: {
|
||||||
// Returning the definition spelling of a type is a hack (and is why the
|
// Returning the definition spelling of a type is a hack (and is why the
|
||||||
// function has the postfix `ForGotoDefintion`, but it lets the user
|
// function has the postfix `ForGotoDefintion`, but it lets the user
|
||||||
// jump to the start of a type if clicking goto-definition on the same
|
// jump to the start of a type if clicking goto-definition on the same
|
||||||
// type from within the type definition.
|
// type from within the type definition.
|
||||||
QueryType& type = db->types[symbol.idx];
|
QueryType& type = sym.Type(db);
|
||||||
if (type.def) {
|
if (type.def) {
|
||||||
optional<QueryLocation> declaration = type.def->definition_spelling;
|
optional<QueryLocation> declaration = type.def->definition_spelling;
|
||||||
if (declaration)
|
if (declaration)
|
||||||
@ -232,9 +204,9 @@ std::vector<Reference> GetDeclarationsOfSymbolForGotoDefinition(
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case SymbolKind::Func:
|
case SymbolKind::Func:
|
||||||
return db->funcs[symbol.idx].declarations;
|
return sym.Func(db).declarations;
|
||||||
case SymbolKind::Var:
|
case SymbolKind::Var:
|
||||||
return db->vars[symbol.idx].declarations;
|
return sym.Var(db).declarations;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -425,13 +397,13 @@ std::vector<lsLocation> GetLsLocations(
|
|||||||
// Returns a symbol. The symbol will have *NOT* have a location assigned.
|
// Returns a symbol. The symbol will have *NOT* have a location assigned.
|
||||||
optional<lsSymbolInformation> GetSymbolInfo(QueryDatabase* db,
|
optional<lsSymbolInformation> GetSymbolInfo(QueryDatabase* db,
|
||||||
WorkingFiles* working_files,
|
WorkingFiles* working_files,
|
||||||
SymbolIdx symbol,
|
SymbolRef sym,
|
||||||
bool use_short_name) {
|
bool use_short_name) {
|
||||||
switch (symbol.kind) {
|
switch (sym.kind) {
|
||||||
case SymbolKind::File: {
|
case SymbolKind::File: {
|
||||||
QueryFile& file = db->files[symbol.idx];
|
QueryFile& file = db->files[sym.Idx()];
|
||||||
if (!file.def)
|
if (!file.def)
|
||||||
return nullopt;
|
break;
|
||||||
|
|
||||||
lsSymbolInformation info;
|
lsSymbolInformation info;
|
||||||
info.name = file.def->path;
|
info.name = file.def->path;
|
||||||
@ -439,9 +411,9 @@ optional<lsSymbolInformation> GetSymbolInfo(QueryDatabase* db,
|
|||||||
return info;
|
return info;
|
||||||
}
|
}
|
||||||
case SymbolKind::Type: {
|
case SymbolKind::Type: {
|
||||||
QueryType& type = db->types[symbol.idx];
|
QueryType& type = sym.Type(db);
|
||||||
if (!type.def)
|
if (!type.def)
|
||||||
return nullopt;
|
break;
|
||||||
|
|
||||||
lsSymbolInformation info;
|
lsSymbolInformation info;
|
||||||
if (use_short_name)
|
if (use_short_name)
|
||||||
@ -462,9 +434,9 @@ optional<lsSymbolInformation> GetSymbolInfo(QueryDatabase* db,
|
|||||||
return info;
|
return info;
|
||||||
}
|
}
|
||||||
case SymbolKind::Func: {
|
case SymbolKind::Func: {
|
||||||
QueryFunc& func = db->funcs[symbol.idx];
|
QueryFunc& func = sym.Func(db);
|
||||||
if (!func.def)
|
if (!func.def)
|
||||||
return nullopt;
|
break;
|
||||||
|
|
||||||
lsSymbolInformation info;
|
lsSymbolInformation info;
|
||||||
if (use_short_name)
|
if (use_short_name)
|
||||||
@ -483,9 +455,9 @@ optional<lsSymbolInformation> GetSymbolInfo(QueryDatabase* db,
|
|||||||
return info;
|
return info;
|
||||||
}
|
}
|
||||||
case SymbolKind::Var: {
|
case SymbolKind::Var: {
|
||||||
QueryVar& var = db->vars[symbol.idx];
|
QueryVar& var = sym.Var(db);
|
||||||
if (!var.def)
|
if (!var.def)
|
||||||
return nullopt;
|
break;
|
||||||
|
|
||||||
lsSymbolInformation info;
|
lsSymbolInformation info;
|
||||||
if (use_short_name)
|
if (use_short_name)
|
||||||
@ -496,10 +468,9 @@ optional<lsSymbolInformation> GetSymbolInfo(QueryDatabase* db,
|
|||||||
info.kind = lsSymbolKind::Variable;
|
info.kind = lsSymbolKind::Variable;
|
||||||
return info;
|
return info;
|
||||||
}
|
}
|
||||||
case SymbolKind::Invalid: {
|
case SymbolKind::Invalid:
|
||||||
return nullopt;
|
break;
|
||||||
}
|
}
|
||||||
};
|
|
||||||
|
|
||||||
return nullopt;
|
return nullopt;
|
||||||
}
|
}
|
||||||
@ -520,9 +491,9 @@ std::vector<SymbolRef> FindSymbolsAtLocation(WorkingFile* working_file,
|
|||||||
target_line = *index_line;
|
target_line = *index_line;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const SymbolRef& ref : file->def->all_symbols) {
|
for (const SymbolRef& sym : file->def->all_symbols) {
|
||||||
if (ref.loc.range.Contains(target_line, target_column))
|
if (sym.range.Contains(target_line, target_column))
|
||||||
symbols.push_back(ref);
|
symbols.push_back(sym);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Order shorter ranges first, since they are more detailed/precise. This is
|
// 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.
|
// better on constructors.
|
||||||
std::sort(symbols.begin(), symbols.end(),
|
std::sort(symbols.begin(), symbols.end(),
|
||||||
[](const SymbolRef& a, const SymbolRef& b) {
|
[](const SymbolRef& a, const SymbolRef& b) {
|
||||||
int a_size = ComputeRangeSize(a.loc.range);
|
int a_size = ComputeRangeSize(a.range);
|
||||||
int b_size = ComputeRangeSize(b.loc.range);
|
int b_size = ComputeRangeSize(b.range);
|
||||||
|
|
||||||
if (a_size != b_size)
|
if (a_size != b_size)
|
||||||
return a_size < b_size;
|
return a_size < b_size;
|
||||||
// operator> orders Var/Func before Type.
|
// operator> orders Var/Func before Type.
|
||||||
int t =
|
int t = static_cast<int>(a.kind) - static_cast<int>(b.kind);
|
||||||
static_cast<int>(a.idx.kind) - static_cast<int>(b.idx.kind);
|
|
||||||
if (t)
|
if (t)
|
||||||
return t > 0;
|
return t > 0;
|
||||||
return a.idx.idx < b.idx.idx;
|
return a.Idx() < b.Idx();
|
||||||
});
|
});
|
||||||
|
|
||||||
return symbols;
|
return symbols;
|
||||||
|
@ -14,13 +14,11 @@ optional<QueryLocation> GetDefinitionSpellingOfSymbol(QueryDatabase* db,
|
|||||||
optional<QueryLocation> GetDefinitionSpellingOfSymbol(QueryDatabase* db,
|
optional<QueryLocation> GetDefinitionSpellingOfSymbol(QueryDatabase* db,
|
||||||
const QueryVarId& id);
|
const QueryVarId& id);
|
||||||
optional<QueryLocation> GetDefinitionSpellingOfSymbol(QueryDatabase* db,
|
optional<QueryLocation> GetDefinitionSpellingOfSymbol(QueryDatabase* db,
|
||||||
const SymbolIdx& symbol);
|
SymbolRef sym);
|
||||||
optional<QueryLocation> GetDefinitionExtentOfSymbol(QueryDatabase* db,
|
optional<QueryLocation> GetDefinitionExtentOfSymbol(QueryDatabase* db,
|
||||||
const SymbolIdx& symbol);
|
SymbolRef sym);
|
||||||
optional<QueryFileId> GetDeclarationFileForSymbol(QueryDatabase* db,
|
optional<QueryFileId> GetDeclarationFileForSymbol(QueryDatabase* db,
|
||||||
const SymbolIdx& symbol);
|
SymbolRef sym);
|
||||||
|
|
||||||
QueryFileId GetFileId(QueryDatabase* db, Reference ref);
|
|
||||||
|
|
||||||
std::vector<Reference> ToReference(QueryDatabase* db,
|
std::vector<Reference> ToReference(QueryDatabase* db,
|
||||||
const std::vector<QueryFuncRef>& refs);
|
const std::vector<QueryFuncRef>& refs);
|
||||||
@ -39,11 +37,11 @@ std::vector<Reference> ToReference(QueryDatabase* db,
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::vector<Reference> GetUsesOfSymbol(QueryDatabase* db,
|
std::vector<Reference> GetUsesOfSymbol(QueryDatabase* db,
|
||||||
const SymbolIdx& symbol,
|
SymbolRef sym,
|
||||||
bool include_decl);
|
bool include_decl);
|
||||||
std::vector<Reference> GetDeclarationsOfSymbolForGotoDefinition(
|
std::vector<Reference> GetDeclarationsOfSymbolForGotoDefinition(
|
||||||
QueryDatabase* db,
|
QueryDatabase* db,
|
||||||
SymbolIdx symbol);
|
SymbolRef sym);
|
||||||
|
|
||||||
bool HasCallersOnSelfOrBaseOrDerived(QueryDatabase* db, QueryFunc& root);
|
bool HasCallersOnSelfOrBaseOrDerived(QueryDatabase* db, QueryFunc& root);
|
||||||
std::vector<QueryFuncRef> GetCallersForAllBaseFunctions(QueryDatabase* db,
|
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.
|
// Returns a symbol. The symbol will have *NOT* have a location assigned.
|
||||||
optional<lsSymbolInformation> GetSymbolInfo(QueryDatabase* db,
|
optional<lsSymbolInformation> GetSymbolInfo(QueryDatabase* db,
|
||||||
WorkingFiles* working_files,
|
WorkingFiles* working_files,
|
||||||
SymbolIdx symbol,
|
SymbolRef sym,
|
||||||
bool use_short_name);
|
bool use_short_name);
|
||||||
|
|
||||||
std::vector<SymbolRef> FindSymbolsAtLocation(WorkingFile* working_file,
|
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