mirror of
https://github.com/MaskRay/ccls.git
synced 2024-11-22 15:45:08 +00:00
Add Id<QueryFile> file; to Use and simplify query.cc
This commit is contained in:
parent
2d6fd4e240
commit
afd38cbce9
@ -657,8 +657,8 @@ void OnIndexReference_Function(IndexFile* db,
|
|||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
// static
|
// static
|
||||||
const int IndexFile::kMajorVersion = 12;
|
const int IndexFile::kMajorVersion = 13;
|
||||||
const int IndexFile::kMinorVersion = 1;
|
const int IndexFile::kMinorVersion = 0;
|
||||||
|
|
||||||
IndexFile::IndexFile(const std::string& path, const std::string& contents)
|
IndexFile::IndexFile(const std::string& path, const std::string& contents)
|
||||||
: id_cache(path), path(path), file_contents(contents) {}
|
: id_cache(path), path(path), file_contents(contents) {}
|
||||||
@ -1542,7 +1542,9 @@ void OnIndexDeclaration(CXClientData client_data, const CXIdxDeclInfo* decl) {
|
|||||||
SetUse(db, &var->def.spell, decl_spell, lex_parent, Role::Definition);
|
SetUse(db, &var->def.spell, decl_spell, lex_parent, Role::Definition);
|
||||||
SetUse(db, &var->def.extent, decl_cursor.get_extent(), lex_parent, Role::None);
|
SetUse(db, &var->def.extent, decl_cursor.get_extent(), lex_parent, Role::None);
|
||||||
} else {
|
} else {
|
||||||
var->declarations.push_back(decl_spell);
|
Maybe<Use> use;
|
||||||
|
SetUse(db, &use, decl_spell, lex_parent, Role::Declaration);
|
||||||
|
var->declarations.push_back(*use);
|
||||||
}
|
}
|
||||||
|
|
||||||
AddDeclInitializerUsages(db, decl_cursor);
|
AddDeclInitializerUsages(db, decl_cursor);
|
||||||
@ -2374,6 +2376,9 @@ std::string GetClangVersion() {
|
|||||||
return ToString(clang_getClangVersion());
|
return ToString(clang_getClangVersion());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// |SymbolRef| is serialized this way.
|
||||||
|
// |Use| also uses this though it has an extra field |file|,
|
||||||
|
// which is not used by Index* so it does not need to be serialized.
|
||||||
void Reflect(Reader& visitor, Reference& value) {
|
void Reflect(Reader& visitor, Reference& value) {
|
||||||
if (visitor.Format() == SerializeFormat::Json) {
|
if (visitor.Format() == SerializeFormat::Json) {
|
||||||
std::string t = visitor.GetString();
|
std::string t = visitor.GetString();
|
||||||
|
@ -136,13 +136,19 @@ struct SymbolRef : Reference {
|
|||||||
: Reference{Range(), si.id, si.kind, Role::None} {}
|
: Reference{Range(), si.id, si.kind, Role::None} {}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct QueryFile;
|
||||||
|
|
||||||
// Represents an occurrence of a variable/type, |id,kind| refer to the lexical
|
// Represents an occurrence of a variable/type, |id,kind| refer to the lexical
|
||||||
// parent.
|
// parent.
|
||||||
struct Use : Reference {
|
struct Use : Reference {
|
||||||
|
// |file| is used in Query* but not in Index*
|
||||||
|
Id<QueryFile> file;
|
||||||
Use() = default;
|
Use() = default;
|
||||||
Use(Reference ref) : Reference(ref) {}
|
Use(Reference ref) : Reference(ref) {}
|
||||||
Use(Range range, Id<void> id, SymbolKind kind, Role role)
|
Use(Range range, Id<void> id, SymbolKind kind, Role role)
|
||||||
: Reference{range, id, kind, role} {}
|
: Reference{range, id, kind, role} {}
|
||||||
|
Use(Range range, Id<void> id, SymbolKind kind, Role role, Id<QueryFile> file)
|
||||||
|
: Reference{range, id, kind, role}, file(file) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
void Reflect(Reader& visitor, Reference& value);
|
void Reflect(Reader& visitor, Reference& value);
|
||||||
@ -433,7 +439,7 @@ struct IndexVar {
|
|||||||
|
|
||||||
Def def;
|
Def def;
|
||||||
|
|
||||||
std::vector<Range> declarations;
|
std::vector<Use> declarations;
|
||||||
// Usages.
|
// Usages.
|
||||||
std::vector<Use> uses;
|
std::vector<Use> uses;
|
||||||
|
|
||||||
|
@ -80,7 +80,7 @@ std::vector<Out_CqueryCallTree::CallEntry> BuildExpandCallTree(
|
|||||||
|
|
||||||
std::vector<Out_CqueryCallTree::CallEntry> result;
|
std::vector<Out_CqueryCallTree::CallEntry> result;
|
||||||
|
|
||||||
auto handle_caller = [&](QueryFuncRef caller,
|
auto handle_caller = [&](Use caller,
|
||||||
Out_CqueryCallTree::CallType call_type) {
|
Out_CqueryCallTree::CallType call_type) {
|
||||||
optional<lsLocation> call_location =
|
optional<lsLocation> call_location =
|
||||||
GetLsLocation(db, working_files, caller);
|
GetLsLocation(db, working_files, caller);
|
||||||
@ -130,21 +130,21 @@ std::vector<Out_CqueryCallTree::CallEntry> BuildExpandCallTree(
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
std::vector<QueryFuncRef> base_callers =
|
std::vector<Use> base_callers =
|
||||||
GetCallersForAllBaseFunctions(db, root_func);
|
GetCallersForAllBaseFunctions(db, root_func);
|
||||||
std::vector<QueryFuncRef> derived_callers =
|
std::vector<Use> derived_callers =
|
||||||
GetCallersForAllDerivedFunctions(db, root_func);
|
GetCallersForAllDerivedFunctions(db, root_func);
|
||||||
result.reserve(root_func.uses.size() + base_callers.size() +
|
result.reserve(root_func.uses.size() + base_callers.size() +
|
||||||
derived_callers.size());
|
derived_callers.size());
|
||||||
|
|
||||||
for (QueryFuncRef caller : root_func.uses)
|
for (Use caller : root_func.uses)
|
||||||
handle_caller(caller, Out_CqueryCallTree::CallType::Direct);
|
handle_caller(caller, Out_CqueryCallTree::CallType::Direct);
|
||||||
for (QueryFuncRef caller : base_callers)
|
for (Use caller : base_callers)
|
||||||
if (caller.kind == SymbolKind::Func && caller.id != Id<void>(root)) {
|
if (caller.kind == SymbolKind::Func && caller.id != Id<void>(root)) {
|
||||||
// Do not show calls to the base function coming from this function.
|
// Do not show calls to the base function coming from this function.
|
||||||
handle_caller(caller, Out_CqueryCallTree::CallType::Base);
|
handle_caller(caller, Out_CqueryCallTree::CallType::Base);
|
||||||
}
|
}
|
||||||
for (QueryFuncRef caller : derived_callers)
|
for (Use caller : derived_callers)
|
||||||
handle_caller(caller, Out_CqueryCallTree::CallType::Derived);
|
handle_caller(caller, Out_CqueryCallTree::CallType::Derived);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
@ -73,7 +73,7 @@ optional<QueryFileId> GetImplementationFile(QueryDatabase* db,
|
|||||||
// Note: we ignore the definition if it is in the same file (ie,
|
// Note: we ignore the definition if it is in the same file (ie,
|
||||||
// possibly a header).
|
// possibly a header).
|
||||||
if (func.def && func.def->extent) {
|
if (func.def && func.def->extent) {
|
||||||
Maybe<QueryFileId> t = db->GetFileId(*func.def->extent);
|
QueryFileId t = func.def->extent->file;
|
||||||
if (t != file_id)
|
if (t != file_id)
|
||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
@ -84,7 +84,7 @@ optional<QueryFileId> GetImplementationFile(QueryDatabase* db,
|
|||||||
// Note: we ignore the definition if it is in the same file (ie,
|
// Note: we ignore the definition if it is in the same file (ie,
|
||||||
// possibly a header).
|
// possibly a header).
|
||||||
if (var.def && var.def->extent) {
|
if (var.def && var.def->extent) {
|
||||||
Maybe<QueryFileId> t = db->GetFileId(*var.def->extent);
|
QueryFileId t = var.def->extent->file;
|
||||||
if (t != file_id)
|
if (t != file_id)
|
||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
@ -150,8 +150,8 @@ optional<lsTextEdit> BuildAutoImplementForFunction(QueryDatabase* db,
|
|||||||
QueryFileId impl_file_id,
|
QueryFileId impl_file_id,
|
||||||
QueryFunc& func) {
|
QueryFunc& func) {
|
||||||
assert(func.def);
|
assert(func.def);
|
||||||
for (const Reference& decl : func.declarations) {
|
for (Use decl : func.declarations) {
|
||||||
if (db->GetFileId(decl) != decl_file_id)
|
if (decl.file != decl_file_id)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
optional<lsRange> ls_decl = GetLsRange(working_file, decl.range);
|
optional<lsRange> ls_decl = GetLsRange(working_file, decl.range);
|
||||||
@ -204,8 +204,8 @@ optional<lsTextEdit> BuildAutoImplementForFunction(QueryDatabase* db,
|
|||||||
if (!sym_func.def || !sym_func.def->extent)
|
if (!sym_func.def || !sym_func.def->extent)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
for (const Reference& func_decl : sym_func.declarations) {
|
for (Use func_decl : sym_func.declarations) {
|
||||||
if (db->GetFileId(func_decl) == decl_file_id) {
|
if (func_decl.file == decl_file_id) {
|
||||||
int dist = func_decl.range.start.line - decl.range.start.line;
|
int dist = func_decl.range.start.line - decl.range.start.line;
|
||||||
if (abs(dist) < abs(best_dist)) {
|
if (abs(dist) < abs(best_dist)) {
|
||||||
optional<lsLocation> def_loc = GetLsLocation(
|
optional<lsLocation> def_loc = GetLsLocation(
|
||||||
|
@ -91,6 +91,7 @@ void AddCodeLens(const char* singular,
|
|||||||
optional<lsRange> range = GetLsRange(common->working_file, loc.range);
|
optional<lsRange> range = GetLsRange(common->working_file, loc.range);
|
||||||
if (!range)
|
if (!range)
|
||||||
return;
|
return;
|
||||||
|
// FIXME SymbolRef loc -> Use loc
|
||||||
Maybe<QueryFileId> file_id = common->db->GetFileId(loc);
|
Maybe<QueryFileId> file_id = common->db->GetFileId(loc);
|
||||||
if (!file_id)
|
if (!file_id)
|
||||||
return;
|
return;
|
||||||
@ -178,7 +179,7 @@ struct TextDocumentCodeLensHandler
|
|||||||
// extent location to the spelling location.
|
// extent location to the spelling location.
|
||||||
auto try_ensure_spelling = [&](SymbolRef sym) {
|
auto try_ensure_spelling = [&](SymbolRef sym) {
|
||||||
Maybe<Use> def = GetDefinitionSpellingOfSymbol(db, sym);
|
Maybe<Use> def = GetDefinitionSpellingOfSymbol(db, sym);
|
||||||
if (!def || db->GetFileId(*def) != db->GetFileId(sym) ||
|
if (!def || def->file != *db->GetFileId(sym) ||
|
||||||
def->range.start.line != sym.range.start.line) {
|
def->range.start.line != sym.range.start.line) {
|
||||||
return sym;
|
return sym;
|
||||||
}
|
}
|
||||||
|
@ -86,7 +86,7 @@ struct TextDocumentDefinitionHandler
|
|||||||
// 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 || (db->GetFileId(*def_loc) == file_id &&
|
if (!def_loc || (def_loc->file == file_id &&
|
||||||
def_loc->range.Contains(target_line, target_column))) {
|
def_loc->range.Contains(target_line, target_column))) {
|
||||||
// Goto declaration.
|
// Goto declaration.
|
||||||
|
|
||||||
|
@ -41,7 +41,7 @@ struct TextDocumentDocumentHighlightHandler
|
|||||||
std::vector<Use> uses = GetUsesOfSymbol(db, sym, true);
|
std::vector<Use> uses = GetUsesOfSymbol(db, sym, true);
|
||||||
out.result.reserve(uses.size());
|
out.result.reserve(uses.size());
|
||||||
for (Use use : uses) {
|
for (Use use : uses) {
|
||||||
if (db->GetFileId(use) != file_id)
|
if (use.file != file_id)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
optional<lsLocation> ls_location =
|
optional<lsLocation> ls_location =
|
||||||
|
@ -16,23 +16,21 @@ lsWorkspaceEdit BuildWorkspaceEdit(QueryDatabase* db,
|
|||||||
if (!ls_location)
|
if (!ls_location)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
Maybe<QueryFileId> file_id = db->GetFileId(use);
|
QueryFileId file_id = use.file;
|
||||||
if (!file_id)
|
if (path_to_edit.find(file_id) == path_to_edit.end()) {
|
||||||
continue;
|
path_to_edit[file_id] = lsTextDocumentEdit();
|
||||||
if (path_to_edit.find(*file_id) == path_to_edit.end()) {
|
|
||||||
path_to_edit[*file_id] = lsTextDocumentEdit();
|
|
||||||
|
|
||||||
QueryFile& file = db->files[file_id->id];
|
QueryFile& file = db->files[file_id.id];
|
||||||
if (!file.def)
|
if (!file.def)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
const std::string& path = file.def->path;
|
const std::string& path = file.def->path;
|
||||||
path_to_edit[*file_id].textDocument.uri =
|
path_to_edit[file_id].textDocument.uri =
|
||||||
lsDocumentUri::FromPath(path);
|
lsDocumentUri::FromPath(path);
|
||||||
|
|
||||||
WorkingFile* working_file = working_files->GetFileByFilename(path);
|
WorkingFile* working_file = working_files->GetFileByFilename(path);
|
||||||
if (working_file)
|
if (working_file)
|
||||||
path_to_edit[*file_id].textDocument.version =
|
path_to_edit[file_id].textDocument.version =
|
||||||
working_file->version;
|
working_file->version;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -41,7 +39,7 @@ lsWorkspaceEdit BuildWorkspaceEdit(QueryDatabase* db,
|
|||||||
edit.newText = new_text;
|
edit.newText = new_text;
|
||||||
|
|
||||||
// vscode complains if we submit overlapping text edits.
|
// vscode complains if we submit overlapping text edits.
|
||||||
auto& edits = path_to_edit[*file_id].edits;
|
auto& edits = path_to_edit[file_id].edits;
|
||||||
if (std::find(edits.begin(), edits.end(), edit) == edits.end())
|
if (std::find(edits.begin(), edits.end(), edit) == edits.end())
|
||||||
edits.push_back(edit);
|
edits.push_back(edit);
|
||||||
}
|
}
|
||||||
|
67
src/query.cc
67
src/query.cc
@ -233,10 +233,6 @@ QueryFile::DefUpdate BuildFileDefUpdate(const IdMap& id_map, const IndexFile& in
|
|||||||
Role role) {
|
Role role) {
|
||||||
def.outline.push_back(SymbolRef(range, id, kind, role));
|
def.outline.push_back(SymbolRef(range, id, kind, role));
|
||||||
};
|
};
|
||||||
auto add_all_symbols = [&](Range range, Id<void> id, SymbolKind kind,
|
|
||||||
Role role) {
|
|
||||||
def.all_symbols.push_back(SymbolRef(range, id, kind, role));
|
|
||||||
};
|
|
||||||
auto add_all_symbols_use = [&](Use use, Id<void> id, SymbolKind kind) {
|
auto add_all_symbols_use = [&](Use use, Id<void> id, SymbolKind kind) {
|
||||||
def.all_symbols.push_back(
|
def.all_symbols.push_back(
|
||||||
SymbolRef(use.range, id, kind, use.role));
|
SymbolRef(use.range, id, kind, use.role));
|
||||||
@ -252,7 +248,7 @@ QueryFile::DefUpdate BuildFileDefUpdate(const IdMap& id_map, const IndexFile& in
|
|||||||
if (type.def.extent)
|
if (type.def.extent)
|
||||||
add_outline_use(*type.def.extent, id, SymbolKind::Type);
|
add_outline_use(*type.def.extent, id, SymbolKind::Type);
|
||||||
for (Use use : type.uses)
|
for (Use use : type.uses)
|
||||||
add_all_symbols(use.range, id, SymbolKind::Type, use.role);
|
add_all_symbols_use(use, id, SymbolKind::Type);
|
||||||
}
|
}
|
||||||
for (const IndexFunc& func : indexed.funcs) {
|
for (const IndexFunc& func : indexed.funcs) {
|
||||||
QueryFuncId id = id_map.ToQuery(func.id);
|
QueryFuncId id = id_map.ToQuery(func.id);
|
||||||
@ -261,23 +257,21 @@ QueryFile::DefUpdate BuildFileDefUpdate(const IdMap& id_map, const IndexFile& in
|
|||||||
if (func.def.extent)
|
if (func.def.extent)
|
||||||
add_outline_use(*func.def.extent, id, SymbolKind::Func);
|
add_outline_use(*func.def.extent, id, SymbolKind::Func);
|
||||||
for (const IndexFunc::Declaration& decl : func.declarations) {
|
for (const IndexFunc::Declaration& decl : func.declarations) {
|
||||||
add_all_symbols(decl.spelling, id, SymbolKind::Func,
|
def.all_symbols.push_back(
|
||||||
Role::Declaration);
|
SymbolRef(decl.spelling, id, SymbolKind::Func, Role::Declaration));
|
||||||
add_outline(decl.spelling, id, SymbolKind::Func, Role::Declaration);
|
add_outline(decl.spelling, id, SymbolKind::Func, Role::Declaration);
|
||||||
}
|
}
|
||||||
for (Use caller : func.uses) {
|
for (Use use : func.uses) {
|
||||||
// Make ranges of implicit function calls larger (spanning one more column
|
// Make ranges of implicit function calls larger (spanning one more column
|
||||||
// to the left/right). This is hacky but useful. e.g.
|
// to the left/right). This is hacky but useful. e.g.
|
||||||
// textDocument/definition on the space/semicolon in `A a;` or `return
|
// textDocument/definition on the space/semicolon in `A a;` or `return
|
||||||
// 42;` will take you to the constructor.
|
// 42;` will take you to the constructor.
|
||||||
Range range = caller.range;
|
if (use.role & Role::Implicit) {
|
||||||
if (caller.role & Role::Implicit) {
|
if (use.range.start.column > 0)
|
||||||
if (range.start.column > 0)
|
use.range.start.column--;
|
||||||
range.start.column--;
|
use.range.end.column++;
|
||||||
range.end.column++;
|
|
||||||
}
|
}
|
||||||
add_all_symbols(range, id, SymbolKind::Func,
|
add_all_symbols_use(use, id, SymbolKind::Func);
|
||||||
caller.role | Role::Call);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (const IndexVar& var : indexed.vars) {
|
for (const IndexVar& var : indexed.vars) {
|
||||||
@ -286,15 +280,12 @@ QueryFile::DefUpdate BuildFileDefUpdate(const IdMap& id_map, const IndexFile& in
|
|||||||
add_all_symbols_use(*var.def.spell, id, SymbolKind::Var);
|
add_all_symbols_use(*var.def.spell, id, SymbolKind::Var);
|
||||||
if (var.def.extent)
|
if (var.def.extent)
|
||||||
add_outline_use(*var.def.extent, id, SymbolKind::Var);
|
add_outline_use(*var.def.extent, id, SymbolKind::Var);
|
||||||
for (const Range& decl : var.declarations) {
|
for (Use decl : var.declarations) {
|
||||||
add_all_symbols(decl, id_map.ToQuery(var.id), SymbolKind::Var,
|
add_all_symbols_use(decl, id, SymbolKind::Var);
|
||||||
Role::Definition);
|
add_outline_use(decl, id, SymbolKind::Var);
|
||||||
add_outline(decl, id_map.ToQuery(var.id), SymbolKind::Var,
|
|
||||||
Role::Declaration);
|
|
||||||
}
|
}
|
||||||
for (Use use : var.uses)
|
for (Use use : var.uses)
|
||||||
add_all_symbols(use.range, id_map.ToQuery(var.id), SymbolKind::Var,
|
add_all_symbols_use(use, id, SymbolKind::Var);
|
||||||
use.role);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::sort(def.outline.begin(), def.outline.end(),
|
std::sort(def.outline.begin(), def.outline.end(),
|
||||||
@ -411,14 +402,12 @@ IdMap::IdMap(QueryDatabase* query_db, const IdCache& local_ids)
|
|||||||
*GetQueryVarIdFromUsr(query_db, entry.second, true);
|
*GetQueryVarIdFromUsr(query_db, entry.second, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
Use IdMap::ToQuery(Range range, Role role) const {
|
|
||||||
return Use(range, primary_file, SymbolKind:: File, role);
|
|
||||||
}
|
|
||||||
QueryTypeId IdMap::ToQuery(IndexTypeId id) const {
|
QueryTypeId IdMap::ToQuery(IndexTypeId id) const {
|
||||||
assert(cached_type_ids_.find(id) != cached_type_ids_.end());
|
assert(cached_type_ids_.find(id) != cached_type_ids_.end());
|
||||||
return QueryTypeId(cached_type_ids_.find(id)->second);
|
return QueryTypeId(cached_type_ids_.find(id)->second);
|
||||||
}
|
}
|
||||||
QueryFuncId IdMap::ToQuery(IndexFuncId id) const {
|
QueryFuncId IdMap::ToQuery(IndexFuncId id) const {
|
||||||
|
// FIXME id shouldn't be invalid
|
||||||
if (id == IndexFuncId())
|
if (id == IndexFuncId())
|
||||||
return QueryFuncId();
|
return QueryFuncId();
|
||||||
assert(cached_func_ids_.find(id) != cached_func_ids_.end());
|
assert(cached_func_ids_.find(id) != cached_func_ids_.end());
|
||||||
@ -430,44 +419,38 @@ QueryVarId IdMap::ToQuery(IndexVarId id) const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Use IdMap::ToQuery(Reference ref) const {
|
Use IdMap::ToQuery(Reference ref) const {
|
||||||
|
Use ret(ref);
|
||||||
|
ret.file = primary_file;
|
||||||
switch (ref.kind) {
|
switch (ref.kind) {
|
||||||
case SymbolKind::Invalid:
|
case SymbolKind::Invalid:
|
||||||
break;
|
break;
|
||||||
case SymbolKind::File:
|
case SymbolKind::File:
|
||||||
ref.id = primary_file;
|
ret.id = primary_file;
|
||||||
break;
|
break;
|
||||||
case SymbolKind::Func:
|
case SymbolKind::Func:
|
||||||
ref.id = ToQuery(IndexFuncId(ref.id));
|
ret.id = ToQuery(IndexFuncId(ref.id));
|
||||||
break;
|
break;
|
||||||
case SymbolKind::Type:
|
case SymbolKind::Type:
|
||||||
ref.id = ToQuery(IndexTypeId(ref.id));
|
ret.id = ToQuery(IndexTypeId(ref.id));
|
||||||
break;
|
break;
|
||||||
case SymbolKind::Var:
|
case SymbolKind::Var:
|
||||||
ref.id = ToQuery(IndexVarId(ref.id));
|
ret.id = ToQuery(IndexVarId(ref.id));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return ref;
|
return ret;
|
||||||
}
|
}
|
||||||
SymbolRef IdMap::ToQuery(SymbolRef ref) const {
|
SymbolRef IdMap::ToQuery(SymbolRef ref) const {
|
||||||
ref.Reference::operator=(ToQuery(static_cast<Reference>(ref)));
|
ref.Reference::operator=(ToQuery(static_cast<Reference>(ref)));
|
||||||
return ref;
|
return ref;
|
||||||
}
|
}
|
||||||
Use IdMap::ToQuery(Use use) const {
|
Use IdMap::ToQuery(Use use) const {
|
||||||
use.Reference::operator=(ToQuery(static_cast<Reference>(use)));
|
return ToQuery(static_cast<Reference>(use));
|
||||||
return use;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Use IdMap::ToQuery(IndexFunc::Declaration decl) const {
|
Use IdMap::ToQuery(IndexFunc::Declaration decl) const {
|
||||||
// TODO: expose more than just QueryLocation.
|
// TODO: expose more than just QueryLocation.
|
||||||
return Use(decl.spelling, primary_file, SymbolKind::File,
|
return {decl.spelling, primary_file, SymbolKind::File, Role::Declaration,
|
||||||
Role::Declaration);
|
primary_file};
|
||||||
}
|
|
||||||
std::vector<Use> IdMap::ToQuery(const std::vector<Range>& a) const {
|
|
||||||
std::vector<Use> ret;
|
|
||||||
ret.reserve(a.size());
|
|
||||||
for (auto& x : a)
|
|
||||||
ret.push_back(ToQuery(x, Role::Reference));
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ----------------------
|
// ----------------------
|
||||||
@ -1241,4 +1224,4 @@ TEST_SUITE("query") {
|
|||||||
// FIXME/TODO: See https://github.com/cquery-project/cquery/issues/443.
|
// FIXME/TODO: See https://github.com/cquery-project/cquery/issues/443.
|
||||||
// REQUIRE(db.vars[0].uses.size() == 0);
|
// REQUIRE(db.vars[0].uses.size() == 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -20,8 +20,6 @@ using QueryVarId = Id<QueryVar>;
|
|||||||
|
|
||||||
struct IdMap;
|
struct IdMap;
|
||||||
|
|
||||||
using QueryFuncRef = Use;
|
|
||||||
|
|
||||||
// There are two sources of reindex updates: the (single) definition of a
|
// There are two sources of reindex updates: the (single) definition of a
|
||||||
// symbol has changed, or one of many users of the symbol has changed.
|
// symbol has changed, or one of many users of the symbol has changed.
|
||||||
//
|
//
|
||||||
@ -341,7 +339,6 @@ template <> struct IndexToQuery<IndexTypeId> { using type = QueryTypeId; };
|
|||||||
template <> struct IndexToQuery<IndexVarId> { using type = QueryVarId; };
|
template <> struct IndexToQuery<IndexVarId> { using type = QueryVarId; };
|
||||||
template <> struct IndexToQuery<Use> { using type = Use; };
|
template <> struct IndexToQuery<Use> { using type = Use; };
|
||||||
template <> struct IndexToQuery<SymbolRef> { using type = SymbolRef; };
|
template <> struct IndexToQuery<SymbolRef> { using type = SymbolRef; };
|
||||||
template <> struct IndexToQuery<Range> { using type = Use; };
|
|
||||||
template <> struct IndexToQuery<IndexFunc::Declaration> { using type = Use; };
|
template <> struct IndexToQuery<IndexFunc::Declaration> { using type = Use; };
|
||||||
template <typename I> struct IndexToQuery<optional<I>> {
|
template <typename I> struct IndexToQuery<optional<I>> {
|
||||||
using type = optional<typename IndexToQuery<I>::type>;
|
using type = optional<typename IndexToQuery<I>::type>;
|
||||||
@ -363,7 +360,6 @@ struct IdMap {
|
|||||||
QueryFuncId ToQuery(IndexFuncId id) const;
|
QueryFuncId ToQuery(IndexFuncId id) const;
|
||||||
QueryVarId ToQuery(IndexVarId id) const;
|
QueryVarId ToQuery(IndexVarId id) const;
|
||||||
SymbolRef ToQuery(SymbolRef ref) const;
|
SymbolRef ToQuery(SymbolRef ref) const;
|
||||||
Use ToQuery(Range range, Role role) const;
|
|
||||||
Use ToQuery(Reference ref) const;
|
Use ToQuery(Reference ref) const;
|
||||||
Use ToQuery(Use ref) const;
|
Use ToQuery(Use ref) const;
|
||||||
Use ToQuery(IndexFunc::Declaration decl) const;
|
Use ToQuery(IndexFunc::Declaration decl) const;
|
||||||
@ -381,7 +377,6 @@ struct IdMap {
|
|||||||
ret.push_back(ToQuery(x));
|
ret.push_back(ToQuery(x));
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
std::vector<Use> ToQuery(const std::vector<Range>& a) const;
|
|
||||||
// clang-format on
|
// clang-format on
|
||||||
|
|
||||||
|
|
||||||
|
@ -16,19 +16,13 @@ int ComputeRangeSize(const Range& range) {
|
|||||||
return range.end.column - range.start.column;
|
return range.end.column - range.start.column;
|
||||||
}
|
}
|
||||||
|
|
||||||
Maybe<Use> UseWithFileId(Maybe<Use> use, QueryFileId file_id) {
|
|
||||||
if (!use)
|
|
||||||
return nullopt;
|
|
||||||
return Use(use->range, file_id, SymbolKind::File, use->role);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
Maybe<Use> GetDefinitionSpellingOfSymbol(QueryDatabase* db,
|
Maybe<Use> GetDefinitionSpellingOfSymbol(QueryDatabase* db,
|
||||||
QueryFuncId id) {
|
QueryFuncId id) {
|
||||||
QueryFunc& func = db->funcs[id.id];
|
QueryFunc& func = db->funcs[id.id];
|
||||||
if (func.def)
|
if (func.def)
|
||||||
return UseWithFileId(func.def->spell, func.def->file);
|
return func.def->spell;
|
||||||
return nullopt;
|
return nullopt;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -38,19 +32,19 @@ Maybe<Use> GetDefinitionSpellingOfSymbol(QueryDatabase* db,
|
|||||||
case SymbolKind::Type: {
|
case SymbolKind::Type: {
|
||||||
QueryType& type = db->GetType(sym);
|
QueryType& type = db->GetType(sym);
|
||||||
if (type.def)
|
if (type.def)
|
||||||
return UseWithFileId(type.def->spell, type.def->file);
|
return type.def->spell;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case SymbolKind::Func: {
|
case SymbolKind::Func: {
|
||||||
QueryFunc& func = db->GetFunc(sym);
|
QueryFunc& func = db->GetFunc(sym);
|
||||||
if (func.def)
|
if (func.def)
|
||||||
return UseWithFileId(func.def->spell, func.def->file);
|
return func.def->spell;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case SymbolKind::Var: {
|
case SymbolKind::Var: {
|
||||||
QueryVar& var = db->GetVar(sym);
|
QueryVar& var = db->GetVar(sym);
|
||||||
if (var.def)
|
if (var.def)
|
||||||
return UseWithFileId(var.def->spell, var.def->file);
|
return var.def->spell;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case SymbolKind::File:
|
case SymbolKind::File:
|
||||||
@ -67,24 +61,24 @@ Maybe<Use> GetDefinitionExtentOfSymbol(QueryDatabase* db, SymbolIdx sym) {
|
|||||||
case SymbolKind::Type: {
|
case SymbolKind::Type: {
|
||||||
QueryType& type = db->GetType(sym);
|
QueryType& type = db->GetType(sym);
|
||||||
if (type.def)
|
if (type.def)
|
||||||
return UseWithFileId(type.def->extent, type.def->file);
|
return type.def->extent;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case SymbolKind::Func: {
|
case SymbolKind::Func: {
|
||||||
QueryFunc& func = db->GetFunc(sym);
|
QueryFunc& func = db->GetFunc(sym);
|
||||||
if (func.def)
|
if (func.def)
|
||||||
return UseWithFileId(func.def->extent, func.def->file);
|
return func.def->extent;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case SymbolKind::Var: {
|
case SymbolKind::Var: {
|
||||||
QueryVar& var = db->GetVar(sym);
|
QueryVar& var = db->GetVar(sym);
|
||||||
if (var.def)
|
if (var.def)
|
||||||
return UseWithFileId(var.def->extent, var.def->file);
|
return var.def->extent;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case SymbolKind::File:
|
case SymbolKind::File:
|
||||||
return Use(Range(Position(0, 0), Position(0, 0)), sym.id, sym.kind,
|
return Use(Range(Position(0, 0), Position(0, 0)), sym.id, sym.kind,
|
||||||
Role::None);
|
Role::None, QueryFileId(sym.id));
|
||||||
case SymbolKind::Invalid: {
|
case SymbolKind::Invalid: {
|
||||||
assert(false && "unexpected");
|
assert(false && "unexpected");
|
||||||
break;
|
break;
|
||||||
@ -105,7 +99,7 @@ Maybe<QueryFileId> GetDeclarationFileForSymbol(QueryDatabase* db,
|
|||||||
case SymbolKind::Func: {
|
case SymbolKind::Func: {
|
||||||
QueryFunc& func = db->GetFunc(sym);
|
QueryFunc& func = db->GetFunc(sym);
|
||||||
if (!func.declarations.empty())
|
if (!func.declarations.empty())
|
||||||
return db->GetFileId(func.declarations[0]);
|
return func.declarations[0].file;
|
||||||
if (func.def)
|
if (func.def)
|
||||||
return func.def->file;
|
return func.def->file;
|
||||||
break;
|
break;
|
||||||
@ -383,14 +377,11 @@ lsDocumentUri GetLsDocumentUri(QueryDatabase* db, QueryFileId file_id) {
|
|||||||
|
|
||||||
optional<lsLocation> GetLsLocation(QueryDatabase* db,
|
optional<lsLocation> GetLsLocation(QueryDatabase* db,
|
||||||
WorkingFiles* working_files,
|
WorkingFiles* working_files,
|
||||||
Reference ref) {
|
Use use) {
|
||||||
std::string path;
|
std::string path;
|
||||||
Maybe<QueryFileId> file_id = db->GetFileId(ref);
|
lsDocumentUri uri = GetLsDocumentUri(db, use.file, &path);
|
||||||
if (!file_id)
|
|
||||||
return nullopt;
|
|
||||||
lsDocumentUri uri = GetLsDocumentUri(db, *file_id, &path);
|
|
||||||
optional<lsRange> range =
|
optional<lsRange> range =
|
||||||
GetLsRange(working_files->GetFileByFilename(path), ref.range);
|
GetLsRange(working_files->GetFileByFilename(path), use.range);
|
||||||
if (!range)
|
if (!range)
|
||||||
return nullopt;
|
return nullopt;
|
||||||
return lsLocation(uri, *range);
|
return lsLocation(uri, *range);
|
||||||
|
@ -44,7 +44,7 @@ lsDocumentUri GetLsDocumentUri(QueryDatabase* db, QueryFileId file_id);
|
|||||||
|
|
||||||
optional<lsLocation> GetLsLocation(QueryDatabase* db,
|
optional<lsLocation> GetLsLocation(QueryDatabase* db,
|
||||||
WorkingFiles* working_files,
|
WorkingFiles* working_files,
|
||||||
Reference location);
|
Use use);
|
||||||
optional<lsLocationEx> GetLsLocationEx(QueryDatabase* db,
|
optional<lsLocationEx> GetLsLocationEx(QueryDatabase* db,
|
||||||
WorkingFiles* working_files,
|
WorkingFiles* working_files,
|
||||||
Use use,
|
Use use,
|
||||||
|
Loading…
Reference in New Issue
Block a user