mirror of
https://github.com/MaskRay/ccls.git
synced 2024-11-27 10:02:03 +00:00
Better definition/references on #include lines
This commit is contained in:
parent
75638b5387
commit
2a06fb55dd
16
src/lsp.h
16
src/lsp.h
@ -8,22 +8,6 @@
|
||||
#include <iosfwd>
|
||||
#include <unordered_map>
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
///////////////////////////// OUTGOING MESSAGES /////////////////////////////
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
///////////////////////////// INCOMING MESSAGES /////////////////////////////
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#define REGISTER_IN_MESSAGE(type) \
|
||||
static MessageRegistryRegister<type> type##message_handler_instance_;
|
||||
|
||||
|
@ -182,7 +182,7 @@ struct Handler_CclsCallHierarchy
|
||||
}
|
||||
|
||||
void Run(In_CclsCallHierarchy* request) override {
|
||||
const auto& params = request->params;
|
||||
auto& params = request->params;
|
||||
Out_CclsCallHierarchy out;
|
||||
out.id = request->id;
|
||||
|
||||
|
@ -139,7 +139,7 @@ struct Handler_CclsInheritanceHierarchy
|
||||
}
|
||||
|
||||
void Run(In_CclsInheritanceHierarchy* request) override {
|
||||
const auto& params = request->params;
|
||||
auto& params = request->params;
|
||||
Out_CclsInheritanceHierarchy out;
|
||||
out.id = request->id;
|
||||
|
||||
@ -158,11 +158,11 @@ struct Handler_CclsInheritanceHierarchy
|
||||
if (!FindFileOrFail(db, project, request->id,
|
||||
params.textDocument.uri.GetPath(), &file))
|
||||
return;
|
||||
WorkingFile* working_file =
|
||||
WorkingFile* wfile =
|
||||
working_files->GetFileByFilename(file->def->path);
|
||||
|
||||
for (SymbolRef sym : FindSymbolsAtLocation(working_file, file,
|
||||
request->params.position)) {
|
||||
for (SymbolRef sym :
|
||||
FindSymbolsAtLocation(wfile, file, params.position)) {
|
||||
if (sym.kind == SymbolKind::Func || sym.kind == SymbolKind::Type) {
|
||||
out.result = BuildInitial(sym, params.derived, params.qualified,
|
||||
params.levels);
|
||||
|
@ -202,7 +202,7 @@ struct Handler_CclsMemberHierarchy
|
||||
}
|
||||
|
||||
void Run(In_CclsMemberHierarchy* request) override {
|
||||
const auto& params = request->params;
|
||||
auto& params = request->params;
|
||||
Out_CclsMemberHierarchy out;
|
||||
out.id = request->id;
|
||||
|
||||
@ -218,10 +218,10 @@ struct Handler_CclsMemberHierarchy
|
||||
if (!FindFileOrFail(db, project, request->id,
|
||||
params.textDocument.uri.GetPath(), &file))
|
||||
return;
|
||||
WorkingFile* working_file =
|
||||
WorkingFile* wfile =
|
||||
working_files->GetFileByFilename(file->def->path);
|
||||
for (SymbolRef sym :
|
||||
FindSymbolsAtLocation(working_file, file, params.position)) {
|
||||
FindSymbolsAtLocation(wfile, file, params.position)) {
|
||||
switch (sym.kind) {
|
||||
case SymbolKind::Func:
|
||||
out.result = BuildInitial(QueryFuncId(sym.id), params.qualified,
|
||||
|
@ -50,27 +50,23 @@ struct Handler_TextDocumentDefinition
|
||||
: BaseMessageHandler<In_TextDocumentDefinition> {
|
||||
MethodType GetMethodType() const override { return kMethodType; }
|
||||
void Run(In_TextDocumentDefinition* request) override {
|
||||
auto& params = request->params;
|
||||
QueryFileId file_id;
|
||||
QueryFile* file;
|
||||
if (!FindFileOrFail(db, project, request->id,
|
||||
request->params.textDocument.uri.GetPath(), &file,
|
||||
&file_id)) {
|
||||
params.textDocument.uri.GetPath(), &file, &file_id))
|
||||
return;
|
||||
}
|
||||
|
||||
WorkingFile* working_file =
|
||||
working_files->GetFileByFilename(file->def->path);
|
||||
|
||||
Out_TextDocumentDefinition out;
|
||||
out.id = request->id;
|
||||
|
||||
Maybe<Use> on_def;
|
||||
bool has_symbol = false;
|
||||
int target_line = request->params.position.line;
|
||||
int target_column = request->params.position.character;
|
||||
WorkingFile* wfile =
|
||||
working_files->GetFileByFilename(file->def->path);
|
||||
lsPosition& ls_pos = params.position;
|
||||
|
||||
for (SymbolRef sym :
|
||||
FindSymbolsAtLocation(working_file, file, request->params.position)) {
|
||||
for (SymbolRef sym : FindSymbolsAtLocation(wfile, file, ls_pos)) {
|
||||
// Found symbol. Return definition.
|
||||
has_symbol = true;
|
||||
|
||||
@ -84,7 +80,7 @@ struct Handler_TextDocumentDefinition
|
||||
Use spell = *def.spell;
|
||||
// If on a definition, clear |uses| to find declarations below.
|
||||
if (spell.file == file_id &&
|
||||
spell.range.Contains(target_line, target_column)) {
|
||||
spell.range.Contains(ls_pos.line, ls_pos.character)) {
|
||||
on_def = spell;
|
||||
uses.clear();
|
||||
return false;
|
||||
@ -114,7 +110,7 @@ struct Handler_TextDocumentDefinition
|
||||
// No symbols - check for includes.
|
||||
if (out.result.empty()) {
|
||||
for (const IndexInclude& include : file->def->includes) {
|
||||
if (include.line == target_line) {
|
||||
if (include.line == ls_pos.line) {
|
||||
lsLocationEx result;
|
||||
result.uri = lsDocumentUri::FromPath(include.resolved_path);
|
||||
out.result.push_back(result);
|
||||
@ -125,7 +121,7 @@ struct Handler_TextDocumentDefinition
|
||||
// Find the best match of the identifier at point.
|
||||
if (!has_symbol) {
|
||||
lsPosition position = request->params.position;
|
||||
const std::string& buffer = working_file->buffer_content;
|
||||
const std::string& buffer = wfile->buffer_content;
|
||||
std::string_view query = LexIdentifierAroundPos(position, buffer);
|
||||
std::string_view short_query = query;
|
||||
{
|
||||
|
@ -45,26 +45,25 @@ struct Handler_TextDocumentReferences
|
||||
MethodType GetMethodType() const override { return kMethodType; }
|
||||
|
||||
void Run(In_TextDocumentReferences* request) override {
|
||||
auto& params = request->params;
|
||||
QueryFile* file;
|
||||
if (!FindFileOrFail(db, project, request->id,
|
||||
request->params.textDocument.uri.GetPath(), &file)) {
|
||||
params.textDocument.uri.GetPath(), &file))
|
||||
return;
|
||||
}
|
||||
|
||||
WorkingFile* working_file =
|
||||
WorkingFile* wfile =
|
||||
working_files->GetFileByFilename(file->def->path);
|
||||
|
||||
Out_TextDocumentReferences out;
|
||||
out.id = request->id;
|
||||
bool container = g_config->xref.container;
|
||||
|
||||
for (const SymbolRef& sym :
|
||||
FindSymbolsAtLocation(working_file, file, request->params.position)) {
|
||||
for (SymbolRef sym : FindSymbolsAtLocation(wfile, file, params.position)) {
|
||||
// Found symbol. Return references.
|
||||
EachOccurrenceWithParent(
|
||||
db, sym, request->params.context.includeDeclaration,
|
||||
db, sym, params.context.includeDeclaration,
|
||||
[&](Use use, lsSymbolKind parent_kind) {
|
||||
if (use.role & request->params.context.role)
|
||||
if (use.role & params.context.role)
|
||||
if (std::optional<lsLocationEx> ls_loc =
|
||||
GetLsLocationEx(db, working_files, use, container)) {
|
||||
if (container)
|
||||
@ -75,24 +74,32 @@ struct Handler_TextDocumentReferences
|
||||
break;
|
||||
}
|
||||
|
||||
if (out.result.empty())
|
||||
if (out.result.empty()) {
|
||||
// |path| is the #include line. If the cursor is not on such line but line
|
||||
// = 0,
|
||||
// use the current filename.
|
||||
std::string path;
|
||||
if (params.position.line == 0)
|
||||
path = file->def->path;
|
||||
for (const IndexInclude& include : file->def->includes)
|
||||
if (include.line == request->params.position.line) {
|
||||
// |include| is the line the cursor is on.
|
||||
for (QueryFile& file1 : db->files)
|
||||
if (file1.def)
|
||||
for (const IndexInclude& include1 : file1.def->includes)
|
||||
if (include1.resolved_path == include.resolved_path) {
|
||||
// Another file |file1| has the same include line.
|
||||
lsLocationEx result;
|
||||
result.uri = lsDocumentUri::FromPath(file1.def->path);
|
||||
result.range.start.line = result.range.end.line =
|
||||
include1.line;
|
||||
out.result.push_back(std::move(result));
|
||||
break;
|
||||
}
|
||||
if (include.line == params.position.line) {
|
||||
path = include.resolved_path;
|
||||
break;
|
||||
}
|
||||
if (path.size())
|
||||
for (QueryFile& file1 : db->files)
|
||||
if (file1.def)
|
||||
for (const IndexInclude& include : file1.def->includes)
|
||||
if (include.resolved_path == path) {
|
||||
// Another file |file1| has the same include line.
|
||||
lsLocationEx result;
|
||||
result.uri = lsDocumentUri::FromPath(file1.def->path);
|
||||
result.range.start.line = result.range.end.line =
|
||||
include.line;
|
||||
out.result.push_back(std::move(result));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ((int)out.result.size() >= g_config->xref.maxNum)
|
||||
out.result.resize(g_config->xref.maxNum);
|
||||
|
@ -318,21 +318,20 @@ std::optional<lsSymbolInformation> GetSymbolInfo(QueryDatabase* db,
|
||||
|
||||
std::vector<SymbolRef> FindSymbolsAtLocation(WorkingFile* working_file,
|
||||
QueryFile* file,
|
||||
lsPosition position) {
|
||||
lsPosition& ls_pos) {
|
||||
std::vector<SymbolRef> symbols;
|
||||
symbols.reserve(1);
|
||||
|
||||
int target_line = position.line;
|
||||
int target_column = position.character;
|
||||
if (working_file) {
|
||||
std::optional<int> index_line = working_file->GetIndexPosFromBufferPos(
|
||||
target_line, &target_column, false);
|
||||
if (index_line)
|
||||
target_line = *index_line;
|
||||
if (auto line = working_file->GetIndexPosFromBufferPos(
|
||||
ls_pos.line, &ls_pos.character, false)) {
|
||||
ls_pos.line = *line;
|
||||
} else {
|
||||
ls_pos.line = -1;
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
||||
for (const SymbolRef& sym : file->def->all_symbols) {
|
||||
if (sym.range.Contains(target_line, target_column))
|
||||
if (sym.range.Contains(ls_pos.line, ls_pos.character))
|
||||
symbols.push_back(sym);
|
||||
}
|
||||
|
||||
|
@ -50,7 +50,7 @@ std::optional<lsSymbolInformation> GetSymbolInfo(QueryDatabase* db,
|
||||
|
||||
std::vector<SymbolRef> FindSymbolsAtLocation(WorkingFile* working_file,
|
||||
QueryFile* file,
|
||||
lsPosition position);
|
||||
lsPosition& ls_pos);
|
||||
|
||||
template <typename Fn>
|
||||
void WithEntity(QueryDatabase* db, SymbolIdx sym, Fn&& fn) {
|
||||
|
Loading…
Reference in New Issue
Block a user