diff --git a/src/indexer.h b/src/indexer.h index 73cfb91c..39dea771 100644 --- a/src/indexer.h +++ b/src/indexer.h @@ -452,7 +452,7 @@ struct IndexVar { std::vector declarations; // Usages. - std::vector uses; + std::vector uses; IndexVar() {} // For serialization. IndexVar(IndexVarId id, Usr usr) : usr(usr), id(id) { diff --git a/src/messages/text_document_code_action.cc b/src/messages/text_document_code_action.cc index 97d14a47..22c8d990 100644 --- a/src/messages/text_document_code_action.cc +++ b/src/messages/text_document_code_action.cc @@ -148,8 +148,8 @@ optional BuildAutoImplementForFunction(QueryDatabase* db, QueryFileId impl_file_id, QueryFunc& func) { assert(func.def); - for (const QueryLocation& decl : func.declarations) { - if (decl.FileId() != decl_file_id) + for (const Reference& decl : func.declarations) { + if (GetFileId(db, decl) != decl_file_id) continue; optional ls_decl = GetLsRange(working_file, decl.range); @@ -202,8 +202,8 @@ optional BuildAutoImplementForFunction(QueryDatabase* db, if (!sym_func.def || !sym_func.def->definition_extent) break; - for (QueryLocation& func_decl : sym_func.declarations) { - if (func_decl.FileId() == decl_file_id) { + for (const Reference& func_decl : sym_func.declarations) { + if (GetFileId(db, func_decl) == 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 4a72514d..bda5df3d 100644 --- a/src/messages/text_document_code_lens.cc +++ b/src/messages/text_document_code_lens.cc @@ -76,6 +76,7 @@ struct CommonCodeLensParams { WorkingFile* working_file; }; +// FIXME Reference void AddCodeLens(const char* singular, const char* plural, CommonCodeLensParams* common, @@ -270,8 +271,13 @@ struct TextDocumentCodeLensHandler if (var.def->is_macro()) force_display = false; + // FIXME Reference + std::vector uses; + for (auto x: var.uses) + uses.push_back(QueryLocation{x.range, GetFileId(db, x), x.role}); + AddCodeLens("ref", "refs", &common, ref.loc.OffsetStartColumn(0), - var.uses, var.def->definition_spelling, force_display); + uses, var.def->definition_spelling, force_display); break; } case SymbolKind::File: diff --git a/src/messages/text_document_definition.cc b/src/messages/text_document_definition.cc index b85b4425..b3559538 100644 --- a/src/messages/text_document_definition.cc +++ b/src/messages/text_document_definition.cc @@ -23,20 +23,18 @@ struct Out_TextDocumentDefinition }; MAKE_REFLECT_STRUCT(Out_TextDocumentDefinition, jsonrpc, id, result); -std::vector GetGotoDefinitionTargets(QueryDatabase* db, - const SymbolIdx& symbol) { +std::vector GetGotoDefinitionTargets(QueryDatabase* db, + const SymbolIdx& symbol) { switch (symbol.kind) { // Returns GetDeclarationsOfSymbolForGotoDefinition and // variable type definition. case SymbolKind::Var: { - std::vector ret = + std::vector ret = GetDeclarationsOfSymbolForGotoDefinition(db, symbol); QueryVar& var = db->vars[symbol.idx]; - // FIXME WithGen if (var.def && var.def->variable_type) { - std::vector types = - GetDeclarationsOfSymbolForGotoDefinition( - db, SymbolIdx(SymbolKind::Type, var.def->variable_type->id)); + std::vector types = GetDeclarationsOfSymbolForGotoDefinition( + db, SymbolIdx(SymbolKind::Type, var.def->variable_type->id)); ret.insert(ret.end(), types.begin(), types.end()); } return ret; @@ -94,9 +92,8 @@ struct TextDocumentDefinitionHandler def_loc->range.Contains(target_line, target_column))) { // Goto declaration. - std::vector targets = - GetGotoDefinitionTargets(db, ref.idx); - for (QueryLocation target : targets) { + std::vector targets = GetGotoDefinitionTargets(db, ref.idx); + for (Reference target : targets) { optional ls_target = GetLsLocation(db, working_files, target); if (ls_target) diff --git a/src/messages/text_document_highlight.cc b/src/messages/text_document_highlight.cc index 515b1b72..507f2369 100644 --- a/src/messages/text_document_highlight.cc +++ b/src/messages/text_document_highlight.cc @@ -38,10 +38,10 @@ struct TextDocumentDocumentHighlightHandler for (const SymbolRef& ref : FindSymbolsAtLocation(working_file, file, request->params.position)) { // Found symbol. Return references to highlight. - std::vector uses = GetUsesOfSymbol(db, ref.idx, true); + std::vector uses = GetUsesOfSymbol(db, ref.idx, true); out.result.reserve(uses.size()); - for (const QueryLocation& use : uses) { - if (use.FileId() != file_id) + for (const Reference& use : uses) { + if (GetFileId(db, use) != file_id) continue; optional ls_location = diff --git a/src/messages/text_document_references.cc b/src/messages/text_document_references.cc index 2617a1d6..7a71debb 100644 --- a/src/messages/text_document_references.cc +++ b/src/messages/text_document_references.cc @@ -54,10 +54,10 @@ struct TextDocumentReferencesHandler for (const SymbolRef& ref : FindSymbolsAtLocation(working_file, file, request->params.position)) { // Found symbol. Return references. - std::vector uses = GetUsesOfSymbol( + std::vector uses = GetUsesOfSymbol( db, ref.idx, request->params.context.includeDeclaration); out.result.reserve(uses.size()); - for (const QueryLocation& use : uses) { + for (const Reference& use : uses) { optional ls_location = GetLsLocation(db, working_files, use); if (ls_location) diff --git a/src/messages/text_document_rename.cc b/src/messages/text_document_rename.cc index 4a789fbc..53f8c438 100644 --- a/src/messages/text_document_rename.cc +++ b/src/messages/text_document_rename.cc @@ -6,17 +6,17 @@ namespace { lsWorkspaceEdit BuildWorkspaceEdit(QueryDatabase* db, WorkingFiles* working_files, - const std::vector& locations, + const std::vector& refs, const std::string& new_text) { std::unordered_map path_to_edit; - for (auto& location : locations) { + for (auto& ref : refs) { optional ls_location = - GetLsLocation(db, working_files, location); + GetLsLocation(db, working_files, ref); if (!ls_location) continue; - QueryFileId file_id = location.FileId(); + QueryFileId file_id = GetFileId(db, ref); if (path_to_edit.find(file_id) == path_to_edit.end()) { path_to_edit[file_id] = lsTextDocumentEdit(); @@ -98,9 +98,9 @@ struct TextDocumentRenameHandler : BaseMessageHandler { for (const SymbolRef& ref : FindSymbolsAtLocation(working_file, file, request->params.position)) { // Found symbol. Return references to rename. - std::vector uses = GetUsesOfSymbol(db, ref.idx, true); - out.result = - BuildWorkspaceEdit(db, working_files, uses, request->params.newName); + out.result = BuildWorkspaceEdit(db, working_files, + GetUsesOfSymbol(db, ref.idx, true), + request->params.newName); break; } diff --git a/src/messages/workspace_symbol.cc b/src/messages/workspace_symbol.cc index d2414a01..f6dcc5a7 100644 --- a/src/messages/workspace_symbol.cc +++ b/src/messages/workspace_symbol.cc @@ -23,15 +23,17 @@ bool InsertSymbolIntoResult(QueryDatabase* db, return false; optional location = GetDefinitionExtentOfSymbol(db, symbol); - if (!location) { + Reference loc; + if (location) + loc = *location; + else { auto decls = GetDeclarationsOfSymbolForGotoDefinition(db, symbol); if (decls.empty()) return false; - location = decls[0]; + loc = decls[0]; } - optional ls_location = - GetLsLocation(db, working_files, *location); + optional ls_location = GetLsLocation(db, working_files, loc); if (!ls_location) return false; info->location = *ls_location; diff --git a/src/query.cc b/src/query.cc index bea56521..9a5e9a1f 100644 --- a/src/query.cc +++ b/src/query.cc @@ -293,8 +293,8 @@ QueryFile::DefUpdate BuildFileDefUpdate(const IdMap& id_map, const IndexFile& in add_all_symbols(id_map.ToSymbol(var.id), SymbolRole::Declaration, decl); add_outline(id_map.ToSymbol(var.id), decl); } - for (const Range& use : var.uses) - add_all_symbols(id_map.ToSymbol(var.id), SymbolRole::Reference, use); + for (auto& use : var.uses) + add_all_symbols(id_map.ToSymbol(var.id), use.role, use.range); } std::sort(def.outline.begin(), def.outline.end(), @@ -453,12 +453,12 @@ QueryVarId IdMap::ToQuery(IndexVarId id) const { QueryFuncRef IdMap::ToQuery(IndexFuncRef ref) const { return QueryFuncRef{ToQuery(ref.id), ToQuery(ref.loc, ref.role)}; } -QueryLocation IdMap::ToQuery(IndexFunc::Declaration decl) const { +Reference IdMap::ToQuery(IndexFunc::Declaration decl) const { // TODO: expose more than just QueryLocation. - return QueryLocation{decl.spelling, primary_file, SymbolRole::Declaration}; + return Reference{decl.spelling, Id(primary_file), SymbolKind::File, SymbolRole::Declaration}; } -std::vector IdMap::ToQuery(const std::vector& a) const { - std::vector ret; +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)); @@ -645,7 +645,7 @@ IndexUpdate::IndexUpdate(const IdMap& previous_id_map, } PROCESS_UPDATE_DIFF(QueryFuncId, funcs_declarations, declarations, - QueryLocation); + Reference); PROCESS_UPDATE_DIFF(QueryFuncId, funcs_derived, derived, QueryFuncId); PROCESS_UPDATE_DIFF(QueryFuncId, funcs_callers, callers, QueryFuncRef); }); @@ -697,8 +697,8 @@ IndexUpdate::IndexUpdate(const IdMap& previous_id_map, current->usr, std::move(*current_remapped_def))); PROCESS_UPDATE_DIFF(QueryVarId, vars_declarations, declarations, - QueryLocation); - PROCESS_UPDATE_DIFF(QueryVarId, vars_uses, uses, QueryLocation); + Reference); + PROCESS_UPDATE_DIFF(QueryVarId, vars_uses, uses, Reference); }); #undef PROCESS_UPDATE_DIFF @@ -1031,7 +1031,7 @@ TEST_SUITE("query") { ->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))); + ->uses.push_back(Reference{Range(Position(3, 0))}); IndexUpdate update = GetDelta(previous, current); diff --git a/src/query.h b/src/query.h index 727a181f..d584c383 100644 --- a/src/query.h +++ b/src/query.h @@ -34,6 +34,10 @@ struct QueryLocation { bool HasValue() const { return range.HasValue(); } QueryFileId FileId() const { return path; } + operator Reference() const { + return Reference{range, Id(path), SymbolKind::File, role}; + } + std::tuple ToTuple() const { return std::make_tuple(range, path, role); } @@ -246,14 +250,14 @@ struct QueryFunc { QueryFuncRef, QueryLocation>; using DefUpdate = WithUsr; - using DeclarationsUpdate = MergeableUpdate; + using DeclarationsUpdate = MergeableUpdate; using DerivedUpdate = MergeableUpdate; using CallersUpdate = MergeableUpdate; Usr usr; Maybe> symbol_idx; optional def; - std::vector declarations; + std::vector declarations; std::vector derived; std::vector callers; @@ -267,14 +271,14 @@ struct QueryVar { QueryVarId, QueryLocation>; using DefUpdate = WithUsr; - using DeclarationsUpdate = MergeableUpdate; - using UsesUpdate = MergeableUpdate; + using DeclarationsUpdate = MergeableUpdate; + using UsesUpdate = MergeableUpdate; Usr usr; Maybe> symbol_idx; optional def; - std::vector declarations; - std::vector uses; + std::vector declarations; + std::vector uses; explicit QueryVar(const Usr& usr) : usr(usr) {} }; @@ -400,9 +404,9 @@ template <> struct IndexToQuery { using type = QueryFuncId; }; template <> struct IndexToQuery { using type = QueryTypeId; }; template <> struct IndexToQuery { using type = QueryVarId; }; template <> struct IndexToQuery { using type = QueryFuncRef; }; -template <> struct IndexToQuery { using type = QueryLocation; }; +template <> struct IndexToQuery { using type = Reference; }; template <> struct IndexToQuery { using type = Reference; }; -template <> struct IndexToQuery { using type = QueryLocation; }; +template <> struct IndexToQuery { using type = Reference; }; template struct IndexToQuery> { using type = optional::type>; }; @@ -425,7 +429,7 @@ struct IdMap { QueryFuncId ToQuery(IndexFuncId id) const; QueryVarId ToQuery(IndexVarId id) const; QueryFuncRef ToQuery(IndexFuncRef ref) const; - QueryLocation ToQuery(IndexFunc::Declaration decl) const; + Reference ToQuery(IndexFunc::Declaration decl) const; template Maybe::type> ToQuery(Maybe id) const { if (!id) @@ -440,7 +444,7 @@ struct IdMap { ret.push_back(ToQuery(x)); return ret; } - std::vector ToQuery(const std::vector& a) const; + 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 0fe25733..7d79d274 100644 --- a/src/query_utils.cc +++ b/src/query_utils.cc @@ -28,36 +28,36 @@ std::vector ToQueryLocationHelper( return locs; } +} // namespace + 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; - } + 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 - optional GetDefinitionSpellingOfSymbol(QueryDatabase* db, const QueryTypeId& id) { QueryType& type = db->types[id.id]; @@ -157,7 +157,7 @@ optional GetDeclarationFileForSymbol(QueryDatabase* db, case SymbolKind::Func: { QueryFunc& func = db->funcs[symbol.idx]; if (!func.declarations.empty()) - return func.declarations[0].FileId(); + return GetFileId(db, func.declarations[0]); if (func.def && func.def->definition_spelling) return func.def->definition_spelling->FileId(); break; @@ -183,6 +183,16 @@ QueryLocation ToQueryLocation(QueryDatabase* db, Reference ref) { return QueryLocation{ref.range, GetFileId(db, ref), ref.role}; } +std::vector ToReference(QueryDatabase* db, + const std::vector& refs) { + std::vector ret; + ret.reserve(refs.size()); + for (auto& ref : refs) + ret.push_back(Reference{ref.loc.range, Id(ref.id_), SymbolKind::Func, + ref.loc.role}); + return ret; +} + std::vector ToQueryLocation( QueryDatabase* db, const std::vector& refs) { @@ -208,16 +218,13 @@ std::vector ToQueryLocation( return ToQueryLocationHelper(db, ids); } -std::vector GetUsesOfSymbol(QueryDatabase* db, - const SymbolIdx& symbol, - bool include_decl) { +std::vector GetUsesOfSymbol(QueryDatabase* db, + const SymbolIdx& symbol, + bool include_decl) { switch (symbol.kind) { case SymbolKind::Type: { QueryType& type = db->types[symbol.idx]; - std::vector ret; - ret.reserve(type.uses.size()); - for (auto& x : type.uses) - ret.push_back(ToQueryLocation(db, x)); + std::vector ret = type.uses; if (include_decl && type.def && type.def->definition_spelling) ret.push_back(*type.def->definition_spelling); return ret; @@ -225,17 +232,17 @@ std::vector GetUsesOfSymbol(QueryDatabase* db, case SymbolKind::Func: { // TODO: the vector allocation could be avoided. QueryFunc& func = db->funcs[symbol.idx]; - std::vector result = ToQueryLocation(db, func.callers); + std::vector ret = ToReference(db, func.callers); if (include_decl) { - AddRange(&result, func.declarations); + AddRange(&ret, func.declarations); if (func.def && func.def->definition_spelling) - result.push_back(*func.def->definition_spelling); + ret.push_back(*func.def->definition_spelling); } - return result; + return ret; } case SymbolKind::Var: { QueryVar& var = db->vars[symbol.idx]; - std::vector ret = var.uses; + std::vector ret = var.uses; if (include_decl) { if (var.def && var.def->definition_spelling) ret.push_back(*var.def->definition_spelling); @@ -246,15 +253,14 @@ std::vector GetUsesOfSymbol(QueryDatabase* db, case SymbolKind::File: case SymbolKind::Invalid: { assert(false && "unexpected"); - break; + return {}; } } - return {}; } -std::vector GetDeclarationsOfSymbolForGotoDefinition( +std::vector GetDeclarationsOfSymbolForGotoDefinition( QueryDatabase* db, - const SymbolIdx& symbol) { + SymbolIdx symbol) { switch (symbol.kind) { case SymbolKind::Type: { // Returning the definition spelling of a type is a hack (and is why the @@ -265,17 +271,14 @@ std::vector GetDeclarationsOfSymbolForGotoDefinition( if (type.def) { optional declaration = type.def->definition_spelling; if (declaration) - return {*declaration}; + return {Reference(*declaration)}; } break; } - case SymbolKind::Func: { - QueryFunc& func = db->funcs[symbol.idx]; - return func.declarations; - } - case SymbolKind::Var: { + case SymbolKind::Func: + return db->funcs[symbol.idx].declarations; + case SymbolKind::Var: return db->vars[symbol.idx].declarations; - } default: break; } @@ -434,11 +437,11 @@ lsDocumentUri GetLsDocumentUri(QueryDatabase* db, QueryFileId file_id) { optional GetLsLocation(QueryDatabase* db, WorkingFiles* working_files, - const QueryLocation& location) { + Reference ref) { std::string path; - lsDocumentUri uri = GetLsDocumentUri(db, location.FileId(), &path); + lsDocumentUri uri = GetLsDocumentUri(db, GetFileId(db, ref), &path); optional range = - GetLsRange(working_files->GetFileByFilename(path), location.range); + GetLsRange(working_files->GetFileByFilename(path), ref.range); if (!range) return nullopt; return lsLocation(uri, *range); diff --git a/src/query_utils.h b/src/query_utils.h index 6c2d4ad8..09a04c7d 100644 --- a/src/query_utils.h +++ b/src/query_utils.h @@ -21,6 +21,10 @@ optional GetDeclarationFileForSymbol(QueryDatabase* db, const SymbolIdx& symbol); QueryLocation ToQueryLocation(QueryDatabase* db, Reference ref); +QueryFileId GetFileId(QueryDatabase* db, Reference ref); + +std::vector ToReference(QueryDatabase* db, + const std::vector& refs); std::vector ToQueryLocation( QueryDatabase* db, const std::vector& refs); @@ -32,12 +36,12 @@ std::vector ToQueryLocation( const std::vector& refs); std::vector ToQueryLocation(QueryDatabase* db, const std::vector& ids); -std::vector GetUsesOfSymbol(QueryDatabase* db, - const SymbolIdx& symbol, - bool include_decl); -std::vector GetDeclarationsOfSymbolForGotoDefinition( +std::vector GetUsesOfSymbol(QueryDatabase* db, + const SymbolIdx& symbol, + bool include_decl); +std::vector GetDeclarationsOfSymbolForGotoDefinition( QueryDatabase* db, - const SymbolIdx& symbol); + SymbolIdx symbol); bool HasCallersOnSelfOrBaseOrDerived(QueryDatabase* db, QueryFunc& root); std::vector GetCallersForAllBaseFunctions(QueryDatabase* db, @@ -51,9 +55,10 @@ lsDocumentUri GetLsDocumentUri(QueryDatabase* db, QueryFileId file_id, std::string* path); lsDocumentUri GetLsDocumentUri(QueryDatabase* db, QueryFileId file_id); + optional GetLsLocation(QueryDatabase* db, WorkingFiles* working_files, - const QueryLocation& location); + Reference location); std::vector GetLsLocations( QueryDatabase* db, WorkingFiles* working_files,