From 7f438dc9993142c861d65c87c722c9343a455350 Mon Sep 17 00:00:00 2001 From: Ludovic Jozeau Date: Thu, 2 Jul 2020 21:06:11 +0200 Subject: [PATCH] Fix outline of member definition in namespace --- src/indexer.cc | 7 +++++-- src/indexer.hh | 11 ++++++++--- src/messages/textDocument_document.cc | 20 ++++++++++++++++++++ src/query.cc | 18 ++++++++++++++++++ src/query.hh | 2 ++ src/serializer.cc | 3 +++ 6 files changed, 56 insertions(+), 5 deletions(-) diff --git a/src/indexer.cc b/src/indexer.cc index 7b7c1480..8ba3649a 100644 --- a/src/indexer.cc +++ b/src/indexer.cc @@ -785,7 +785,10 @@ public: entity->def.spell = {use, fromTokenRangeDefaulted(sm, lang, sr, fid, loc)}; entity->def.parent_kind = SymbolKind::File; - getKind(cast(sem_dc), entity->def.parent_kind); + const Decl *dc = cast(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, diff --git a/src/indexer.hh b/src/indexer.hh index cd4669a9..ed71bdac 100644 --- a/src/indexer.hh +++ b/src/indexer.hh @@ -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> { 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> { }; REFLECT_STRUCT(FuncDef, 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 { using Def = FuncDef; @@ -203,13 +206,14 @@ struct TypeDef : NameMixin> { 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, 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; @@ -236,6 +240,7 @@ struct VarDef : NameMixin { 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 { }; 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; diff --git a/src/messages/textDocument_document.cc b/src/messages/textDocument_document.cc index 30d6a222..152717c8 100644 --- a/src/messages/textDocument_document.cc +++ b/src/messages/textDocument_document.cc @@ -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 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> result; for (auto &[_, ds] : sym2ds) if (ds) { diff --git a/src/query.cc b/src/query.cc index c7bfcfe3..4c6c4361 100644 --- a/src/query.cc +++ b/src/query.cc @@ -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 findSymbolsAtLocation(WorkingFile *wfile, return symbols; } + +std::optional 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 diff --git a/src/query.hh b/src/query.hh index cd3a19c1..7c716f63 100644 --- a/src/query.hh +++ b/src/query.hh @@ -258,6 +258,8 @@ void eachOccurrence(DB *db, SymbolIdx sym, bool include_decl, Fn &&fn) { SymbolKind getSymbolKind(DB *db, SymbolIdx sym); +std::optional getNamespace(DB *db, SymbolIdx sym); + template void eachDefinedFunc(DB *db, const C &usrs, Fn &&fn) { for (Usr usr : usrs) { diff --git a/src/serializer.cc b/src/serializer.cc index b1b93faa..90bbfa2e 100644 --- a/src/serializer.cc +++ b/src/serializer.cc @@ -297,6 +297,7 @@ template 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 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 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);