diff --git a/src/indexer.cc b/src/indexer.cc index 3046b8a3..a973ea30 100644 --- a/src/indexer.cc +++ b/src/indexer.cc @@ -584,7 +584,7 @@ void OnIndexReference_Function(IndexFile* db, ClangCursor caller_cursor, IndexFuncId called_id, IndexFunc* called, - bool is_implicit) { + SymbolRole role) { if (IsFunctionCallContext(caller_cursor.get_kind())) { IndexFuncId caller_id = db->ToFuncId(caller_cursor.cx_cursor); IndexFunc* caller = db->Resolve(caller_id); @@ -592,10 +592,10 @@ void OnIndexReference_Function(IndexFile* db, called = db->Resolve(called_id); AddFuncRef(&caller->def.callees, - IndexFuncRef(called->id, loc, is_implicit)); - AddFuncRef(&called->callers, IndexFuncRef(caller->id, loc, is_implicit)); + IndexFuncRef{loc, called->id, role}); + AddFuncRef(&called->callers, IndexFuncRef{loc, caller->id, role}); } 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 const int IndexFile::kMajorVersion = 11; -const int IndexFile::kMinorVersion = 1; +const int IndexFile::kMinorVersion = 2; IndexFile::IndexFile(const std::string& path, const std::string& contents) @@ -1258,7 +1258,7 @@ ClangCursor::VisitResult TemplateVisitor(ClangCursor cursor, IndexFunc* called = db->Resolve(called_id); OnIndexReference_Function(db, cursor.get_spelling_range(), data->container, called_id, called, - /*implicit=*/false); + SymbolRole::None); break; } } @@ -1992,8 +1992,9 @@ void OnIndexReference(CXClientData client_data, const CXIdxEntityRefInfo* ref) { else CheckTypeDependentMemberRefExpr(&loc, ref_cursor, param, db); - OnIndexReference_Function(db, loc, ref->container->cursor, called_id, - called, is_implicit); + OnIndexReference_Function( + db, loc, ref->container->cursor, called_id, called, + is_implicit ? SymbolRole::Implicit : SymbolRole::None); // Checks if |str| starts with |start|. Ignores case. 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); if (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(); const char* str_value = s.c_str(); if (str_value[0] == '~') { - value.is_implicit = true; + value.role = SymbolRole::Implicit; ++str_value; } RawId id = atol(str_value); @@ -2324,15 +2326,15 @@ void Reflect(Reader& visitor, IndexFuncRef& value) { value.id = IndexFuncId(id); value.loc = Range(loc_string); } else { - Reflect(visitor, value.id); Reflect(visitor, value.loc); - Reflect(visitor, value.is_implicit); + Reflect(visitor, value.id); + Reflect(visitor, value.role); } } void Reflect(Writer& visitor, IndexFuncRef& value) { if (visitor.Format() == SerializeFormat::Json) { std::string s; - if (value.is_implicit) + if (value.role & SymbolRole::Implicit) s += "~"; // id.id is unsigned, special case -1 value @@ -2344,8 +2346,8 @@ void Reflect(Writer& visitor, IndexFuncRef& value) { s += "@" + value.loc.ToString(); visitor.String(s.c_str()); } else { - Reflect(visitor, value.id); Reflect(visitor, value.loc); - Reflect(visitor, value.is_implicit); + Reflect(visitor, value.id); + Reflect(visitor, value.role); } } diff --git a/src/indexer.h b/src/indexer.h index 3dcf7381..306ba4fe 100644 --- a/src/indexer.h +++ b/src/indexer.h @@ -27,6 +27,7 @@ #include #include +struct IndexFile; struct IndexType; struct IndexFunc; struct IndexVar; @@ -61,7 +62,7 @@ struct Id { namespace std { template struct hash> { - size_t operator()(const Id& k) const { return hash()(k.id); } + size_t operator()(const Id& k) const { return hash()(k.id); } }; } // namespace std @@ -70,6 +71,7 @@ void Reflect(TVisitor& visitor, Id& id) { Reflect(visitor, id.id); } +using IndexFileId = Id; using IndexTypeId = Id; using IndexFuncId = Id; using IndexVarId = Id; @@ -88,18 +90,10 @@ struct IndexFuncRef { // NOTE: id can be -1 if the function call is not coming from a function. Range loc; IndexFuncId id; - SymbolRole role = SymbolRole::None; - bool is_implicit = false; + SymbolRole role; - IndexFuncRef() {} // For serialization. - - 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 ToTuple() const { - return std::make_tuple(id, loc, is_implicit); + std::tuple ToTuple() const { + return std::make_tuple(id, loc, role); } bool operator==(const IndexFuncRef& o) { return ToTuple() == o.ToTuple(); } bool operator!=(const IndexFuncRef& o) { return !(*this == o); } @@ -111,7 +105,11 @@ struct IndexFuncRef { void Reflect(Reader& visitor, IndexFuncRef& value); void Reflect(Writer& visitor, IndexFuncRef& value); -template +template struct TypeDefDefinitionData { // General metadata. std::string detailed_name; @@ -130,10 +128,6 @@ struct TypeDefDefinitionData { Maybe definition_spelling; Maybe 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 alias_of; - // Immediate parent types. std::vector parents; @@ -142,6 +136,11 @@ struct TypeDefDefinitionData { std::vector funcs; std::vector 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 alias_of; + int16_t short_name_offset = 0; int16_t short_name_size = 0; ClangSymbolKind kind = ClangSymbolKind::Unknown; @@ -164,12 +163,14 @@ struct TypeDefDefinitionData { } }; template -void Reflect(TVisitor& visitor, - TypeDefDefinitionData& value) { +void Reflect( + TVisitor& visitor, + TypeDefDefinitionData& value) { REFLECT_MEMBER_START(); REFLECT_MEMBER(detailed_name); REFLECT_MEMBER(short_name_offset); @@ -179,6 +180,7 @@ void Reflect(TVisitor& visitor, REFLECT_MEMBER(comments); REFLECT_MEMBER(definition_spelling); REFLECT_MEMBER(definition_extent); + REFLECT_MEMBER(file); REFLECT_MEMBER(alias_of); REFLECT_MEMBER(parents); REFLECT_MEMBER(types); @@ -188,8 +190,11 @@ void Reflect(TVisitor& visitor, } struct IndexType { - using Def = - TypeDefDefinitionData; + using Def = TypeDefDefinitionData; Usr usr; IndexTypeId id; @@ -213,7 +218,8 @@ struct IndexType { }; MAKE_HASHABLE(IndexType, t.id); -template definition_spelling; Maybe definition_extent; - // Type which declares this one (ie, it is a method) - Maybe declaring_type; - // Method this method overrides. std::vector base; @@ -238,6 +241,9 @@ struct FuncDefDefinitionData { // Functions that this function calls. std::vector callees; + FileId file; + // Type which declares this one (ie, it is a method) + Maybe declaring_type; int16_t short_name_offset = 0; int16_t short_name_size = 0; ClangSymbolKind kind = ClangSymbolKind::Unknown; @@ -262,6 +268,7 @@ struct FuncDefDefinitionData { }; template void Reflect( TVisitor& visitor, - FuncDefDefinitionData& value) { + FuncDefDefinitionData& + value) { REFLECT_MEMBER_START(); REFLECT_MEMBER(detailed_name); REFLECT_MEMBER(short_name_offset); @@ -280,6 +288,7 @@ void Reflect( REFLECT_MEMBER(comments); REFLECT_MEMBER(definition_spelling); REFLECT_MEMBER(definition_extent); + REFLECT_MEMBER(file); REFLECT_MEMBER(declaring_type); REFLECT_MEMBER(base); REFLECT_MEMBER(locals); @@ -288,7 +297,8 @@ void Reflect( } struct IndexFunc { - using Def = FuncDefDefinitionData +template struct VarDefDefinitionData { // General metadata. std::string detailed_name; @@ -348,6 +362,7 @@ struct VarDefDefinitionData { Maybe definition_spelling; Maybe definition_extent; + FileId file; // Type of the variable. Maybe variable_type; @@ -376,8 +391,7 @@ struct VarDefDefinitionData { parent_kind == o.parent_kind && kind == o.kind && storage == o.storage && hover == o.hover && comments == o.comments; } - bool operator!=( - const VarDefDefinitionData& other) const { + bool operator!=(const VarDefDefinitionData& other) const { return !(*this == other); } @@ -388,12 +402,14 @@ struct VarDefDefinitionData { }; template -void Reflect(TVisitor& visitor, - VarDefDefinitionData& value) { +void Reflect( + TVisitor& visitor, + VarDefDefinitionData& value) { REFLECT_MEMBER_START(); REFLECT_MEMBER(detailed_name); REFLECT_MEMBER(short_name_size); @@ -402,6 +418,7 @@ void Reflect(TVisitor& visitor, REFLECT_MEMBER(comments); REFLECT_MEMBER(definition_spelling); REFLECT_MEMBER(definition_extent); + REFLECT_MEMBER(file); REFLECT_MEMBER(variable_type); REFLECT_MEMBER(parent_id); REFLECT_MEMBER(parent_kind); @@ -411,7 +428,11 @@ void Reflect(TVisitor& visitor, } struct IndexVar { - using Def = VarDefDefinitionData; + using Def = VarDefDefinitionData; Usr usr; IndexVarId id; diff --git a/src/messages/text_document_code_action.cc b/src/messages/text_document_code_action.cc index cdff4518..97d14a47 100644 --- a/src/messages/text_document_code_action.cc +++ b/src/messages/text_document_code_action.cc @@ -73,8 +73,8 @@ optional GetImplementationFile(QueryDatabase* db, // Note: we ignore the definition if it is in the same file (ie, // possibly a header). if (func.def && func.def->definition_extent && - func.def->definition_extent->path != file_id) { - return func.def->definition_extent->path; + func.def->definition_extent->FileId() != file_id) { + return func.def->definition_extent->FileId(); } break; } @@ -83,8 +83,8 @@ optional GetImplementationFile(QueryDatabase* db, // Note: we ignore the definition if it is in the same file (ie, // possibly a header). if (var.def && var.def->definition_extent && - var.def->definition_extent->path != file_id) { - return db->vars[sym.idx.idx].def->definition_extent->path; + var.def->definition_extent->FileId() != file_id) { + return db->vars[sym.idx.idx].def->definition_extent->FileId(); } break; } @@ -149,7 +149,7 @@ optional BuildAutoImplementForFunction(QueryDatabase* db, QueryFunc& func) { assert(func.def); for (const QueryLocation& decl : func.declarations) { - if (decl.path != decl_file_id) + if (decl.FileId() != decl_file_id) continue; optional ls_decl = GetLsRange(working_file, decl.range); @@ -203,7 +203,7 @@ optional BuildAutoImplementForFunction(QueryDatabase* db, break; 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; if (abs(dist) < abs(best_dist)) { optional def_loc = GetLsLocation( diff --git a/src/messages/text_document_code_lens.cc b/src/messages/text_document_code_lens.cc index 3a85d4eb..3ce850b5 100644 --- a/src/messages/text_document_code_lens.cc +++ b/src/messages/text_document_code_lens.cc @@ -90,7 +90,7 @@ void AddCodeLens(const char* singular, code_lens.range = *range; code_lens.command = lsCommand(); 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; // Add unique uses. @@ -179,7 +179,7 @@ struct TextDocumentCodeLensHandler auto try_ensure_spelling = [&](SymbolRef sym) { optional def = 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) { return sym.loc; } diff --git a/src/messages/text_document_definition.cc b/src/messages/text_document_definition.cc index 07d6995e..b85b4425 100644 --- a/src/messages/text_document_definition.cc +++ b/src/messages/text_document_definition.cc @@ -90,7 +90,7 @@ struct TextDocumentDefinitionHandler // the declaration if possible. We also want to use declarations if // we're pointing to, ie, a pure virtual function which has no // 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))) { // Goto declaration. diff --git a/src/messages/text_document_highlight.cc b/src/messages/text_document_highlight.cc index 89229660..515b1b72 100644 --- a/src/messages/text_document_highlight.cc +++ b/src/messages/text_document_highlight.cc @@ -41,7 +41,7 @@ struct TextDocumentDocumentHighlightHandler std::vector uses = GetUsesOfSymbol(db, ref.idx, true); out.result.reserve(uses.size()); for (const QueryLocation& use : uses) { - if (use.path != file_id) + if (use.FileId() != file_id) continue; optional ls_location = diff --git a/src/messages/text_document_rename.cc b/src/messages/text_document_rename.cc index 7534c114..4a789fbc 100644 --- a/src/messages/text_document_rename.cc +++ b/src/messages/text_document_rename.cc @@ -16,20 +16,21 @@ lsWorkspaceEdit BuildWorkspaceEdit(QueryDatabase* db, if (!ls_location) continue; - if (path_to_edit.find(location.path) == path_to_edit.end()) { - path_to_edit[location.path] = lsTextDocumentEdit(); + QueryFileId file_id = location.FileId(); + 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) continue; const std::string& path = file.def->path; - path_to_edit[location.path].textDocument.uri = + path_to_edit[file_id].textDocument.uri = lsDocumentUri::FromPath(path); WorkingFile* working_file = working_files->GetFileByFilename(path); if (working_file) - path_to_edit[location.path].textDocument.version = + path_to_edit[file_id].textDocument.version = working_file->version; } @@ -38,7 +39,7 @@ lsWorkspaceEdit BuildWorkspaceEdit(QueryDatabase* db, edit.newText = new_text; // 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()) edits.push_back(edit); } diff --git a/src/query.cc b/src/query.cc index e9ac884b..3e6bd280 100644 --- a/src/query.cc +++ b/src/query.cc @@ -42,8 +42,12 @@ optional ToQuery(const IdMap& id_map, result.kind = type.kind; result.hover = type.hover; result.comments = type.comments; - result.definition_spelling = id_map.ToQuery(type.definition_spelling); - result.definition_extent = id_map.ToQuery(type.definition_extent); + if (type.definition_spelling) + 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.parents = id_map.ToQuery(type.parents); result.types = id_map.ToQuery(type.types); @@ -65,8 +69,12 @@ optional ToQuery(const IdMap& id_map, result.storage = func.storage; result.hover = func.hover; result.comments = func.comments; - result.definition_spelling = id_map.ToQuery(func.definition_spelling); - result.definition_extent = id_map.ToQuery(func.definition_extent); + if (func.definition_spelling) + 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.base = id_map.ToQuery(func.base); result.locals = id_map.ToQuery(func.locals); @@ -84,8 +92,12 @@ optional ToQuery(const IdMap& id_map, const IndexVar::Def& var) { result.short_name_size = var.short_name_size; result.hover = var.hover; result.comments = var.comments; - result.definition_spelling = id_map.ToQuery(var.definition_spelling); - result.definition_extent = id_map.ToQuery(var.definition_extent); + if (var.definition_spelling) + 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.parent_id = var.parent_id; 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) { 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, 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) { @@ -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 // 42;` will take you to the constructor. Range range = caller.loc; - if (caller.is_implicit) { + if (caller.role & SymbolRole::Implicit) { if (range.start.column > 0) range.start.column--; range.end.column++; } add_all_symbols(id_map.ToSymbol(func.id), - caller.is_implicit - ? SymbolRole::Implicit | SymbolRole::CalledBy - : SymbolRole::CalledBy, - range); + caller.role | SymbolRole::CalledBy, range); } } 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); } -QueryLocation IdMap::ToQuery(Range range) const { - return QueryLocation(primary_file, range); +QueryLocation IdMap::ToQuery(Range range, SymbolRole role) const { + return QueryLocation{range, primary_file, role}; +} +QueryFileId IdMap::ToQuery(IndexFileId) const { + return primary_file; } QueryTypeId IdMap::ToQuery(IndexTypeId id) const { 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); } 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 { // TODO: expose more than just QueryLocation. - return QueryLocation(primary_file, decl.spelling); + return QueryLocation{decl.spelling, primary_file, SymbolRole::Declaration}; +} +std::vector IdMap::ToQuery(const std::vector& a) const { + std::vector ret; + ret.reserve(a.size()); + for (auto& x : a) + ret.push_back(ToQuery(x, SymbolRole::Reference)); + return ret; } SymbolIdx IdMap::ToSymbol(IndexTypeId id) const { @@ -734,7 +755,6 @@ void QueryDatabase::RemoveUsrs(SymbolKind usr_kind, QueryType& type = types[usr_to_type[usr].id]; if (type.symbol_idx) symbols[type.symbol_idx->id].kind = SymbolKind::Invalid; - type.gen++; //type.def = QueryType::Def(); type.def = nullopt; } @@ -745,7 +765,6 @@ void QueryDatabase::RemoveUsrs(SymbolKind usr_kind, QueryFunc& func = funcs[usr_to_func[usr].id]; if (func.symbol_idx) symbols[func.symbol_idx->id].kind = SymbolKind::Invalid; - func.gen++; //func.def = QueryFunc::Def(); func.def = nullopt; } @@ -756,7 +775,6 @@ void QueryDatabase::RemoveUsrs(SymbolKind usr_kind, QueryVar& var = vars[usr_to_var[usr].id]; if (var.symbol_idx) symbols[var.symbol_idx->id].kind = SymbolKind::Invalid; - var.gen++; //var.def = QueryVar::Def(); var.def = nullopt; } @@ -987,8 +1005,8 @@ TEST_SUITE("query") { previous.Resolve(previous.ToTypeId(HashUsr("usr1"))) ->uses.push_back(Range(Position(1, 0))); previous.Resolve(previous.ToFuncId(HashUsr("usr2"))) - ->callers.push_back(IndexFuncRef(IndexFuncId(0), Range(Position(2, 0)), - false /*is_implicit*/)); + ->callers.push_back(IndexFuncRef{Range(Position(2, 0)), IndexFuncId(0), + SymbolRole::None}); previous.Resolve(previous.ToVarId(HashUsr("usr3"))) ->uses.push_back(Range(Position(3, 0))); @@ -1006,10 +1024,10 @@ TEST_SUITE("query") { IndexFunc* pf = previous.Resolve(previous.ToFuncId(HashUsr("usr"))); IndexFunc* cf = current.Resolve(current.ToFuncId(HashUsr("usr"))); - pf->callers.push_back(IndexFuncRef(IndexFuncId(0), Range(Position(1, 0)), - false /*is_implicit*/)); - cf->callers.push_back(IndexFuncRef(IndexFuncId(0), Range(Position(2, 0)), - false /*is_implicit*/)); + pf->callers.push_back( + IndexFuncRef{Range(Position(1, 0)), IndexFuncId(0), SymbolRole::None}); + cf->callers.push_back( + IndexFuncRef{Range(Position(2, 0)), IndexFuncId(0), SymbolRole::None}); IndexUpdate update = GetDelta(previous, current); @@ -1051,14 +1069,14 @@ TEST_SUITE("query") { IndexFunc* pf = previous.Resolve(previous.ToFuncId(HashUsr("usr"))); IndexFunc* cf = current.Resolve(current.ToFuncId(HashUsr("usr"))); - pf->callers.push_back(IndexFuncRef(IndexFuncId(0), Range(Position(1, 0)), - false /*is_implicit*/)); - pf->callers.push_back(IndexFuncRef(IndexFuncId(0), Range(Position(2, 0)), - false /*is_implicit*/)); - cf->callers.push_back(IndexFuncRef(IndexFuncId(0), Range(Position(4, 0)), - false /*is_implicit*/)); - cf->callers.push_back(IndexFuncRef(IndexFuncId(0), Range(Position(5, 0)), - false /*is_implicit*/)); + pf->callers.push_back( + IndexFuncRef{Range(Position(1, 0)), IndexFuncId(0), SymbolRole::None}); + pf->callers.push_back( + IndexFuncRef{Range(Position(2, 0)), IndexFuncId(0), SymbolRole::None}); + cf->callers.push_back( + IndexFuncRef{Range(Position(4, 0)), IndexFuncId(0), SymbolRole::None}); + cf->callers.push_back( + IndexFuncRef{Range(Position(5, 0)), IndexFuncId(0), SymbolRole::None}); QueryDatabase db; IdMap previous_map(&db, previous.id_cache); diff --git a/src/query.h b/src/query.h index 35c92715..9142d748 100644 --- a/src/query.h +++ b/src/query.h @@ -20,40 +20,10 @@ using QueryVarId = Id; struct IdMap; -using Generation = uint32_t; - -// Example use: |WithGen>|, 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 -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 -void Reflect(TVisitor& visitor, WithGen& value) { - Reflect(visitor, value.value); -} - struct QueryLocation { Range range; QueryFileId path; - SymbolRole role = SymbolRole::None; - - QueryLocation() {} // Do not use, needed for reflect. - QueryLocation(QueryFileId path, Range range) : range(range), path(path) {} + SymbolRole role; QueryLocation OffsetStartColumn(int16_t offset) const { QueryLocation result = *this; @@ -62,6 +32,7 @@ struct QueryLocation { } bool HasValue() const { return range.HasValue(); } + QueryFileId FileId() const { return path; } bool operator==(const QueryLocation& o) const { 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. QueryFuncId id_; QueryLocation loc; - bool is_implicit = false; bool HasValue() const { return id_.HasValue(); } - QueryFuncRef() {} // Do not use, needed for reflect. - QueryFuncRef(QueryFuncId id, QueryLocation loc, bool is_implicit) - : id_(id), loc(loc), is_implicit(is_implicit) {} - - std::tuple ToTuple() const { - return std::make_tuple(id_, loc, is_implicit); + std::tuple ToTuple() const { + return std::make_tuple(id_, loc); } bool operator==(const QueryFuncRef& o) const { return ToTuple() == o.ToTuple(); @@ -148,7 +114,7 @@ struct QueryFuncRef { 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 // symbol has changed, or one of many users of the symbol has changed. @@ -251,7 +217,8 @@ MAKE_REFLECT_STRUCT(QueryFile::Def, dependencies); struct QueryType { - using Def = TypeDefDefinitionData; @@ -261,18 +228,18 @@ struct QueryType { using UsesUpdate = MergeableUpdate; Usr usr; - Generation gen; Maybe> symbol_idx; optional def; std::vector derived; std::vector instances; std::vector uses; - explicit QueryType(const Usr& usr) : usr(usr), gen(0) {} + explicit QueryType(const Usr& usr) : usr(usr) {} }; struct QueryFunc { - using Def = FuncDefDefinitionData; Usr usr; - Generation gen; Maybe> symbol_idx; optional def; std::vector declarations; std::vector derived; std::vector callers; - explicit QueryFunc(const Usr& usr) : usr(usr), gen(0) {} + explicit QueryFunc(const Usr& usr) : usr(usr) {} }; struct QueryVar { - using Def = VarDefDefinitionData; @@ -303,13 +270,12 @@ struct QueryVar { using UsesUpdate = MergeableUpdate; Usr usr; - Generation gen; Maybe> symbol_idx; optional def; std::vector declarations; std::vector uses; - explicit QueryVar(const Usr& usr) : usr(usr), gen(0) {} + explicit QueryVar(const Usr& usr) : usr(usr) {} }; struct IndexUpdate { @@ -428,6 +394,7 @@ template struct IndexToQuery; // clang-format off +template <> struct IndexToQuery { using type = QueryFileId; }; template <> struct IndexToQuery { using type = QueryFuncId; }; template <> struct IndexToQuery { using type = QueryTypeId; }; template <> struct IndexToQuery { using type = QueryVarId; }; @@ -450,7 +417,8 @@ struct IdMap { // FIXME Too verbose // clang-format off - QueryLocation ToQuery(Range range) const; + QueryLocation ToQuery(Range range, SymbolRole role) const; + QueryFileId ToQuery(IndexFileId) const; QueryTypeId ToQuery(IndexTypeId id) const; QueryFuncId ToQuery(IndexFuncId id) const; QueryVarId ToQuery(IndexVarId id) const; @@ -463,12 +431,6 @@ struct IdMap { return ToQuery(*id); } template - Maybe::type>> ToQuery(Maybe id, int) const { - if (!id) - return nullopt; - return ToQuery(*id, 0); - } - template std::vector::type> ToQuery(const std::vector& a) const { std::vector::type> ret; ret.reserve(a.size()); @@ -476,14 +438,7 @@ struct IdMap { ret.push_back(ToQuery(x)); return ret; } - template - std::vector::type>> ToQuery(std::vector a, int) const { - std::vector::type>> ret; - ret.reserve(a.size()); - for (auto& x : a) - ret.push_back(ToQuery(x, 0)); - return ret; - } + std::vector ToQuery(const std::vector& a) const; // clang-format on SymbolIdx ToSymbol(IndexTypeId id) const; diff --git a/src/query_utils.cc b/src/query_utils.cc index 202a0bf9..236e27b9 100644 --- a/src/query_utils.cc +++ b/src/query_utils.cc @@ -106,8 +106,8 @@ optional GetDefinitionExtentOfSymbol(QueryDatabase* db, break; } case SymbolKind::File: { - return QueryLocation(QueryFileId(symbol.idx), - Range(Position(1, 1), Position(1, 1))); + return QueryLocation{Range(Position(0, 0), Position(0, 0)), + QueryFileId(symbol.idx), SymbolRole::None}; } case SymbolKind::Invalid: { assert(false && "unexpected"); @@ -123,21 +123,21 @@ optional GetDeclarationFileForSymbol(QueryDatabase* db, case SymbolKind::Type: { QueryType& type = db->types[symbol.idx]; if (type.def && type.def->definition_spelling) - return type.def->definition_spelling->path; + return type.def->definition_spelling->FileId(); break; } case SymbolKind::Func: { QueryFunc& func = db->funcs[symbol.idx]; if (!func.declarations.empty()) - return func.declarations[0].path; + return func.declarations[0].FileId(); if (func.def && func.def->definition_spelling) - return func.def->definition_spelling->path; + return func.def->definition_spelling->FileId(); break; } case SymbolKind::Var: { QueryVar& var = db->vars[symbol.idx]; if (var.def && var.def->definition_spelling) - return var.def->definition_spelling->path; + return var.def->definition_spelling->FileId(); break; } case SymbolKind::File: { @@ -401,7 +401,7 @@ optional GetLsLocation(QueryDatabase* db, WorkingFiles* working_files, const QueryLocation& location) { std::string path; - lsDocumentUri uri = GetLsDocumentUri(db, location.path, &path); + lsDocumentUri uri = GetLsDocumentUri(db, location.FileId(), &path); optional range = GetLsRange(working_files->GetFileByFilename(path), location.range); if (!range)