Fix outline of member definition in namespace

This commit is contained in:
Ludovic Jozeau 2020-07-02 21:06:11 +02:00
parent d0edae6ef4
commit 7f438dc999
6 changed files with 56 additions and 5 deletions

View File

@ -785,7 +785,10 @@ public:
entity->def.spell = {use,
fromTokenRangeDefaulted(sm, lang, sr, fid, loc)};
entity->def.parent_kind = SymbolKind::File;
getKind(cast<Decl>(sem_dc), entity->def.parent_kind);
const Decl *dc = cast<Decl>(sem_dc);
if (Kind parent_kind = getKind(dc, entity->def.parent_kind);
parent_kind != Kind::Invalid)
entity->def.parent = {getUsr(dc), parent_kind};
} else if (is_decl) {
SourceRange sr = origD->getSourceRange();
entity->declarations.push_back(
@ -1205,7 +1208,7 @@ public:
};
} // namespace
const int IndexFile::kMajorVersion = 21;
const int IndexFile::kMajorVersion = 22;
const int IndexFile::kMinorVersion = 0;
IndexFile::IndexFile(const std::string &path, const std::string &contents,

View File

@ -65,6 +65,8 @@ struct SymbolIdx {
}
};
REFLECT_STRUCT(SymbolIdx, usr, kind);
// |id,kind| refer to the referenced entity.
struct SymbolRef {
Range range;
@ -163,6 +165,7 @@ struct FuncDef : NameMixin<FuncDef<V>> {
int16_t short_name_size = 0;
SymbolKind kind = SymbolKind::Unknown;
SymbolKind parent_kind = SymbolKind::Unknown;
SymbolIdx parent = {0, Kind::Invalid};
uint8_t storage = clang::SC_None;
const Usr *bases_begin() const { return bases.begin(); }
@ -170,7 +173,7 @@ struct FuncDef : NameMixin<FuncDef<V>> {
};
REFLECT_STRUCT(FuncDef<VectorAdapter>, detailed_name, hover, comments, spell,
bases, vars, callees, qual_name_offset, short_name_offset,
short_name_size, kind, parent_kind, storage);
short_name_size, kind, parent_kind, parent, storage);
struct IndexFunc : NameMixin<IndexFunc> {
using Def = FuncDef<VectorAdapter>;
@ -203,13 +206,14 @@ struct TypeDef : NameMixin<TypeDef<V>> {
int16_t short_name_size = 0;
SymbolKind kind = SymbolKind::Unknown;
SymbolKind parent_kind = SymbolKind::Unknown;
SymbolIdx parent = {0, Kind::Invalid};
const Usr *bases_begin() const { return bases.begin(); }
const Usr *bases_end() const { return bases.end(); }
};
REFLECT_STRUCT(TypeDef<VectorAdapter>, detailed_name, hover, comments, spell,
bases, funcs, types, vars, alias_of, qual_name_offset,
short_name_offset, short_name_size, kind, parent_kind);
short_name_offset, short_name_size, kind, parent_kind, parent);
struct IndexType {
using Def = TypeDef<VectorAdapter>;
@ -236,6 +240,7 @@ struct VarDef : NameMixin<VarDef> {
int16_t short_name_size = 0;
SymbolKind kind = SymbolKind::Unknown;
SymbolKind parent_kind = SymbolKind::Unknown;
SymbolIdx parent = {0, Kind::Invalid};
// Note a variable may have instances of both |None| and |Extern|
// (declaration).
uint8_t storage = clang::SC_None;
@ -255,7 +260,7 @@ struct VarDef : NameMixin<VarDef> {
};
REFLECT_STRUCT(VarDef, detailed_name, hover, comments, spell, type,
qual_name_offset, short_name_offset, short_name_size, kind,
parent_kind, storage);
parent_kind, parent, storage);
struct IndexVar {
using Def = VarDef;

View File

@ -247,6 +247,26 @@ void MessageHandler::textDocument_documentSymbol(JsonReader &reader,
ds->children.push_back(std::move(it->second));
}
}
// put member definition in their namespace
// when definition is in separate file(cpp), we have NS -> Type -> member
// but the Type is not defined here(in .cpp), so we do NS -> member instead
for (auto &[sym, ds] : sym2ds) {
if (!ds)
continue;
SymbolKind sym_kind = getSymbolKind(db, sym);
std::optional<SymbolIdx> ns;
bool is_member = sym_kind == SymbolKind::Field ||
sym_kind == SymbolKind::Method ||
sym_kind == SymbolKind::StaticMethod;
if (is_member && (ns = getNamespace(db, sym))) {
auto it = sym2ds.find(*ns);
if (it != sym2ds.end() && it->second)
it->second->children.push_back(std::move(ds));
}
}
std::vector<std::unique_ptr<DocumentSymbol>> result;
for (auto &[_, ds] : sym2ds)
if (ds) {

View File

@ -90,6 +90,7 @@ QueryFunc::Def convert(const IndexFunc::Def &o) {
r.short_name_size = o.short_name_size;
r.kind = o.kind;
r.parent_kind = o.parent_kind;
r.parent = o.parent;
r.storage = o.storage;
return r;
}
@ -111,6 +112,7 @@ QueryType::Def convert(const IndexType::Def &o) {
r.short_name_size = o.short_name_size;
r.kind = o.kind;
r.parent_kind = o.parent_kind;
r.parent = o.parent;
return r;
}
@ -839,4 +841,20 @@ std::vector<SymbolRef> findSymbolsAtLocation(WorkingFile *wfile,
return symbols;
}
std::optional<SymbolIdx> getNamespace(DB *db, SymbolIdx sym) {
SymbolKind kind;
do {
withEntity(db, sym,
[&sym](auto const &entity) { sym = entity.anyDef()->parent; });
kind = getSymbolKind(db, sym);
} while (kind != SymbolKind::Namespace && kind != SymbolKind::File &&
kind != SymbolKind::Unknown);
if (kind == SymbolKind::Namespace)
return sym;
else
return std::nullopt;
}
} // namespace ccls

View File

@ -258,6 +258,8 @@ void eachOccurrence(DB *db, SymbolIdx sym, bool include_decl, Fn &&fn) {
SymbolKind getSymbolKind(DB *db, SymbolIdx sym);
std::optional<SymbolIdx> getNamespace(DB *db, SymbolIdx sym);
template <typename C, typename Fn>
void eachDefinedFunc(DB *db, const C &usrs, Fn &&fn) {
for (Usr usr : usrs) {

View File

@ -297,6 +297,7 @@ template <typename TVisitor> void reflect1(TVisitor &vis, IndexFunc &v) {
REFLECT_MEMBER2("callees", v.def.callees);
REFLECT_MEMBER2("kind", v.def.kind);
REFLECT_MEMBER2("parent_kind", v.def.parent_kind);
REFLECT_MEMBER2("parent", v.def.parent);
REFLECT_MEMBER2("storage", v.def.storage);
REFLECT_MEMBER2("declarations", v.declarations);
@ -324,6 +325,7 @@ template <typename Vis> void reflect1(Vis &vis, IndexType &v) {
REFLECT_MEMBER2("alias_of", v.def.alias_of);
REFLECT_MEMBER2("kind", v.def.kind);
REFLECT_MEMBER2("parent_kind", v.def.parent_kind);
REFLECT_MEMBER2("parent", v.def.parent);
REFLECT_MEMBER2("declarations", v.declarations);
REFLECT_MEMBER2("derived", v.derived);
@ -347,6 +349,7 @@ template <typename TVisitor> void reflect1(TVisitor &vis, IndexVar &v) {
REFLECT_MEMBER2("type", v.def.type);
REFLECT_MEMBER2("kind", v.def.kind);
REFLECT_MEMBER2("parent_kind", v.def.parent_kind);
REFLECT_MEMBER2("parent", v.def.parent);
REFLECT_MEMBER2("storage", v.def.storage);
REFLECT_MEMBER2("declarations", v.declarations);