mirror of
				https://github.com/MaskRay/ccls.git
				synced 2025-10-30 20:22:38 +00:00 
			
		
		
		
	{Index,Query}Type::uses: Range/QueryLocation -> Reference
And add serialization for Reference
This commit is contained in:
		
							parent
							
								
									5f85867f88
								
							
						
					
					
						commit
						2d255da07b
					
				| @ -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 = 2; | const int IndexFile::kMinorVersion = 3; | ||||||
| 
 | 
 | ||||||
| IndexFile::IndexFile(const std::string& path, | IndexFile::IndexFile(const std::string& path, | ||||||
|                      const std::string& contents) |                      const std::string& contents) | ||||||
| @ -693,6 +693,20 @@ 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
 | ||||||
|  | void AddUse(std::vector<Reference>& values, Range value) { | ||||||
|  |   values.push_back(Reference{value, Id<void>(), SymbolKind::Invalid, | ||||||
|  |                              SymbolRole::Reference}); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // FIXME Reference: set lex_parent_id in call sites and remove this
 | ||||||
|  | void UniqueAdd(std::vector<Reference>& values, Range value) { | ||||||
|  |   if (std::find_if(values.begin(), values.end(), [&](const Reference& ref) { | ||||||
|  |         return ref.range == value; | ||||||
|  |       }) == values.end()) | ||||||
|  |     AddUse(values, value); | ||||||
|  | } | ||||||
|  | 
 | ||||||
| IdCache::IdCache(const std::string& primary_file) | IdCache::IdCache(const std::string& primary_file) | ||||||
|     : primary_file(primary_file) {} |     : primary_file(primary_file) {} | ||||||
| 
 | 
 | ||||||
| @ -1238,7 +1252,7 @@ ClangCursor::VisitResult TemplateVisitor(ClangCursor cursor, | |||||||
|             // seems no way to extract the spelling range of `type` and we do
 |             // seems no way to extract the spelling range of `type` and we do
 | ||||||
|             // not want to do subtraction here.
 |             // not want to do subtraction here.
 | ||||||
|             // See https://github.com/jacobdufault/cquery/issues/252
 |             // See https://github.com/jacobdufault/cquery/issues/252
 | ||||||
|             ref_type_index->uses.push_back(ref_cursor.get_extent()); |             UniqueAdd(ref_type_index->uses, ref_cursor.get_extent()); | ||||||
|           } |           } | ||||||
|         } |         } | ||||||
|         UniqueAdd(ref_index->uses, cursor.get_spelling_range()); |         UniqueAdd(ref_index->uses, cursor.get_spelling_range()); | ||||||
| @ -1439,7 +1453,7 @@ void OnIndexDeclaration(CXClientData client_data, const CXIdxDeclInfo* decl) { | |||||||
|           ns->def.parents.push_back(parent_id); |           ns->def.parents.push_back(parent_id); | ||||||
|         } |         } | ||||||
|       } |       } | ||||||
|       ns->uses.push_back(decl_spell); |       AddUse(ns->uses, decl_spell); | ||||||
|       break; |       break; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| @ -1745,7 +1759,7 @@ void OnIndexDeclaration(CXClientData client_data, const CXIdxDeclInfo* decl) { | |||||||
|           if (!enum_type.is_fundamental()) { |           if (!enum_type.is_fundamental()) { | ||||||
|             IndexType* int_type = |             IndexType* int_type = | ||||||
|                 db->Resolve(db->ToTypeId(enum_type.get_usr_hash())); |                 db->Resolve(db->ToTypeId(enum_type.get_usr_hash())); | ||||||
|             int_type->uses.push_back(decl_spell); |             AddUse(int_type->uses, decl_spell); | ||||||
|             // type is invalidated.
 |             // type is invalidated.
 | ||||||
|             type = db->Resolve(type_id); |             type = db->Resolve(type_id); | ||||||
|           } |           } | ||||||
| @ -1899,7 +1913,7 @@ void OnIndexReference(CXClientData client_data, const CXIdxEntityRefInfo* ref) { | |||||||
|     case CXIdxEntity_CXXNamespace: { |     case CXIdxEntity_CXXNamespace: { | ||||||
|       ClangCursor referenced = ref->referencedEntity->cursor; |       ClangCursor referenced = ref->referencedEntity->cursor; | ||||||
|       IndexType* ns = db->Resolve(db->ToTypeId(referenced.get_usr_hash())); |       IndexType* ns = db->Resolve(db->ToTypeId(referenced.get_usr_hash())); | ||||||
|       ns->uses.push_back(cursor.get_spelling_range()); |       AddUse(ns->uses, cursor.get_spelling_range()); | ||||||
|       break; |       break; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| @ -2352,3 +2366,42 @@ void Reflect(Writer& visitor, IndexFuncRef& value) { | |||||||
|     Reflect(visitor, value.role); |     Reflect(visitor, value.role); | ||||||
|   } |   } | ||||||
| } | } | ||||||
|  | 
 | ||||||
|  | void Reflect(Reader& visitor, Reference& value) { | ||||||
|  |   if (visitor.Format() == SerializeFormat::Json) { | ||||||
|  |     std::string s = visitor.GetString(); | ||||||
|  |     value = Reference{}; | ||||||
|  |     value.range = Range(s.c_str()); | ||||||
|  |     auto sep = s.find('|'); | ||||||
|  |     if (sep == std::string::npos) | ||||||
|  |       value.role = SymbolRole::Reference; | ||||||
|  |     else { | ||||||
|  |       char* p = const_cast<char*>(s.c_str()) + sep; | ||||||
|  |       value.role = SymbolRole(strtol(p + 1, &p, 10)); | ||||||
|  |       value.lex_parent_kind = SymbolKind(strtol(p + 1, &p, 10)); | ||||||
|  |       value.lex_parent_id = Id<void>(strtol(p + 1, &p, 10)); | ||||||
|  |     } | ||||||
|  |   } else { | ||||||
|  |     Reflect(visitor, value.range); | ||||||
|  |     Reflect(visitor, value.lex_parent_id); | ||||||
|  |     Reflect(visitor, value.lex_parent_kind); | ||||||
|  |     Reflect(visitor, value.role); | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | void Reflect(Writer& visitor, Reference& value) { | ||||||
|  |   if (visitor.Format() == SerializeFormat::Json) { | ||||||
|  |     std::string s = value.range.ToString(); | ||||||
|  |     if (value.role != SymbolRole::Reference || | ||||||
|  |         value.lex_parent_kind != SymbolKind::Invalid) { | ||||||
|  |       s += '|' + std::to_string(uint8_t(value.role)); | ||||||
|  |       s += '|' + std::to_string(uint8_t(value.lex_parent_kind)); | ||||||
|  |       s += '|' + std::to_string(RawId(value.lex_parent_id)); | ||||||
|  |     } | ||||||
|  |     visitor.String(s.c_str()); | ||||||
|  |   } else { | ||||||
|  |     Reflect(visitor, value.range); | ||||||
|  |     Reflect(visitor, value.lex_parent_id); | ||||||
|  |     Reflect(visitor, value.lex_parent_kind); | ||||||
|  |     Reflect(visitor, value.role); | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | |||||||
| @ -78,13 +78,22 @@ using IndexVarId = Id<IndexVar>; | |||||||
| 
 | 
 | ||||||
| struct IdCache; | struct IdCache; | ||||||
| 
 | 
 | ||||||
| struct IndexLocation { | struct Reference { | ||||||
|   Range loc; |   Range range; | ||||||
|   Id<void> parent_id; |   Id<void> lex_parent_id; | ||||||
|   SymbolKind parent_kind = SymbolKind::Invalid; |   SymbolKind lex_parent_kind; | ||||||
|   SymbolRole role = SymbolRole::None; |   SymbolRole role; | ||||||
|  | 
 | ||||||
|  |   std::tuple<Range, Id<void>, SymbolKind, SymbolRole> ToTuple() const { | ||||||
|  |     return std::make_tuple(range, lex_parent_id, lex_parent_kind, role); | ||||||
|  |   } | ||||||
|  |   bool operator==(const Reference& o) const { | ||||||
|  |     return ToTuple() == o.ToTuple(); | ||||||
|  |   } | ||||||
|  |   bool operator<(const Reference& o) const { | ||||||
|  |     return ToTuple() < o.ToTuple(); | ||||||
|  |   } | ||||||
| }; | }; | ||||||
| MAKE_REFLECT_STRUCT(IndexLocation, loc, parent_id, parent_kind, role); |  | ||||||
| 
 | 
 | ||||||
| struct IndexFuncRef { | 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.
 | ||||||
| @ -104,6 +113,8 @@ 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); | ||||||
|  | void Reflect(Reader& visitor, Reference& value); | ||||||
|  | void Reflect(Writer& visitor, Reference& value); | ||||||
| 
 | 
 | ||||||
| template <typename FileId, | template <typename FileId, | ||||||
|           typename TypeId, |           typename TypeId, | ||||||
| @ -209,7 +220,7 @@ struct IndexType { | |||||||
| 
 | 
 | ||||||
|   // Every usage, useful for things like renames.
 |   // Every usage, useful for things like renames.
 | ||||||
|   // NOTE: Do not insert directly! Use AddUsage instead.
 |   // NOTE: Do not insert directly! Use AddUsage instead.
 | ||||||
|   std::vector<Range> uses; |   std::vector<Reference> uses; | ||||||
| 
 | 
 | ||||||
|   IndexType() {}  // For serialization.
 |   IndexType() {}  // For serialization.
 | ||||||
|   IndexType(IndexTypeId id, Usr usr); |   IndexType(IndexTypeId id, Usr usr); | ||||||
|  | |||||||
| @ -154,8 +154,13 @@ struct TextDocumentCodeLensHandler | |||||||
|             continue; |             continue; | ||||||
|           if (type.def->kind == ClangSymbolKind::Namespace) |           if (type.def->kind == ClangSymbolKind::Namespace) | ||||||
|             continue; |             continue; | ||||||
|  |           // FIXME QueryRef
 | ||||||
|  |           std::vector<QueryLocation> uses; | ||||||
|  |           uses.reserve(type.uses.size()); | ||||||
|  |           for (auto& x : type.uses) | ||||||
|  |             uses.push_back(ToQueryLocation(db, x)); | ||||||
|           AddCodeLens("ref", "refs", &common, ref.loc.OffsetStartColumn(0), |           AddCodeLens("ref", "refs", &common, ref.loc.OffsetStartColumn(0), | ||||||
|                       type.uses, type.def->definition_spelling, |                       uses, type.def->definition_spelling, | ||||||
|                       true /*force_display*/); |                       true /*force_display*/); | ||||||
|           AddCodeLens("derived", "derived", &common, |           AddCodeLens("derived", "derived", &common, | ||||||
|                       ref.loc.OffsetStartColumn(1), |                       ref.loc.OffsetStartColumn(1), | ||||||
|  | |||||||
							
								
								
									
										62
									
								
								src/query.cc
									
									
									
									
									
								
							
							
						
						
									
										62
									
								
								src/query.cc
									
									
									
									
									
								
							| @ -254,8 +254,8 @@ QueryFile::DefUpdate BuildFileDefUpdate(const IdMap& id_map, const IndexFile& in | |||||||
|                       *type.def.definition_spelling); |                       *type.def.definition_spelling); | ||||||
|     if (type.def.definition_extent.has_value()) |     if (type.def.definition_extent.has_value()) | ||||||
|       add_outline(id_map.ToSymbol(type.id), *type.def.definition_extent); |       add_outline(id_map.ToSymbol(type.id), *type.def.definition_extent); | ||||||
|     for (const Range& use : type.uses) |     for (const Reference& use : type.uses) | ||||||
|       add_all_symbols(id_map.ToSymbol(type.id), SymbolRole::Reference, use); |       add_all_symbols(id_map.ToSymbol(type.id), use.role, use.range); | ||||||
|   } |   } | ||||||
|   for (const IndexFunc& func : indexed.funcs) { |   for (const IndexFunc& func : indexed.funcs) { | ||||||
|     if (func.def.definition_spelling.has_value()) |     if (func.def.definition_spelling.has_value()) | ||||||
| @ -372,34 +372,6 @@ Maybe<QueryVarId> GetQueryVarIdFromUsr(QueryDatabase* query_db, | |||||||
| 
 | 
 | ||||||
| }  // namespace
 | }  // namespace
 | ||||||
| 
 | 
 | ||||||
| QueryFileId QueryRef::FileId(QueryDatabase* db) const { |  | ||||||
|   switch (lex_parent_kind) { |  | ||||||
|   case SymbolKind::Invalid: |  | ||||||
|     break; |  | ||||||
|   case SymbolKind::File: |  | ||||||
|     return QueryFileId(lex_parent_id); |  | ||||||
|   case SymbolKind::Func: { |  | ||||||
|     QueryFunc& file = db->funcs[lex_parent_id.id]; |  | ||||||
|     if (file.def) |  | ||||||
|       return file.def->file; |  | ||||||
|     break; |  | ||||||
|   } |  | ||||||
|   case SymbolKind::Type: { |  | ||||||
|     QueryType& type = db->types[lex_parent_id.id]; |  | ||||||
|     if (type.def) |  | ||||||
|       return type.def->file; |  | ||||||
|     break; |  | ||||||
|   } |  | ||||||
|   case SymbolKind::Var: { |  | ||||||
|     QueryVar& var = db->vars[lex_parent_id.id]; |  | ||||||
|     if (var.def) |  | ||||||
|       return var.def->file; |  | ||||||
|     break; |  | ||||||
|   } |  | ||||||
|   } |  | ||||||
|   return QueryFileId(); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| 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); | ||||||
| @ -442,6 +414,28 @@ IdMap::IdMap(QueryDatabase* query_db, const IdCache& local_ids) | |||||||
| QueryLocation IdMap::ToQuery(Range range, SymbolRole role) const { | 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 { | ||||||
|  |   switch (ref.lex_parent_kind) { | ||||||
|  |     case SymbolKind::Invalid: | ||||||
|  |     case SymbolKind::File: | ||||||
|  |       ref.lex_parent_kind = SymbolKind::File; | ||||||
|  |       ref.lex_parent_id = Id<void>(primary_file); | ||||||
|  |       break; | ||||||
|  |     case SymbolKind::Func: | ||||||
|  |       ref.lex_parent_id = Id<void>( | ||||||
|  |           cached_func_ids_.find(IndexFuncId(ref.lex_parent_id))->second); | ||||||
|  |       break; | ||||||
|  |     case SymbolKind::Type: | ||||||
|  |       ref.lex_parent_id = Id<void>( | ||||||
|  |           cached_type_ids_.find(IndexTypeId(ref.lex_parent_id))->second); | ||||||
|  |       break; | ||||||
|  |     case SymbolKind::Var: | ||||||
|  |       ref.lex_parent_id = | ||||||
|  |           Id<void>(cached_var_ids_.find(IndexVarId(ref.lex_parent_id))->second); | ||||||
|  |       break; | ||||||
|  |   } | ||||||
|  |   return ref; | ||||||
|  | } | ||||||
| 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()); | ||||||
|   return QueryTypeId(cached_type_ids_.find(id)->second); |   return QueryTypeId(cached_type_ids_.find(id)->second); | ||||||
| @ -591,7 +585,7 @@ IndexUpdate::IndexUpdate(const IdMap& previous_id_map, | |||||||
|         PROCESS_UPDATE_DIFF(QueryTypeId, types_derived, derived, QueryTypeId); |         PROCESS_UPDATE_DIFF(QueryTypeId, types_derived, derived, QueryTypeId); | ||||||
|         PROCESS_UPDATE_DIFF(QueryTypeId, types_instances, instances, |         PROCESS_UPDATE_DIFF(QueryTypeId, types_instances, instances, | ||||||
|                             QueryVarId); |                             QueryVarId); | ||||||
|         PROCESS_UPDATE_DIFF(QueryTypeId, types_uses, uses, QueryLocation); |         PROCESS_UPDATE_DIFF(QueryTypeId, types_uses, uses, Reference); | ||||||
|       }); |       }); | ||||||
| 
 | 
 | ||||||
|   // Functions
 |   // Functions
 | ||||||
| @ -1032,7 +1026,7 @@ TEST_SUITE("query") { | |||||||
|     IndexFile current("foo.cc", "<empty>"); |     IndexFile current("foo.cc", "<empty>"); | ||||||
| 
 | 
 | ||||||
|     previous.Resolve(previous.ToTypeId(HashUsr("usr1"))) |     previous.Resolve(previous.ToTypeId(HashUsr("usr1"))) | ||||||
|         ->uses.push_back(Range(Position(1, 0))); |         ->uses.push_back(Reference{Range(Position(1, 0))}); | ||||||
|     previous.Resolve(previous.ToFuncId(HashUsr("usr2"))) |     previous.Resolve(previous.ToFuncId(HashUsr("usr2"))) | ||||||
|         ->callers.push_back(IndexFuncRef{Range(Position(2, 0)), IndexFuncId(0), |         ->callers.push_back(IndexFuncRef{Range(Position(2, 0)), IndexFuncId(0), | ||||||
|                                          SymbolRole::None}); |                                          SymbolRole::None}); | ||||||
| @ -1078,8 +1072,8 @@ TEST_SUITE("query") { | |||||||
|     IndexType* pt = previous.Resolve(previous.ToTypeId(HashUsr("usr"))); |     IndexType* pt = previous.Resolve(previous.ToTypeId(HashUsr("usr"))); | ||||||
|     IndexType* ct = current.Resolve(current.ToTypeId(HashUsr("usr"))); |     IndexType* ct = current.Resolve(current.ToTypeId(HashUsr("usr"))); | ||||||
| 
 | 
 | ||||||
|     pt->uses.push_back(Range(Position(1, 0))); |     pt->uses.push_back(Reference{Range(Position(1, 0))}); | ||||||
|     ct->uses.push_back(Range(Position(2, 0))); |     ct->uses.push_back(Reference{Range(Position(2, 0))}); | ||||||
| 
 | 
 | ||||||
|     IndexUpdate update = GetDelta(previous, current); |     IndexUpdate update = GetDelta(previous, current); | ||||||
| 
 | 
 | ||||||
|  | |||||||
							
								
								
									
										17
									
								
								src/query.h
									
									
									
									
									
								
							
							
						
						
									
										17
									
								
								src/query.h
									
									
									
									
									
								
							| @ -57,15 +57,6 @@ struct hash<::SymbolKind> { | |||||||
| }; | }; | ||||||
| }  // namespace std
 | }  // namespace std
 | ||||||
| 
 | 
 | ||||||
| struct QueryRef { |  | ||||||
|   Range range; |  | ||||||
|   Id<void> lex_parent_id; |  | ||||||
|   SymbolKind lex_parent_kind; |  | ||||||
|   SymbolRole role; |  | ||||||
|   QueryFileId FileId(QueryDatabase*) const; |  | ||||||
| }; |  | ||||||
| //MAKE_REFLECT_STRUCT(QueryRef, range, lex_parent_id, lex_parent_kind, role);
 |  | ||||||
| 
 |  | ||||||
| struct SymbolIdx { | struct SymbolIdx { | ||||||
|   SymbolKind kind; |   SymbolKind kind; | ||||||
|   RawId idx; |   RawId idx; | ||||||
| @ -235,14 +226,14 @@ struct QueryType { | |||||||
|   using DefUpdate = WithUsr<Def>; |   using DefUpdate = WithUsr<Def>; | ||||||
|   using DerivedUpdate = MergeableUpdate<QueryTypeId, QueryTypeId>; |   using DerivedUpdate = MergeableUpdate<QueryTypeId, QueryTypeId>; | ||||||
|   using InstancesUpdate = MergeableUpdate<QueryTypeId, QueryVarId>; |   using InstancesUpdate = MergeableUpdate<QueryTypeId, QueryVarId>; | ||||||
|   using UsesUpdate = MergeableUpdate<QueryTypeId, QueryLocation>; |   using UsesUpdate = MergeableUpdate<QueryTypeId, Reference>; | ||||||
| 
 | 
 | ||||||
|   Usr usr; |   Usr usr; | ||||||
|   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<Reference> uses; | ||||||
| 
 | 
 | ||||||
|   explicit QueryType(const Usr& usr) : usr(usr) {} |   explicit QueryType(const Usr& usr) : usr(usr) {} | ||||||
| }; | }; | ||||||
| @ -410,6 +401,7 @@ template <> struct IndexToQuery<IndexTypeId> { using type = QueryTypeId; }; | |||||||
| template <> struct IndexToQuery<IndexVarId> { using type = QueryVarId; }; | template <> struct IndexToQuery<IndexVarId> { using type = QueryVarId; }; | ||||||
| template <> struct IndexToQuery<IndexFuncRef> { using type = QueryFuncRef; }; | template <> struct IndexToQuery<IndexFuncRef> { using type = QueryFuncRef; }; | ||||||
| template <> struct IndexToQuery<Range> { using type = QueryLocation; }; | template <> struct IndexToQuery<Range> { using type = QueryLocation; }; | ||||||
|  | template <> struct IndexToQuery<Reference> { using type = Reference; }; | ||||||
| template <> struct IndexToQuery<IndexFunc::Declaration> { using type = QueryLocation; }; | template <> struct IndexToQuery<IndexFunc::Declaration> { using type = QueryLocation; }; | ||||||
| template <typename I> struct IndexToQuery<optional<I>> { | template <typename I> struct IndexToQuery<optional<I>> { | ||||||
|   using type = optional<typename IndexToQuery<I>::type>; |   using type = optional<typename IndexToQuery<I>::type>; | ||||||
| @ -428,6 +420,7 @@ struct IdMap { | |||||||
|   // FIXME Too verbose
 |   // FIXME Too verbose
 | ||||||
|   // clang-format off
 |   // clang-format off
 | ||||||
|   QueryLocation ToQuery(Range range, SymbolRole role) const; |   QueryLocation ToQuery(Range range, SymbolRole role) const; | ||||||
|  |   Reference ToQuery(Reference ref) 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; | ||||||
| @ -459,3 +452,5 @@ 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); | ||||||
|  | |||||||
| @ -28,6 +28,34 @@ std::vector<QueryLocation> ToQueryLocationHelper( | |||||||
|   return locs; |   return locs; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | 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(); | ||||||
|  | } | ||||||
|  | 
 | ||||||
| }  // namespace
 | }  // namespace
 | ||||||
| 
 | 
 | ||||||
| optional<QueryLocation> GetDefinitionSpellingOfSymbol(QueryDatabase* db, | optional<QueryLocation> GetDefinitionSpellingOfSymbol(QueryDatabase* db, | ||||||
| @ -151,6 +179,10 @@ optional<QueryFileId> GetDeclarationFileForSymbol(QueryDatabase* db, | |||||||
|   return nullopt; |   return nullopt; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | QueryLocation ToQueryLocation(QueryDatabase* db, Reference ref) { | ||||||
|  |   return QueryLocation{ref.range, GetFileId(db, ref), ref.role}; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| std::vector<QueryLocation> ToQueryLocation( | std::vector<QueryLocation> ToQueryLocation( | ||||||
|     QueryDatabase* db, |     QueryDatabase* db, | ||||||
|     const std::vector<QueryFuncRef>& refs) { |     const std::vector<QueryFuncRef>& refs) { | ||||||
| @ -182,7 +214,10 @@ std::vector<QueryLocation> GetUsesOfSymbol(QueryDatabase* db, | |||||||
|   switch (symbol.kind) { |   switch (symbol.kind) { | ||||||
|     case SymbolKind::Type: { |     case SymbolKind::Type: { | ||||||
|       QueryType& type = db->types[symbol.idx]; |       QueryType& type = db->types[symbol.idx]; | ||||||
|       std::vector<QueryLocation> ret = type.uses; |       std::vector<QueryLocation> ret; | ||||||
|  |       ret.reserve(type.uses.size()); | ||||||
|  |       for (auto& x : type.uses) | ||||||
|  |         ret.push_back(ToQueryLocation(db, x)); | ||||||
|       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); | ||||||
|       return ret; |       return ret; | ||||||
|  | |||||||
| @ -19,6 +19,8 @@ optional<QueryLocation> GetDefinitionExtentOfSymbol(QueryDatabase* db, | |||||||
|                                                     const SymbolIdx& symbol); |                                                     const SymbolIdx& symbol); | ||||||
| optional<QueryFileId> GetDeclarationFileForSymbol(QueryDatabase* db, | optional<QueryFileId> GetDeclarationFileForSymbol(QueryDatabase* db, | ||||||
|                                                   const SymbolIdx& symbol); |                                                   const SymbolIdx& symbol); | ||||||
|  | 
 | ||||||
|  | QueryLocation ToQueryLocation(QueryDatabase* db, Reference ref); | ||||||
| std::vector<QueryLocation> ToQueryLocation( | std::vector<QueryLocation> ToQueryLocation( | ||||||
|     QueryDatabase* db, |     QueryDatabase* db, | ||||||
|     const std::vector<QueryFuncRef>& refs); |     const std::vector<QueryFuncRef>& refs); | ||||||
|  | |||||||
| @ -44,7 +44,7 @@ void Reflect(Writer& visitor, int& value) { | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void Reflect(Reader& visitor, unsigned& value) { | void Reflect(Reader& visitor, unsigned& value) { | ||||||
|   if (!visitor.IsInt()) |   if (!visitor.IsUint64()) | ||||||
|     throw std::invalid_argument("unsigned"); |     throw std::invalid_argument("unsigned"); | ||||||
|   value = visitor.GetUint32(); |   value = visitor.GetUint32(); | ||||||
| } | } | ||||||
|  | |||||||
| @ -109,9 +109,10 @@ void DiffDocuments(std::string path, | |||||||
| 
 | 
 | ||||||
| void VerifySerializeToFrom(IndexFile* file) { | void VerifySerializeToFrom(IndexFile* file) { | ||||||
|   std::string expected = file->ToString(); |   std::string expected = file->ToString(); | ||||||
|   std::unique_ptr<IndexFile> result = Deserialize( |   std::string serialized = Serialize(SerializeFormat::Json, *file); | ||||||
|       SerializeFormat::Json, "--.cc", Serialize(SerializeFormat::Json, *file), "<empty>", |   std::unique_ptr<IndexFile> result = | ||||||
|       nullopt /*expected_version*/); |       Deserialize(SerializeFormat::Json, "--.cc", serialized, "<empty>", | ||||||
|  |                   nullopt /*expected_version*/); | ||||||
|   std::string actual = result->ToString(); |   std::string actual = result->ToString(); | ||||||
|   if (expected != actual) { |   if (expected != actual) { | ||||||
|     std::cerr << "Serialization failure" << std::endl; |     std::cerr << "Serialization failure" << std::endl; | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user