mirror of
https://github.com/MaskRay/ccls.git
synced 2025-01-19 03:55:49 +00:00
Add Config::maxXrefResults and improve textDocument/definition
-std=c++11 => -std=c++14 for generic lambda
This commit is contained in:
parent
40ab5900de
commit
65ba98c3f8
@ -162,6 +162,8 @@ struct Config {
|
|||||||
};
|
};
|
||||||
Completion completion;
|
Completion completion;
|
||||||
|
|
||||||
|
// Maximum number of definition/reference/... results.
|
||||||
|
int maxXrefResults = 500;
|
||||||
struct Extension {
|
struct Extension {
|
||||||
// If true, reference results will include "containerName".
|
// If true, reference results will include "containerName".
|
||||||
bool referenceContainer = false;
|
bool referenceContainer = false;
|
||||||
@ -231,6 +233,7 @@ MAKE_REFLECT_STRUCT(Config,
|
|||||||
|
|
||||||
client,
|
client,
|
||||||
completion,
|
completion,
|
||||||
|
maxXrefResults,
|
||||||
extension,
|
extension,
|
||||||
index,
|
index,
|
||||||
|
|
||||||
|
@ -28,12 +28,12 @@ struct CqueryBaseHandler : BaseMessageHandler<Ipc_CqueryBase> {
|
|||||||
if (sym.kind == SymbolKind::Type) {
|
if (sym.kind == SymbolKind::Type) {
|
||||||
if (const auto* def = db->GetType(sym).AnyDef())
|
if (const auto* def = db->GetType(sym).AnyDef())
|
||||||
out.result = GetLsLocations(db, working_files,
|
out.result = GetLsLocations(db, working_files,
|
||||||
ToUses(db, def->parents));
|
ToUses(db, def->parents), config->maxXrefResults);
|
||||||
break;
|
break;
|
||||||
} else if (sym.kind == SymbolKind::Func) {
|
} else if (sym.kind == SymbolKind::Func) {
|
||||||
if (const auto* def = db->GetFunc(sym).AnyDef())
|
if (const auto* def = db->GetFunc(sym).AnyDef())
|
||||||
out.result = GetLsLocations(db, working_files,
|
out.result = GetLsLocations(db, working_files, ToUses(db, def->base),
|
||||||
ToUses(db, def->base));
|
config->maxXrefResults);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -32,7 +32,8 @@ struct CqueryCallersHandler : BaseMessageHandler<Ipc_CqueryCallers> {
|
|||||||
uses.push_back(func_ref);
|
uses.push_back(func_ref);
|
||||||
for (Use func_ref : GetCallersForAllDerivedFunctions(db, func))
|
for (Use func_ref : GetCallersForAllDerivedFunctions(db, func))
|
||||||
uses.push_back(func_ref);
|
uses.push_back(func_ref);
|
||||||
out.result = GetLsLocations(db, working_files, uses);
|
out.result = GetLsLocations(db, working_files, uses, config->maxXrefResults);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
QueueManager::WriteStdout(IpcId::CqueryCallers, out);
|
QueueManager::WriteStdout(IpcId::CqueryCallers, out);
|
||||||
|
@ -27,13 +27,13 @@ struct CqueryDerivedHandler : BaseMessageHandler<Ipc_CqueryDerived> {
|
|||||||
FindSymbolsAtLocation(working_file, file, request->params.position)) {
|
FindSymbolsAtLocation(working_file, file, request->params.position)) {
|
||||||
if (sym.kind == SymbolKind::Type) {
|
if (sym.kind == SymbolKind::Type) {
|
||||||
QueryType& type = db->GetType(sym);
|
QueryType& type = db->GetType(sym);
|
||||||
out.result =
|
out.result = GetLsLocations(db, working_files, ToUses(db, type.derived),
|
||||||
GetLsLocations(db, working_files, ToUses(db, type.derived));
|
config->maxXrefResults);
|
||||||
break;
|
break;
|
||||||
} else if (sym.kind == SymbolKind::Func) {
|
} else if (sym.kind == SymbolKind::Func) {
|
||||||
QueryFunc& func = db->GetFunc(sym);
|
QueryFunc& func = db->GetFunc(sym);
|
||||||
out.result =
|
out.result = GetLsLocations(db, working_files, ToUses(db, func.derived),
|
||||||
GetLsLocations(db, working_files, ToUses(db, func.derived));
|
config->maxXrefResults);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -39,7 +39,8 @@ struct CqueryVarsHandler : BaseMessageHandler<Ipc_CqueryVars> {
|
|||||||
case SymbolKind::Type: {
|
case SymbolKind::Type: {
|
||||||
QueryType& type = db->types[id.id];
|
QueryType& type = db->types[id.id];
|
||||||
out.result =
|
out.result =
|
||||||
GetLsLocations(db, working_files, ToUses(db, type.instances));
|
GetLsLocations(db, working_files, ToUses(db, type.instances),
|
||||||
|
config->maxXrefResults);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -9,10 +9,6 @@
|
|||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
void PushBack(std::vector<lsLocation>* result, optional<lsLocation> location) {
|
|
||||||
if (location)
|
|
||||||
result->push_back(*location);
|
|
||||||
}
|
|
||||||
|
|
||||||
struct Ipc_TextDocumentDefinition
|
struct Ipc_TextDocumentDefinition
|
||||||
: public RequestMessage<Ipc_TextDocumentDefinition> {
|
: public RequestMessage<Ipc_TextDocumentDefinition> {
|
||||||
@ -84,41 +80,29 @@ struct TextDocumentDefinitionHandler
|
|||||||
// - 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
|
||||||
|
std::vector<Use> uses;
|
||||||
Maybe<Use> def_loc = GetDefinitionSpellingOfSymbol(db, sym);
|
EachDef(db, sym, [&](const auto& def) {
|
||||||
|
if (def.spell && def.extent) {
|
||||||
// We use spelling start and extent end because this causes vscode to
|
Use spell = *def.spell;
|
||||||
// highlight the entire definition when previewing / hoving with the
|
// If on a definition, clear |uses| to find declarations below.
|
||||||
// mouse.
|
if (spell.file == file_id &&
|
||||||
Maybe<Use> extent = GetDefinitionExtentOfSymbol(db, sym);
|
spell.range.Contains(target_line, target_column)) {
|
||||||
if (def_loc && extent)
|
uses.clear();
|
||||||
def_loc->range.end = extent->range.end;
|
return false;
|
||||||
|
|
||||||
// If the cursor is currently at or in the definition we should goto
|
|
||||||
// the declaration if possible. We also want to use declarations if
|
|
||||||
// we're pointing to, ie, a pure virtual function which has no
|
|
||||||
// definition.
|
|
||||||
if (!def_loc || (def_loc->file == file_id &&
|
|
||||||
def_loc->range.Contains(target_line, target_column))) {
|
|
||||||
// Goto declaration.
|
|
||||||
|
|
||||||
std::vector<Use> targets = GetGotoDefinitionTargets(db, sym);
|
|
||||||
for (Use target : targets) {
|
|
||||||
optional<lsLocation> ls_target =
|
|
||||||
GetLsLocation(db, working_files, target);
|
|
||||||
if (ls_target)
|
|
||||||
out.result.push_back(*ls_target);
|
|
||||||
}
|
}
|
||||||
// We found some declarations. Break so we don't add the definition
|
// We use spelling start and extent end because this causes vscode
|
||||||
// location.
|
// to highlight the entire definition when previewing / hoving with
|
||||||
if (!out.result.empty())
|
// the mouse.
|
||||||
break;
|
spell.range.end = def.extent->range.end;
|
||||||
}
|
uses.push_back(spell);
|
||||||
|
|
||||||
if (def_loc) {
|
|
||||||
PushBack(&out.result, GetLsLocation(db, working_files, *def_loc));
|
|
||||||
}
|
}
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
|
||||||
|
if (uses.empty())
|
||||||
|
uses = GetGotoDefinitionTargets(db, sym);
|
||||||
|
AddRange(&out.result,
|
||||||
|
GetLsLocations(db, working_files, uses, config->maxXrefResults));
|
||||||
if (!out.result.empty())
|
if (!out.result.empty())
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -403,10 +403,10 @@ optional<lsLocationEx> GetLsLocationEx(QueryDatabase* db,
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<lsLocation> GetLsLocations(
|
std::vector<lsLocation> GetLsLocations(QueryDatabase* db,
|
||||||
QueryDatabase* db,
|
|
||||||
WorkingFiles* working_files,
|
WorkingFiles* working_files,
|
||||||
const std::vector<Use>& uses) {
|
const std::vector<Use>& uses,
|
||||||
|
int limit) {
|
||||||
std::vector<lsLocation> ret;
|
std::vector<lsLocation> ret;
|
||||||
for (Use use : uses) {
|
for (Use use : uses) {
|
||||||
optional<lsLocation> location =
|
optional<lsLocation> location =
|
||||||
@ -416,6 +416,8 @@ std::vector<lsLocation> GetLsLocations(
|
|||||||
}
|
}
|
||||||
std::sort(ret.begin(), ret.end());
|
std::sort(ret.begin(), ret.end());
|
||||||
ret.erase(std::unique(ret.begin(), ret.end()), ret.end());
|
ret.erase(std::unique(ret.begin(), ret.end()), ret.end());
|
||||||
|
if (ret.size() > limit)
|
||||||
|
ret.resize(limit);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -47,7 +47,8 @@ optional<lsLocationEx> GetLsLocationEx(QueryDatabase* db,
|
|||||||
bool extension);
|
bool extension);
|
||||||
std::vector<lsLocation> GetLsLocations(QueryDatabase* db,
|
std::vector<lsLocation> GetLsLocations(QueryDatabase* db,
|
||||||
WorkingFiles* working_files,
|
WorkingFiles* working_files,
|
||||||
const std::vector<Use>& refs);
|
const std::vector<Use>& refs,
|
||||||
|
int limit);
|
||||||
// Returns a symbol. The symbol will have *NOT* have a location assigned.
|
// Returns a symbol. The symbol will have *NOT* have a location assigned.
|
||||||
optional<lsSymbolInformation> GetSymbolInfo(QueryDatabase* db,
|
optional<lsSymbolInformation> GetSymbolInfo(QueryDatabase* db,
|
||||||
WorkingFiles* working_files,
|
WorkingFiles* working_files,
|
||||||
@ -62,6 +63,30 @@ void EmitDiagnostics(WorkingFiles* working_files,
|
|||||||
std::string path,
|
std::string path,
|
||||||
std::vector<lsDiagnostic> diagnostics);
|
std::vector<lsDiagnostic> diagnostics);
|
||||||
|
|
||||||
|
template <typename Fn>
|
||||||
|
void EachDef(QueryDatabase* db, SymbolIdx sym, Fn fn) {
|
||||||
|
switch (sym.kind) {
|
||||||
|
case SymbolKind::Invalid:
|
||||||
|
case SymbolKind::File:
|
||||||
|
break;
|
||||||
|
case SymbolKind::Func:
|
||||||
|
for (auto& def : db->GetFunc(sym).def)
|
||||||
|
if (!fn(def))
|
||||||
|
break;
|
||||||
|
break;
|
||||||
|
case SymbolKind::Type:
|
||||||
|
for (auto& def : db->GetType(sym).def)
|
||||||
|
if (!fn(def))
|
||||||
|
break;
|
||||||
|
break;
|
||||||
|
case SymbolKind::Var:
|
||||||
|
for (auto& def : db->GetVar(sym).def)
|
||||||
|
if (!fn(def))
|
||||||
|
break;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
template <typename Q, typename Fn>
|
template <typename Q, typename Fn>
|
||||||
void EachWithGen(std::vector<Q>& collection, Id<Q> x, Fn fn) {
|
void EachWithGen(std::vector<Q>& collection, Id<Q> x, Fn fn) {
|
||||||
Q& obj = collection[x.id];
|
Q& obj = collection[x.id];
|
||||||
|
2
wscript
2
wscript
@ -174,7 +174,7 @@ def configure(ctx):
|
|||||||
cxxflags.append('-Wno-unused-result')
|
cxxflags.append('-Wno-unused-result')
|
||||||
|
|
||||||
if all(not x.startswith('-std=') for x in ctx.env.CXXFLAGS):
|
if all(not x.startswith('-std=') for x in ctx.env.CXXFLAGS):
|
||||||
cxxflags.append('-std=c++11')
|
cxxflags.append('-std=c++14')
|
||||||
|
|
||||||
if ctx.options.use_clang_cxx:
|
if ctx.options.use_clang_cxx:
|
||||||
# include/clang/Format/Format.h error: multi-line comment
|
# include/clang/Format/Format.h error: multi-line comment
|
||||||
|
Loading…
Reference in New Issue
Block a user