Better definition/references on #include lines

This commit is contained in:
Fangrui Song 2018-04-08 10:03:50 -07:00
parent 75638b5387
commit 2a06fb55dd
8 changed files with 56 additions and 70 deletions

View File

@ -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_;

View File

@ -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;

View File

@ -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);

View File

@ -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,

View File

@ -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;
{

View File

@ -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);

View File

@ -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);
}

View File

@ -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) {