mirror of
https://github.com/MaskRay/ccls.git
synced 2024-11-22 23:55:08 +00:00
Refactor out FindSymbolsAtLocation
This commit is contained in:
parent
c946fd1b8e
commit
1791f4c3b7
@ -468,6 +468,20 @@ lsWorkspaceEdit BuildWorkspaceEdit(QueryableDatabase* db, WorkingFiles* working_
|
|||||||
return edit;
|
return edit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::vector<SymbolRef> FindSymbolsAtLocation(QueryableFile* file, lsPosition position) {
|
||||||
|
std::vector<SymbolRef> symbols;
|
||||||
|
symbols.reserve(1);
|
||||||
|
|
||||||
|
int target_line = position.line + 1;
|
||||||
|
int target_column = position.character + 1;
|
||||||
|
for (const SymbolRef& ref : file->def.all_symbols) {
|
||||||
|
if (ref.loc.range.Contains(target_line, target_column))
|
||||||
|
symbols.push_back(ref);
|
||||||
|
}
|
||||||
|
|
||||||
|
return symbols;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
|
|
||||||
@ -489,6 +503,34 @@ lsWorkspaceEdit BuildWorkspaceEdit(QueryableDatabase* db, WorkingFiles* working_
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -889,18 +931,11 @@ void QueryDbMainLoop(
|
|||||||
Out_TextDocumentRename response;
|
Out_TextDocumentRename response;
|
||||||
response.id = msg->id;
|
response.id = msg->id;
|
||||||
|
|
||||||
// TODO: consider refactoring into FindSymbolsAtLocation(file);
|
for (const SymbolRef& ref : FindSymbolsAtLocation(file, msg->params.position)) {
|
||||||
int target_line = msg->params.position.line + 1;
|
// Found symbol. Return references to rename.
|
||||||
int target_column = msg->params.position.character + 1;
|
std::vector<QueryableLocation> uses = GetUsesOfSymbol(db, ref.idx);
|
||||||
for (const SymbolRef& ref : file->def.all_symbols) {
|
response.result = BuildWorkspaceEdit(db, working_files, uses, msg->params.newName);
|
||||||
if (ref.loc.range.start.line >= target_line && ref.loc.range.end.line <= target_line &&
|
break;
|
||||||
ref.loc.range.start.column <= target_column && ref.loc.range.end.column >= target_column) {
|
|
||||||
|
|
||||||
// Found symbol. Return references to rename.
|
|
||||||
std::vector<QueryableLocation> uses = GetUsesOfSymbol(db, ref.idx);
|
|
||||||
response.result = BuildWorkspaceEdit(db, working_files, uses, msg->params.newName);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
response.Write(std::cerr);
|
response.Write(std::cerr);
|
||||||
@ -939,49 +974,47 @@ void QueryDbMainLoop(
|
|||||||
int target_line = msg->params.position.line + 1;
|
int target_line = msg->params.position.line + 1;
|
||||||
int target_column = msg->params.position.character + 1;
|
int target_column = msg->params.position.character + 1;
|
||||||
|
|
||||||
for (const SymbolRef& ref : file->def.all_symbols) {
|
for (const SymbolRef& ref : FindSymbolsAtLocation(file, msg->params.position)) {
|
||||||
if (ref.loc.range.Contains(target_line, target_column)) {
|
// Found symbol. Return definition.
|
||||||
// Found symbol. Return definition.
|
|
||||||
|
|
||||||
// Special cases which are handled:
|
// Special cases which are handled:
|
||||||
// - symbol has declaration but no definition (ie, pure virtual)
|
// - symbol has declaration but no definition (ie, pure virtual)
|
||||||
// - start at spelling but end at extent for better mouse tooltip
|
// - start at spelling but end at extent for better mouse tooltip
|
||||||
// - goto declaration while in definition of recursive type
|
// - goto declaration while in definition of recursive type
|
||||||
|
|
||||||
optional<QueryableLocation> def_loc = GetDefinitionSpellingOfSymbol(db, ref.idx);
|
optional<QueryableLocation> def_loc = GetDefinitionSpellingOfSymbol(db, ref.idx);
|
||||||
|
|
||||||
// We use spelling start and extent end because this causes vscode to
|
// We use spelling start and extent end because this causes vscode to
|
||||||
// highlight the entire definition when previewing / hoving with the
|
// highlight the entire definition when previewing / hoving with the
|
||||||
// mouse.
|
// mouse.
|
||||||
optional<QueryableLocation> def_extent = GetDefinitionExtentOfSymbol(db, ref.idx);
|
optional<QueryableLocation> def_extent = GetDefinitionExtentOfSymbol(db, ref.idx);
|
||||||
if (def_loc && def_extent)
|
if (def_loc && def_extent)
|
||||||
def_loc->range.end = def_extent->range.end;
|
def_loc->range.end = def_extent->range.end;
|
||||||
|
|
||||||
// If the cursor is currently at or in the definition we should goto
|
// If the cursor is currently at or in the definition we should goto
|
||||||
// the declaration if possible. We also want to use declarations if
|
// the declaration if possible. We also want to use declarations if
|
||||||
// we're pointing to, ie, a pure virtual function which has no
|
// we're pointing to, ie, a pure virtual function which has no
|
||||||
// definition.
|
// definition.
|
||||||
if (!def_loc || (def_loc->path == file_id &&
|
if (!def_loc || (def_loc->path == file_id &&
|
||||||
def_loc->range.Contains(target_line, target_column))) {
|
def_loc->range.Contains(target_line, target_column))) {
|
||||||
// Goto declaration.
|
// Goto declaration.
|
||||||
|
|
||||||
std::vector<QueryableLocation> declarations = GetDeclarationsOfSymbolForGotoDefinition(db, ref.idx);
|
std::vector<QueryableLocation> declarations = GetDeclarationsOfSymbolForGotoDefinition(db, ref.idx);
|
||||||
for (auto declaration : declarations) {
|
for (auto declaration : declarations) {
|
||||||
optional<lsLocation> ls_declaration = GetLsLocation(db, working_files, declaration);
|
optional<lsLocation> ls_declaration = GetLsLocation(db, working_files, declaration);
|
||||||
if (ls_declaration)
|
if (ls_declaration)
|
||||||
response.result.push_back(*ls_declaration);
|
response.result.push_back(*ls_declaration);
|
||||||
}
|
|
||||||
// We found some declarations. Break so we don't add the definition location.
|
|
||||||
if (!response.result.empty())
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
// We found some declarations. Break so we don't add the definition location.
|
||||||
if (def_loc)
|
|
||||||
PushBack(&response.result, GetLsLocation(db, working_files, *def_loc));
|
|
||||||
|
|
||||||
if (!response.result.empty())
|
if (!response.result.empty())
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (def_loc)
|
||||||
|
PushBack(&response.result, GetLsLocation(db, working_files, *def_loc));
|
||||||
|
|
||||||
|
if (!response.result.empty())
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
SendOutMessageToClient(language_client, response);
|
SendOutMessageToClient(language_client, response);
|
||||||
@ -1000,31 +1033,24 @@ void QueryDbMainLoop(
|
|||||||
Out_TextDocumentDocumentHighlight response;
|
Out_TextDocumentDocumentHighlight response;
|
||||||
response.id = msg->id;
|
response.id = msg->id;
|
||||||
|
|
||||||
// TODO: consider refactoring into FindSymbolsAtLocation(file);
|
for (const SymbolRef& ref : FindSymbolsAtLocation(file, msg->params.position)) {
|
||||||
int target_line = msg->params.position.line + 1;
|
// Found symbol. Return references to highlight.
|
||||||
int target_column = msg->params.position.character + 1;
|
std::vector<QueryableLocation> uses = GetUsesOfSymbol(db, ref.idx);
|
||||||
for (const SymbolRef& ref : file->def.all_symbols) {
|
response.result.reserve(uses.size());
|
||||||
if (ref.loc.range.start.line >= target_line && ref.loc.range.end.line <= target_line &&
|
for (const QueryableLocation& use : uses) {
|
||||||
ref.loc.range.start.column <= target_column && ref.loc.range.end.column >= target_column) {
|
if (use.path != file_id)
|
||||||
|
continue;
|
||||||
|
|
||||||
// Found symbol. Return references to highlight.
|
optional<lsLocation> ls_location = GetLsLocation(db, working_files, use);
|
||||||
std::vector<QueryableLocation> uses = GetUsesOfSymbol(db, ref.idx);
|
if (!ls_location)
|
||||||
response.result.reserve(uses.size());
|
continue;
|
||||||
for (const QueryableLocation& use : uses) {
|
|
||||||
if (use.path != file_id)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
optional<lsLocation> ls_location = GetLsLocation(db, working_files, use);
|
lsDocumentHighlight highlight;
|
||||||
if (!ls_location)
|
highlight.kind = lsDocumentHighlightKind::Text;
|
||||||
continue;
|
highlight.range = ls_location->range;
|
||||||
|
response.result.push_back(highlight);
|
||||||
lsDocumentHighlight highlight;
|
|
||||||
highlight.kind = lsDocumentHighlightKind::Text;
|
|
||||||
highlight.range = ls_location->range;
|
|
||||||
response.result.push_back(highlight);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
SendOutMessageToClient(language_client, response);
|
SendOutMessageToClient(language_client, response);
|
||||||
@ -1042,22 +1068,15 @@ void QueryDbMainLoop(
|
|||||||
Out_TextDocumentHover response;
|
Out_TextDocumentHover response;
|
||||||
response.id = msg->id;
|
response.id = msg->id;
|
||||||
|
|
||||||
// TODO: consider refactoring into FindSymbolsAtLocation(file);
|
for (const SymbolRef& ref : FindSymbolsAtLocation(file, msg->params.position)) {
|
||||||
int target_line = msg->params.position.line + 1;
|
// Found symbol. Return hover.
|
||||||
int target_column = msg->params.position.character + 1;
|
optional<lsRange> ls_range = GetLsRange(working_files->GetFileByFilename(file->def.usr), ref.loc.range);
|
||||||
for (const SymbolRef& ref : file->def.all_symbols) {
|
if (!ls_range)
|
||||||
if (ref.loc.range.start.line >= target_line && ref.loc.range.end.line <= target_line &&
|
continue;
|
||||||
ref.loc.range.start.column <= target_column && ref.loc.range.end.column >= target_column) {
|
|
||||||
|
|
||||||
// Found symbol. Return hover.
|
response.result.contents = GetHoverForSymbol(db, ref.idx);
|
||||||
optional<lsRange> ls_range = GetLsRange(working_files->GetFileByFilename(file->def.usr), ref.loc.range);
|
response.result.range = *ls_range;
|
||||||
if (!ls_range)
|
break;
|
||||||
continue;
|
|
||||||
|
|
||||||
response.result.contents = GetHoverForSymbol(db, ref.idx);
|
|
||||||
response.result.range = *ls_range;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SendOutMessageToClient(language_client, response);
|
SendOutMessageToClient(language_client, response);
|
||||||
@ -1076,32 +1095,25 @@ void QueryDbMainLoop(
|
|||||||
Out_TextDocumentReferences response;
|
Out_TextDocumentReferences response;
|
||||||
response.id = msg->id;
|
response.id = msg->id;
|
||||||
|
|
||||||
// TODO: consider refactoring into FindSymbolsAtLocation(file);
|
for (const SymbolRef& ref : FindSymbolsAtLocation(file, msg->params.position)) {
|
||||||
int target_line = msg->params.position.line + 1;
|
optional<QueryableLocation> excluded_declaration;
|
||||||
int target_column = msg->params.position.character + 1;
|
if (!msg->params.context.includeDeclaration) {
|
||||||
for (const SymbolRef& ref : file->def.all_symbols) {
|
std::cerr << "Excluding declaration in references" << std::endl;
|
||||||
if (ref.loc.range.start.line >= target_line && ref.loc.range.end.line <= target_line &&
|
excluded_declaration = GetDefinitionSpellingOfSymbol(db, ref.idx);
|
||||||
ref.loc.range.start.column <= target_column && ref.loc.range.end.column >= target_column) {
|
|
||||||
|
|
||||||
optional<QueryableLocation> excluded_declaration;
|
|
||||||
if (!msg->params.context.includeDeclaration) {
|
|
||||||
std::cerr << "Excluding declaration in references" << std::endl;
|
|
||||||
excluded_declaration = GetDefinitionSpellingOfSymbol(db, ref.idx);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Found symbol. Return references.
|
|
||||||
std::vector<QueryableLocation> uses = GetUsesOfSymbol(db, ref.idx);
|
|
||||||
response.result.reserve(uses.size());
|
|
||||||
for (const QueryableLocation& use : uses) {
|
|
||||||
if (excluded_declaration.has_value() && use == *excluded_declaration)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
optional<lsLocation> ls_location = GetLsLocation(db, working_files, use);
|
|
||||||
if (ls_location)
|
|
||||||
response.result.push_back(*ls_location);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Found symbol. Return references.
|
||||||
|
std::vector<QueryableLocation> uses = GetUsesOfSymbol(db, ref.idx);
|
||||||
|
response.result.reserve(uses.size());
|
||||||
|
for (const QueryableLocation& use : uses) {
|
||||||
|
if (excluded_declaration.has_value() && use == *excluded_declaration)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
optional<lsLocation> ls_location = GetLsLocation(db, working_files, use);
|
||||||
|
if (ls_location)
|
||||||
|
response.result.push_back(*ls_location);
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
SendOutMessageToClient(language_client, response);
|
SendOutMessageToClient(language_client, response);
|
||||||
|
Loading…
Reference in New Issue
Block a user