From 50cf05763b82c2b6d462bf8c10d6f1546a59ba90 Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Fri, 9 Feb 2018 17:30:22 -0800 Subject: [PATCH] Query* structs: QueryLocation -> Reference --- src/messages/text_document_code_action.cc | 14 ++++--- src/messages/text_document_code_lens.cc | 42 ++++++++----------- src/messages/text_document_definition.cc | 6 +-- src/messages/workspace_symbol.cc | 2 +- src/query.cc | 38 ++++-------------- src/query.h | 49 +++++++++++++++++++++-- src/query_utils.cc | 49 +++++++++++------------ src/query_utils.h | 22 +++++----- 8 files changed, 114 insertions(+), 108 deletions(-) diff --git a/src/messages/text_document_code_action.cc b/src/messages/text_document_code_action.cc index 71ca3158..589ae3d9 100644 --- a/src/messages/text_document_code_action.cc +++ b/src/messages/text_document_code_action.cc @@ -72,9 +72,10 @@ optional GetImplementationFile(QueryDatabase* db, QueryFunc& func = sym.Func(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->FileId() != file_id) { - return func.def->definition_extent->FileId(); + if (func.def && func.def->definition_extent) { + QueryFileId t = GetFileId(db, *func.def->definition_extent); + if (t != file_id) + return t; } break; } @@ -82,9 +83,10 @@ optional GetImplementationFile(QueryDatabase* db, QueryVar& var = sym.Var(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->FileId() != file_id) { - return var.def->definition_extent->FileId(); + if (var.def && var.def->definition_extent) { + QueryFileId t = GetFileId(db, *var.def->definition_extent); + if (t != file_id) + return t; } break; } diff --git a/src/messages/text_document_code_lens.cc b/src/messages/text_document_code_lens.cc index bbfc2b96..6a577bb6 100644 --- a/src/messages/text_document_code_lens.cc +++ b/src/messages/text_document_code_lens.cc @@ -82,7 +82,6 @@ void AddCodeLens(const char* singular, CommonCodeLensParams* common, QueryLocation loc, const std::vector& uses, - optional excluded, bool force_display) { TCodeLens code_lens; optional range = GetLsRange(common->working_file, loc.range); @@ -97,8 +96,6 @@ void AddCodeLens(const char* singular, // Add unique uses. std::unordered_set unique_uses; for (const Reference& use : uses) { - if (excluded && Reference(*excluded) == use) - continue; optional location = GetLsLocation(common->db, common->working_files, use); if (!location) @@ -155,14 +152,12 @@ struct TextDocumentCodeLensHandler if (type.def->kind == ClangSymbolKind::Namespace) continue; AddCodeLens("ref", "refs", &common, sym.OffsetStartColumn(db, 0), - type.uses, type.def->definition_spelling, - true /*force_display*/); - AddCodeLens( - "derived", "derived", &common, sym.OffsetStartColumn(db, 1), - ToReference(db, type.derived), nullopt, false /*force_display*/); + type.uses, true /*force_display*/); + AddCodeLens("derived", "derived", &common, + sym.OffsetStartColumn(db, 1), + ToReference(db, type.derived), false /*force_display*/); AddCodeLens("var", "vars", &common, sym.OffsetStartColumn(db, 2), - ToReference(db, type.instances), nullopt, - false /*force_display*/); + ToReference(db, type.instances), false /*force_display*/); break; } case SymbolKind::Func: { @@ -176,14 +171,13 @@ struct TextDocumentCodeLensHandler // extent since that is better for outline. This tries to convert the // extent location to the spelling location. auto try_ensure_spelling = [&](SymbolRef sym) { - optional def = + optional def = GetDefinitionSpellingOfSymbol(db, sym); - if (!def || def->FileId() != GetFileId(db, sym) || + if (!def || db->GetFileId(*def) != db->GetFileId(sym) || def->range.start.line != sym.range.start.line) { return sym; } - return SymbolRef(def->range, Id(def->FileId()), - SymbolKind::File, SymbolRole::None); + return SymbolRef(*def); }; std::vector base_callers = @@ -194,35 +188,31 @@ struct TextDocumentCodeLensHandler SymbolRef loc = try_ensure_spelling(sym); AddCodeLens("call", "calls", &common, loc.OffsetStartColumn(db, offset++), - ToReference(db, func.callers), nullopt, - true /*force_display*/); + ToReference(db, func.callers), true /*force_display*/); } else { SymbolRef loc = try_ensure_spelling(sym); AddCodeLens("direct call", "direct calls", &common, loc.OffsetStartColumn(db, offset++), - ToReference(db, func.callers), nullopt, - false /*force_display*/); + ToReference(db, func.callers), false /*force_display*/); if (!base_callers.empty()) AddCodeLens("base call", "base calls", &common, loc.OffsetStartColumn(db, offset++), - ToReference(db, base_callers), nullopt, + ToReference(db, base_callers), false /*force_display*/); if (!derived_callers.empty()) AddCodeLens("derived call", "derived calls", &common, loc.OffsetStartColumn(db, offset++), - ToReference(db, derived_callers), nullopt, + ToReference(db, derived_callers), false /*force_display*/); } AddCodeLens("derived", "derived", &common, sym.OffsetStartColumn(db, offset++), - ToReference(db, func.derived), nullopt, - false /*force_display*/); + ToReference(db, func.derived), false /*force_display*/); // "Base" if (func.def->base.size() == 1) { - // FIXME WithGen - optional base_loc = + optional base_loc = GetDefinitionSpellingOfSymbol(db, func.def->base[0]); if (base_loc) { optional ls_base = @@ -245,7 +235,7 @@ struct TextDocumentCodeLensHandler } } else { AddCodeLens("base", "base", &common, sym.OffsetStartColumn(db, 1), - ToReference(db, func.def->base), nullopt, + ToReference(db, func.def->base), false /*force_display*/); } @@ -266,7 +256,7 @@ struct TextDocumentCodeLensHandler force_display = false; AddCodeLens("ref", "refs", &common, sym.OffsetStartColumn(db, 0), - var.uses, var.def->definition_spelling, force_display); + var.uses, force_display); break; } case SymbolKind::File: diff --git a/src/messages/text_document_definition.cc b/src/messages/text_document_definition.cc index 9e05ed2f..aeea04e1 100644 --- a/src/messages/text_document_definition.cc +++ b/src/messages/text_document_definition.cc @@ -74,12 +74,12 @@ struct TextDocumentDefinitionHandler // - start at spelling but end at extent for better mouse tooltip // - goto declaration while in definition of recursive type - optional def_loc = GetDefinitionSpellingOfSymbol(db, sym); + optional def_loc = GetDefinitionSpellingOfSymbol(db, sym); // We use spelling start and extent end because this causes vscode to // highlight the entire definition when previewing / hoving with the // mouse. - optional def_extent = GetDefinitionExtentOfSymbol(db, sym); + optional def_extent = GetDefinitionExtentOfSymbol(db, sym); if (def_loc && def_extent) def_loc->range.end = def_extent->range.end; @@ -87,7 +87,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->FileId() == file_id && + if (!def_loc || (db->GetFileId(*def_loc) == file_id && def_loc->range.Contains(target_line, target_column))) { // Goto declaration. diff --git a/src/messages/workspace_symbol.cc b/src/messages/workspace_symbol.cc index f6dcc5a7..a814de8b 100644 --- a/src/messages/workspace_symbol.cc +++ b/src/messages/workspace_symbol.cc @@ -22,7 +22,7 @@ bool InsertSymbolIntoResult(QueryDatabase* db, if (!info) return false; - optional location = GetDefinitionExtentOfSymbol(db, symbol); + optional location = GetDefinitionExtentOfSymbol(db, symbol); Reference loc; if (location) loc = *location; diff --git a/src/query.cc b/src/query.cc index e204fb1c..0ff0b8fa 100644 --- a/src/query.cc +++ b/src/query.cc @@ -97,11 +97,10 @@ optional ToQuery(const IdMap& id_map, const IndexVar::Def& var) { result.file = id_map.primary_file; if (var.definition_spelling) result.definition_spelling = - QueryLocation{*var.definition_spelling, id_map.primary_file, - SymbolRole::Definition}; + id_map.ToQuery(*var.definition_spelling, SymbolRole::Definition); if (var.definition_extent) - result.definition_extent = QueryLocation{ - *var.definition_extent, id_map.primary_file, SymbolRole::None}; + result.definition_extent = + id_map.ToQuery(*var.definition_extent, SymbolRole::None); result.variable_type = id_map.ToQuery(var.variable_type); if (result.parent_id) switch (var.parent_kind) { @@ -394,32 +393,9 @@ Maybe GetQueryVarIdFromUsr(QueryDatabase* query_db, } // namespace +// FIXME Reference Remove QueryFileId GetFileId(QueryDatabase* db, Reference ref) { - switch (ref.kind) { - case SymbolKind::Invalid: - break; - case SymbolKind::File: - return QueryFileId(ref.id); - case SymbolKind::Func: { - QueryFunc& file = db->funcs[ref.id.id]; - if (file.def) - return file.def->file; - break; - } - case SymbolKind::Type: { - QueryType& type = db->types[ref.id.id]; - if (type.def) - return type.def->file; - break; - } - case SymbolKind::Var: { - QueryVar& var = db->vars[ref.id.id]; - if (var.def) - return var.def->file; - break; - } - } - return QueryFileId(); + return db->GetFileId(ref); } QueryFunc& SymbolRef::Func(QueryDatabase* db) const { @@ -471,8 +447,8 @@ IdMap::IdMap(QueryDatabase* query_db, const IdCache& local_ids) *GetQueryVarIdFromUsr(query_db, entry.second, true); } -QueryLocation IdMap::ToQuery(Range range, SymbolRole role) const { - return QueryLocation{range, primary_file, role}; +Reference IdMap::ToQuery(Range range, SymbolRole role) const { + return Reference{range, Id(primary_file), SymbolKind:: File, role}; } Reference IdMap::ToQuery(Reference ref) const { switch (ref.kind) { diff --git a/src/query.h b/src/query.h index 5d38f213..46862f51 100644 --- a/src/query.h +++ b/src/query.h @@ -69,6 +69,7 @@ struct SymbolRef : Reference { SymbolRef() = default; SymbolRef(Range range, Id id, SymbolKind kind, SymbolRole role) : Reference{range, id, kind, role} {} + SymbolRef(Reference ref) : Reference{ref} {} SymbolRef(SymbolIdx si) : Reference{Range(), Id(si.idx), si.kind, SymbolRole::None} {} @@ -202,7 +203,7 @@ struct QueryType { QueryTypeId, QueryFuncId, QueryVarId, - QueryLocation>; + Reference>; using DefUpdate = WithUsr; using DerivedUpdate = MergeableUpdate; using InstancesUpdate = MergeableUpdate; @@ -224,7 +225,7 @@ struct QueryFunc { QueryFuncId, QueryVarId, QueryFuncRef, - QueryLocation>; + Reference>; using DefUpdate = WithUsr; using DeclarationsUpdate = MergeableUpdate; using DerivedUpdate = MergeableUpdate; @@ -245,7 +246,7 @@ struct QueryVar { QueryTypeId, QueryFuncId, QueryVarId, - QueryLocation>; + Reference>; using DefUpdate = WithUsr; using DeclarationsUpdate = MergeableUpdate; using UsesUpdate = MergeableUpdate; @@ -369,6 +370,46 @@ struct QueryDatabase { Maybe GetQueryTypeIdFromUsr(Usr usr); Maybe GetQueryFuncIdFromUsr(Usr usr); Maybe GetQueryVarIdFromUsr(Usr usr); + + QueryFileId GetFileId(Reference ref) { + switch (ref.kind) { + case SymbolKind::Invalid: + break; + case SymbolKind::File: + return QueryFileId(ref.id); + case SymbolKind::Func: { + QueryFunc& file = funcs[ref.id.id]; + if (file.def) + return file.def->file; + break; + } + case SymbolKind::Type: { + QueryType& type = types[ref.id.id]; + if (type.def) + return type.def->file; + break; + } + case SymbolKind::Var: { + QueryVar& var = vars[ref.id.id]; + if (var.def) + return var.def->file; + break; + } + } + return QueryFileId(); + } + QueryFile& GetFile(Reference ref) { + return files[ref.id.id]; + } + QueryFunc& GetFunc(Reference ref) { + return funcs[ref.id.id]; + } + QueryType& GetType(Reference ref) { + return types[ref.id.id]; + } + QueryVar& GetVar(Reference ref) { + return vars[ref.id.id]; + } }; template @@ -399,7 +440,7 @@ struct IdMap { // FIXME Too verbose // clang-format off - QueryLocation ToQuery(Range range, SymbolRole role) const; + Reference ToQuery(Range range, SymbolRole role) const; Reference ToQuery(Reference ref) const; QueryTypeId ToQuery(IndexTypeId id) const; QueryFuncId ToQuery(IndexFuncId id) const; diff --git a/src/query_utils.cc b/src/query_utils.cc index aee21339..c9611c49 100644 --- a/src/query_utils.cc +++ b/src/query_utils.cc @@ -18,32 +18,32 @@ int ComputeRangeSize(const Range& range) { } // namespace -optional GetDefinitionSpellingOfSymbol(QueryDatabase* db, - const QueryTypeId& id) { +optional GetDefinitionSpellingOfSymbol(QueryDatabase* db, + const QueryTypeId& id) { QueryType& type = db->types[id.id]; if (type.def) return type.def->definition_spelling; return nullopt; } -optional GetDefinitionSpellingOfSymbol(QueryDatabase* db, - const QueryFuncId& id) { +optional GetDefinitionSpellingOfSymbol(QueryDatabase* db, + const QueryFuncId& id) { QueryFunc& func = db->funcs[id.id]; if (func.def) return func.def->definition_spelling; return nullopt; } -optional GetDefinitionSpellingOfSymbol(QueryDatabase* db, - const QueryVarId& id) { +optional GetDefinitionSpellingOfSymbol(QueryDatabase* db, + const QueryVarId& id) { QueryVar& var = db->vars[id.id]; if (var.def) return var.def->definition_spelling; return nullopt; } -optional GetDefinitionSpellingOfSymbol(QueryDatabase* db, - SymbolRef sym) { +optional GetDefinitionSpellingOfSymbol(QueryDatabase* db, + SymbolRef sym) { switch (sym.kind) { case SymbolKind::Type: { QueryType& type = sym.Type(db); @@ -72,8 +72,8 @@ optional GetDefinitionSpellingOfSymbol(QueryDatabase* db, return nullopt; } -optional GetDefinitionExtentOfSymbol(QueryDatabase* db, - SymbolRef sym) { +optional GetDefinitionExtentOfSymbol(QueryDatabase* db, + SymbolRef sym) { switch (sym.kind) { case SymbolKind::Type: { QueryType& type = sym.Type(db); @@ -93,10 +93,8 @@ optional GetDefinitionExtentOfSymbol(QueryDatabase* db, return var.def->definition_extent; break; } - case SymbolKind::File: { - return QueryLocation{Range(Position(0, 0), Position(0, 0)), - QueryFileId(sym.Idx()), SymbolRole::None}; - } + case SymbolKind::File: + return sym; case SymbolKind::Invalid: { assert(false && "unexpected"); break; @@ -111,26 +109,25 @@ optional GetDeclarationFileForSymbol(QueryDatabase* db, case SymbolKind::Type: { QueryType& type = sym.Type(db); if (type.def && type.def->definition_spelling) - return type.def->definition_spelling->FileId(); + return db->GetFileId(*type.def->definition_spelling); break; } case SymbolKind::Func: { QueryFunc& func = sym.Func(db); if (!func.declarations.empty()) - return GetFileId(db, func.declarations[0]); + return db->GetFileId(func.declarations[0]); if (func.def && func.def->definition_spelling) - return func.def->definition_spelling->FileId(); + return db->GetFileId(*func.def->definition_spelling); break; } case SymbolKind::Var: { QueryVar& var = sym.Var(db); if (var.def && var.def->definition_spelling) - return var.def->definition_spelling->FileId(); + return db->GetFileId(*var.def->definition_spelling); break; } - case SymbolKind::File: { + case SymbolKind::File: return QueryFileId(sym.Idx()); - } case SymbolKind::Invalid: { assert(false && "unexpected"); break; @@ -197,18 +194,18 @@ std::vector GetDeclarationsOfSymbolForGotoDefinition( // function has the postfix `ForGotoDefintion`, but it lets the user // jump to the start of a type if clicking goto-definition on the same // type from within the type definition. - QueryType& type = sym.Type(db); + QueryType& type = db->GetType(sym); if (type.def) { - optional declaration = type.def->definition_spelling; - if (declaration) - return {Reference(*declaration)}; + Maybe def = type.def->definition_spelling; + if (def) + return {*def}; } break; } case SymbolKind::Func: - return sym.Func(db).declarations; + return db->GetFunc(sym).declarations; case SymbolKind::Var: - return sym.Var(db).declarations; + return db->GetVar(sym).declarations; default: break; } diff --git a/src/query_utils.h b/src/query_utils.h index bb0752f3..b0994fe8 100644 --- a/src/query_utils.h +++ b/src/query_utils.h @@ -7,16 +7,16 @@ #include -optional GetDefinitionSpellingOfSymbol(QueryDatabase* db, - const QueryTypeId& id); -optional GetDefinitionSpellingOfSymbol(QueryDatabase* db, - const QueryFuncId& id); -optional GetDefinitionSpellingOfSymbol(QueryDatabase* db, - const QueryVarId& id); -optional GetDefinitionSpellingOfSymbol(QueryDatabase* db, - SymbolRef sym); -optional GetDefinitionExtentOfSymbol(QueryDatabase* db, - SymbolRef sym); +optional GetDefinitionSpellingOfSymbol(QueryDatabase* db, + const QueryTypeId& id); +optional GetDefinitionSpellingOfSymbol(QueryDatabase* db, + const QueryFuncId& id); +optional GetDefinitionSpellingOfSymbol(QueryDatabase* db, + const QueryVarId& id); +optional GetDefinitionSpellingOfSymbol(QueryDatabase* db, + SymbolRef sym); +optional GetDefinitionExtentOfSymbol(QueryDatabase* db, + SymbolRef sym); optional GetDeclarationFileForSymbol(QueryDatabase* db, SymbolRef sym); @@ -29,7 +29,7 @@ std::vector ToReference(QueryDatabase* db, std::vector ret; ret.reserve(ids.size()); for (auto id : ids) { - optional loc = GetDefinitionSpellingOfSymbol(db, id); + optional loc = GetDefinitionSpellingOfSymbol(db, id); if (loc) ret.push_back(*loc); }