mirror of
https://github.com/MaskRay/ccls.git
synced 2025-01-19 12:05:50 +00:00
Make goto declaration work from on a recursively defined type when used inside the type definition
This commit is contained in:
parent
c9a251b7ab
commit
91febd7343
@ -161,8 +161,18 @@ optional<QueryableLocation> GetDefinitionExtentOfSymbol(QueryableDatabase* db, c
|
|||||||
return nullopt;
|
return nullopt;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<QueryableLocation> GetDeclarationsOfSymbol(QueryableDatabase* db, const SymbolIdx& symbol) {
|
std::vector<QueryableLocation> GetDeclarationsOfSymbolForGotoDefinition(QueryableDatabase* db, const SymbolIdx& symbol) {
|
||||||
switch (symbol.kind) {
|
switch (symbol.kind) {
|
||||||
|
case SymbolKind::Type: {
|
||||||
|
// Returning the definition spelling of a type is a hack (and is why the
|
||||||
|
// 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.
|
||||||
|
optional<QueryableLocation> declaration = db->types[symbol.idx].def.definition_spelling;
|
||||||
|
if (declaration)
|
||||||
|
return { *declaration };
|
||||||
|
break;
|
||||||
|
}
|
||||||
case SymbolKind::Func:
|
case SymbolKind::Func:
|
||||||
return db->funcs[symbol.idx].declarations;
|
return db->funcs[symbol.idx].declarations;
|
||||||
case SymbolKind::Var: {
|
case SymbolKind::Var: {
|
||||||
@ -781,38 +791,42 @@ void QueryDbMainLoop(
|
|||||||
for (const SymbolRef& ref : file->def.all_symbols) {
|
for (const SymbolRef& ref : file->def.all_symbols) {
|
||||||
if (ref.loc.range.Contains(target_line, target_column)) {
|
if (ref.loc.range.Contains(target_line, target_column)) {
|
||||||
// Found symbol. Return definition.
|
// Found symbol. Return definition.
|
||||||
|
|
||||||
|
|
||||||
optional<QueryableLocation> definition_spelling = GetDefinitionSpellingOfSymbol(db, ref.idx);
|
optional<QueryableLocation> definition_spelling = GetDefinitionSpellingOfSymbol(db, ref.idx);
|
||||||
if (definition_spelling) {
|
if (!definition_spelling)
|
||||||
|
break;
|
||||||
|
|
||||||
// If the cursor is currently at the definition we should goto the declaration if possible.
|
// We use spelling start and extent end because this causes vscode
|
||||||
if (definition_spelling->path == file_id && definition_spelling->range.Contains(target_line, target_column)) {
|
// to highlight the entire definition when previewing / hoving with
|
||||||
// Goto declaration.
|
// the mouse.
|
||||||
|
optional<QueryableLocation> extent = GetDefinitionExtentOfSymbol(db, ref.idx);
|
||||||
|
if (extent)
|
||||||
|
definition_spelling->range.end = extent->range.end;
|
||||||
|
|
||||||
std::vector<QueryableLocation> declarations = GetDeclarationsOfSymbol(db, ref.idx);
|
|
||||||
for (auto declaration : declarations) {
|
|
||||||
optional<lsLocation> ls_declaration = GetLsLocation(db, working_files, declaration);
|
|
||||||
if (ls_declaration)
|
|
||||||
response.result.push_back(*ls_declaration);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!response.result.empty())
|
// If the cursor is currently at or in the definition we should goto the declaration if possible.
|
||||||
break;
|
if (definition_spelling->path == file_id && definition_spelling->range.Contains(target_line, target_column)) {
|
||||||
|
// Goto declaration.
|
||||||
|
|
||||||
|
std::vector<QueryableLocation> declarations = GetDeclarationsOfSymbolForGotoDefinition(db, ref.idx);
|
||||||
|
for (auto declaration : declarations) {
|
||||||
|
optional<lsLocation> ls_declaration = GetLsLocation(db, working_files, declaration);
|
||||||
|
if (ls_declaration)
|
||||||
|
response.result.push_back(*ls_declaration);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!response.result.empty())
|
||||||
// Goto definition.
|
break;
|
||||||
|
|
||||||
// We use spelling start and extent end because this causes vscode
|
|
||||||
// to highlight the entire definition when previewing / hoving with
|
|
||||||
// the mouse.
|
|
||||||
optional<QueryableLocation> extent = GetDefinitionExtentOfSymbol(db, ref.idx);
|
|
||||||
if (extent)
|
|
||||||
definition_spelling->range.end = extent->range.end;
|
|
||||||
|
|
||||||
optional<lsLocation> ls_location = GetLsLocation(db, working_files, definition_spelling.value());
|
|
||||||
if (ls_location)
|
|
||||||
response.result.push_back(*ls_location);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Goto definition.
|
||||||
|
|
||||||
|
|
||||||
|
optional<lsLocation> ls_location = GetLsLocation(db, working_files, definition_spelling.value());
|
||||||
|
if (ls_location)
|
||||||
|
response.result.push_back(*ls_location);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user