mirror of
				https://github.com/MaskRay/ccls.git
				synced 2025-10-31 20:53:01 +00:00 
			
		
		
		
	Use DeclRef spell to represent Use spell + Use extent
This commit is contained in:
		
							parent
							
								
									fc4b5b00c0
								
							
						
					
					
						commit
						53e6a15f34
					
				| @ -762,12 +762,10 @@ public: | ||||
| 
 | ||||
|     auto do_def_decl = [&](auto *entity) { | ||||
|       if (is_def) { | ||||
|         entity->def.spell = {{loc, role}, lid}; | ||||
|         SourceRange R = OrigD->getSourceRange(); | ||||
|         entity->def.extent = { | ||||
|             {R.getBegin().isFileID() ? FromTokenRange(SM, Lang, R) : loc, | ||||
|              Role::None}, | ||||
|             lid}; | ||||
|         entity->def.spell = { | ||||
|             Use{{loc, role}, lid}, | ||||
|             R.getBegin().isFileID() ? FromTokenRange(SM, Lang, R) : loc}; | ||||
|         entity->def.parent_kind = lsSymbolKind::File; | ||||
|         GetSymbolKind(cast<Decl>(SemDC), entity->def.parent_kind); | ||||
|       } else if (is_decl) { | ||||
| @ -862,10 +860,9 @@ public: | ||||
|                 IndexType &type1 = db->ToType(usr1); | ||||
|                 SourceLocation L1 = D1->getLocation(); | ||||
|                 type1.def.spell = { | ||||
|                     {FromTokenRange(SM, Lang, {L1, L1}), Role::Definition}, | ||||
|                     lid}; | ||||
|                 type1.def.extent = {{FromTokenRange(SM, Lang, R1), Role::None}, | ||||
|                                     lid}; | ||||
|                     Use{{FromTokenRange(SM, Lang, {L1, L1}), Role::Definition}, | ||||
|                         lid}, | ||||
|                     FromTokenRange(SM, Lang, R1)}; | ||||
|                 type1.def.detailed_name = Intern(info1->short_name); | ||||
|                 type1.def.short_name_size = int16_t(info1->short_name.size()); | ||||
|                 type1.def.kind = lsSymbolKind::TypeParameter; | ||||
| @ -887,9 +884,8 @@ public: | ||||
|         SourceLocation L = D->getLocation(); | ||||
|         if (SM.getFileID(L) == LocFID) { | ||||
|           var->def.spell = { | ||||
|               {FromTokenRange(SM, Lang, {L, L}), Role::Definition}, lid}; | ||||
|           var->def.extent = { | ||||
|               {FromTokenRange(SM, Lang, D->getSourceRange()), Role::None}, lid}; | ||||
|               Use{{FromTokenRange(SM, Lang, {L, L}), Role::Definition}, lid}, | ||||
|               FromTokenRange(SM, Lang, D->getSourceRange())}; | ||||
|           var->def.parent_kind = lsSymbolKind::Method; | ||||
|         } | ||||
|       } | ||||
| @ -1086,19 +1082,15 @@ public: | ||||
|     if (IndexFile *db = param.ConsumeFile(*FE)) { | ||||
|       auto [Name, usr] = GetMacro(Tok); | ||||
|       IndexVar &var = db->ToVar(usr); | ||||
|       auto range = FromTokenRange(SM, Lang, {L, L}, &UniqueID); | ||||
|       Range range = FromTokenRange(SM, Lang, {L, L}, &UniqueID); | ||||
|       var.def.kind = lsSymbolKind::Macro; | ||||
|       var.def.parent_kind = lsSymbolKind::File; | ||||
|       if (var.def.spell) { | ||||
|         DeclRef &d = var.declarations.emplace_back(); | ||||
|         static_cast<Use&>(d) = *var.def.spell; | ||||
|         d.extent = var.def.spell->range; | ||||
|       } | ||||
|       var.def.spell = Use{{range, Role::Definition}}; | ||||
|       if (var.def.spell) | ||||
|         var.declarations.push_back(*var.def.spell); | ||||
|       const MacroInfo *MI = MD->getMacroInfo(); | ||||
|       SourceRange R(MI->getDefinitionLoc(), MI->getDefinitionEndLoc()); | ||||
|       range = FromTokenRange(SM, param.Ctx->getLangOpts(), R); | ||||
|       var.def.extent = Use{{range, Role::None}}; | ||||
|       Range extent = FromTokenRange(SM, param.Ctx->getLangOpts(), R); | ||||
|       var.def.spell = {Use{{range, Role::Definition}}, extent}; | ||||
|       if (var.def.detailed_name[0] == '\0') { | ||||
|         var.def.detailed_name = Intern(Name); | ||||
|         var.def.short_name_size = Name.size(); | ||||
|  | ||||
| @ -106,8 +106,7 @@ struct FuncDef : NameMixin<FuncDef> { | ||||
|   const char *detailed_name = ""; | ||||
|   const char *hover = ""; | ||||
|   const char *comments = ""; | ||||
|   Maybe<Use> spell; | ||||
|   Maybe<Use> extent; | ||||
|   Maybe<DeclRef> spell; | ||||
| 
 | ||||
|   // Method this method overrides.
 | ||||
|   std::vector<Usr> bases; | ||||
| @ -126,8 +125,8 @@ struct FuncDef : NameMixin<FuncDef> { | ||||
| 
 | ||||
|   std::vector<Usr> GetBases() const { return bases; } | ||||
| }; | ||||
| MAKE_REFLECT_STRUCT(FuncDef, detailed_name, hover, comments, spell, extent, | ||||
|                     bases, vars, callees, qual_name_offset, short_name_offset, | ||||
| MAKE_REFLECT_STRUCT(FuncDef, detailed_name, hover, comments, spell, bases, vars, | ||||
|                     callees, qual_name_offset, short_name_offset, | ||||
|                     short_name_size, kind, parent_kind, storage); | ||||
| 
 | ||||
| struct IndexFunc : NameMixin<IndexFunc> { | ||||
| @ -143,8 +142,7 @@ struct TypeDef : NameMixin<TypeDef> { | ||||
|   const char *detailed_name = ""; | ||||
|   const char *hover = ""; | ||||
|   const char *comments = ""; | ||||
|   Maybe<Use> spell; | ||||
|   Maybe<Use> extent; | ||||
|   Maybe<DeclRef> spell; | ||||
| 
 | ||||
|   std::vector<Usr> bases; | ||||
|   // Types, functions, and variables defined in this type.
 | ||||
| @ -164,8 +162,8 @@ struct TypeDef : NameMixin<TypeDef> { | ||||
| 
 | ||||
|   std::vector<Usr> GetBases() const { return bases; } | ||||
| }; | ||||
| MAKE_REFLECT_STRUCT(TypeDef, detailed_name, hover, comments, spell, extent, | ||||
|                     bases, funcs, types, vars, alias_of, qual_name_offset, | ||||
| MAKE_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); | ||||
| 
 | ||||
| struct IndexType { | ||||
| @ -183,8 +181,7 @@ struct VarDef : NameMixin<VarDef> { | ||||
|   const char *detailed_name = ""; | ||||
|   const char *hover = ""; | ||||
|   const char *comments = ""; | ||||
|   Maybe<Use> spell; | ||||
|   Maybe<Use> extent; | ||||
|   Maybe<DeclRef> spell; | ||||
| 
 | ||||
|   // Type of the variable.
 | ||||
|   Usr type = 0; | ||||
| @ -208,7 +205,7 @@ struct VarDef : NameMixin<VarDef> { | ||||
| 
 | ||||
|   std::vector<Usr> GetBases() const { return {}; } | ||||
| }; | ||||
| MAKE_REFLECT_STRUCT(VarDef, detailed_name, hover, comments, spell, extent, type, | ||||
| MAKE_REFLECT_STRUCT(VarDef, detailed_name, hover, comments, spell, type, | ||||
|                     qual_name_offset, short_name_offset, short_name_size, kind, | ||||
|                     parent_kind, storage); | ||||
| 
 | ||||
|  | ||||
| @ -106,7 +106,7 @@ struct Handler_TextDocumentCodeLens | ||||
|     }; | ||||
| 
 | ||||
|     auto ToSpell = [&](SymbolRef sym, int file_id) -> Use { | ||||
|       Maybe<Use> def = GetDefinitionSpell(db, sym); | ||||
|       Maybe<DeclRef> def = GetDefinitionSpell(db, sym); | ||||
|       if (def && def->file_id == file_id && | ||||
|           def->range.start.line == sym.range.start.line) | ||||
|         return *def; | ||||
|  | ||||
| @ -29,7 +29,7 @@ std::vector<Use> GetNonDefDeclarationTargets(DB *db, SymbolRef sym) { | ||||
|     if (ret.empty()) { | ||||
|       for (auto &def : db->GetVar(sym).def) | ||||
|         if (def.type) { | ||||
|           if (Maybe<Use> use = GetDefinitionSpell( | ||||
|           if (Maybe<DeclRef> use = GetDefinitionSpell( | ||||
|                   db, SymbolIdx{def.type, SymbolKind::Type})) { | ||||
|             ret.push_back(*use); | ||||
|             break; | ||||
| @ -135,11 +135,11 @@ struct Handler_TextDocumentDefinition | ||||
|                                       : short_name; | ||||
|           if (short_name != short_query) | ||||
|             return; | ||||
|           if (Maybe<Use> use = GetDefinitionSpell(db, sym)) { | ||||
|           if (Maybe<DeclRef> dr = GetDefinitionSpell(db, sym)) { | ||||
|             std::tuple<int, int, bool, int> score{ | ||||
|                 int(name.size() - short_query.size()), 0, | ||||
|                 use->file_id != file_id, | ||||
|                 std::abs(use->range.start.line - position.line)}; | ||||
|                 dr->file_id != file_id, | ||||
|                 std::abs(dr->range.start.line - position.line)}; | ||||
|             // Update the score with qualified name if the qualified name
 | ||||
|             // occurs in |name|.
 | ||||
|             auto pos = name.rfind(query); | ||||
| @ -162,9 +162,9 @@ struct Handler_TextDocumentDefinition | ||||
|             fn({var.usr, SymbolKind::Var}); | ||||
| 
 | ||||
|         if (best_sym.kind != SymbolKind::Invalid) { | ||||
|           Maybe<Use> use = GetDefinitionSpell(db, best_sym); | ||||
|           assert(use); | ||||
|           if (auto loc = GetLsLocation(db, working_files, *use)) | ||||
|           Maybe<DeclRef> dr = GetDefinitionSpell(db, best_sym); | ||||
|           assert(dr); | ||||
|           if (auto loc = GetLsLocation(db, working_files, *dr)) | ||||
|             out.result.push_back(*loc); | ||||
|         } | ||||
|       } | ||||
|  | ||||
| @ -120,10 +120,10 @@ struct Handler_TextDocumentDocumentSymbol | ||||
|           ds.detail = def->Name(true); | ||||
|           for (auto &def : entity.def) | ||||
|             if (def.file_id == file_id) { | ||||
|               if (!def.spell || !def.extent) | ||||
|               if (!def.spell) | ||||
|                 break; | ||||
|               ds.kind = def.kind; | ||||
|               if (auto ls_range = GetLsRange(wfile, def.extent->range)) | ||||
|               if (auto ls_range = GetLsRange(wfile, def.spell->extent)) | ||||
|                 ds.range = *ls_range; | ||||
|               else | ||||
|                 break; | ||||
|  | ||||
| @ -25,8 +25,8 @@ bool AddSymbol( | ||||
|     return false; | ||||
| 
 | ||||
|   Use loc; | ||||
|   if (Maybe<Use> location = GetDefinitionExtent(db, sym)) | ||||
|     loc = *location; | ||||
|   if (Maybe<DeclRef> dr = GetDefinitionSpell(db, sym)) | ||||
|     loc = *dr; | ||||
|   else { | ||||
|     auto decls = GetNonDefDeclarations(db, sym); | ||||
|     if (decls.empty()) | ||||
|  | ||||
							
								
								
									
										65
									
								
								src/query.cc
									
									
									
									
									
								
							
							
						
						
									
										65
									
								
								src/query.cc
									
									
									
									
									
								
							| @ -221,28 +221,19 @@ void DB::ApplyIndexUpdate(IndexUpdate *u) { | ||||
| 
 | ||||
|   // References (Use &use) in this function are important to update file_id.
 | ||||
|   auto Ref = [&](std::unordered_map<int, int> &lid2fid, Usr usr, | ||||
|                  SymbolKind kind, Use &use, int delta, int k = 1) { | ||||
|                  SymbolKind kind, Use &use, int delta) { | ||||
|     use.file_id = | ||||
|         use.file_id == -1 ? u->file_id : lid2fid.find(use.file_id)->second; | ||||
|     SymbolRef sym{use.range, usr, kind, use.role}; | ||||
|     if (k & 1) { | ||||
|       int &v = files[use.file_id].symbol2refcnt[sym]; | ||||
|       v += delta; | ||||
|       assert(v >= 0); | ||||
|       if (!v) | ||||
|         files[use.file_id].symbol2refcnt.erase(sym); | ||||
|     } | ||||
|     if (k & 2) { | ||||
|       int &v = files[use.file_id].outline2refcnt[sym]; | ||||
|       v += delta; | ||||
|       assert(v >= 0); | ||||
|       if (!v) | ||||
|         files[use.file_id].outline2refcnt.erase(sym); | ||||
|     } | ||||
|     int &v = files[use.file_id].symbol2refcnt[sym]; | ||||
|     v += delta; | ||||
|     assert(v >= 0); | ||||
|     if (!v) | ||||
|       files[use.file_id].symbol2refcnt.erase(sym); | ||||
|   }; | ||||
|   auto RefDecl = [&](std::unordered_map<int, int> &lid2fid, Usr usr, | ||||
|                      SymbolKind kind, DeclRef &dr, int delta) { | ||||
|     Ref(lid2fid, usr, kind, dr, delta, 1); | ||||
|     Ref(lid2fid, usr, kind, dr, delta); | ||||
|     files[dr.file_id] | ||||
|         .outline2refcnt[SymbolRef{dr.extent, usr, kind, dr.role}] += delta; | ||||
|   }; | ||||
| @ -293,12 +284,9 @@ void DB::ApplyIndexUpdate(IndexUpdate *u) { | ||||
|     funcs.reserve(t); | ||||
|     func_usr.reserve(t); | ||||
|   } | ||||
|   for (auto &[usr, def] : u->funcs_removed) { | ||||
|   for (auto &[usr, def] : u->funcs_removed) | ||||
|     if (def.spell) | ||||
|       Ref(prev_lid2file_id, usr, SymbolKind::Func, *def.spell, -1); | ||||
|     if (def.extent) | ||||
|       Ref(prev_lid2file_id, usr, SymbolKind::Func, *def.extent, -1, 2); | ||||
|   } | ||||
|       RefDecl(prev_lid2file_id, usr, SymbolKind::Func, *def.spell, -1); | ||||
|   RemoveUsrs(SymbolKind::Func, u->file_id, u->funcs_removed); | ||||
|   Update(lid2file_id, u->file_id, std::move(u->funcs_def_update)); | ||||
|   for (auto &[usr, del_add]: u->funcs_declarations) { | ||||
| @ -317,12 +305,9 @@ void DB::ApplyIndexUpdate(IndexUpdate *u) { | ||||
|     types.reserve(t); | ||||
|     type_usr.reserve(t); | ||||
|   } | ||||
|   for (auto &[usr, def] : u->types_removed) { | ||||
|   for (auto &[usr, def] : u->types_removed) | ||||
|     if (def.spell) | ||||
|       Ref(prev_lid2file_id, usr, SymbolKind::Type, *def.spell, -1); | ||||
|     if (def.extent) | ||||
|       Ref(prev_lid2file_id, usr, SymbolKind::Type, *def.extent, -1, 2); | ||||
|   } | ||||
|       RefDecl(prev_lid2file_id, usr, SymbolKind::Type, *def.spell, -1); | ||||
|   RemoveUsrs(SymbolKind::Type, u->file_id, u->types_removed); | ||||
|   Update(lid2file_id, u->file_id, std::move(u->types_def_update)); | ||||
|   for (auto &[usr, del_add]: u->types_declarations) { | ||||
| @ -342,12 +327,9 @@ void DB::ApplyIndexUpdate(IndexUpdate *u) { | ||||
|     vars.reserve(t); | ||||
|     var_usr.reserve(t); | ||||
|   } | ||||
|   for (auto &[usr, def] : u->vars_removed) { | ||||
|   for (auto &[usr, def] : u->vars_removed) | ||||
|     if (def.spell) | ||||
|       Ref(prev_lid2file_id, usr, SymbolKind::Var, *def.spell, -1); | ||||
|     if (def.extent) | ||||
|       Ref(prev_lid2file_id, usr, SymbolKind::Var, *def.extent, -1, 2); | ||||
|   } | ||||
|       RefDecl(prev_lid2file_id, usr, SymbolKind::Var, *def.spell, -1); | ||||
|   RemoveUsrs(SymbolKind::Var, u->file_id, u->vars_removed); | ||||
|   Update(lid2file_id, u->file_id, std::move(u->vars_def_update)); | ||||
|   for (auto &[usr, del_add]: u->vars_declarations) { | ||||
| @ -388,11 +370,8 @@ void DB::Update(const Lid2file_id &lid2file_id, int file_id, | ||||
|       AssignFileId(lid2file_id, file_id, *def.spell); | ||||
|       files[def.spell->file_id].symbol2refcnt[{ | ||||
|           def.spell->range, u.first, SymbolKind::Func, def.spell->role}]++; | ||||
|     } | ||||
|     if (def.extent) { | ||||
|       AssignFileId(lid2file_id, file_id, *def.extent); | ||||
|       files[def.extent->file_id].outline2refcnt[{ | ||||
|           def.extent->range, u.first, SymbolKind::Func, def.extent->role}]++; | ||||
|       files[def.spell->file_id].outline2refcnt[{ | ||||
|           def.spell->extent, u.first, SymbolKind::Func, def.spell->role}]++; | ||||
|     } | ||||
| 
 | ||||
|     auto R = func_usr.try_emplace({u.first}, func_usr.size()); | ||||
| @ -415,11 +394,8 @@ void DB::Update(const Lid2file_id &lid2file_id, int file_id, | ||||
|       AssignFileId(lid2file_id, file_id, *def.spell); | ||||
|       files[def.spell->file_id].symbol2refcnt[{ | ||||
|           def.spell->range, u.first, SymbolKind::Type, def.spell->role}]++; | ||||
|     } | ||||
|     if (def.extent) { | ||||
|       AssignFileId(lid2file_id, file_id, *def.extent); | ||||
|       files[def.extent->file_id].outline2refcnt[{ | ||||
|           def.extent->range, u.first, SymbolKind::Type, def.extent->role}]++; | ||||
|       files[def.spell->file_id].outline2refcnt[{ | ||||
|           def.spell->extent, u.first, SymbolKind::Type, def.spell->role}]++; | ||||
|     } | ||||
|     auto R = type_usr.try_emplace({u.first}, type_usr.size()); | ||||
|     if (R.second) | ||||
| @ -441,11 +417,8 @@ void DB::Update(const Lid2file_id &lid2file_id, int file_id, | ||||
|       AssignFileId(lid2file_id, file_id, *def.spell); | ||||
|       files[def.spell->file_id].symbol2refcnt[{ | ||||
|           def.spell->range, u.first, SymbolKind::Var, def.spell->role}]++; | ||||
|     } | ||||
|     if (def.extent) { | ||||
|       AssignFileId(lid2file_id, file_id, *def.extent); | ||||
|       files[def.extent->file_id].outline2refcnt[{ | ||||
|           def.extent->range, u.first, SymbolKind::Var, def.extent->role}]++; | ||||
|       files[def.spell->file_id].outline2refcnt[{ | ||||
|           def.spell->extent, u.first, SymbolKind::Var, def.spell->role}]++; | ||||
|     } | ||||
|     auto R = var_usr.try_emplace({u.first}, var_usr.size()); | ||||
|     if (R.second) | ||||
|  | ||||
| @ -40,21 +40,12 @@ GetDeclarations(llvm::DenseMap<Usr, int, DenseMapInfoForUsr> &entity_usr, | ||||
| 
 | ||||
| } // namespace
 | ||||
| 
 | ||||
| Maybe<Use> GetDefinitionSpell(DB *db, SymbolIdx sym) { | ||||
|   Maybe<Use> ret; | ||||
| Maybe<DeclRef> GetDefinitionSpell(DB *db, SymbolIdx sym) { | ||||
|   Maybe<DeclRef> ret; | ||||
|   EachEntityDef(db, sym, [&](const auto &def) { return !(ret = def.spell); }); | ||||
|   return ret; | ||||
| } | ||||
| 
 | ||||
| Maybe<Use> GetDefinitionExtent(DB *db, SymbolIdx sym) { | ||||
|   // Used to jump to file.
 | ||||
|   if (sym.kind == SymbolKind::File) | ||||
|     return Use{{Range{{0, 0}, {0, 0}}, Role::None}, int(sym.usr)}; | ||||
|   Maybe<Use> ret; | ||||
|   EachEntityDef(db, sym, [&](const auto &def) { return !(ret = def.extent); }); | ||||
|   return ret; | ||||
| } | ||||
| 
 | ||||
| std::vector<Use> GetFuncDeclarations(DB *db, const std::vector<Usr> &usrs) { | ||||
|   return GetDeclarations(db->func_usr, db->funcs, usrs); | ||||
| } | ||||
|  | ||||
| @ -8,8 +8,7 @@ | ||||
| 
 | ||||
| #include <optional> | ||||
| 
 | ||||
| Maybe<Use> GetDefinitionSpell(DB *db, SymbolIdx sym); | ||||
| Maybe<Use> GetDefinitionExtent(DB *db, SymbolIdx sym); | ||||
| Maybe<DeclRef> GetDefinitionSpell(DB *db, SymbolIdx sym); | ||||
| 
 | ||||
| // Get defining declaration (if exists) or an arbitrary declaration (otherwise)
 | ||||
| // for each id.
 | ||||
|  | ||||
| @ -250,7 +250,6 @@ template <typename TVisitor> void Reflect(TVisitor &visitor, IndexFunc &value) { | ||||
|   REFLECT_MEMBER2("qual_name_offset", value.def.qual_name_offset); | ||||
|   ReflectShortName(visitor, value.def); | ||||
|   REFLECT_MEMBER2("spell", value.def.spell); | ||||
|   REFLECT_MEMBER2("extent", value.def.extent); | ||||
|   ReflectHoverAndComments(visitor, value.def); | ||||
|   REFLECT_MEMBER2("bases", value.def.bases); | ||||
|   REFLECT_MEMBER2("vars", value.def.vars); | ||||
| @ -273,7 +272,6 @@ template <typename TVisitor> void Reflect(TVisitor &visitor, IndexType &value) { | ||||
|   ReflectShortName(visitor, value.def); | ||||
|   ReflectHoverAndComments(visitor, value.def); | ||||
|   REFLECT_MEMBER2("spell", value.def.spell); | ||||
|   REFLECT_MEMBER2("extent", value.def.extent); | ||||
|   REFLECT_MEMBER2("bases", value.def.bases); | ||||
|   REFLECT_MEMBER2("funcs", value.def.funcs); | ||||
|   REFLECT_MEMBER2("types", value.def.types); | ||||
| @ -297,7 +295,6 @@ template <typename TVisitor> void Reflect(TVisitor &visitor, IndexVar &value) { | ||||
|   ReflectShortName(visitor, value.def); | ||||
|   ReflectHoverAndComments(visitor, value.def); | ||||
|   REFLECT_MEMBER2("spell", value.def.spell); | ||||
|   REFLECT_MEMBER2("extent", value.def.extent); | ||||
|   REFLECT_MEMBER2("type", value.def.type); | ||||
|   REFLECT_MEMBER2("kind", value.def.kind); | ||||
|   REFLECT_MEMBER2("parent_kind", value.def.parent_kind); | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user