mirror of
https://github.com/MaskRay/ccls.git
synced 2025-02-22 00:19:28 +00:00
Change is_implicit to role in {Index,Query}FuncRef
Add `FileId file` to *DefDefinitionData::Def
This commit is contained in:
parent
10c2843846
commit
dbdab02ff4
@ -584,7 +584,7 @@ void OnIndexReference_Function(IndexFile* db,
|
|||||||
ClangCursor caller_cursor,
|
ClangCursor caller_cursor,
|
||||||
IndexFuncId called_id,
|
IndexFuncId called_id,
|
||||||
IndexFunc* called,
|
IndexFunc* called,
|
||||||
bool is_implicit) {
|
SymbolRole role) {
|
||||||
if (IsFunctionCallContext(caller_cursor.get_kind())) {
|
if (IsFunctionCallContext(caller_cursor.get_kind())) {
|
||||||
IndexFuncId caller_id = db->ToFuncId(caller_cursor.cx_cursor);
|
IndexFuncId caller_id = db->ToFuncId(caller_cursor.cx_cursor);
|
||||||
IndexFunc* caller = db->Resolve(caller_id);
|
IndexFunc* caller = db->Resolve(caller_id);
|
||||||
@ -592,10 +592,10 @@ void OnIndexReference_Function(IndexFile* db,
|
|||||||
called = db->Resolve(called_id);
|
called = db->Resolve(called_id);
|
||||||
|
|
||||||
AddFuncRef(&caller->def.callees,
|
AddFuncRef(&caller->def.callees,
|
||||||
IndexFuncRef(called->id, loc, is_implicit));
|
IndexFuncRef{loc, called->id, role});
|
||||||
AddFuncRef(&called->callers, IndexFuncRef(caller->id, loc, is_implicit));
|
AddFuncRef(&called->callers, IndexFuncRef{loc, caller->id, role});
|
||||||
} else {
|
} else {
|
||||||
AddFuncRef(&called->callers, IndexFuncRef(loc, is_implicit));
|
AddFuncRef(&called->callers, IndexFuncRef{loc, IndexFuncId(), role});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -603,7 +603,7 @@ void OnIndexReference_Function(IndexFile* db,
|
|||||||
|
|
||||||
// static
|
// static
|
||||||
const int IndexFile::kMajorVersion = 11;
|
const int IndexFile::kMajorVersion = 11;
|
||||||
const int IndexFile::kMinorVersion = 1;
|
const int IndexFile::kMinorVersion = 2;
|
||||||
|
|
||||||
IndexFile::IndexFile(const std::string& path,
|
IndexFile::IndexFile(const std::string& path,
|
||||||
const std::string& contents)
|
const std::string& contents)
|
||||||
@ -1258,7 +1258,7 @@ ClangCursor::VisitResult TemplateVisitor(ClangCursor cursor,
|
|||||||
IndexFunc* called = db->Resolve(called_id);
|
IndexFunc* called = db->Resolve(called_id);
|
||||||
OnIndexReference_Function(db, cursor.get_spelling_range(),
|
OnIndexReference_Function(db, cursor.get_spelling_range(),
|
||||||
data->container, called_id, called,
|
data->container, called_id, called,
|
||||||
/*implicit=*/false);
|
SymbolRole::None);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1992,8 +1992,9 @@ void OnIndexReference(CXClientData client_data, const CXIdxEntityRefInfo* ref) {
|
|||||||
else
|
else
|
||||||
CheckTypeDependentMemberRefExpr(&loc, ref_cursor, param, db);
|
CheckTypeDependentMemberRefExpr(&loc, ref_cursor, param, db);
|
||||||
|
|
||||||
OnIndexReference_Function(db, loc, ref->container->cursor, called_id,
|
OnIndexReference_Function(
|
||||||
called, is_implicit);
|
db, loc, ref->container->cursor, called_id, called,
|
||||||
|
is_implicit ? SymbolRole::Implicit : SymbolRole::None);
|
||||||
|
|
||||||
// Checks if |str| starts with |start|. Ignores case.
|
// Checks if |str| starts with |start|. Ignores case.
|
||||||
auto str_begin = [](const char* start, const char* str) {
|
auto str_begin = [](const char* start, const char* str) {
|
||||||
@ -2033,7 +2034,8 @@ void OnIndexReference(CXClientData client_data, const CXIdxEntityRefInfo* ref) {
|
|||||||
param->ctors.TryFindConstructorUsr(ctor_type_usr, call_type_desc);
|
param->ctors.TryFindConstructorUsr(ctor_type_usr, call_type_desc);
|
||||||
if (ctor_usr) {
|
if (ctor_usr) {
|
||||||
IndexFunc* ctor = db->Resolve(db->ToFuncId(*ctor_usr));
|
IndexFunc* ctor = db->Resolve(db->ToFuncId(*ctor_usr));
|
||||||
AddFuncRef(&ctor->callers, IndexFuncRef(loc, true /*is_implicit*/));
|
AddFuncRef(&ctor->callers,
|
||||||
|
IndexFuncRef{loc, IndexFuncId(), SymbolRole::Implicit});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2315,7 +2317,7 @@ void Reflect(Reader& visitor, IndexFuncRef& value) {
|
|||||||
std::string s = visitor.GetString();
|
std::string s = visitor.GetString();
|
||||||
const char* str_value = s.c_str();
|
const char* str_value = s.c_str();
|
||||||
if (str_value[0] == '~') {
|
if (str_value[0] == '~') {
|
||||||
value.is_implicit = true;
|
value.role = SymbolRole::Implicit;
|
||||||
++str_value;
|
++str_value;
|
||||||
}
|
}
|
||||||
RawId id = atol(str_value);
|
RawId id = atol(str_value);
|
||||||
@ -2324,15 +2326,15 @@ void Reflect(Reader& visitor, IndexFuncRef& value) {
|
|||||||
value.id = IndexFuncId(id);
|
value.id = IndexFuncId(id);
|
||||||
value.loc = Range(loc_string);
|
value.loc = Range(loc_string);
|
||||||
} else {
|
} else {
|
||||||
Reflect(visitor, value.id);
|
|
||||||
Reflect(visitor, value.loc);
|
Reflect(visitor, value.loc);
|
||||||
Reflect(visitor, value.is_implicit);
|
Reflect(visitor, value.id);
|
||||||
|
Reflect(visitor, value.role);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void Reflect(Writer& visitor, IndexFuncRef& value) {
|
void Reflect(Writer& visitor, IndexFuncRef& value) {
|
||||||
if (visitor.Format() == SerializeFormat::Json) {
|
if (visitor.Format() == SerializeFormat::Json) {
|
||||||
std::string s;
|
std::string s;
|
||||||
if (value.is_implicit)
|
if (value.role & SymbolRole::Implicit)
|
||||||
s += "~";
|
s += "~";
|
||||||
|
|
||||||
// id.id is unsigned, special case -1 value
|
// id.id is unsigned, special case -1 value
|
||||||
@ -2344,8 +2346,8 @@ void Reflect(Writer& visitor, IndexFuncRef& value) {
|
|||||||
s += "@" + value.loc.ToString();
|
s += "@" + value.loc.ToString();
|
||||||
visitor.String(s.c_str());
|
visitor.String(s.c_str());
|
||||||
} else {
|
} else {
|
||||||
Reflect(visitor, value.id);
|
|
||||||
Reflect(visitor, value.loc);
|
Reflect(visitor, value.loc);
|
||||||
Reflect(visitor, value.is_implicit);
|
Reflect(visitor, value.id);
|
||||||
|
Reflect(visitor, value.role);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -27,6 +27,7 @@
|
|||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
struct IndexFile;
|
||||||
struct IndexType;
|
struct IndexType;
|
||||||
struct IndexFunc;
|
struct IndexFunc;
|
||||||
struct IndexVar;
|
struct IndexVar;
|
||||||
@ -61,7 +62,7 @@ struct Id {
|
|||||||
namespace std {
|
namespace std {
|
||||||
template <typename T>
|
template <typename T>
|
||||||
struct hash<Id<T>> {
|
struct hash<Id<T>> {
|
||||||
size_t operator()(const Id<T>& k) const { return hash<size_t>()(k.id); }
|
size_t operator()(const Id<T>& k) const { return hash<RawId>()(k.id); }
|
||||||
};
|
};
|
||||||
} // namespace std
|
} // namespace std
|
||||||
|
|
||||||
@ -70,6 +71,7 @@ void Reflect(TVisitor& visitor, Id<T>& id) {
|
|||||||
Reflect(visitor, id.id);
|
Reflect(visitor, id.id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
using IndexFileId = Id<IndexFile>;
|
||||||
using IndexTypeId = Id<IndexType>;
|
using IndexTypeId = Id<IndexType>;
|
||||||
using IndexFuncId = Id<IndexFunc>;
|
using IndexFuncId = Id<IndexFunc>;
|
||||||
using IndexVarId = Id<IndexVar>;
|
using IndexVarId = Id<IndexVar>;
|
||||||
@ -88,18 +90,10 @@ struct IndexFuncRef {
|
|||||||
// NOTE: id can be -1 if the function call is not coming from a function.
|
// NOTE: id can be -1 if the function call is not coming from a function.
|
||||||
Range loc;
|
Range loc;
|
||||||
IndexFuncId id;
|
IndexFuncId id;
|
||||||
SymbolRole role = SymbolRole::None;
|
SymbolRole role;
|
||||||
bool is_implicit = false;
|
|
||||||
|
|
||||||
IndexFuncRef() {} // For serialization.
|
std::tuple<IndexFuncId, Range, SymbolRole> ToTuple() const {
|
||||||
|
return std::make_tuple(id, loc, role);
|
||||||
IndexFuncRef(IndexFuncId id, Range loc, bool is_implicit)
|
|
||||||
: loc(loc), id(id), is_implicit(is_implicit) {}
|
|
||||||
IndexFuncRef(Range loc, bool is_implicit)
|
|
||||||
: loc(loc), is_implicit(is_implicit) {}
|
|
||||||
|
|
||||||
std::tuple<IndexFuncId, Range, bool> ToTuple() const {
|
|
||||||
return std::make_tuple(id, loc, is_implicit);
|
|
||||||
}
|
}
|
||||||
bool operator==(const IndexFuncRef& o) { return ToTuple() == o.ToTuple(); }
|
bool operator==(const IndexFuncRef& o) { return ToTuple() == o.ToTuple(); }
|
||||||
bool operator!=(const IndexFuncRef& o) { return !(*this == o); }
|
bool operator!=(const IndexFuncRef& o) { return !(*this == o); }
|
||||||
@ -111,7 +105,11 @@ struct IndexFuncRef {
|
|||||||
void Reflect(Reader& visitor, IndexFuncRef& value);
|
void Reflect(Reader& visitor, IndexFuncRef& value);
|
||||||
void Reflect(Writer& visitor, IndexFuncRef& value);
|
void Reflect(Writer& visitor, IndexFuncRef& value);
|
||||||
|
|
||||||
template <typename TypeId, typename FuncId, typename VarId, typename Range>
|
template <typename FileId,
|
||||||
|
typename TypeId,
|
||||||
|
typename FuncId,
|
||||||
|
typename VarId,
|
||||||
|
typename Range>
|
||||||
struct TypeDefDefinitionData {
|
struct TypeDefDefinitionData {
|
||||||
// General metadata.
|
// General metadata.
|
||||||
std::string detailed_name;
|
std::string detailed_name;
|
||||||
@ -130,10 +128,6 @@ struct TypeDefDefinitionData {
|
|||||||
Maybe<Range> definition_spelling;
|
Maybe<Range> definition_spelling;
|
||||||
Maybe<Range> definition_extent;
|
Maybe<Range> definition_extent;
|
||||||
|
|
||||||
// If set, then this is the same underlying type as the given value (ie, this
|
|
||||||
// type comes from a using or typedef statement).
|
|
||||||
Maybe<TypeId> alias_of;
|
|
||||||
|
|
||||||
// Immediate parent types.
|
// Immediate parent types.
|
||||||
std::vector<TypeId> parents;
|
std::vector<TypeId> parents;
|
||||||
|
|
||||||
@ -142,6 +136,11 @@ struct TypeDefDefinitionData {
|
|||||||
std::vector<FuncId> funcs;
|
std::vector<FuncId> funcs;
|
||||||
std::vector<VarId> vars;
|
std::vector<VarId> vars;
|
||||||
|
|
||||||
|
FileId file;
|
||||||
|
// If set, then this is the same underlying type as the given value (ie, this
|
||||||
|
// type comes from a using or typedef statement).
|
||||||
|
Maybe<TypeId> alias_of;
|
||||||
|
|
||||||
int16_t short_name_offset = 0;
|
int16_t short_name_offset = 0;
|
||||||
int16_t short_name_size = 0;
|
int16_t short_name_size = 0;
|
||||||
ClangSymbolKind kind = ClangSymbolKind::Unknown;
|
ClangSymbolKind kind = ClangSymbolKind::Unknown;
|
||||||
@ -164,12 +163,14 @@ struct TypeDefDefinitionData {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
template <typename TVisitor,
|
template <typename TVisitor,
|
||||||
|
typename FileId,
|
||||||
typename TypeId,
|
typename TypeId,
|
||||||
typename FuncId,
|
typename FuncId,
|
||||||
typename VarId,
|
typename VarId,
|
||||||
typename Range>
|
typename Range>
|
||||||
void Reflect(TVisitor& visitor,
|
void Reflect(
|
||||||
TypeDefDefinitionData<TypeId, FuncId, VarId, Range>& value) {
|
TVisitor& visitor,
|
||||||
|
TypeDefDefinitionData<FileId, TypeId, FuncId, VarId, Range>& value) {
|
||||||
REFLECT_MEMBER_START();
|
REFLECT_MEMBER_START();
|
||||||
REFLECT_MEMBER(detailed_name);
|
REFLECT_MEMBER(detailed_name);
|
||||||
REFLECT_MEMBER(short_name_offset);
|
REFLECT_MEMBER(short_name_offset);
|
||||||
@ -179,6 +180,7 @@ void Reflect(TVisitor& visitor,
|
|||||||
REFLECT_MEMBER(comments);
|
REFLECT_MEMBER(comments);
|
||||||
REFLECT_MEMBER(definition_spelling);
|
REFLECT_MEMBER(definition_spelling);
|
||||||
REFLECT_MEMBER(definition_extent);
|
REFLECT_MEMBER(definition_extent);
|
||||||
|
REFLECT_MEMBER(file);
|
||||||
REFLECT_MEMBER(alias_of);
|
REFLECT_MEMBER(alias_of);
|
||||||
REFLECT_MEMBER(parents);
|
REFLECT_MEMBER(parents);
|
||||||
REFLECT_MEMBER(types);
|
REFLECT_MEMBER(types);
|
||||||
@ -188,8 +190,11 @@ void Reflect(TVisitor& visitor,
|
|||||||
}
|
}
|
||||||
|
|
||||||
struct IndexType {
|
struct IndexType {
|
||||||
using Def =
|
using Def = TypeDefDefinitionData<IndexFileId,
|
||||||
TypeDefDefinitionData<IndexTypeId, IndexFuncId, IndexVarId, Range>;
|
IndexTypeId,
|
||||||
|
IndexFuncId,
|
||||||
|
IndexVarId,
|
||||||
|
Range>;
|
||||||
|
|
||||||
Usr usr;
|
Usr usr;
|
||||||
IndexTypeId id;
|
IndexTypeId id;
|
||||||
@ -213,7 +218,8 @@ struct IndexType {
|
|||||||
};
|
};
|
||||||
MAKE_HASHABLE(IndexType, t.id);
|
MAKE_HASHABLE(IndexType, t.id);
|
||||||
|
|
||||||
template <typename TypeId,
|
template <typename FileId,
|
||||||
|
typename TypeId,
|
||||||
typename FuncId,
|
typename FuncId,
|
||||||
typename VarId,
|
typename VarId,
|
||||||
typename FuncRef,
|
typename FuncRef,
|
||||||
@ -226,9 +232,6 @@ struct FuncDefDefinitionData {
|
|||||||
Maybe<Range> definition_spelling;
|
Maybe<Range> definition_spelling;
|
||||||
Maybe<Range> definition_extent;
|
Maybe<Range> definition_extent;
|
||||||
|
|
||||||
// Type which declares this one (ie, it is a method)
|
|
||||||
Maybe<TypeId> declaring_type;
|
|
||||||
|
|
||||||
// Method this method overrides.
|
// Method this method overrides.
|
||||||
std::vector<FuncId> base;
|
std::vector<FuncId> base;
|
||||||
|
|
||||||
@ -238,6 +241,9 @@ struct FuncDefDefinitionData {
|
|||||||
// Functions that this function calls.
|
// Functions that this function calls.
|
||||||
std::vector<FuncRef> callees;
|
std::vector<FuncRef> callees;
|
||||||
|
|
||||||
|
FileId file;
|
||||||
|
// Type which declares this one (ie, it is a method)
|
||||||
|
Maybe<TypeId> declaring_type;
|
||||||
int16_t short_name_offset = 0;
|
int16_t short_name_offset = 0;
|
||||||
int16_t short_name_size = 0;
|
int16_t short_name_size = 0;
|
||||||
ClangSymbolKind kind = ClangSymbolKind::Unknown;
|
ClangSymbolKind kind = ClangSymbolKind::Unknown;
|
||||||
@ -262,6 +268,7 @@ struct FuncDefDefinitionData {
|
|||||||
};
|
};
|
||||||
|
|
||||||
template <typename TVisitor,
|
template <typename TVisitor,
|
||||||
|
typename FileId,
|
||||||
typename TypeId,
|
typename TypeId,
|
||||||
typename FuncId,
|
typename FuncId,
|
||||||
typename VarId,
|
typename VarId,
|
||||||
@ -269,7 +276,8 @@ template <typename TVisitor,
|
|||||||
typename Range>
|
typename Range>
|
||||||
void Reflect(
|
void Reflect(
|
||||||
TVisitor& visitor,
|
TVisitor& visitor,
|
||||||
FuncDefDefinitionData<TypeId, FuncId, VarId, FuncRef, Range>& value) {
|
FuncDefDefinitionData<FileId, TypeId, FuncId, VarId, FuncRef, Range>&
|
||||||
|
value) {
|
||||||
REFLECT_MEMBER_START();
|
REFLECT_MEMBER_START();
|
||||||
REFLECT_MEMBER(detailed_name);
|
REFLECT_MEMBER(detailed_name);
|
||||||
REFLECT_MEMBER(short_name_offset);
|
REFLECT_MEMBER(short_name_offset);
|
||||||
@ -280,6 +288,7 @@ void Reflect(
|
|||||||
REFLECT_MEMBER(comments);
|
REFLECT_MEMBER(comments);
|
||||||
REFLECT_MEMBER(definition_spelling);
|
REFLECT_MEMBER(definition_spelling);
|
||||||
REFLECT_MEMBER(definition_extent);
|
REFLECT_MEMBER(definition_extent);
|
||||||
|
REFLECT_MEMBER(file);
|
||||||
REFLECT_MEMBER(declaring_type);
|
REFLECT_MEMBER(declaring_type);
|
||||||
REFLECT_MEMBER(base);
|
REFLECT_MEMBER(base);
|
||||||
REFLECT_MEMBER(locals);
|
REFLECT_MEMBER(locals);
|
||||||
@ -288,7 +297,8 @@ void Reflect(
|
|||||||
}
|
}
|
||||||
|
|
||||||
struct IndexFunc {
|
struct IndexFunc {
|
||||||
using Def = FuncDefDefinitionData<IndexTypeId,
|
using Def = FuncDefDefinitionData<IndexFileId,
|
||||||
|
IndexTypeId,
|
||||||
IndexFuncId,
|
IndexFuncId,
|
||||||
IndexVarId,
|
IndexVarId,
|
||||||
IndexFuncRef,
|
IndexFuncRef,
|
||||||
@ -337,7 +347,11 @@ MAKE_REFLECT_STRUCT(IndexFunc::Declaration,
|
|||||||
content,
|
content,
|
||||||
param_spellings);
|
param_spellings);
|
||||||
|
|
||||||
template <typename TypeId, typename FuncId, typename VarId, typename Range>
|
template <typename FileId,
|
||||||
|
typename TypeId,
|
||||||
|
typename FuncId,
|
||||||
|
typename VarId,
|
||||||
|
typename Range>
|
||||||
struct VarDefDefinitionData {
|
struct VarDefDefinitionData {
|
||||||
// General metadata.
|
// General metadata.
|
||||||
std::string detailed_name;
|
std::string detailed_name;
|
||||||
@ -348,6 +362,7 @@ struct VarDefDefinitionData {
|
|||||||
Maybe<Range> definition_spelling;
|
Maybe<Range> definition_spelling;
|
||||||
Maybe<Range> definition_extent;
|
Maybe<Range> definition_extent;
|
||||||
|
|
||||||
|
FileId file;
|
||||||
// Type of the variable.
|
// Type of the variable.
|
||||||
Maybe<TypeId> variable_type;
|
Maybe<TypeId> variable_type;
|
||||||
|
|
||||||
@ -376,8 +391,7 @@ struct VarDefDefinitionData {
|
|||||||
parent_kind == o.parent_kind && kind == o.kind &&
|
parent_kind == o.parent_kind && kind == o.kind &&
|
||||||
storage == o.storage && hover == o.hover && comments == o.comments;
|
storage == o.storage && hover == o.hover && comments == o.comments;
|
||||||
}
|
}
|
||||||
bool operator!=(
|
bool operator!=(const VarDefDefinitionData& other) const {
|
||||||
const VarDefDefinitionData<TypeId, FuncId, VarId, Range>& other) const {
|
|
||||||
return !(*this == other);
|
return !(*this == other);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -388,12 +402,14 @@ struct VarDefDefinitionData {
|
|||||||
};
|
};
|
||||||
|
|
||||||
template <typename TVisitor,
|
template <typename TVisitor,
|
||||||
|
typename FileId,
|
||||||
typename TypeId,
|
typename TypeId,
|
||||||
typename FuncId,
|
typename FuncId,
|
||||||
typename VarId,
|
typename VarId,
|
||||||
typename Range>
|
typename Range>
|
||||||
void Reflect(TVisitor& visitor,
|
void Reflect(
|
||||||
VarDefDefinitionData<TypeId, FuncId, VarId, Range>& value) {
|
TVisitor& visitor,
|
||||||
|
VarDefDefinitionData<FileId, TypeId, FuncId, VarId, Range>& value) {
|
||||||
REFLECT_MEMBER_START();
|
REFLECT_MEMBER_START();
|
||||||
REFLECT_MEMBER(detailed_name);
|
REFLECT_MEMBER(detailed_name);
|
||||||
REFLECT_MEMBER(short_name_size);
|
REFLECT_MEMBER(short_name_size);
|
||||||
@ -402,6 +418,7 @@ void Reflect(TVisitor& visitor,
|
|||||||
REFLECT_MEMBER(comments);
|
REFLECT_MEMBER(comments);
|
||||||
REFLECT_MEMBER(definition_spelling);
|
REFLECT_MEMBER(definition_spelling);
|
||||||
REFLECT_MEMBER(definition_extent);
|
REFLECT_MEMBER(definition_extent);
|
||||||
|
REFLECT_MEMBER(file);
|
||||||
REFLECT_MEMBER(variable_type);
|
REFLECT_MEMBER(variable_type);
|
||||||
REFLECT_MEMBER(parent_id);
|
REFLECT_MEMBER(parent_id);
|
||||||
REFLECT_MEMBER(parent_kind);
|
REFLECT_MEMBER(parent_kind);
|
||||||
@ -411,7 +428,11 @@ void Reflect(TVisitor& visitor,
|
|||||||
}
|
}
|
||||||
|
|
||||||
struct IndexVar {
|
struct IndexVar {
|
||||||
using Def = VarDefDefinitionData<IndexTypeId, IndexFuncId, IndexVarId, Range>;
|
using Def = VarDefDefinitionData<IndexFileId,
|
||||||
|
IndexTypeId,
|
||||||
|
IndexFuncId,
|
||||||
|
IndexVarId,
|
||||||
|
Range>;
|
||||||
|
|
||||||
Usr usr;
|
Usr usr;
|
||||||
IndexVarId id;
|
IndexVarId id;
|
||||||
|
@ -73,8 +73,8 @@ optional<QueryFileId> GetImplementationFile(QueryDatabase* db,
|
|||||||
// Note: we ignore the definition if it is in the same file (ie,
|
// Note: we ignore the definition if it is in the same file (ie,
|
||||||
// possibly a header).
|
// possibly a header).
|
||||||
if (func.def && func.def->definition_extent &&
|
if (func.def && func.def->definition_extent &&
|
||||||
func.def->definition_extent->path != file_id) {
|
func.def->definition_extent->FileId() != file_id) {
|
||||||
return func.def->definition_extent->path;
|
return func.def->definition_extent->FileId();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -83,8 +83,8 @@ optional<QueryFileId> GetImplementationFile(QueryDatabase* db,
|
|||||||
// Note: we ignore the definition if it is in the same file (ie,
|
// Note: we ignore the definition if it is in the same file (ie,
|
||||||
// possibly a header).
|
// possibly a header).
|
||||||
if (var.def && var.def->definition_extent &&
|
if (var.def && var.def->definition_extent &&
|
||||||
var.def->definition_extent->path != file_id) {
|
var.def->definition_extent->FileId() != file_id) {
|
||||||
return db->vars[sym.idx.idx].def->definition_extent->path;
|
return db->vars[sym.idx.idx].def->definition_extent->FileId();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -149,7 +149,7 @@ optional<lsTextEdit> BuildAutoImplementForFunction(QueryDatabase* db,
|
|||||||
QueryFunc& func) {
|
QueryFunc& func) {
|
||||||
assert(func.def);
|
assert(func.def);
|
||||||
for (const QueryLocation& decl : func.declarations) {
|
for (const QueryLocation& decl : func.declarations) {
|
||||||
if (decl.path != decl_file_id)
|
if (decl.FileId() != decl_file_id)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
optional<lsRange> ls_decl = GetLsRange(working_file, decl.range);
|
optional<lsRange> ls_decl = GetLsRange(working_file, decl.range);
|
||||||
@ -203,7 +203,7 @@ optional<lsTextEdit> BuildAutoImplementForFunction(QueryDatabase* db,
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
for (QueryLocation& func_decl : sym_func.declarations) {
|
for (QueryLocation& func_decl : sym_func.declarations) {
|
||||||
if (func_decl.path == decl_file_id) {
|
if (func_decl.FileId() == decl_file_id) {
|
||||||
int dist = func_decl.range.start.line - decl.range.start.line;
|
int dist = func_decl.range.start.line - decl.range.start.line;
|
||||||
if (abs(dist) < abs(best_dist)) {
|
if (abs(dist) < abs(best_dist)) {
|
||||||
optional<lsLocation> def_loc = GetLsLocation(
|
optional<lsLocation> def_loc = GetLsLocation(
|
||||||
|
@ -90,7 +90,7 @@ void AddCodeLens(const char* singular,
|
|||||||
code_lens.range = *range;
|
code_lens.range = *range;
|
||||||
code_lens.command = lsCommand<lsCodeLensCommandArguments>();
|
code_lens.command = lsCommand<lsCodeLensCommandArguments>();
|
||||||
code_lens.command->command = "cquery.showReferences";
|
code_lens.command->command = "cquery.showReferences";
|
||||||
code_lens.command->arguments.uri = GetLsDocumentUri(common->db, loc.path);
|
code_lens.command->arguments.uri = GetLsDocumentUri(common->db, loc.FileId());
|
||||||
code_lens.command->arguments.position = code_lens.range.start;
|
code_lens.command->arguments.position = code_lens.range.start;
|
||||||
|
|
||||||
// Add unique uses.
|
// Add unique uses.
|
||||||
@ -179,7 +179,7 @@ struct TextDocumentCodeLensHandler
|
|||||||
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.idx);
|
||||||
if (!def || def->path != sym.loc.path ||
|
if (!def || def->FileId() != sym.loc.FileId() ||
|
||||||
def->range.start.line != sym.loc.range.start.line) {
|
def->range.start.line != sym.loc.range.start.line) {
|
||||||
return sym.loc;
|
return sym.loc;
|
||||||
}
|
}
|
||||||
|
@ -90,7 +90,7 @@ struct TextDocumentDefinitionHandler
|
|||||||
// the declaration if possible. We also want to use declarations if
|
// the declaration if possible. We also want to use declarations if
|
||||||
// we're pointing to, ie, a pure virtual function which has no
|
// we're pointing to, ie, a pure virtual function which has no
|
||||||
// definition.
|
// definition.
|
||||||
if (!def_loc || (def_loc->path == file_id &&
|
if (!def_loc || (def_loc->FileId() == file_id &&
|
||||||
def_loc->range.Contains(target_line, target_column))) {
|
def_loc->range.Contains(target_line, target_column))) {
|
||||||
// Goto declaration.
|
// Goto declaration.
|
||||||
|
|
||||||
|
@ -41,7 +41,7 @@ struct TextDocumentDocumentHighlightHandler
|
|||||||
std::vector<QueryLocation> uses = GetUsesOfSymbol(db, ref.idx, true);
|
std::vector<QueryLocation> uses = GetUsesOfSymbol(db, ref.idx, true);
|
||||||
out.result.reserve(uses.size());
|
out.result.reserve(uses.size());
|
||||||
for (const QueryLocation& use : uses) {
|
for (const QueryLocation& use : uses) {
|
||||||
if (use.path != file_id)
|
if (use.FileId() != file_id)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
optional<lsLocation> ls_location =
|
optional<lsLocation> ls_location =
|
||||||
|
@ -16,20 +16,21 @@ lsWorkspaceEdit BuildWorkspaceEdit(QueryDatabase* db,
|
|||||||
if (!ls_location)
|
if (!ls_location)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (path_to_edit.find(location.path) == path_to_edit.end()) {
|
QueryFileId file_id = location.FileId();
|
||||||
path_to_edit[location.path] = lsTextDocumentEdit();
|
if (path_to_edit.find(file_id) == path_to_edit.end()) {
|
||||||
|
path_to_edit[file_id] = lsTextDocumentEdit();
|
||||||
|
|
||||||
QueryFile& file = db->files[location.path.id];
|
QueryFile& file = db->files[file_id.id];
|
||||||
if (!file.def)
|
if (!file.def)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
const std::string& path = file.def->path;
|
const std::string& path = file.def->path;
|
||||||
path_to_edit[location.path].textDocument.uri =
|
path_to_edit[file_id].textDocument.uri =
|
||||||
lsDocumentUri::FromPath(path);
|
lsDocumentUri::FromPath(path);
|
||||||
|
|
||||||
WorkingFile* working_file = working_files->GetFileByFilename(path);
|
WorkingFile* working_file = working_files->GetFileByFilename(path);
|
||||||
if (working_file)
|
if (working_file)
|
||||||
path_to_edit[location.path].textDocument.version =
|
path_to_edit[file_id].textDocument.version =
|
||||||
working_file->version;
|
working_file->version;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -38,7 +39,7 @@ lsWorkspaceEdit BuildWorkspaceEdit(QueryDatabase* db,
|
|||||||
edit.newText = new_text;
|
edit.newText = new_text;
|
||||||
|
|
||||||
// vscode complains if we submit overlapping text edits.
|
// vscode complains if we submit overlapping text edits.
|
||||||
auto& edits = path_to_edit[location.path].edits;
|
auto& edits = path_to_edit[file_id].edits;
|
||||||
if (std::find(edits.begin(), edits.end(), edit) == edits.end())
|
if (std::find(edits.begin(), edits.end(), edit) == edits.end())
|
||||||
edits.push_back(edit);
|
edits.push_back(edit);
|
||||||
}
|
}
|
||||||
|
86
src/query.cc
86
src/query.cc
@ -42,8 +42,12 @@ optional<QueryType::Def> ToQuery(const IdMap& id_map,
|
|||||||
result.kind = type.kind;
|
result.kind = type.kind;
|
||||||
result.hover = type.hover;
|
result.hover = type.hover;
|
||||||
result.comments = type.comments;
|
result.comments = type.comments;
|
||||||
result.definition_spelling = id_map.ToQuery(type.definition_spelling);
|
if (type.definition_spelling)
|
||||||
result.definition_extent = id_map.ToQuery(type.definition_extent);
|
result.definition_spelling =
|
||||||
|
id_map.ToQuery(*type.definition_spelling, SymbolRole::Definition);
|
||||||
|
if (type.definition_extent)
|
||||||
|
result.definition_extent =
|
||||||
|
id_map.ToQuery(*type.definition_extent, SymbolRole::None);
|
||||||
result.alias_of = id_map.ToQuery(type.alias_of);
|
result.alias_of = id_map.ToQuery(type.alias_of);
|
||||||
result.parents = id_map.ToQuery(type.parents);
|
result.parents = id_map.ToQuery(type.parents);
|
||||||
result.types = id_map.ToQuery(type.types);
|
result.types = id_map.ToQuery(type.types);
|
||||||
@ -65,8 +69,12 @@ optional<QueryFunc::Def> ToQuery(const IdMap& id_map,
|
|||||||
result.storage = func.storage;
|
result.storage = func.storage;
|
||||||
result.hover = func.hover;
|
result.hover = func.hover;
|
||||||
result.comments = func.comments;
|
result.comments = func.comments;
|
||||||
result.definition_spelling = id_map.ToQuery(func.definition_spelling);
|
if (func.definition_spelling)
|
||||||
result.definition_extent = id_map.ToQuery(func.definition_extent);
|
result.definition_spelling =
|
||||||
|
id_map.ToQuery(*func.definition_spelling, SymbolRole::Definition);
|
||||||
|
if (func.definition_extent)
|
||||||
|
result.definition_extent =
|
||||||
|
id_map.ToQuery(*func.definition_extent, SymbolRole::None);
|
||||||
result.declaring_type = id_map.ToQuery(func.declaring_type);
|
result.declaring_type = id_map.ToQuery(func.declaring_type);
|
||||||
result.base = id_map.ToQuery(func.base);
|
result.base = id_map.ToQuery(func.base);
|
||||||
result.locals = id_map.ToQuery(func.locals);
|
result.locals = id_map.ToQuery(func.locals);
|
||||||
@ -84,8 +92,12 @@ optional<QueryVar::Def> ToQuery(const IdMap& id_map, const IndexVar::Def& var) {
|
|||||||
result.short_name_size = var.short_name_size;
|
result.short_name_size = var.short_name_size;
|
||||||
result.hover = var.hover;
|
result.hover = var.hover;
|
||||||
result.comments = var.comments;
|
result.comments = var.comments;
|
||||||
result.definition_spelling = id_map.ToQuery(var.definition_spelling);
|
if (var.definition_spelling)
|
||||||
result.definition_extent = id_map.ToQuery(var.definition_extent);
|
result.definition_spelling =
|
||||||
|
id_map.ToQuery(*var.definition_spelling, SymbolRole::Definition);
|
||||||
|
if (var.definition_extent)
|
||||||
|
result.definition_extent =
|
||||||
|
id_map.ToQuery(*var.definition_extent, SymbolRole::None);
|
||||||
result.variable_type = id_map.ToQuery(var.variable_type);
|
result.variable_type = id_map.ToQuery(var.variable_type);
|
||||||
result.parent_id = var.parent_id;
|
result.parent_id = var.parent_id;
|
||||||
result.parent_kind = var.parent_kind;
|
result.parent_kind = var.parent_kind;
|
||||||
@ -223,11 +235,13 @@ QueryFile::DefUpdate BuildFileDefUpdate(const IdMap& id_map, const IndexFile& in
|
|||||||
|
|
||||||
auto add_outline = [&def, &id_map](SymbolIdx idx, Range range) {
|
auto add_outline = [&def, &id_map](SymbolIdx idx, Range range) {
|
||||||
def.outline.push_back(
|
def.outline.push_back(
|
||||||
SymbolRef(idx, SymbolRole::Declaration, id_map.ToQuery(range)));
|
SymbolRef(idx, SymbolRole::Declaration,
|
||||||
|
id_map.ToQuery(range, SymbolRole::Declaration)));
|
||||||
};
|
};
|
||||||
auto add_all_symbols = [&def, &id_map](SymbolIdx idx, SymbolRole role,
|
auto add_all_symbols = [&def, &id_map](SymbolIdx idx, SymbolRole role,
|
||||||
Range range) {
|
Range range) {
|
||||||
def.all_symbols.push_back(SymbolRef(idx, role, id_map.ToQuery(range)));
|
def.all_symbols.push_back(
|
||||||
|
SymbolRef(idx, role, id_map.ToQuery(range, role)));
|
||||||
};
|
};
|
||||||
|
|
||||||
for (const IndexType& type : indexed.types) {
|
for (const IndexType& type : indexed.types) {
|
||||||
@ -256,16 +270,13 @@ QueryFile::DefUpdate BuildFileDefUpdate(const IdMap& id_map, const IndexFile& in
|
|||||||
// textDocument/definition on the space/semicolon in `A a;` or `return
|
// textDocument/definition on the space/semicolon in `A a;` or `return
|
||||||
// 42;` will take you to the constructor.
|
// 42;` will take you to the constructor.
|
||||||
Range range = caller.loc;
|
Range range = caller.loc;
|
||||||
if (caller.is_implicit) {
|
if (caller.role & SymbolRole::Implicit) {
|
||||||
if (range.start.column > 0)
|
if (range.start.column > 0)
|
||||||
range.start.column--;
|
range.start.column--;
|
||||||
range.end.column++;
|
range.end.column++;
|
||||||
}
|
}
|
||||||
add_all_symbols(id_map.ToSymbol(func.id),
|
add_all_symbols(id_map.ToSymbol(func.id),
|
||||||
caller.is_implicit
|
caller.role | SymbolRole::CalledBy, range);
|
||||||
? SymbolRole::Implicit | SymbolRole::CalledBy
|
|
||||||
: SymbolRole::CalledBy,
|
|
||||||
range);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (const IndexVar& var : indexed.vars) {
|
for (const IndexVar& var : indexed.vars) {
|
||||||
@ -396,8 +407,11 @@ IdMap::IdMap(QueryDatabase* query_db, const IdCache& local_ids)
|
|||||||
*GetQueryVarIdFromUsr(query_db, entry.second, true);
|
*GetQueryVarIdFromUsr(query_db, entry.second, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
QueryLocation IdMap::ToQuery(Range range) const {
|
QueryLocation IdMap::ToQuery(Range range, SymbolRole role) const {
|
||||||
return QueryLocation(primary_file, range);
|
return QueryLocation{range, primary_file, role};
|
||||||
|
}
|
||||||
|
QueryFileId IdMap::ToQuery(IndexFileId) const {
|
||||||
|
return primary_file;
|
||||||
}
|
}
|
||||||
QueryTypeId IdMap::ToQuery(IndexTypeId id) const {
|
QueryTypeId IdMap::ToQuery(IndexTypeId id) const {
|
||||||
assert(cached_type_ids_.find(id) != cached_type_ids_.end());
|
assert(cached_type_ids_.find(id) != cached_type_ids_.end());
|
||||||
@ -414,11 +428,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 {
|
||||||
return QueryFuncRef(ToQuery(ref.id), ToQuery(ref.loc), ref.is_implicit);
|
return QueryFuncRef{ToQuery(ref.id), ToQuery(ref.loc, ref.role)};
|
||||||
}
|
}
|
||||||
QueryLocation IdMap::ToQuery(IndexFunc::Declaration decl) const {
|
QueryLocation IdMap::ToQuery(IndexFunc::Declaration decl) const {
|
||||||
// TODO: expose more than just QueryLocation.
|
// TODO: expose more than just QueryLocation.
|
||||||
return QueryLocation(primary_file, decl.spelling);
|
return QueryLocation{decl.spelling, primary_file, SymbolRole::Declaration};
|
||||||
|
}
|
||||||
|
std::vector<QueryLocation> IdMap::ToQuery(const std::vector<Range>& a) const {
|
||||||
|
std::vector<QueryLocation> ret;
|
||||||
|
ret.reserve(a.size());
|
||||||
|
for (auto& x : a)
|
||||||
|
ret.push_back(ToQuery(x, SymbolRole::Reference));
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
SymbolIdx IdMap::ToSymbol(IndexTypeId id) const {
|
SymbolIdx IdMap::ToSymbol(IndexTypeId id) const {
|
||||||
@ -734,7 +755,6 @@ void QueryDatabase::RemoveUsrs(SymbolKind usr_kind,
|
|||||||
QueryType& type = types[usr_to_type[usr].id];
|
QueryType& type = types[usr_to_type[usr].id];
|
||||||
if (type.symbol_idx)
|
if (type.symbol_idx)
|
||||||
symbols[type.symbol_idx->id].kind = SymbolKind::Invalid;
|
symbols[type.symbol_idx->id].kind = SymbolKind::Invalid;
|
||||||
type.gen++;
|
|
||||||
//type.def = QueryType::Def();
|
//type.def = QueryType::Def();
|
||||||
type.def = nullopt;
|
type.def = nullopt;
|
||||||
}
|
}
|
||||||
@ -745,7 +765,6 @@ void QueryDatabase::RemoveUsrs(SymbolKind usr_kind,
|
|||||||
QueryFunc& func = funcs[usr_to_func[usr].id];
|
QueryFunc& func = funcs[usr_to_func[usr].id];
|
||||||
if (func.symbol_idx)
|
if (func.symbol_idx)
|
||||||
symbols[func.symbol_idx->id].kind = SymbolKind::Invalid;
|
symbols[func.symbol_idx->id].kind = SymbolKind::Invalid;
|
||||||
func.gen++;
|
|
||||||
//func.def = QueryFunc::Def();
|
//func.def = QueryFunc::Def();
|
||||||
func.def = nullopt;
|
func.def = nullopt;
|
||||||
}
|
}
|
||||||
@ -756,7 +775,6 @@ void QueryDatabase::RemoveUsrs(SymbolKind usr_kind,
|
|||||||
QueryVar& var = vars[usr_to_var[usr].id];
|
QueryVar& var = vars[usr_to_var[usr].id];
|
||||||
if (var.symbol_idx)
|
if (var.symbol_idx)
|
||||||
symbols[var.symbol_idx->id].kind = SymbolKind::Invalid;
|
symbols[var.symbol_idx->id].kind = SymbolKind::Invalid;
|
||||||
var.gen++;
|
|
||||||
//var.def = QueryVar::Def();
|
//var.def = QueryVar::Def();
|
||||||
var.def = nullopt;
|
var.def = nullopt;
|
||||||
}
|
}
|
||||||
@ -987,8 +1005,8 @@ TEST_SUITE("query") {
|
|||||||
previous.Resolve(previous.ToTypeId(HashUsr("usr1")))
|
previous.Resolve(previous.ToTypeId(HashUsr("usr1")))
|
||||||
->uses.push_back(Range(Position(1, 0)));
|
->uses.push_back(Range(Position(1, 0)));
|
||||||
previous.Resolve(previous.ToFuncId(HashUsr("usr2")))
|
previous.Resolve(previous.ToFuncId(HashUsr("usr2")))
|
||||||
->callers.push_back(IndexFuncRef(IndexFuncId(0), Range(Position(2, 0)),
|
->callers.push_back(IndexFuncRef{Range(Position(2, 0)), IndexFuncId(0),
|
||||||
false /*is_implicit*/));
|
SymbolRole::None});
|
||||||
previous.Resolve(previous.ToVarId(HashUsr("usr3")))
|
previous.Resolve(previous.ToVarId(HashUsr("usr3")))
|
||||||
->uses.push_back(Range(Position(3, 0)));
|
->uses.push_back(Range(Position(3, 0)));
|
||||||
|
|
||||||
@ -1006,10 +1024,10 @@ TEST_SUITE("query") {
|
|||||||
IndexFunc* pf = previous.Resolve(previous.ToFuncId(HashUsr("usr")));
|
IndexFunc* pf = previous.Resolve(previous.ToFuncId(HashUsr("usr")));
|
||||||
IndexFunc* cf = current.Resolve(current.ToFuncId(HashUsr("usr")));
|
IndexFunc* cf = current.Resolve(current.ToFuncId(HashUsr("usr")));
|
||||||
|
|
||||||
pf->callers.push_back(IndexFuncRef(IndexFuncId(0), Range(Position(1, 0)),
|
pf->callers.push_back(
|
||||||
false /*is_implicit*/));
|
IndexFuncRef{Range(Position(1, 0)), IndexFuncId(0), SymbolRole::None});
|
||||||
cf->callers.push_back(IndexFuncRef(IndexFuncId(0), Range(Position(2, 0)),
|
cf->callers.push_back(
|
||||||
false /*is_implicit*/));
|
IndexFuncRef{Range(Position(2, 0)), IndexFuncId(0), SymbolRole::None});
|
||||||
|
|
||||||
IndexUpdate update = GetDelta(previous, current);
|
IndexUpdate update = GetDelta(previous, current);
|
||||||
|
|
||||||
@ -1051,14 +1069,14 @@ TEST_SUITE("query") {
|
|||||||
|
|
||||||
IndexFunc* pf = previous.Resolve(previous.ToFuncId(HashUsr("usr")));
|
IndexFunc* pf = previous.Resolve(previous.ToFuncId(HashUsr("usr")));
|
||||||
IndexFunc* cf = current.Resolve(current.ToFuncId(HashUsr("usr")));
|
IndexFunc* cf = current.Resolve(current.ToFuncId(HashUsr("usr")));
|
||||||
pf->callers.push_back(IndexFuncRef(IndexFuncId(0), Range(Position(1, 0)),
|
pf->callers.push_back(
|
||||||
false /*is_implicit*/));
|
IndexFuncRef{Range(Position(1, 0)), IndexFuncId(0), SymbolRole::None});
|
||||||
pf->callers.push_back(IndexFuncRef(IndexFuncId(0), Range(Position(2, 0)),
|
pf->callers.push_back(
|
||||||
false /*is_implicit*/));
|
IndexFuncRef{Range(Position(2, 0)), IndexFuncId(0), SymbolRole::None});
|
||||||
cf->callers.push_back(IndexFuncRef(IndexFuncId(0), Range(Position(4, 0)),
|
cf->callers.push_back(
|
||||||
false /*is_implicit*/));
|
IndexFuncRef{Range(Position(4, 0)), IndexFuncId(0), SymbolRole::None});
|
||||||
cf->callers.push_back(IndexFuncRef(IndexFuncId(0), Range(Position(5, 0)),
|
cf->callers.push_back(
|
||||||
false /*is_implicit*/));
|
IndexFuncRef{Range(Position(5, 0)), IndexFuncId(0), SymbolRole::None});
|
||||||
|
|
||||||
QueryDatabase db;
|
QueryDatabase db;
|
||||||
IdMap previous_map(&db, previous.id_cache);
|
IdMap previous_map(&db, previous.id_cache);
|
||||||
|
81
src/query.h
81
src/query.h
@ -20,40 +20,10 @@ using QueryVarId = Id<QueryVar>;
|
|||||||
|
|
||||||
struct IdMap;
|
struct IdMap;
|
||||||
|
|
||||||
using Generation = uint32_t;
|
|
||||||
|
|
||||||
// Example use: |WithGen<Id<QueryType>>|, to mark an |Id| reference with
|
|
||||||
// generation, so that by comparising the generation with that stored in the
|
|
||||||
// referenced Query object, we can tell if the reference is stale (the
|
|
||||||
// referenced object has been deleted or reused).
|
|
||||||
template <typename T>
|
|
||||||
struct WithGen {
|
|
||||||
Generation gen;
|
|
||||||
T value;
|
|
||||||
WithGen() : gen(-1) {}
|
|
||||||
WithGen(const T& value) : gen(-1), value(value) {}
|
|
||||||
WithGen(Generation gen, const T& value) : gen(gen), value(value) {}
|
|
||||||
|
|
||||||
bool HasValue() const { return value.HasValue(); }
|
|
||||||
explicit operator bool() const { return HasValue(); }
|
|
||||||
|
|
||||||
bool operator==(const WithGen& o) const {
|
|
||||||
return gen == o.gen && value == o.value;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename TVisitor, typename T>
|
|
||||||
void Reflect(TVisitor& visitor, WithGen<T>& value) {
|
|
||||||
Reflect(visitor, value.value);
|
|
||||||
}
|
|
||||||
|
|
||||||
struct QueryLocation {
|
struct QueryLocation {
|
||||||
Range range;
|
Range range;
|
||||||
QueryFileId path;
|
QueryFileId path;
|
||||||
SymbolRole role = SymbolRole::None;
|
SymbolRole role;
|
||||||
|
|
||||||
QueryLocation() {} // Do not use, needed for reflect.
|
|
||||||
QueryLocation(QueryFileId path, Range range) : range(range), path(path) {}
|
|
||||||
|
|
||||||
QueryLocation OffsetStartColumn(int16_t offset) const {
|
QueryLocation OffsetStartColumn(int16_t offset) const {
|
||||||
QueryLocation result = *this;
|
QueryLocation result = *this;
|
||||||
@ -62,6 +32,7 @@ struct QueryLocation {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool HasValue() const { return range.HasValue(); }
|
bool HasValue() const { return range.HasValue(); }
|
||||||
|
QueryFileId FileId() const { return path; }
|
||||||
|
|
||||||
bool operator==(const QueryLocation& o) const {
|
bool operator==(const QueryLocation& o) const {
|
||||||
return path == o.path && range == o.range;
|
return path == o.path && range == o.range;
|
||||||
@ -129,16 +100,11 @@ struct QueryFuncRef {
|
|||||||
// NOTE: id_ can be -1 if the function call is not coming from a function.
|
// NOTE: id_ can be -1 if the function call is not coming from a function.
|
||||||
QueryFuncId id_;
|
QueryFuncId id_;
|
||||||
QueryLocation loc;
|
QueryLocation loc;
|
||||||
bool is_implicit = false;
|
|
||||||
|
|
||||||
bool HasValue() const { return id_.HasValue(); }
|
bool HasValue() const { return id_.HasValue(); }
|
||||||
|
|
||||||
QueryFuncRef() {} // Do not use, needed for reflect.
|
std::tuple<QueryFuncId, QueryLocation> ToTuple() const {
|
||||||
QueryFuncRef(QueryFuncId id, QueryLocation loc, bool is_implicit)
|
return std::make_tuple(id_, loc);
|
||||||
: id_(id), loc(loc), is_implicit(is_implicit) {}
|
|
||||||
|
|
||||||
std::tuple<QueryFuncId, QueryLocation, bool> ToTuple() const {
|
|
||||||
return std::make_tuple(id_, loc, is_implicit);
|
|
||||||
}
|
}
|
||||||
bool operator==(const QueryFuncRef& o) const {
|
bool operator==(const QueryFuncRef& o) const {
|
||||||
return ToTuple() == o.ToTuple();
|
return ToTuple() == o.ToTuple();
|
||||||
@ -148,7 +114,7 @@ struct QueryFuncRef {
|
|||||||
return ToTuple() < o.ToTuple();
|
return ToTuple() < o.ToTuple();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
MAKE_REFLECT_STRUCT(QueryFuncRef, id_, loc, is_implicit);
|
MAKE_REFLECT_STRUCT(QueryFuncRef, id_, loc);
|
||||||
|
|
||||||
// There are two sources of reindex updates: the (single) definition of a
|
// There are two sources of reindex updates: the (single) definition of a
|
||||||
// symbol has changed, or one of many users of the symbol has changed.
|
// symbol has changed, or one of many users of the symbol has changed.
|
||||||
@ -251,7 +217,8 @@ MAKE_REFLECT_STRUCT(QueryFile::Def,
|
|||||||
dependencies);
|
dependencies);
|
||||||
|
|
||||||
struct QueryType {
|
struct QueryType {
|
||||||
using Def = TypeDefDefinitionData<QueryTypeId,
|
using Def = TypeDefDefinitionData<QueryFileId,
|
||||||
|
QueryTypeId,
|
||||||
QueryFuncId,
|
QueryFuncId,
|
||||||
QueryVarId,
|
QueryVarId,
|
||||||
QueryLocation>;
|
QueryLocation>;
|
||||||
@ -261,18 +228,18 @@ struct QueryType {
|
|||||||
using UsesUpdate = MergeableUpdate<QueryTypeId, QueryLocation>;
|
using UsesUpdate = MergeableUpdate<QueryTypeId, QueryLocation>;
|
||||||
|
|
||||||
Usr usr;
|
Usr usr;
|
||||||
Generation gen;
|
|
||||||
Maybe<Id<void>> symbol_idx;
|
Maybe<Id<void>> symbol_idx;
|
||||||
optional<Def> def;
|
optional<Def> def;
|
||||||
std::vector<QueryTypeId> derived;
|
std::vector<QueryTypeId> derived;
|
||||||
std::vector<QueryVarId> instances;
|
std::vector<QueryVarId> instances;
|
||||||
std::vector<QueryLocation> uses;
|
std::vector<QueryLocation> uses;
|
||||||
|
|
||||||
explicit QueryType(const Usr& usr) : usr(usr), gen(0) {}
|
explicit QueryType(const Usr& usr) : usr(usr) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct QueryFunc {
|
struct QueryFunc {
|
||||||
using Def = FuncDefDefinitionData<QueryTypeId,
|
using Def = FuncDefDefinitionData<QueryFileId,
|
||||||
|
QueryTypeId,
|
||||||
QueryFuncId,
|
QueryFuncId,
|
||||||
QueryVarId,
|
QueryVarId,
|
||||||
QueryFuncRef,
|
QueryFuncRef,
|
||||||
@ -283,18 +250,18 @@ struct QueryFunc {
|
|||||||
using CallersUpdate = MergeableUpdate<QueryFuncId, QueryFuncRef>;
|
using CallersUpdate = MergeableUpdate<QueryFuncId, QueryFuncRef>;
|
||||||
|
|
||||||
Usr usr;
|
Usr usr;
|
||||||
Generation gen;
|
|
||||||
Maybe<Id<void>> symbol_idx;
|
Maybe<Id<void>> symbol_idx;
|
||||||
optional<Def> def;
|
optional<Def> def;
|
||||||
std::vector<QueryLocation> declarations;
|
std::vector<QueryLocation> declarations;
|
||||||
std::vector<QueryFuncId> derived;
|
std::vector<QueryFuncId> derived;
|
||||||
std::vector<QueryFuncRef> callers;
|
std::vector<QueryFuncRef> callers;
|
||||||
|
|
||||||
explicit QueryFunc(const Usr& usr) : usr(usr), gen(0) {}
|
explicit QueryFunc(const Usr& usr) : usr(usr) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct QueryVar {
|
struct QueryVar {
|
||||||
using Def = VarDefDefinitionData<QueryTypeId,
|
using Def = VarDefDefinitionData<QueryFileId,
|
||||||
|
QueryTypeId,
|
||||||
QueryFuncId,
|
QueryFuncId,
|
||||||
QueryVarId,
|
QueryVarId,
|
||||||
QueryLocation>;
|
QueryLocation>;
|
||||||
@ -303,13 +270,12 @@ struct QueryVar {
|
|||||||
using UsesUpdate = MergeableUpdate<QueryVarId, QueryLocation>;
|
using UsesUpdate = MergeableUpdate<QueryVarId, QueryLocation>;
|
||||||
|
|
||||||
Usr usr;
|
Usr usr;
|
||||||
Generation gen;
|
|
||||||
Maybe<Id<void>> symbol_idx;
|
Maybe<Id<void>> symbol_idx;
|
||||||
optional<Def> def;
|
optional<Def> def;
|
||||||
std::vector<QueryLocation> declarations;
|
std::vector<QueryLocation> declarations;
|
||||||
std::vector<QueryLocation> uses;
|
std::vector<QueryLocation> uses;
|
||||||
|
|
||||||
explicit QueryVar(const Usr& usr) : usr(usr), gen(0) {}
|
explicit QueryVar(const Usr& usr) : usr(usr) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct IndexUpdate {
|
struct IndexUpdate {
|
||||||
@ -428,6 +394,7 @@ template <typename I>
|
|||||||
struct IndexToQuery;
|
struct IndexToQuery;
|
||||||
|
|
||||||
// clang-format off
|
// clang-format off
|
||||||
|
template <> struct IndexToQuery<IndexFileId> { using type = QueryFileId; };
|
||||||
template <> struct IndexToQuery<IndexFuncId> { using type = QueryFuncId; };
|
template <> struct IndexToQuery<IndexFuncId> { using type = QueryFuncId; };
|
||||||
template <> struct IndexToQuery<IndexTypeId> { using type = QueryTypeId; };
|
template <> struct IndexToQuery<IndexTypeId> { using type = QueryTypeId; };
|
||||||
template <> struct IndexToQuery<IndexVarId> { using type = QueryVarId; };
|
template <> struct IndexToQuery<IndexVarId> { using type = QueryVarId; };
|
||||||
@ -450,7 +417,8 @@ struct IdMap {
|
|||||||
|
|
||||||
// FIXME Too verbose
|
// FIXME Too verbose
|
||||||
// clang-format off
|
// clang-format off
|
||||||
QueryLocation ToQuery(Range range) const;
|
QueryLocation ToQuery(Range range, SymbolRole role) const;
|
||||||
|
QueryFileId ToQuery(IndexFileId) const;
|
||||||
QueryTypeId ToQuery(IndexTypeId id) const;
|
QueryTypeId ToQuery(IndexTypeId id) const;
|
||||||
QueryFuncId ToQuery(IndexFuncId id) const;
|
QueryFuncId ToQuery(IndexFuncId id) const;
|
||||||
QueryVarId ToQuery(IndexVarId id) const;
|
QueryVarId ToQuery(IndexVarId id) const;
|
||||||
@ -463,12 +431,6 @@ struct IdMap {
|
|||||||
return ToQuery(*id);
|
return ToQuery(*id);
|
||||||
}
|
}
|
||||||
template <typename I>
|
template <typename I>
|
||||||
Maybe<WithGen<typename IndexToQuery<I>::type>> ToQuery(Maybe<I> id, int) const {
|
|
||||||
if (!id)
|
|
||||||
return nullopt;
|
|
||||||
return ToQuery(*id, 0);
|
|
||||||
}
|
|
||||||
template <typename I>
|
|
||||||
std::vector<typename IndexToQuery<I>::type> ToQuery(const std::vector<I>& a) const {
|
std::vector<typename IndexToQuery<I>::type> ToQuery(const std::vector<I>& a) const {
|
||||||
std::vector<typename IndexToQuery<I>::type> ret;
|
std::vector<typename IndexToQuery<I>::type> ret;
|
||||||
ret.reserve(a.size());
|
ret.reserve(a.size());
|
||||||
@ -476,14 +438,7 @@ struct IdMap {
|
|||||||
ret.push_back(ToQuery(x));
|
ret.push_back(ToQuery(x));
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
template <typename I>
|
std::vector<QueryLocation> ToQuery(const std::vector<Range>& a) const;
|
||||||
std::vector<WithGen<typename IndexToQuery<I>::type>> ToQuery(std::vector<I> a, int) const {
|
|
||||||
std::vector<WithGen<typename IndexToQuery<I>::type>> ret;
|
|
||||||
ret.reserve(a.size());
|
|
||||||
for (auto& x : a)
|
|
||||||
ret.push_back(ToQuery(x, 0));
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
// clang-format on
|
// clang-format on
|
||||||
|
|
||||||
SymbolIdx ToSymbol(IndexTypeId id) const;
|
SymbolIdx ToSymbol(IndexTypeId id) const;
|
||||||
|
@ -106,8 +106,8 @@ optional<QueryLocation> GetDefinitionExtentOfSymbol(QueryDatabase* db,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case SymbolKind::File: {
|
case SymbolKind::File: {
|
||||||
return QueryLocation(QueryFileId(symbol.idx),
|
return QueryLocation{Range(Position(0, 0), Position(0, 0)),
|
||||||
Range(Position(1, 1), Position(1, 1)));
|
QueryFileId(symbol.idx), SymbolRole::None};
|
||||||
}
|
}
|
||||||
case SymbolKind::Invalid: {
|
case SymbolKind::Invalid: {
|
||||||
assert(false && "unexpected");
|
assert(false && "unexpected");
|
||||||
@ -123,21 +123,21 @@ optional<QueryFileId> GetDeclarationFileForSymbol(QueryDatabase* db,
|
|||||||
case SymbolKind::Type: {
|
case SymbolKind::Type: {
|
||||||
QueryType& type = db->types[symbol.idx];
|
QueryType& type = db->types[symbol.idx];
|
||||||
if (type.def && type.def->definition_spelling)
|
if (type.def && type.def->definition_spelling)
|
||||||
return type.def->definition_spelling->path;
|
return type.def->definition_spelling->FileId();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case SymbolKind::Func: {
|
case SymbolKind::Func: {
|
||||||
QueryFunc& func = db->funcs[symbol.idx];
|
QueryFunc& func = db->funcs[symbol.idx];
|
||||||
if (!func.declarations.empty())
|
if (!func.declarations.empty())
|
||||||
return func.declarations[0].path;
|
return func.declarations[0].FileId();
|
||||||
if (func.def && func.def->definition_spelling)
|
if (func.def && func.def->definition_spelling)
|
||||||
return func.def->definition_spelling->path;
|
return func.def->definition_spelling->FileId();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case SymbolKind::Var: {
|
case SymbolKind::Var: {
|
||||||
QueryVar& var = db->vars[symbol.idx];
|
QueryVar& var = db->vars[symbol.idx];
|
||||||
if (var.def && var.def->definition_spelling)
|
if (var.def && var.def->definition_spelling)
|
||||||
return var.def->definition_spelling->path;
|
return var.def->definition_spelling->FileId();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case SymbolKind::File: {
|
case SymbolKind::File: {
|
||||||
@ -401,7 +401,7 @@ optional<lsLocation> GetLsLocation(QueryDatabase* db,
|
|||||||
WorkingFiles* working_files,
|
WorkingFiles* working_files,
|
||||||
const QueryLocation& location) {
|
const QueryLocation& location) {
|
||||||
std::string path;
|
std::string path;
|
||||||
lsDocumentUri uri = GetLsDocumentUri(db, location.path, &path);
|
lsDocumentUri uri = GetLsDocumentUri(db, location.FileId(), &path);
|
||||||
optional<lsRange> range =
|
optional<lsRange> range =
|
||||||
GetLsRange(working_files->GetFileByFilename(path), location.range);
|
GetLsRange(working_files->GetFileByFilename(path), location.range);
|
||||||
if (!range)
|
if (!range)
|
||||||
|
Loading…
Reference in New Issue
Block a user