textDocument/definition: find macro definition instead of Type definition if the macro expands to tokens led by a SymbolKind::Type

This commit is contained in:
Fangrui Song 2017-12-17 17:50:19 -08:00 committed by Jacob Dufault
parent 2fb135e10a
commit ef7215cd7f
2 changed files with 12 additions and 7 deletions

View File

@ -51,6 +51,7 @@ struct QueryLocation {
MAKE_REFLECT_STRUCT(QueryLocation, path, range);
MAKE_HASHABLE(QueryLocation, t.path, t.range);
// The order matters. In FindSymbolsAtLocation, we want Var/Func ordered in front of others.
enum class SymbolKind : int { Invalid, File, Type, Func, Var };
MAKE_REFLECT_TYPE_PROXY(SymbolKind, int);

View File

@ -579,18 +579,22 @@ std::vector<SymbolRef> FindSymbolsAtLocation(WorkingFile* working_file,
// important for macros which generate code so that we can resolving the
// macro argument takes priority over the entire macro body.
//
// Order functions before other types, which makes goto definition work
// Order SymbolKind::Var before SymbolKind::Type. Macro calls are treated as Var
// currently. If a macro expands to tokens led by a SymbolKind::Type, the
// macro and the Type have the same range. We want to find the macro
// definition instead of the Type definition.
//
// Then order functions before other types, which makes goto definition work
// better on constructors.
std::sort(symbols.begin(), symbols.end(),
[](const SymbolRef& a, const SymbolRef& b) {
int a_size = ComputeRangeSize(a.loc.range);
int b_size = ComputeRangeSize(b.loc.range);
if (a_size == b_size)
return a.idx.kind != b.idx.kind &&
a.idx.kind == SymbolKind::Func;
return a_size < b_size;
if (a_size != b_size)
return a_size < b_size;
// operator> orders Var/Func in front of orders.
return static_cast<int>(a.idx.kind) > static_cast<int>(b.idx.kind);
});
return symbols;
@ -618,4 +622,4 @@ void InsertSymbolIntoResult(QueryDatabase* db,
return;
info->location = *ls_location;
result->push_back(*info);
}
}