mirror of
https://github.com/MaskRay/ccls.git
synced 2024-11-25 17:11:59 +00:00
Index namespace alias and MSVC __interface; add --enable-assert to waf; add lexical container to xref requests
This commit is contained in:
parent
909c2e247a
commit
1a4da727da
@ -23,7 +23,6 @@
|
||||
#include "serializer.h"
|
||||
#include "serializers/json.h"
|
||||
#include "test.h"
|
||||
#include "threaded_queue.h"
|
||||
#include "timer.h"
|
||||
#include "timestamp_manager.h"
|
||||
#include "work_thread.h"
|
||||
|
17
src/config.h
17
src/config.h
@ -162,13 +162,13 @@ struct Config {
|
||||
};
|
||||
Completion completion;
|
||||
|
||||
// Maximum number of definition/reference/... results.
|
||||
int maxXrefResults = 500;
|
||||
struct Extension {
|
||||
// If true, reference results will include "containerName".
|
||||
bool referenceContainer = false;
|
||||
struct Xref {
|
||||
// If true, |Location[]| response will include lexical container.
|
||||
bool container = false;
|
||||
// Maximum number of definition/reference/... results.
|
||||
int maxNum = 300;
|
||||
};
|
||||
Extension extension;
|
||||
Xref xref;
|
||||
|
||||
struct Index {
|
||||
// 0: none, 1: doxygen, 2: all comments
|
||||
@ -195,7 +195,7 @@ struct Config {
|
||||
};
|
||||
MAKE_REFLECT_STRUCT(Config::ClientCapability, snippetSupport);
|
||||
MAKE_REFLECT_STRUCT(Config::Completion, filterAndSort, detailedLabel);
|
||||
MAKE_REFLECT_STRUCT(Config::Extension, referenceContainer);
|
||||
MAKE_REFLECT_STRUCT(Config::Xref, container, maxNum);
|
||||
MAKE_REFLECT_STRUCT(Config::Index, comments, attributeMakeCallsToCtor);
|
||||
MAKE_REFLECT_STRUCT(Config,
|
||||
compilationDatabaseCommand,
|
||||
@ -233,8 +233,7 @@ MAKE_REFLECT_STRUCT(Config,
|
||||
|
||||
client,
|
||||
completion,
|
||||
maxXrefResults,
|
||||
extension,
|
||||
xref,
|
||||
index,
|
||||
|
||||
dumpAST);
|
||||
|
@ -1510,20 +1510,24 @@ void OnIndexDeclaration(CXClientData client_data, const CXIdxDeclInfo* decl) {
|
||||
ClangCursor lex_parent(fromContainer(decl->lexicalContainer));
|
||||
SetUsePreflight(db, sem_parent);
|
||||
SetUsePreflight(db, lex_parent);
|
||||
ClangCursor cursor = decl->cursor;
|
||||
|
||||
switch (decl->entityInfo->kind) {
|
||||
case CXIdxEntity_Unexposed:
|
||||
LOG_S(INFO) << "CXIdxEntity_Unexposed " << cursor.get_spell_name();
|
||||
break;
|
||||
|
||||
case CXIdxEntity_CXXNamespace: {
|
||||
ClangCursor decl_cursor = decl->cursor;
|
||||
Range spell = decl_cursor.get_spell();
|
||||
Range spell = cursor.get_spell();
|
||||
IndexTypeId ns_id = db->ToTypeId(HashUsr(decl->entityInfo->USR));
|
||||
IndexType* ns = db->Resolve(ns_id);
|
||||
ns->def.kind = GetSymbolKind(decl->entityInfo->kind);
|
||||
if (ns->def.detailed_name.empty()) {
|
||||
SetTypeName(ns, decl_cursor, decl->semanticContainer,
|
||||
SetTypeName(ns, cursor, decl->semanticContainer,
|
||||
decl->entityInfo->name, param);
|
||||
ns->def.spell = SetUse(db, spell, sem_parent, Role::Definition);
|
||||
ns->def.extent =
|
||||
SetUse(db, decl_cursor.get_extent(), lex_parent, Role::None);
|
||||
SetUse(db, cursor.get_extent(), lex_parent, Role::None);
|
||||
if (decl->semanticContainer) {
|
||||
IndexTypeId parent_id = db->ToTypeId(
|
||||
ClangCursor(decl->semanticContainer->cursor).get_usr_hash());
|
||||
@ -1537,6 +1541,10 @@ void OnIndexDeclaration(CXClientData client_data, const CXIdxDeclInfo* decl) {
|
||||
break;
|
||||
}
|
||||
|
||||
case CXIdxEntity_CXXNamespaceAlias:
|
||||
assert(false && "CXXNamespaceAlias");
|
||||
break;
|
||||
|
||||
case CXIdxEntity_ObjCProperty:
|
||||
case CXIdxEntity_ObjCIvar:
|
||||
case CXIdxEntity_EnumConstant:
|
||||
@ -1804,6 +1812,7 @@ void OnIndexDeclaration(CXClientData client_data, const CXIdxDeclInfo* decl) {
|
||||
case CXIdxEntity_Enum:
|
||||
case CXIdxEntity_Union:
|
||||
case CXIdxEntity_Struct:
|
||||
case CXIdxEntity_CXXInterface:
|
||||
case CXIdxEntity_CXXClass: {
|
||||
ClangCursor decl_cursor = decl->cursor;
|
||||
Range spell = decl_cursor.get_spell();
|
||||
@ -1919,30 +1928,6 @@ void OnIndexDeclaration(CXClientData client_data, const CXIdxDeclInfo* decl) {
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
std::cerr
|
||||
<< "!! Unhandled indexDeclaration: "
|
||||
<< ClangCursor(decl->cursor).ToString() << " at "
|
||||
<< ClangCursor(decl->cursor).get_spell().start.ToString()
|
||||
<< std::endl;
|
||||
std::cerr << " entityInfo->kind = " << decl->entityInfo->kind
|
||||
<< std::endl;
|
||||
std::cerr << " entityInfo->USR = " << decl->entityInfo->USR
|
||||
<< std::endl;
|
||||
if (decl->declAsContainer)
|
||||
std::cerr << " declAsContainer = "
|
||||
<< ClangCursor(decl->declAsContainer->cursor).ToString()
|
||||
<< std::endl;
|
||||
if (decl->semanticContainer)
|
||||
std::cerr << " semanticContainer = "
|
||||
<< ClangCursor(decl->semanticContainer->cursor).ToString()
|
||||
<< std::endl;
|
||||
if (decl->lexicalContainer)
|
||||
std::cerr << " lexicalContainer = "
|
||||
<< ClangCursor(decl->lexicalContainer->cursor).get_usr_hash()
|
||||
<< std::endl;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1990,17 +1975,38 @@ void OnIndexReference(CXClientData client_data, const CXIdxEntityRefInfo* ref) {
|
||||
|
||||
ClangCursor cursor(ref->cursor);
|
||||
ClangCursor lex_parent(fromContainer(ref->container));
|
||||
ClangCursor referenced;
|
||||
if (ref->referencedEntity)
|
||||
referenced = ref->referencedEntity->cursor;
|
||||
SetUsePreflight(db, lex_parent);
|
||||
|
||||
switch (ref->referencedEntity->kind) {
|
||||
case CXIdxEntity_CXXNamespaceAlias:
|
||||
case CXIdxEntity_Unexposed:
|
||||
LOG_S(INFO) << "CXIdxEntity_Unexposed " << cursor.get_spell_name();
|
||||
break;
|
||||
|
||||
case CXIdxEntity_CXXNamespace: {
|
||||
ClangCursor referenced = ref->referencedEntity->cursor;
|
||||
IndexType* ns = db->Resolve(db->ToTypeId(referenced.get_usr_hash()));
|
||||
AddUse(db, ns->uses, cursor.get_spell(), fromContainer(ref->container));
|
||||
break;
|
||||
}
|
||||
|
||||
case CXIdxEntity_CXXNamespaceAlias: {
|
||||
IndexType* ns = db->Resolve(db->ToTypeId(referenced.get_usr_hash()));
|
||||
AddUse(db, ns->uses, cursor.get_spell(), fromContainer(ref->container));
|
||||
if (!ns->def.spell) {
|
||||
ClangCursor sem_parent = referenced.get_semantic_parent();
|
||||
ClangCursor lex_parent = referenced.get_lexical_parent();
|
||||
SetUsePreflight(db, sem_parent);
|
||||
SetUsePreflight(db, lex_parent);
|
||||
ns->def.spell = SetUse(db, referenced.get_spell(), sem_parent, Role::Definition);
|
||||
ns->def.extent = SetUse(db, referenced.get_extent(), lex_parent, Role::None);
|
||||
std::string name = referenced.get_spell_name();
|
||||
SetTypeName(ns, referenced, nullptr, name.c_str(), param);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case CXIdxEntity_ObjCProperty:
|
||||
case CXIdxEntity_ObjCIvar:
|
||||
case CXIdxEntity_EnumConstant:
|
||||
@ -2146,6 +2152,7 @@ void OnIndexReference(CXClientData client_data, const CXIdxEntityRefInfo* ref) {
|
||||
case CXIdxEntity_ObjCProtocol:
|
||||
case CXIdxEntity_ObjCClass:
|
||||
case CXIdxEntity_Typedef:
|
||||
case CXIdxEntity_CXXInterface: // MSVC __interface
|
||||
case CXIdxEntity_CXXTypeAlias:
|
||||
case CXIdxEntity_Enum:
|
||||
case CXIdxEntity_Union:
|
||||
@ -2176,36 +2183,6 @@ void OnIndexReference(CXClientData client_data, const CXIdxEntityRefInfo* ref) {
|
||||
UniqueAddUseSpell(db, ref_type->uses, ref->cursor);
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
std::cerr
|
||||
<< "!! Unhandled indexEntityReference: " << cursor.ToString()
|
||||
<< " at "
|
||||
<< ClangCursor(ref->cursor).get_spell().start.ToString()
|
||||
<< std::endl;
|
||||
std::cerr << " ref->referencedEntity->kind = "
|
||||
<< ref->referencedEntity->kind << std::endl;
|
||||
if (ref->parentEntity)
|
||||
std::cerr << " ref->parentEntity->kind = "
|
||||
<< ref->parentEntity->kind << std::endl;
|
||||
std::cerr
|
||||
<< " ref->loc = "
|
||||
<< ClangCursor(ref->cursor).get_spell().start.ToString()
|
||||
<< std::endl;
|
||||
std::cerr << " ref->kind = " << ref->kind << std::endl;
|
||||
if (ref->parentEntity)
|
||||
std::cerr << " parentEntity = "
|
||||
<< ClangCursor(ref->parentEntity->cursor).ToString()
|
||||
<< std::endl;
|
||||
if (ref->referencedEntity)
|
||||
std::cerr << " referencedEntity = "
|
||||
<< ClangCursor(ref->referencedEntity->cursor).ToString()
|
||||
<< std::endl;
|
||||
if (ref->container)
|
||||
std::cerr << " container = "
|
||||
<< ClangCursor(ref->container->cursor).ToString()
|
||||
<< std::endl;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -638,6 +638,6 @@ MAKE_REFLECT_STRUCT(Out_CquerySetInactiveRegion, jsonrpc, method, params);
|
||||
|
||||
struct Out_LocationList : public lsOutMessage<Out_LocationList> {
|
||||
lsRequestId id;
|
||||
std::vector<lsLocation> result;
|
||||
std::vector<lsLocationEx> result;
|
||||
};
|
||||
MAKE_REFLECT_STRUCT(Out_LocationList, jsonrpc, id, result);
|
||||
|
@ -27,13 +27,15 @@ struct CqueryBaseHandler : BaseMessageHandler<Ipc_CqueryBase> {
|
||||
FindSymbolsAtLocation(working_file, file, request->params.position)) {
|
||||
if (sym.kind == SymbolKind::Type) {
|
||||
if (const auto* def = db->GetType(sym).AnyDef())
|
||||
out.result = GetLsLocations(db, working_files,
|
||||
ToUses(db, def->parents), config->maxXrefResults);
|
||||
out.result =
|
||||
GetLsLocationExs(db, working_files, ToUses(db, def->parents),
|
||||
config->xref.container, config->xref.maxNum);
|
||||
break;
|
||||
} else if (sym.kind == SymbolKind::Func) {
|
||||
if (const auto* def = db->GetFunc(sym).AnyDef())
|
||||
out.result = GetLsLocations(db, working_files, ToUses(db, def->base),
|
||||
config->maxXrefResults);
|
||||
out.result =
|
||||
GetLsLocationExs(db, working_files, ToUses(db, def->base),
|
||||
config->xref.container, config->xref.maxNum);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -32,7 +32,9 @@ struct CqueryCallersHandler : BaseMessageHandler<Ipc_CqueryCallers> {
|
||||
uses.push_back(func_ref);
|
||||
for (Use func_ref : GetCallersForAllDerivedFunctions(db, func))
|
||||
uses.push_back(func_ref);
|
||||
out.result = GetLsLocations(db, working_files, uses, config->maxXrefResults);
|
||||
out.result =
|
||||
GetLsLocationExs(db, working_files, uses, config->xref.container,
|
||||
config->xref.maxNum);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -27,13 +27,14 @@ struct CqueryDerivedHandler : BaseMessageHandler<Ipc_CqueryDerived> {
|
||||
FindSymbolsAtLocation(working_file, file, request->params.position)) {
|
||||
if (sym.kind == SymbolKind::Type) {
|
||||
QueryType& type = db->GetType(sym);
|
||||
out.result = GetLsLocations(db, working_files, ToUses(db, type.derived),
|
||||
config->maxXrefResults);
|
||||
out.result =
|
||||
GetLsLocationExs(db, working_files, ToUses(db, type.derived),
|
||||
config->xref.container, config->xref.maxNum);
|
||||
break;
|
||||
} else if (sym.kind == SymbolKind::Func) {
|
||||
QueryFunc& func = db->GetFunc(sym);
|
||||
out.result = GetLsLocations(db, working_files, ToUses(db, func.derived),
|
||||
config->maxXrefResults);
|
||||
out.result = GetLsLocationExs(db, working_files, ToUses(db, func.derived),
|
||||
config->xref.container, config->xref.maxNum);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -101,7 +101,7 @@ struct CqueryRandomHandler : BaseMessageHandler<Ipc_CqueryRandom> {
|
||||
}
|
||||
|
||||
std::vector<double> x(n, 1), y;
|
||||
for (int j = 0; j < 30; j++) {
|
||||
for (int j = 0; j < 8; j++) {
|
||||
y.assign(n, kDamping);
|
||||
for (int i = 0; i < n; i++)
|
||||
for (auto& it : adj[i])
|
||||
@ -124,8 +124,8 @@ struct CqueryRandomHandler : BaseMessageHandler<Ipc_CqueryRandom> {
|
||||
Maybe<Use> use = GetDefinitionExtentOfSymbol(db, syms[i]);
|
||||
if (!use)
|
||||
continue;
|
||||
optional<lsLocation> ls_loc = GetLsLocation(db, working_files, *use);
|
||||
if (ls_loc)
|
||||
if (auto ls_loc = GetLsLocationEx(db, working_files, *use,
|
||||
config->xref.container))
|
||||
out.result.push_back(*ls_loc);
|
||||
break;
|
||||
}
|
||||
|
@ -39,8 +39,8 @@ struct CqueryVarsHandler : BaseMessageHandler<Ipc_CqueryVars> {
|
||||
case SymbolKind::Type: {
|
||||
QueryType& type = db->types[id.id];
|
||||
out.result =
|
||||
GetLsLocations(db, working_files, ToUses(db, type.instances),
|
||||
config->maxXrefResults);
|
||||
GetLsLocationExs(db, working_files, ToUses(db, type.instances),
|
||||
config->xref.container, config->xref.maxNum);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,3 @@
|
||||
#include "fuzzy_match.h"
|
||||
#include "lex_utils.h"
|
||||
#include "message_handler.h"
|
||||
#include "query_utils.h"
|
||||
@ -21,18 +20,17 @@ REGISTER_IPC_MESSAGE(Ipc_TextDocumentDefinition);
|
||||
struct Out_TextDocumentDefinition
|
||||
: public lsOutMessage<Out_TextDocumentDefinition> {
|
||||
lsRequestId id;
|
||||
std::vector<lsLocation> result;
|
||||
std::vector<lsLocationEx> result;
|
||||
};
|
||||
MAKE_REFLECT_STRUCT(Out_TextDocumentDefinition, jsonrpc, id, result);
|
||||
|
||||
std::vector<Use> GetGotoDefinitionTargets(QueryDatabase* db,
|
||||
SymbolRef sym) {
|
||||
switch (sym.kind) {
|
||||
// Returns GetDeclarationsOfSymbolForGotoDefinition and
|
||||
// variable type definition.
|
||||
case SymbolKind::Var: {
|
||||
std::vector<Use> ret =
|
||||
GetDeclarationsOfSymbolForGotoDefinition(db, sym);
|
||||
// If there is no declaration, jump the its type.
|
||||
if (ret.empty()) {
|
||||
for (auto& def : db->GetVar(sym).def)
|
||||
if (def.type) {
|
||||
@ -67,6 +65,7 @@ struct TextDocumentDefinitionHandler
|
||||
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;
|
||||
@ -87,6 +86,7 @@ struct TextDocumentDefinitionHandler
|
||||
// If on a definition, clear |uses| to find declarations below.
|
||||
if (spell.file == file_id &&
|
||||
spell.range.Contains(target_line, target_column)) {
|
||||
on_def = spell;
|
||||
uses.clear();
|
||||
return false;
|
||||
}
|
||||
@ -99,10 +99,16 @@ struct TextDocumentDefinitionHandler
|
||||
return true;
|
||||
});
|
||||
|
||||
if (uses.empty())
|
||||
if (uses.empty()) {
|
||||
// The symbol has no definition or the cursor is on a definition.
|
||||
uses = GetGotoDefinitionTargets(db, sym);
|
||||
// There is no declaration but the cursor is on a definition.
|
||||
if (uses.empty() && on_def)
|
||||
uses.push_back(*on_def);
|
||||
}
|
||||
AddRange(&out.result,
|
||||
GetLsLocations(db, working_files, uses, config->maxXrefResults));
|
||||
GetLsLocationExs(db, working_files, uses, config->xref.container,
|
||||
config->xref.maxNum));
|
||||
if (!out.result.empty())
|
||||
break;
|
||||
}
|
||||
@ -111,7 +117,7 @@ struct TextDocumentDefinitionHandler
|
||||
if (out.result.empty()) {
|
||||
for (const IndexInclude& include : file->def->includes) {
|
||||
if (include.line == target_line) {
|
||||
lsLocation result;
|
||||
lsLocationEx result;
|
||||
result.uri = lsDocumentUri::FromPath(include.resolved_path);
|
||||
out.result.push_back(result);
|
||||
has_symbol = true;
|
||||
@ -154,8 +160,8 @@ struct TextDocumentDefinitionHandler
|
||||
if (best_i != -1) {
|
||||
Maybe<Use> use = GetDefinitionSpellingOfSymbol(db, db->symbols[best_i]);
|
||||
assert(use);
|
||||
optional<lsLocation> ls_loc = GetLsLocation(db, working_files, *use);
|
||||
if (ls_loc)
|
||||
if (auto ls_loc = GetLsLocationEx(db, working_files, *use,
|
||||
config->xref.container))
|
||||
out.result.push_back(*ls_loc);
|
||||
}
|
||||
}
|
||||
|
@ -56,9 +56,8 @@ struct TextDocumentReferencesHandler
|
||||
// Found symbol. Return references.
|
||||
EachUse(db, sym, request->params.context.includeDeclaration,
|
||||
[&](Use use) {
|
||||
if (optional<lsLocationEx> ls_loc =
|
||||
GetLsLocationEx(db, working_files, use,
|
||||
config->extension.referenceContainer))
|
||||
if (optional<lsLocationEx> ls_loc = GetLsLocationEx(
|
||||
db, working_files, use, config->xref.container))
|
||||
out.result.push_back(*ls_loc);
|
||||
});
|
||||
break;
|
||||
|
@ -6,6 +6,7 @@
|
||||
|
||||
#include <climits>
|
||||
#include <queue>
|
||||
#include <stack>
|
||||
#include <unordered_set>
|
||||
|
||||
namespace {
|
||||
@ -118,25 +119,25 @@ std::vector<Use> GetDeclarationsOfSymbolForGotoDefinition(
|
||||
|
||||
bool HasCallersOnSelfOrBaseOrDerived(QueryDatabase* db, QueryFunc& root) {
|
||||
std::unordered_set<Usr> seen;
|
||||
std::queue<QueryFunc*> queue;
|
||||
std::stack<QueryFunc*> stack;
|
||||
seen.insert(root.usr);
|
||||
queue.push(&root);
|
||||
while (!queue.empty()) {
|
||||
QueryFunc& func = *queue.front();
|
||||
queue.pop();
|
||||
stack.push(&root);
|
||||
while (!stack.empty()) {
|
||||
QueryFunc& func = *stack.top();
|
||||
stack.pop();
|
||||
if (!func.uses.empty())
|
||||
return true;
|
||||
if (auto* def = func.AnyDef()) {
|
||||
EachDefinedEntity(db->funcs, def->base, [&](QueryFunc& func1) {
|
||||
if (!seen.count(func1.usr)) {
|
||||
seen.insert(func1.usr);
|
||||
queue.push(&func1);
|
||||
stack.push(&func1);
|
||||
}
|
||||
});
|
||||
EachDefinedEntity(db->funcs, func.derived, [&](QueryFunc& func1) {
|
||||
if (!seen.count(func1.usr)) {
|
||||
seen.insert(func1.usr);
|
||||
queue.push(&func1);
|
||||
stack.push(&func1);
|
||||
}
|
||||
});
|
||||
}
|
||||
@ -147,22 +148,20 @@ bool HasCallersOnSelfOrBaseOrDerived(QueryDatabase* db, QueryFunc& root) {
|
||||
std::vector<Use> GetCallersForAllBaseFunctions(QueryDatabase* db,
|
||||
QueryFunc& root) {
|
||||
std::vector<Use> callers;
|
||||
const QueryFunc::Def* def = root.AnyDef();
|
||||
if (!def)
|
||||
return callers;
|
||||
|
||||
std::queue<QueryFunc*> queue;
|
||||
EachDefinedEntity(db->funcs, def->base, [&](QueryFunc& func1) {
|
||||
queue.push(&func1);
|
||||
});
|
||||
while (!queue.empty()) {
|
||||
QueryFunc& func = *queue.front();
|
||||
queue.pop();
|
||||
|
||||
std::unordered_set<Usr> seen;
|
||||
std::stack<QueryFunc*> stack;
|
||||
seen.insert(root.usr);
|
||||
stack.push(&root);
|
||||
while (!stack.empty()) {
|
||||
QueryFunc& func = *stack.top();
|
||||
stack.pop();
|
||||
AddRange(&callers, func.uses);
|
||||
if (const QueryFunc::Def* def1 = func.AnyDef()) {
|
||||
EachDefinedEntity(db->funcs, def1->base, [&](QueryFunc& func1) {
|
||||
queue.push(&func1);
|
||||
if (auto* def = func.AnyDef()) {
|
||||
EachDefinedEntity(db->funcs, def->base, [&](QueryFunc& func1) {
|
||||
if (!seen.count(func1.usr)) {
|
||||
seen.insert(func1.usr);
|
||||
stack.push(&func1);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
@ -173,20 +172,20 @@ std::vector<Use> GetCallersForAllBaseFunctions(QueryDatabase* db,
|
||||
std::vector<Use> GetCallersForAllDerivedFunctions(QueryDatabase* db,
|
||||
QueryFunc& root) {
|
||||
std::vector<Use> callers;
|
||||
|
||||
std::queue<QueryFunc*> queue;
|
||||
EachDefinedEntity(db->funcs, root.derived, [&](QueryFunc& func) {
|
||||
queue.push(&func);
|
||||
});
|
||||
|
||||
while (!queue.empty()) {
|
||||
QueryFunc& func = *queue.front();
|
||||
queue.pop();
|
||||
|
||||
EachDefinedEntity(db->funcs, func.derived, [&](QueryFunc& func1) {
|
||||
queue.push(&func1);
|
||||
});
|
||||
std::unordered_set<Usr> seen;
|
||||
std::stack<QueryFunc*> stack;
|
||||
seen.insert(root.usr);
|
||||
stack.push(&root);
|
||||
while (!stack.empty()) {
|
||||
QueryFunc& func = *stack.top();
|
||||
stack.pop();
|
||||
AddRange(&callers, func.uses);
|
||||
EachDefinedEntity(db->funcs, func.derived, [&](QueryFunc& func1) {
|
||||
if (!seen.count(func1.usr)) {
|
||||
seen.insert(func1.usr);
|
||||
stack.push(&func1);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return callers;
|
||||
@ -198,12 +197,10 @@ optional<lsPosition> GetLsPosition(WorkingFile* working_file,
|
||||
return lsPosition(position.line, position.column);
|
||||
|
||||
int column = position.column;
|
||||
optional<int> start =
|
||||
working_file->GetBufferPosFromIndexPos(position.line, &column, false);
|
||||
if (!start)
|
||||
return nullopt;
|
||||
|
||||
return lsPosition(*start, column);
|
||||
if (optional<int> start =
|
||||
working_file->GetBufferPosFromIndexPos(position.line, &column, false))
|
||||
return lsPosition(*start, column);
|
||||
return nullopt;
|
||||
}
|
||||
|
||||
optional<lsRange> GetLsRange(WorkingFile* working_file, const Range& location) {
|
||||
@ -272,13 +269,13 @@ optional<lsLocation> GetLsLocation(QueryDatabase* db,
|
||||
optional<lsLocationEx> GetLsLocationEx(QueryDatabase* db,
|
||||
WorkingFiles* working_files,
|
||||
Use use,
|
||||
bool extension) {
|
||||
bool container) {
|
||||
optional<lsLocation> ls_loc = GetLsLocation(db, working_files, use);
|
||||
if (!ls_loc)
|
||||
return nullopt;
|
||||
lsLocationEx ret;
|
||||
ret.lsLocation::operator=(*ls_loc);
|
||||
if (extension) {
|
||||
if (container) {
|
||||
EachEntityDef(db, use, [&](const auto& def) {
|
||||
ret.containerName = std::string_view(def.detailed_name);
|
||||
return false;
|
||||
@ -287,17 +284,15 @@ optional<lsLocationEx> GetLsLocationEx(QueryDatabase* db,
|
||||
return ret;
|
||||
}
|
||||
|
||||
std::vector<lsLocation> GetLsLocations(QueryDatabase* db,
|
||||
WorkingFiles* working_files,
|
||||
const std::vector<Use>& uses,
|
||||
int limit) {
|
||||
std::vector<lsLocation> ret;
|
||||
for (Use use : uses) {
|
||||
optional<lsLocation> location =
|
||||
GetLsLocation(db, working_files, use);
|
||||
if (location)
|
||||
ret.push_back(*location);
|
||||
}
|
||||
std::vector<lsLocationEx> GetLsLocationExs(QueryDatabase* db,
|
||||
WorkingFiles* working_files,
|
||||
const std::vector<Use>& uses,
|
||||
bool container,
|
||||
int limit) {
|
||||
std::vector<lsLocationEx> ret;
|
||||
for (Use use : uses)
|
||||
if (auto loc = GetLsLocationEx(db, working_files, use, container))
|
||||
ret.push_back(*loc);
|
||||
std::sort(ret.begin(), ret.end());
|
||||
ret.erase(std::unique(ret.begin(), ret.end()), ret.end());
|
||||
if (ret.size() > limit)
|
||||
@ -311,6 +306,8 @@ optional<lsSymbolInformation> GetSymbolInfo(QueryDatabase* db,
|
||||
SymbolIdx sym,
|
||||
bool use_short_name) {
|
||||
switch (sym.kind) {
|
||||
case SymbolKind::Invalid:
|
||||
break;
|
||||
case SymbolKind::File: {
|
||||
QueryFile& file = db->GetFile(sym);
|
||||
if (!file.def)
|
||||
@ -321,51 +318,19 @@ optional<lsSymbolInformation> GetSymbolInfo(QueryDatabase* db,
|
||||
info.kind = lsSymbolKind::File;
|
||||
return info;
|
||||
}
|
||||
case SymbolKind::Type: {
|
||||
const QueryType::Def* def = db->GetType(sym).AnyDef();
|
||||
if (!def)
|
||||
break;
|
||||
|
||||
default: {
|
||||
lsSymbolInformation info;
|
||||
if (use_short_name)
|
||||
info.name = def->ShortName();
|
||||
else
|
||||
info.name = def->detailed_name;
|
||||
info.kind = def->kind;
|
||||
if (def->detailed_name.c_str() != def->ShortName())
|
||||
info.containerName = def->detailed_name;
|
||||
EachEntityDef(db, sym, [&](const auto& def) {
|
||||
if (use_short_name)
|
||||
info.name = def.ShortName();
|
||||
else
|
||||
info.name = def.detailed_name;
|
||||
info.kind = def.kind;
|
||||
info.containerName = def.detailed_name;
|
||||
return false;
|
||||
});
|
||||
return info;
|
||||
}
|
||||
case SymbolKind::Func: {
|
||||
const QueryFunc::Def* def = db->GetFunc(sym).AnyDef();
|
||||
if (!def)
|
||||
break;
|
||||
|
||||
lsSymbolInformation info;
|
||||
if (use_short_name)
|
||||
info.name = def->ShortName();
|
||||
else
|
||||
info.name = def->detailed_name;
|
||||
info.kind = def->kind;
|
||||
info.containerName = def->detailed_name;
|
||||
return info;
|
||||
}
|
||||
case SymbolKind::Var: {
|
||||
const QueryVar::Def* def = db->GetVar(sym).AnyDef();
|
||||
if (!def)
|
||||
break;
|
||||
|
||||
lsSymbolInformation info;
|
||||
if (use_short_name)
|
||||
info.name = def->ShortName();
|
||||
else
|
||||
info.name = def->detailed_name;
|
||||
info.kind = def->kind;
|
||||
info.containerName = def->detailed_name;
|
||||
return info;
|
||||
}
|
||||
case SymbolKind::Invalid:
|
||||
break;
|
||||
}
|
||||
|
||||
return nullopt;
|
||||
|
@ -41,11 +41,12 @@ optional<lsLocation> GetLsLocation(QueryDatabase* db,
|
||||
optional<lsLocationEx> GetLsLocationEx(QueryDatabase* db,
|
||||
WorkingFiles* working_files,
|
||||
Use use,
|
||||
bool extension);
|
||||
std::vector<lsLocation> GetLsLocations(QueryDatabase* db,
|
||||
WorkingFiles* working_files,
|
||||
const std::vector<Use>& refs,
|
||||
int limit);
|
||||
bool container);
|
||||
std::vector<lsLocationEx> GetLsLocationExs(QueryDatabase* db,
|
||||
WorkingFiles* working_files,
|
||||
const std::vector<Use>& refs,
|
||||
bool container,
|
||||
int limit);
|
||||
// Returns a symbol. The symbol will have *NOT* have a location assigned.
|
||||
optional<lsSymbolInformation> GetSymbolInfo(QueryDatabase* db,
|
||||
WorkingFiles* working_files,
|
||||
|
14
wscript
14
wscript
@ -83,8 +83,7 @@ def patch_byte_in_libclang(filename, offset, old, new):
|
||||
def options(opt):
|
||||
opt.load('compiler_cxx')
|
||||
grp = opt.add_option_group('Configuration options related to use of clang from the system (not recommended)')
|
||||
grp.add_option('--use-system-clang', dest='use_system_clang', default=False, action='store_true',
|
||||
help='deprecated. Please specify --llvm-config, e.g. /usr/bin/llvm-config llvm-config-6.0')
|
||||
grp.add_option('--enable-assert', action='store_true')
|
||||
grp.add_option('--use-clang-cxx', dest='use_clang_cxx', default=False, action='store_true',
|
||||
help='use clang C++ API')
|
||||
grp.add_option('--bundled-clang', dest='bundled_clang', default='5.0.1',
|
||||
@ -188,6 +187,12 @@ def configure(ctx):
|
||||
if 'release' in ctx.options.variant:
|
||||
cxxflags.append('-O' if 'asan' in ctx.options.variant else '-O3')
|
||||
|
||||
if ctx.options.enable_assert is None:
|
||||
if 'debug' in ctx.options.variant:
|
||||
ctx.options.enable_assert = True
|
||||
if not ctx.options.enable_assert:
|
||||
ctx.define('NDEBUG', 1)
|
||||
|
||||
if ctx.env.CXX_NAME == 'clang' and 'debug' in ctx.options.variant:
|
||||
cxxflags.append('-fno-limit-debug-info')
|
||||
|
||||
@ -208,11 +213,6 @@ def configure(ctx):
|
||||
return 'lib' + lib
|
||||
return lib
|
||||
|
||||
# TODO remove
|
||||
if ctx.options.use_system_clang:
|
||||
print((('!' * 50)+'\n')*3)
|
||||
print('--use-system-clang is deprecated. Please specify --llvm-config, e.g. /usr/bin/llvm-config llvm-config-6.0')
|
||||
|
||||
# Do not use bundled clang+llvm
|
||||
if ctx.options.llvm_config is not None or ctx.options.clang_prefix is not None:
|
||||
if ctx.options.llvm_config is not None:
|
||||
|
Loading…
Reference in New Issue
Block a user