Simplify Index* Query*

This commit is contained in:
Fangrui Song 2018-02-18 10:07:13 -08:00
parent afdde4d59f
commit f3134d564c
11 changed files with 200 additions and 275 deletions

View File

@ -662,16 +662,14 @@ ClangCompleteManager::~ClangCompleteManager() {}
void ClangCompleteManager::CodeComplete( void ClangCompleteManager::CodeComplete(
const lsTextDocumentPositionParams& completion_location, const lsTextDocumentPositionParams& completion_location,
const OnComplete& on_complete) { const OnComplete& on_complete) {
completion_request_.PushBack(MakeUnique<CompletionRequest>(completion_location.textDocument, completion_request_.PushBack(MakeUnique<CompletionRequest>(
completion_location.position, completion_location.textDocument, completion_location.position,
on_complete, on_complete, false));
false));
} }
void ClangCompleteManager::DiagnosticsUpdate( void ClangCompleteManager::DiagnosticsUpdate(
const lsTextDocumentIdentifier& document) { const lsTextDocumentIdentifier& document) {
completion_request_.PushBack(MakeUnique<CompletionRequest>(document, completion_request_.PushBack(MakeUnique<CompletionRequest>(document, true));
true));
} }
void ClangCompleteManager::NotifyView(const std::string& filename) { void ClangCompleteManager::NotifyView(const std::string& filename) {

View File

@ -84,7 +84,7 @@ ClangType ClangType::strip_qualifiers() const {
return cx; return cx;
} }
std::string ClangType::get_spelling() const { std::string ClangType::get_spell_name() const {
return ToString(clang_getTypeSpelling(cx_type)); return ToString(clang_getTypeSpelling(cx_type));
} }
@ -141,11 +141,11 @@ ClangType ClangCursor::get_type() const {
return ClangType(clang_getCursorType(cx_cursor)); return ClangType(clang_getCursorType(cx_cursor));
} }
std::string ClangCursor::get_spelling() const { std::string ClangCursor::get_spell_name() const {
return ::ToString(clang_getCursorSpelling(cx_cursor)); return ::ToString(clang_getCursorSpelling(cx_cursor));
} }
Range ClangCursor::get_spelling_range(CXFile* cx_file) const { Range ClangCursor::get_spell(CXFile* cx_file) const {
// TODO for Objective-C methods and Objective-C message expressions, there are // TODO for Objective-C methods and Objective-C message expressions, there are
// multiple pieces for each selector identifier. // multiple pieces for each selector identifier.
CXSourceRange range = clang_Cursor_getSpellingNameRange(cx_cursor, 0, 0); CXSourceRange range = clang_Cursor_getSpellingNameRange(cx_cursor, 0, 0);
@ -294,5 +294,5 @@ NtString ClangCursor::get_comments() const {
} }
std::string ClangCursor::ToString() const { std::string ClangCursor::ToString() const {
return ::ToString(get_kind()) + " " + get_spelling(); return ::ToString(get_kind()) + " " + get_spell_name();
} }

View File

@ -30,7 +30,7 @@ class ClangType {
ClangCursor get_declaration() const; ClangCursor get_declaration() const;
std::string get_usr() const; std::string get_usr() const;
Usr get_usr_hash() const; Usr get_usr_hash() const;
std::string get_spelling() const; std::string get_spell_name() const;
ClangType get_canonical() const; ClangType get_canonical() const;
// Try to resolve this type and remove qualifies, ie, Foo* will become Foo // Try to resolve this type and remove qualifies, ie, Foo* will become Foo
@ -54,8 +54,8 @@ class ClangCursor {
CXCursorKind get_kind() const; CXCursorKind get_kind() const;
ClangType get_type() const; ClangType get_type() const;
std::string get_spelling() const; std::string get_spell_name() const;
Range get_spelling_range(CXFile* cx_file = nullptr) const; Range get_spell(CXFile* cx_file = nullptr) const;
Range get_extent() const; Range get_extent() const;
std::string get_display_name() const; std::string get_display_name() const;
std::string get_usr() const; std::string get_usr() const;

View File

@ -448,8 +448,6 @@ std::string GetDocumentContentInRange(CXTranslationUnit cx_tu,
void SetUsePreflight(IndexFile* db, ClangCursor parent) { void SetUsePreflight(IndexFile* db, ClangCursor parent) {
switch (GetSymbolKind(parent.get_kind())) { switch (GetSymbolKind(parent.get_kind())) {
default:
break;
case SymbolKind::Func: { case SymbolKind::Func: {
(void)db->ToFuncId(parent.cx_cursor); (void)db->ToFuncId(parent.cx_cursor);
break; break;
@ -461,36 +459,30 @@ void SetUsePreflight(IndexFile* db, ClangCursor parent) {
case SymbolKind::Var: { case SymbolKind::Var: {
(void)db->ToVarId(parent.cx_cursor); (void)db->ToVarId(parent.cx_cursor);
break; break;
default:
break;
} }
} }
} }
// |parent| should be resolved before using |SetUsePreflight| so that |def| will // |parent| should be resolved before using |SetUsePreflight| so that |def| will
// not be invalidated by |To{Func,Type,Var}Id|. // not be invalidated by |To{Func,Type,Var}Id|.
void SetUse(IndexFile* db, Use SetUse(IndexFile* db, Range range, ClangCursor parent, Role role) {
Maybe<Use>* def,
Range range,
ClangCursor parent,
Role role) {
switch (GetSymbolKind(parent.get_kind())) { switch (GetSymbolKind(parent.get_kind())) {
default:
*def = Use(range, Id<void>(), SymbolKind::File, role);
break;
case SymbolKind::Func: { case SymbolKind::Func: {
IndexFuncId id = db->ToFuncId(parent.cx_cursor); IndexFuncId id = db->ToFuncId(parent.cx_cursor);
*def = Use(range, id, SymbolKind::Func, Role::Definition); return Use(range, id, SymbolKind::Func, Role::Definition, {});
break;
} }
case SymbolKind::Type: { case SymbolKind::Type: {
IndexTypeId id = db->ToTypeId(parent.cx_cursor); IndexTypeId id = db->ToTypeId(parent.cx_cursor);
*def = Use(range, id, SymbolKind::Type, Role::Definition); return Use(range, id, SymbolKind::Type, Role::Definition, {});
break;
} }
case SymbolKind::Var: { case SymbolKind::Var: {
IndexVarId id = db->ToVarId(parent.cx_cursor); IndexVarId id = db->ToVarId(parent.cx_cursor);
*def = Use(range, id, SymbolKind::Var, Role::Definition); return Use(range, id, SymbolKind::Var, Role::Definition, {});
break;
} }
default:
return Use(range, Id<void>(), SymbolKind::File, role, {});
} }
} }
@ -552,7 +544,7 @@ optional<IndexTypeId> ResolveToDeclarationType(IndexFile* db,
IndexTypeId type_id = db->ToTypeId(usr); IndexTypeId type_id = db->ToTypeId(usr);
IndexType* typ = db->Resolve(type_id); IndexType* typ = db->Resolve(type_id);
if (typ->def.detailed_name.empty()) { if (typ->def.detailed_name.empty()) {
std::string name = declaration.get_spelling(); std::string name = declaration.get_spell_name();
SetTypeName(typ, declaration, nullptr, name.c_str(), param); SetTypeName(typ, declaration, nullptr, name.c_str(), param);
} }
return type_id; return type_id;
@ -616,7 +608,7 @@ void SetVarDetail(IndexVar* var,
clang_getResultType(deref).kind == CXType_Invalid && clang_getResultType(deref).kind == CXType_Invalid &&
clang_getElementType(deref).kind == CXType_Invalid) { clang_getElementType(deref).kind == CXType_Invalid) {
const FileContents& fc = param->file_contents[db->path]; const FileContents& fc = param->file_contents[db->path];
optional<int> spell_end = fc.ToOffset(cursor.get_spelling_range().end); optional<int> spell_end = fc.ToOffset(cursor.get_spell().end);
optional<int> extent_end = fc.ToOffset(cursor.get_extent().end); optional<int> extent_end = fc.ToOffset(cursor.get_extent().end);
if (extent_end && *spell_end < *extent_end) if (extent_end && *spell_end < *extent_end)
def.hover = std::string(def.detailed_name.c_str()) + def.hover = std::string(def.detailed_name.c_str()) +
@ -656,19 +648,19 @@ void OnIndexReference_Function(IndexFile* db,
IndexFunc* called = db->Resolve(called_id); IndexFunc* called = db->Resolve(called_id);
parent->def.callees.push_back( parent->def.callees.push_back(
SymbolRef(loc, called->id, SymbolKind::Func, role)); SymbolRef(loc, called->id, SymbolKind::Func, role));
AddFuncUse(&called->uses, Use(loc, parent->id, SymbolKind::Func, role)); AddFuncUse(&called->uses, Use(loc, parent->id, SymbolKind::Func, role, {}));
break; break;
} }
case SymbolKind::Type: { case SymbolKind::Type: {
IndexType* parent = db->Resolve(db->ToTypeId(parent_cursor.cx_cursor)); IndexType* parent = db->Resolve(db->ToTypeId(parent_cursor.cx_cursor));
IndexFunc* called = db->Resolve(called_id); IndexFunc* called = db->Resolve(called_id);
called = db->Resolve(called_id); called = db->Resolve(called_id);
AddFuncUse(&called->uses, Use(loc, parent->id, SymbolKind::Type, role)); AddFuncUse(&called->uses, Use(loc, parent->id, SymbolKind::Type, role, {}));
break; break;
} }
default: { default: {
IndexFunc* called = db->Resolve(called_id); IndexFunc* called = db->Resolve(called_id);
AddFuncUse(&called->uses, Use(loc, Id<void>(), SymbolKind::File, role)); AddFuncUse(&called->uses, Use(loc, Id<void>(), SymbolKind::File, role, {}));
break; break;
} }
} }
@ -677,7 +669,7 @@ void OnIndexReference_Function(IndexFile* db,
} // namespace } // namespace
// static // static
const int IndexFile::kMajorVersion = 13; const int IndexFile::kMajorVersion = 14;
const int IndexFile::kMinorVersion = 0; 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)
@ -761,7 +753,7 @@ void UniqueAdd(std::vector<T>& values, T value) {
// FIXME Reference: set id in call sites and remove this // FIXME Reference: set id in call sites and remove this
void AddUse(std::vector<Use>& values, Range value) { void AddUse(std::vector<Use>& values, Range value) {
values.push_back( values.push_back(
Use(value, Id<void>(), SymbolKind::File, Role::Reference)); Use(value, Id<void>(), SymbolKind::File, Role::Reference, {}));
} }
void AddUse(IndexFile* db, void AddUse(IndexFile* db,
@ -770,16 +762,16 @@ void AddUse(IndexFile* db,
ClangCursor parent, ClangCursor parent,
Role role = Role::Reference) { Role role = Role::Reference) {
switch (GetSymbolKind(parent.get_kind())) { switch (GetSymbolKind(parent.get_kind())) {
default:
uses.push_back(Use(range, Id<void>(), SymbolKind::File, role));
break;
case SymbolKind::Func: case SymbolKind::Func:
uses.push_back( uses.push_back(Use(range, db->ToFuncId(parent.cx_cursor),
Use(range, db->ToFuncId(parent.cx_cursor), SymbolKind::Func, role)); SymbolKind::Func, role, {}));
break; break;
case SymbolKind::Type: case SymbolKind::Type:
uses.push_back( uses.push_back(Use(range, db->ToTypeId(parent.cx_cursor),
Use(range, db->ToTypeId(parent.cx_cursor), SymbolKind::Type, role)); SymbolKind::Type, role, {}));
break;
default:
uses.push_back(Use(range, Id<void>(), SymbolKind::File, role, {}));
break; break;
} }
} }
@ -791,7 +783,7 @@ CXCursor fromContainer(const CXIdxContainerInfo* parent) {
void AddUseSpell(IndexFile* db, void AddUseSpell(IndexFile* db,
std::vector<Use>& uses, std::vector<Use>& uses,
ClangCursor cursor) { ClangCursor cursor) {
AddUse(db, uses, cursor.get_spelling_range(), AddUse(db, uses, cursor.get_spell(),
cursor.get_lexical_parent().cx_cursor, Role::Reference); cursor.get_lexical_parent().cx_cursor, Role::Reference);
} }
@ -804,7 +796,7 @@ void UniqueAddUse(IndexFile* db, std::vector<Use>& uses, Range range, Args&&...
template <typename... Args> template <typename... Args>
void UniqueAddUseSpell(IndexFile* db, std::vector<Use>& uses, ClangCursor cursor, Args&&... args) { void UniqueAddUseSpell(IndexFile* db, std::vector<Use>& uses, ClangCursor cursor, Args&&... args) {
Range range = cursor.get_spelling_range(); Range range = cursor.get_spell();
if (std::find_if(uses.begin(), uses.end(), if (std::find_if(uses.begin(), uses.end(),
[&](Use use) { return use.range == range; }) == uses.end()) [&](Use use) { return use.range == range; }) == uses.end())
AddUse(db, uses, range, cursor.get_lexical_parent().cx_cursor, std::forward<Args>(args)...); AddUse(db, uses, range, cursor.get_lexical_parent().cx_cursor, std::forward<Args>(args)...);
@ -875,7 +867,7 @@ ClangCursor::VisitResult DumpVisitor(ClangCursor cursor,
int* level) { int* level) {
for (int i = 0; i < *level; ++i) for (int i = 0; i < *level; ++i)
std::cerr << " "; std::cerr << " ";
std::cerr << ToString(cursor.get_kind()) << " " << cursor.get_spelling() std::cerr << ToString(cursor.get_kind()) << " " << cursor.get_spell_name()
<< std::endl; << std::endl;
*level += 1; *level += 1;
@ -955,7 +947,7 @@ void VisitDeclForTypeUsageVisitorHandler(ClangCursor cursor,
// We will attribute |::C| to the parent class. // We will attribute |::C| to the parent class.
if (param->toplevel_type) { if (param->toplevel_type) {
IndexType* ref_type = db->Resolve(*param->toplevel_type); IndexType* ref_type = db->Resolve(*param->toplevel_type);
std::string name = cursor.get_referenced().get_spelling(); std::string name = cursor.get_referenced().get_spell_name();
if (name == ref_type->def.ShortName()) { if (name == ref_type->def.ShortName()) {
UniqueAddUseSpell(db, ref_type->uses, cursor); UniqueAddUseSpell(db, ref_type->uses, cursor);
param->toplevel_type = nullopt; param->toplevel_type = nullopt;
@ -1210,20 +1202,6 @@ ClangCursor::VisitResult AddDeclInitializerUsagesVisitor(ClangCursor cursor,
return ClangCursor::VisitResult::Recurse; return ClangCursor::VisitResult::Recurse;
} }
void AddDeclInitializerUsages(IndexFile* db, ClangCursor decl_cursor) {
decl_cursor.VisitChildren(&AddDeclInitializerUsagesVisitor, db);
}
bool AreEqualLocations(CXIdxLoc loc, CXCursor cursor) {
// clang_getCursorExtent
// clang_Cursor_getSpellingNameRange
return clang_equalLocations(
clang_indexLoc_getCXSourceLocation(loc),
// clang_getRangeStart(clang_getCursorExtent(cursor)));
clang_getRangeStart(clang_Cursor_getSpellingNameRange(cursor, 0, 0)));
}
ClangCursor::VisitResult VisitMacroDefinitionAndExpansions(ClangCursor cursor, ClangCursor::VisitResult VisitMacroDefinitionAndExpansions(ClangCursor cursor,
ClangCursor parent, ClangCursor parent,
IndexParam* param) { IndexParam* param) {
@ -1261,10 +1239,10 @@ ClangCursor::VisitResult VisitMacroDefinitionAndExpansions(ClangCursor cursor,
"#define " + GetDocumentContentInRange(param->tu->cx_tu, cx_extent); "#define " + GetDocumentContentInRange(param->tu->cx_tu, cx_extent);
var_def->def.kind = ClangSymbolKind::Macro; var_def->def.kind = ClangSymbolKind::Macro;
var_def->def.comments = cursor.get_comments(); var_def->def.comments = cursor.get_comments();
SetUse(db, &var_def->def.spell, decl_loc_spelling, parent, var_def->def.spell =
Role::Definition); SetUse(db, decl_loc_spelling, parent, Role::Definition);
SetUse(db, &var_def->def.extent, var_def->def.extent = SetUse(
ResolveCXSourceRange(cx_extent, nullptr), parent, Role::None); db, ResolveCXSourceRange(cx_extent, nullptr), parent, Role::None);
} else } else
UniqueAddUse(db, var_def->uses, decl_loc_spelling, parent); UniqueAddUse(db, var_def->uses, decl_loc_spelling, parent);
@ -1300,16 +1278,18 @@ ClangCursor::VisitResult TemplateVisitor(ClangCursor cursor,
IndexVarId ref_var_id = db->ToVarId(ref_cursor.get_usr_hash()); IndexVarId ref_var_id = db->ToVarId(ref_cursor.get_usr_hash());
IndexVar* ref_var = db->Resolve(ref_var_id); IndexVar* ref_var = db->Resolve(ref_var_id);
if (ref_var->def.detailed_name.empty()) { if (ref_var->def.detailed_name.empty()) {
SetUsePreflight(db, ref_cursor.get_semantic_parent()); ClangCursor sem_parent = ref_cursor.get_semantic_parent();
SetUsePreflight(db, ref_cursor.get_lexical_parent()); ClangCursor lex_parent = ref_cursor.get_lexical_parent();
SetUsePreflight(db, sem_parent);
SetUsePreflight(db, lex_parent);
ref_var = db->Resolve(ref_var_id); ref_var = db->Resolve(ref_var_id);
SetUse(db, &ref_var->def.spell, ref_cursor.get_spelling_range(), ref_var->def.spell = SetUse(db, ref_cursor.get_spell(),
ref_cursor.get_semantic_parent(), Role::Definition); sem_parent, Role::Definition);
SetUse(db, &ref_var->def.extent, ref_cursor.get_extent(), ref_var->def.extent =
ref_cursor.get_lexical_parent(), Role::None); SetUse(db, ref_cursor.get_extent(), lex_parent, Role::None);
ref_var = db->Resolve(ref_var_id); ref_var = db->Resolve(ref_var_id);
ref_var->def.kind = ClangSymbolKind::Parameter; ref_var->def.kind = ClangSymbolKind::Parameter;
SetVarDetail(ref_var, ref_cursor.get_spelling(), ref_cursor, SetVarDetail(ref_var, ref_cursor.get_spell_name(), ref_cursor,
nullptr, true, db, param); nullptr, true, db, param);
ClangType ref_type = clang_getCursorType(ref_cursor.cx_cursor); ClangType ref_type = clang_getCursorType(ref_cursor.cx_cursor);
@ -1339,7 +1319,7 @@ ClangCursor::VisitResult TemplateVisitor(ClangCursor cursor,
case CXCursor_FunctionDecl: case CXCursor_FunctionDecl:
case CXCursor_FunctionTemplate: { case CXCursor_FunctionTemplate: {
IndexFuncId called_id = db->ToFuncId(overloaded.get_usr_hash()); IndexFuncId called_id = db->ToFuncId(overloaded.get_usr_hash());
OnIndexReference_Function(db, cursor.get_spelling_range(), OnIndexReference_Function(db, cursor.get_spell(),
data->container, called_id, data->container, called_id,
Role::Call); Role::Call);
break; break;
@ -1359,17 +1339,19 @@ ClangCursor::VisitResult TemplateVisitor(ClangCursor cursor,
// CXCursor_TranslationUnit, but not (confirm this) by visiting // CXCursor_TranslationUnit, but not (confirm this) by visiting
// {Class,Function}Template. Thus we need to initialize it here. // {Class,Function}Template. Thus we need to initialize it here.
if (ref_type->def.detailed_name.empty()) { if (ref_type->def.detailed_name.empty()) {
SetUsePreflight(db, ref_cursor.get_semantic_parent()); ClangCursor sem_parent = ref_cursor.get_semantic_parent();
SetUsePreflight(db, ref_cursor.get_lexical_parent()); ClangCursor lex_parent = ref_cursor.get_lexical_parent();
SetUsePreflight(db, sem_parent);
SetUsePreflight(db, lex_parent);
ref_type = db->Resolve(ref_type_id); ref_type = db->Resolve(ref_type_id);
SetUse(db, &ref_type->def.spell, ref_cursor.get_spelling_range(), ref_type->def.spell = SetUse(db, ref_cursor.get_spell(),
ref_cursor.get_semantic_parent(), Role::Definition); sem_parent, Role::Definition);
SetUse(db, &ref_type->def.extent, ref_cursor.get_extent(), ref_type->def.extent =
ref_cursor.get_lexical_parent(), Role::None); SetUse(db, ref_cursor.get_extent(), lex_parent, Role::None);
#if CINDEX_HAVE_PRETTY #if CINDEX_HAVE_PRETTY
ref_type->def.detailed_name = param->PrettyPrintCursor(ref_cursor.cx_cursor); ref_type->def.detailed_name = param->PrettyPrintCursor(ref_cursor.cx_cursor);
#else #else
ref_type->def.detailed_name = ref_cursor.get_spelling(); ref_type->def.detailed_name = ref_cursor.get_spell_name();
#endif #endif
ref_type->def.short_name_offset = 0; ref_type->def.short_name_offset = 0;
ref_type->def.short_name_size = ref_type->def.short_name_size =
@ -1391,17 +1373,19 @@ ClangCursor::VisitResult TemplateVisitor(ClangCursor cursor,
// CXCursor_TranslationUnit, but not (confirm this) by visiting // CXCursor_TranslationUnit, but not (confirm this) by visiting
// {Class,Function}Template. Thus we need to initialize it here. // {Class,Function}Template. Thus we need to initialize it here.
if (ref_type->def.detailed_name.empty()) { if (ref_type->def.detailed_name.empty()) {
SetUsePreflight(db, ref_cursor.get_semantic_parent()); ClangCursor sem_parent = ref_cursor.get_semantic_parent();
SetUsePreflight(db, ref_cursor.get_lexical_parent()); ClangCursor lex_parent = ref_cursor.get_lexical_parent();
SetUsePreflight(db, sem_parent);
SetUsePreflight(db, lex_parent);
ref_type = db->Resolve(ref_type_id); ref_type = db->Resolve(ref_type_id);
SetUse(db, &ref_type->def.spell, ref_cursor.get_spelling_range(), ref_type->def.spell = SetUse(db, ref_cursor.get_spell(),
ref_cursor.get_semantic_parent(), Role::Definition); sem_parent, Role::Definition);
SetUse(db, &ref_type->def.extent, ref_cursor.get_extent(), ref_type->def.extent =
ref_cursor.get_lexical_parent(), Role::None); SetUse(db, ref_cursor.get_extent(), lex_parent, Role::None);
#if CINDEX_HAVE_PRETTY #if CINDEX_HAVE_PRETTY
ref_type->def.detailed_name = param->PrettyPrintCursor(ref_cursor.cx_cursor); ref_type->def.detailed_name = param->PrettyPrintCursor(ref_cursor.cx_cursor);
#else #else
ref_type->def.detailed_name = ref_cursor.get_spelling(); ref_type->def.detailed_name = ref_cursor.get_spell_name();
#endif #endif
ref_type->def.short_name_offset = 0; ref_type->def.short_name_offset = 0;
ref_type->def.short_name_size = ref_type->def.short_name_size =
@ -1441,7 +1425,7 @@ std::string NamespaceHelper::QualifiedName(const CXIdxContainerInfo* container,
} }
for (size_t i = namespaces.size(); i > 0;) { for (size_t i = namespaces.size(); i > 0;) {
i--; i--;
std::string name = namespaces[i].get_spelling(); std::string name = namespaces[i].get_spell_name();
// Empty name indicates unnamed namespace, anonymous struct, anonymous // Empty name indicates unnamed namespace, anonymous struct, anonymous
// union, ... // union, ...
if (name.size()) if (name.size())
@ -1520,15 +1504,16 @@ void OnIndexDeclaration(CXClientData client_data, const CXIdxDeclInfo* decl) {
switch (decl->entityInfo->kind) { switch (decl->entityInfo->kind) {
case CXIdxEntity_CXXNamespace: { case CXIdxEntity_CXXNamespace: {
ClangCursor decl_cursor = decl->cursor; ClangCursor decl_cursor = decl->cursor;
Range decl_spell = decl_cursor.get_spelling_range(); Range spell = decl_cursor.get_spell();
IndexTypeId ns_id = db->ToTypeId(HashUsr(decl->entityInfo->USR)); IndexTypeId ns_id = db->ToTypeId(HashUsr(decl->entityInfo->USR));
IndexType* ns = db->Resolve(ns_id); IndexType* ns = db->Resolve(ns_id);
ns->def.kind = GetSymbolKind(decl->entityInfo->kind); ns->def.kind = GetSymbolKind(decl->entityInfo->kind);
if (ns->def.detailed_name.empty()) { if (ns->def.detailed_name.empty()) {
SetTypeName(ns, decl_cursor, decl->semanticContainer, SetTypeName(ns, decl_cursor, decl->semanticContainer,
decl->entityInfo->name, param); decl->entityInfo->name, param);
SetUse(db, &ns->def.spell, decl_spell, sem_parent, Role::Definition); ns->def.spell = SetUse(db, spell, sem_parent, Role::Definition);
SetUse(db, &ns->def.extent, decl_cursor.get_extent(), lex_parent, Role::None); ns->def.extent =
SetUse(db, decl_cursor.get_extent(), lex_parent, Role::None);
if (decl->semanticContainer) { if (decl->semanticContainer) {
IndexTypeId parent_id = db->ToTypeId( IndexTypeId parent_id = db->ToTypeId(
ClangCursor(decl->semanticContainer->cursor).get_usr_hash()); ClangCursor(decl->semanticContainer->cursor).get_usr_hash());
@ -1538,7 +1523,7 @@ void OnIndexDeclaration(CXClientData client_data, const CXIdxDeclInfo* decl) {
ns->def.parents.push_back(parent_id); ns->def.parents.push_back(parent_id);
} }
} }
AddUse(ns->uses, decl_spell); AddUse(ns->uses, spell);
break; break;
} }
@ -1548,12 +1533,11 @@ void OnIndexDeclaration(CXClientData client_data, const CXIdxDeclInfo* decl) {
case CXIdxEntity_Field: case CXIdxEntity_Field:
case CXIdxEntity_Variable: case CXIdxEntity_Variable:
case CXIdxEntity_CXXStaticVariable: { case CXIdxEntity_CXXStaticVariable: {
ClangCursor decl_cursor = decl->cursor; ClangCursor cursor = decl->cursor;
Range decl_spell = decl_cursor.get_spelling_range(); Range spell = cursor.get_spell();
// Do not index implicit template instantiations. // Do not index implicit template instantiations.
if (decl_cursor != if (cursor != cursor.template_specialization_to_template_definition())
decl_cursor.template_specialization_to_template_definition())
break; break;
IndexVarId var_id = db->ToVarId(HashUsr(decl->entityInfo->USR)); IndexVarId var_id = db->ToVarId(HashUsr(decl->entityInfo->USR));
@ -1574,15 +1558,15 @@ void OnIndexDeclaration(CXClientData client_data, const CXIdxDeclInfo* decl) {
//} //}
if (decl->isDefinition) { if (decl->isDefinition) {
SetUse(db, &var->def.spell, decl_spell, sem_parent, Role::Definition); var->def.spell = SetUse(db, spell, sem_parent, Role::Definition);
SetUse(db, &var->def.extent, decl_cursor.get_extent(), lex_parent, Role::None); var->def.extent =
SetUse(db, cursor.get_extent(), lex_parent, Role::None);
} else { } else {
Maybe<Use> use; var->declarations.push_back(
SetUse(db, &use, decl_spell, lex_parent, Role::Declaration); SetUse(db, spell, lex_parent, Role::Declaration));
var->declarations.push_back(*use);
} }
AddDeclInitializerUsages(db, decl_cursor); cursor.VisitChildren(&AddDeclInitializerUsagesVisitor, db);
var = db->Resolve(var_id); var = db->Resolve(var_id);
// Declaring variable type information. Note that we do not insert an // Declaring variable type information. Note that we do not insert an
@ -1590,7 +1574,7 @@ void OnIndexDeclaration(CXClientData client_data, const CXIdxDeclInfo* decl) {
// the function declaration is encountered since we won't receive ParmDecl // the function declaration is encountered since we won't receive ParmDecl
// declarations for unnamed parameters. // declarations for unnamed parameters.
// TODO: See if we can remove this function call. // TODO: See if we can remove this function call.
AddDeclTypeUsages(db, decl_cursor, var->def.type, AddDeclTypeUsages(db, cursor, var->def.type,
decl->semanticContainer, decl->lexicalContainer); decl->semanticContainer, decl->lexicalContainer);
// We don't need to assign declaring type multiple times if this variable // We don't need to assign declaring type multiple times if this variable
@ -1621,8 +1605,8 @@ void OnIndexDeclaration(CXClientData client_data, const CXIdxDeclInfo* decl) {
case CXIdxEntity_CXXStaticMethod: case CXIdxEntity_CXXStaticMethod:
case CXIdxEntity_CXXConversionFunction: { case CXIdxEntity_CXXConversionFunction: {
ClangCursor decl_cursor = decl->cursor; ClangCursor decl_cursor = decl->cursor;
Range decl_spelling = decl_cursor.get_spelling_range(); Range spell = decl_cursor.get_spell();
Range decl_extent = decl_cursor.get_extent(); Range extent = decl_cursor.get_extent();
ClangCursor decl_cursor_resolved = ClangCursor decl_cursor_resolved =
decl_cursor.template_specialization_to_template_definition(); decl_cursor.template_specialization_to_template_definition();
@ -1648,20 +1632,17 @@ void OnIndexDeclaration(CXClientData client_data, const CXIdxDeclInfo* decl) {
if (decl->isDefinition && !is_template_specialization) { if (decl->isDefinition && !is_template_specialization) {
// assert(!func->def.spell); // assert(!func->def.spell);
// assert(!func->def.extent); // assert(!func->def.extent);
SetUse(db, &func->def.spell, decl_spelling, sem_parent, Role::Definition); func->def.spell = SetUse(db, spell, sem_parent, Role::Definition);
SetUse(db, &func->def.extent, decl_extent, lex_parent, Role::None); func->def.extent = SetUse(db, extent, lex_parent, Role::None);
} else { } else {
IndexFunc::Declaration declaration; IndexFunc::Declaration declaration;
declaration.spelling = decl_spelling; declaration.spell = SetUse(db, spell, lex_parent, Role::Declaration);
declaration.extent = decl_extent;
declaration.content = GetDocumentContentInRange(
param->tu->cx_tu, clang_getCursorExtent(decl->cursor));
// Add parameters. // Add parameters.
for (ClangCursor arg : decl_cursor.get_arguments()) { for (ClangCursor arg : decl_cursor.get_arguments()) {
switch (arg.get_kind()) { switch (arg.get_kind()) {
case CXCursor_ParmDecl: { case CXCursor_ParmDecl: {
Range param_spelling = arg.get_spelling_range(); Range param_spelling = arg.get_spell();
// If the name is empty (which is common for parameters), clang // If the name is empty (which is common for parameters), clang
// will report a range with length 1, which is not correct. // will report a range with length 1, which is not correct.
@ -1727,7 +1708,7 @@ void OnIndexDeclaration(CXClientData client_data, const CXIdxDeclInfo* decl) {
// Mark a type reference at the ctor/dtor location. // Mark a type reference at the ctor/dtor location.
if (decl->entityInfo->kind == CXIdxEntity_CXXConstructor if (decl->entityInfo->kind == CXIdxEntity_CXXConstructor
|| decl->entityInfo->kind == CXIdxEntity_CXXDestructor) || decl->entityInfo->kind == CXIdxEntity_CXXDestructor)
UniqueAddUse(db, declaring_type_def->uses, decl_spelling, UniqueAddUse(db, declaring_type_def->uses, spell,
fromContainer(decl->lexicalContainer)); fromContainer(decl->lexicalContainer));
// Add function to declaring type. // Add function to declaring type.
@ -1775,10 +1756,10 @@ void OnIndexDeclaration(CXClientData client_data, const CXIdxDeclInfo* decl) {
type->def.alias_of = alias_of.value(); type->def.alias_of = alias_of.value();
ClangCursor decl_cursor = decl->cursor; ClangCursor decl_cursor = decl->cursor;
Range spell = decl_cursor.get_spelling_range(); Range spell = decl_cursor.get_spell();
Range extent = decl_cursor.get_extent(); Range extent = decl_cursor.get_extent();
SetUse(db, &type->def.spell, spell, sem_parent, Role::Definition); type->def.spell = SetUse(db, spell, sem_parent, Role::Definition);
SetUse(db, &type->def.extent, extent, lex_parent, Role::None); type->def.extent = SetUse(db, extent, lex_parent, Role::None);
SetTypeName(type, decl_cursor, decl->semanticContainer, SetTypeName(type, decl_cursor, decl->semanticContainer,
decl->entityInfo->name, param); decl->entityInfo->name, param);
@ -1816,7 +1797,7 @@ void OnIndexDeclaration(CXClientData client_data, const CXIdxDeclInfo* decl) {
case CXIdxEntity_Struct: case CXIdxEntity_Struct:
case CXIdxEntity_CXXClass: { case CXIdxEntity_CXXClass: {
ClangCursor decl_cursor = decl->cursor; ClangCursor decl_cursor = decl->cursor;
Range decl_spell = decl_cursor.get_spelling_range(); Range spell = decl_cursor.get_spell();
IndexTypeId type_id = db->ToTypeId(HashUsr(decl->entityInfo->USR)); IndexTypeId type_id = db->ToTypeId(HashUsr(decl->entityInfo->USR));
IndexType* type = db->Resolve(type_id); IndexType* type = db->Resolve(type_id);
@ -1833,21 +1814,21 @@ void OnIndexDeclaration(CXClientData client_data, const CXIdxDeclInfo* decl) {
// } // }
if (decl->isDefinition) { if (decl->isDefinition) {
SetUse(db, &type->def.spell, decl_spell, sem_parent, Role::Definition); type->def.spell = SetUse(db, spell, sem_parent, Role::Definition);
SetUse(db, &type->def.extent, decl_cursor.get_extent(), lex_parent, Role::None); type->def.extent = SetUse(db, decl_cursor.get_extent(), lex_parent, Role::None);
if (decl_cursor.get_kind() == CXCursor_EnumDecl) { if (decl_cursor.get_kind() == CXCursor_EnumDecl) {
ClangType enum_type = clang_getEnumDeclIntegerType(decl->cursor); ClangType enum_type = clang_getEnumDeclIntegerType(decl->cursor);
if (!enum_type.is_fundamental()) { if (!enum_type.is_fundamental()) {
IndexType* int_type = IndexType* int_type =
db->Resolve(db->ToTypeId(enum_type.get_usr_hash())); db->Resolve(db->ToTypeId(enum_type.get_usr_hash()));
AddUse(db, int_type->uses, decl_spell, fromContainer(decl->lexicalContainer)); AddUse(db, int_type->uses, spell, fromContainer(decl->lexicalContainer));
// type is invalidated. // type is invalidated.
type = db->Resolve(type_id); type = db->Resolve(type_id);
} }
} }
} else } else
UniqueAddUse(db, type->uses, decl_spell, fromContainer(decl->lexicalContainer)); UniqueAddUse(db, type->uses, spell, fromContainer(decl->lexicalContainer));
switch (decl->entityInfo->templateKind) { switch (decl->entityInfo->templateKind) {
default: default:
@ -1872,16 +1853,18 @@ void OnIndexDeclaration(CXClientData client_data, const CXIdxDeclInfo* decl) {
// TODO The name may be assigned in |ResolveToDeclarationType| but // TODO The name may be assigned in |ResolveToDeclarationType| but
// |spell| is nullopt. // |spell| is nullopt.
CXFile origin_file; CXFile origin_file;
Range origin_spell = origin_cursor.get_spelling_range(&origin_file); Range origin_spell = origin_cursor.get_spell(&origin_file);
if (!origin->def.spell && file == origin_file) { if (!origin->def.spell && file == origin_file) {
SetUsePreflight(db, origin_cursor.get_semantic_parent()); ClangCursor origin_sem = origin_cursor.get_semantic_parent();
SetUsePreflight(db, origin_cursor.get_lexical_parent()); ClangCursor origin_lex = origin_cursor.get_lexical_parent();
SetUsePreflight(db, origin_sem);
SetUsePreflight(db, origin_lex);
origin = db->Resolve(origin_id); origin = db->Resolve(origin_id);
type = db->Resolve(type_id); type = db->Resolve(type_id);
SetUse(db, &origin->def.spell, origin_spell, origin->def.spell =
origin_cursor.get_semantic_parent(), Role::Definition); SetUse(db, origin_spell, origin_sem, Role::Definition);
SetUse(db, &origin->def.extent, origin_cursor.get_extent(), origin->def.extent =
origin_cursor.get_lexical_parent(), Role::None); SetUse(db, origin_cursor.get_extent(), origin_lex, Role::None);
} }
origin->derived.push_back(type_id); origin->derived.push_back(type_id);
type->def.parents.push_back(origin_id); type->def.parents.push_back(origin_id);
@ -1931,7 +1914,7 @@ void OnIndexDeclaration(CXClientData client_data, const CXIdxDeclInfo* decl) {
std::cerr std::cerr
<< "!! Unhandled indexDeclaration: " << "!! Unhandled indexDeclaration: "
<< ClangCursor(decl->cursor).ToString() << " at " << ClangCursor(decl->cursor).ToString() << " at "
<< ClangCursor(decl->cursor).get_spelling_range().start.ToString() << ClangCursor(decl->cursor).get_spell().start.ToString()
<< std::endl; << std::endl;
std::cerr << " entityInfo->kind = " << decl->entityInfo->kind std::cerr << " entityInfo->kind = " << decl->entityInfo->kind
<< std::endl; << std::endl;
@ -1972,7 +1955,7 @@ void CheckTypeDependentMemberRefExpr(Range* spell,
IndexParam* param, IndexParam* param,
const IndexFile* db) { const IndexFile* db) {
if (cursor.get_kind() == CXCursor_MemberRefExpr && if (cursor.get_kind() == CXCursor_MemberRefExpr &&
cursor.get_spelling().empty()) { cursor.get_spell_name().empty()) {
*spell = cursor.get_extent().RemovePrefix(spell->end); *spell = cursor.get_extent().RemovePrefix(spell->end);
const FileContents& fc = param->file_contents[db->path]; const FileContents& fc = param->file_contents[db->path];
optional<int> maybe_period = fc.ToOffset(spell->start); optional<int> maybe_period = fc.ToOffset(spell->start);
@ -2004,7 +1987,7 @@ void OnIndexReference(CXClientData client_data, const CXIdxEntityRefInfo* ref) {
case CXIdxEntity_CXXNamespace: { case CXIdxEntity_CXXNamespace: {
ClangCursor referenced = ref->referencedEntity->cursor; ClangCursor referenced = ref->referencedEntity->cursor;
IndexType* ns = db->Resolve(db->ToTypeId(referenced.get_usr_hash())); IndexType* ns = db->Resolve(db->ToTypeId(referenced.get_usr_hash()));
AddUse(db, ns->uses, cursor.get_spelling_range(), fromContainer(ref->container)); AddUse(db, ns->uses, cursor.get_spell(), fromContainer(ref->container));
break; break;
} }
@ -2015,7 +1998,7 @@ void OnIndexReference(CXClientData client_data, const CXIdxEntityRefInfo* ref) {
case CXIdxEntity_Variable: case CXIdxEntity_Variable:
case CXIdxEntity_Field: { case CXIdxEntity_Field: {
ClangCursor ref_cursor(ref->cursor); ClangCursor ref_cursor(ref->cursor);
Range loc = ref_cursor.get_spelling_range(); Range loc = ref_cursor.get_spell();
CheckTypeDependentMemberRefExpr(&loc, ref_cursor, param, db); CheckTypeDependentMemberRefExpr(&loc, ref_cursor, param, db);
ClangCursor referenced = ref->referencedEntity->cursor; ClangCursor referenced = ref->referencedEntity->cursor;
@ -2029,15 +2012,15 @@ void OnIndexReference(CXClientData client_data, const CXIdxEntityRefInfo* ref) {
// as lambdas cannot be split across files. // as lambdas cannot be split across files.
if (var->def.detailed_name.empty()) { if (var->def.detailed_name.empty()) {
CXFile referenced_file; CXFile referenced_file;
Range spelling = referenced.get_spelling_range(&referenced_file); Range spell = referenced.get_spell(&referenced_file);
if (file == referenced_file) { if (file == referenced_file) {
SetUse(db, &var->def.spell, spelling, lex_parent, Role::Definition); var->def.spell = SetUse(db, spell, lex_parent, Role::Definition);
SetUse(db, &var->def.extent, referenced.get_extent(), lex_parent, Role::None); var->def.extent = SetUse(db, referenced.get_extent(), lex_parent, Role::None);
// TODO Some of the logic here duplicates CXIdxEntity_Variable branch // TODO Some of the logic here duplicates CXIdxEntity_Variable branch
// of OnIndexDeclaration. But there `decl` is of type CXIdxDeclInfo // of OnIndexDeclaration. But there `decl` is of type CXIdxDeclInfo
// and has more information, thus not easy to reuse the code. // and has more information, thus not easy to reuse the code.
SetVarDetail(var, referenced.get_spelling(), referenced, nullptr, SetVarDetail(var, referenced.get_spell_name(), referenced, nullptr,
true, db, param); true, db, param);
var->def.kind = ClangSymbolKind::Parameter; var->def.kind = ClangSymbolKind::Parameter;
} }
@ -2065,7 +2048,7 @@ void OnIndexReference(CXClientData client_data, const CXIdxEntityRefInfo* ref) {
// TODO: search full history? // TODO: search full history?
ClangCursor ref_cursor(ref->cursor); ClangCursor ref_cursor(ref->cursor);
Range loc = ref_cursor.get_spelling_range(); Range loc = ref_cursor.get_spell();
IndexFuncId called_id = db->ToFuncId(HashUsr(ref->referencedEntity->USR)); IndexFuncId called_id = db->ToFuncId(HashUsr(ref->referencedEntity->USR));
IndexFunc* called = db->Resolve(called_id); IndexFunc* called = db->Resolve(called_id);
@ -2130,7 +2113,7 @@ void OnIndexReference(CXClientData client_data, const CXIdxEntityRefInfo* ref) {
// can try to find a constructor with the same type description. // can try to find a constructor with the same type description.
std::vector<std::string> call_type_desc; std::vector<std::string> call_type_desc;
for (ClangType type : call_cursor.get_type().get_arguments()) { for (ClangType type : call_cursor.get_type().get_arguments()) {
std::string type_desc = type.get_spelling(); std::string type_desc = type.get_spell_name();
if (!type_desc.empty()) if (!type_desc.empty())
call_type_desc.push_back(type_desc); call_type_desc.push_back(type_desc);
} }
@ -2140,9 +2123,8 @@ void OnIndexReference(CXClientData client_data, const CXIdxEntityRefInfo* ref) {
param->ctors.TryFindConstructorUsr(ctor_type_usr, call_type_desc); param->ctors.TryFindConstructorUsr(ctor_type_usr, call_type_desc);
if (ctor_usr) { if (ctor_usr) {
IndexFunc* ctor = db->Resolve(db->ToFuncId(*ctor_usr)); IndexFunc* ctor = db->Resolve(db->ToFuncId(*ctor_usr));
AddFuncUse(&ctor->uses, AddFuncUse(&ctor->uses, Use(loc, Id<void>(), SymbolKind::File,
Use(loc, Id<void>(), SymbolKind::File, Role::Call | Role::Implicit, {}));
Role::Call | Role::Implicit));
} }
} }
} }
@ -2186,7 +2168,7 @@ void OnIndexReference(CXClientData client_data, const CXIdxEntityRefInfo* ref) {
std::cerr std::cerr
<< "!! Unhandled indexEntityReference: " << cursor.ToString() << "!! Unhandled indexEntityReference: " << cursor.ToString()
<< " at " << " at "
<< ClangCursor(ref->cursor).get_spelling_range().start.ToString() << ClangCursor(ref->cursor).get_spell().start.ToString()
<< std::endl; << std::endl;
std::cerr << " ref->referencedEntity->kind = " std::cerr << " ref->referencedEntity->kind = "
<< ref->referencedEntity->kind << std::endl; << ref->referencedEntity->kind << std::endl;
@ -2195,7 +2177,7 @@ void OnIndexReference(CXClientData client_data, const CXIdxEntityRefInfo* ref) {
<< ref->parentEntity->kind << std::endl; << ref->parentEntity->kind << std::endl;
std::cerr std::cerr
<< " ref->loc = " << " ref->loc = "
<< ClangCursor(ref->cursor).get_spelling_range().start.ToString() << ClangCursor(ref->cursor).get_spell().start.ToString()
<< std::endl; << std::endl;
std::cerr << " ref->kind = " << ref->kind << std::endl; std::cerr << " ref->kind = " << ref->kind << std::endl;
if (ref->parentEntity) if (ref->parentEntity)

View File

@ -138,9 +138,6 @@ struct Use : Reference {
// |file| is used in Query* but not in Index* // |file| is used in Query* but not in Index*
Id<QueryFile> file; Id<QueryFile> file;
Use() = default; Use() = default;
Use(Reference ref) : Reference(ref) {}
Use(Range range, Id<void> id, SymbolKind kind, Role role)
: Reference{range, id, kind, role} {}
Use(Range range, Id<void> id, SymbolKind kind, Role role, Id<QueryFile> file) Use(Range range, Id<void> id, SymbolKind kind, Role role, Id<QueryFile> file)
: Reference{range, id, kind, role}, file(file) {} : Reference{range, id, kind, role}, file(file) {}
}; };
@ -328,11 +325,7 @@ struct IndexFunc {
struct Declaration { struct Declaration {
// Range of only the function name. // Range of only the function name.
Range spelling; Use spell;
// Full range of the declaration.
Range extent;
// Full text of the declaration.
std::string content;
// Location of the parameter names. // Location of the parameter names.
std::vector<Range> param_spellings; std::vector<Range> param_spellings;
}; };
@ -357,9 +350,7 @@ struct IndexFunc {
}; };
MAKE_HASHABLE(IndexFunc, t.id); MAKE_HASHABLE(IndexFunc, t.id);
MAKE_REFLECT_STRUCT(IndexFunc::Declaration, MAKE_REFLECT_STRUCT(IndexFunc::Declaration,
spelling, spell,
extent,
content,
param_spellings); param_spellings);
template <typename F> template <typename F>

View File

@ -76,36 +76,34 @@ struct CommonCodeLensParams {
WorkingFile* working_file; WorkingFile* working_file;
}; };
SymbolRef OffsetStartColumn(SymbolRef sym, int16_t offset) { Use OffsetStartColumn(Use use, int16_t offset) {
sym.range.start.column += offset; use.range.start.column += offset;
return sym; return use;
} }
void AddCodeLens(const char* singular, void AddCodeLens(const char* singular,
const char* plural, const char* plural,
CommonCodeLensParams* common, CommonCodeLensParams* common,
SymbolRef loc, Use use,
const std::vector<Use>& uses, const std::vector<Use>& uses,
bool force_display) { bool force_display) {
TCodeLens code_lens; TCodeLens code_lens;
optional<lsRange> range = GetLsRange(common->working_file, loc.range); optional<lsRange> range = GetLsRange(common->working_file, use.range);
if (!range) if (!range)
return; return;
// FIXME SymbolRef loc -> Use loc if (use.file == QueryFileId())
Maybe<QueryFileId> file_id = common->db->GetFileId(loc);
if (!file_id)
return; return;
code_lens.range = *range; code_lens.range = *range;
code_lens.command = lsCommand<lsCodeLensCommandArguments>(); code_lens.command = lsCommand<lsCodeLensCommandArguments>();
code_lens.command->command = "cquery.showReferences"; code_lens.command->command = "cquery.showReferences";
code_lens.command->arguments.uri = GetLsDocumentUri(common->db, *file_id); code_lens.command->arguments.uri = GetLsDocumentUri(common->db, use.file);
code_lens.command->arguments.position = code_lens.range.start; code_lens.command->arguments.position = code_lens.range.start;
// Add unique uses. // Add unique uses.
std::unordered_set<lsLocation> unique_uses; std::unordered_set<lsLocation> unique_uses;
for (Use use : uses) { for (Use use1 : uses) {
optional<lsLocation> location = optional<lsLocation> location =
GetLsLocation(common->db, common->working_files, use); GetLsLocation(common->db, common->working_files, use1);
if (!location) if (!location)
continue; continue;
unique_uses.insert(*location); unique_uses.insert(*location);
@ -151,6 +149,7 @@ struct TextDocumentCodeLensHandler
for (SymbolRef sym : file->def->outline) { for (SymbolRef sym : file->def->outline) {
// NOTE: We OffsetColumn so that the code lens always show up in a // NOTE: We OffsetColumn so that the code lens always show up in a
// predictable order. Otherwise, the client may randomize it. // predictable order. Otherwise, the client may randomize it.
Use use(sym.range, sym.id, sym.kind, sym.role, file->def->file);
switch (sym.kind) { switch (sym.kind) {
case SymbolKind::Type: { case SymbolKind::Type: {
@ -158,11 +157,11 @@ struct TextDocumentCodeLensHandler
const QueryType::Def* def = type.AnyDef(); const QueryType::Def* def = type.AnyDef();
if (!def || def->kind == ClangSymbolKind::Namespace) if (!def || def->kind == ClangSymbolKind::Namespace)
continue; continue;
AddCodeLens("ref", "refs", &common, OffsetStartColumn(sym, 0), AddCodeLens("ref", "refs", &common, OffsetStartColumn(use, 0),
type.uses, true /*force_display*/); type.uses, true /*force_display*/);
AddCodeLens("derived", "derived", &common, OffsetStartColumn(sym, 1), AddCodeLens("derived", "derived", &common, OffsetStartColumn(use, 1),
ToUses(db, type.derived), false /*force_display*/); ToUses(db, type.derived), false /*force_display*/);
AddCodeLens("var", "vars", &common, OffsetStartColumn(sym, 2), AddCodeLens("var", "vars", &common, OffsetStartColumn(use, 2),
ToUses(db, type.instances), false /*force_display*/); ToUses(db, type.instances), false /*force_display*/);
break; break;
} }
@ -177,13 +176,12 @@ struct TextDocumentCodeLensHandler
// For functions, the outline will report a location that is using the // For functions, the outline will report a location that is using the
// extent since that is better for outline. This tries to convert the // extent since that is better for outline. This tries to convert the
// extent location to the spelling location. // extent location to the spelling location.
auto try_ensure_spelling = [&](SymbolRef sym) { auto try_ensure_spelling = [&](Use use) {
Maybe<Use> def = GetDefinitionSpellingOfSymbol(db, sym); Maybe<Use> def = GetDefinitionSpellingOfSymbol(db, use);
if (!def || def->file != *db->GetFileId(sym) || if (!def || def->range.start.line != use.range.start.line) {
def->range.start.line != sym.range.start.line) { return use;
return sym;
} }
return SymbolRef(*def); return *def;
}; };
std::vector<Use> base_callers = std::vector<Use> base_callers =
@ -191,12 +189,12 @@ struct TextDocumentCodeLensHandler
std::vector<Use> derived_callers = std::vector<Use> derived_callers =
GetCallersForAllDerivedFunctions(db, func); GetCallersForAllDerivedFunctions(db, func);
if (base_callers.empty() && derived_callers.empty()) { if (base_callers.empty() && derived_callers.empty()) {
SymbolRef loc = try_ensure_spelling(sym); Use loc = try_ensure_spelling(use);
AddCodeLens("call", "calls", &common, AddCodeLens("call", "calls", &common,
OffsetStartColumn(loc, offset++), func.uses, OffsetStartColumn(loc, offset++), func.uses,
true /*force_display*/); true /*force_display*/);
} else { } else {
SymbolRef loc = try_ensure_spelling(sym); Use loc = try_ensure_spelling(use);
AddCodeLens("direct call", "direct calls", &common, AddCodeLens("direct call", "direct calls", &common,
OffsetStartColumn(loc, offset++), func.uses, OffsetStartColumn(loc, offset++), func.uses,
false /*force_display*/); false /*force_display*/);
@ -211,7 +209,7 @@ struct TextDocumentCodeLensHandler
} }
AddCodeLens("derived", "derived", &common, AddCodeLens("derived", "derived", &common,
OffsetStartColumn(sym, offset++), OffsetStartColumn(use, offset++),
ToUses(db, func.derived), false /*force_display*/); ToUses(db, func.derived), false /*force_display*/);
// "Base" // "Base"
@ -238,7 +236,7 @@ struct TextDocumentCodeLensHandler
} }
} }
} else { } else {
AddCodeLens("base", "base", &common, OffsetStartColumn(sym, 1), AddCodeLens("base", "base", &common, OffsetStartColumn(use, 1),
ToUses(db, def->base), ToUses(db, def->base),
false /*force_display*/); false /*force_display*/);
} }
@ -257,7 +255,7 @@ struct TextDocumentCodeLensHandler
if (def->is_macro()) if (def->is_macro())
force_display = false; force_display = false;
AddCodeLens("ref", "refs", &common, OffsetStartColumn(sym, 0), AddCodeLens("ref", "refs", &common, OffsetStartColumn(use, 0),
var.uses, force_display); var.uses, force_display);
break; break;
} }

View File

@ -43,15 +43,13 @@ struct TextDocumentDocumentSymbolHandler
if (!info) if (!info)
continue; continue;
// FIXME if (optional<lsLocation> location = GetLsLocation(
Use use(sym); db, working_files,
use.file = file_id; Use(sym.range, sym.id, sym.kind, sym.role, file_id))) {
optional<lsLocation> location = GetLsLocation(db, working_files, use);
if (!location)
continue;
info->location = *location; info->location = *location;
out.result.push_back(*info); out.result.push_back(*info);
} }
}
QueueManager::WriteStdout(IpcId::TextDocumentDocumentSymbol, out); QueueManager::WriteStdout(IpcId::TextDocumentDocumentSymbol, out);
} }

View File

@ -1,5 +1,4 @@
#include "position.h" #include "position.h"
#include "serializers/msgpack.h"
namespace { namespace {
// Skips until the character immediately following |skip_after|. // Skips until the character immediately following |skip_after|.

View File

@ -210,6 +210,7 @@ void CompareGroups(std::vector<T>& previous_data,
QueryFile::DefUpdate BuildFileDefUpdate(const IdMap& id_map, const IndexFile& indexed) { QueryFile::DefUpdate BuildFileDefUpdate(const IdMap& id_map, const IndexFile& indexed) {
QueryFile::Def def; QueryFile::Def def;
def.file = id_map.primary_file;
def.path = indexed.path; def.path = indexed.path;
def.args = indexed.args; def.args = indexed.args;
def.includes = indexed.includes; def.includes = indexed.includes;
@ -232,37 +233,32 @@ QueryFile::DefUpdate BuildFileDefUpdate(const IdMap& id_map, const IndexFile& in
} }
}(); }();
auto add_outline = [&](Range range, Id<void> id, SymbolKind kind, auto add_all_symbols = [&](Use use, Id<void> id, SymbolKind kind) {
Role role) {
def.outline.push_back(SymbolRef(range, id, kind, role));
};
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));
}; };
auto add_outline_use = [&](Use use, Id<void> id, SymbolKind kind) { auto add_outline = [&](Use use, Id<void> id, SymbolKind kind) {
def.outline.push_back(SymbolRef(use.range, id, kind, use.role)); def.outline.push_back(SymbolRef(use.range, id, kind, use.role));
}; };
for (const IndexType& type : indexed.types) { for (const IndexType& type : indexed.types) {
QueryTypeId id = id_map.ToQuery(type.id); QueryTypeId id = id_map.ToQuery(type.id);
if (type.def.spell) if (type.def.spell)
add_all_symbols_use(*type.def.spell, id, SymbolKind::Type); add_all_symbols(*type.def.spell, id, SymbolKind::Type);
if (type.def.extent) if (type.def.extent)
add_outline_use(*type.def.extent, id, SymbolKind::Type); add_outline(*type.def.extent, id, SymbolKind::Type);
for (Use use : type.uses) for (Use use : type.uses)
add_all_symbols_use(use, id, SymbolKind::Type); add_all_symbols(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);
if (func.def.spell) if (func.def.spell)
add_all_symbols_use(*func.def.spell, id, SymbolKind::Func); add_all_symbols(*func.def.spell, id, SymbolKind::Func);
if (func.def.extent) if (func.def.extent)
add_outline_use(*func.def.extent, id, SymbolKind::Func); add_outline(*func.def.extent, id, SymbolKind::Func);
for (const IndexFunc::Declaration& decl : func.declarations) { for (const IndexFunc::Declaration& decl : func.declarations) {
def.all_symbols.push_back( add_all_symbols(decl.spell, id, SymbolKind::Func);
SymbolRef(decl.spelling, id, SymbolKind::Func, Role::Declaration)); add_outline(decl.spell, id, SymbolKind::Func);
add_outline(decl.spelling, id, SymbolKind::Func, Role::Declaration);
} }
for (Use use : 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
@ -274,21 +270,21 @@ QueryFile::DefUpdate BuildFileDefUpdate(const IdMap& id_map, const IndexFile& in
use.range.start.column--; use.range.start.column--;
use.range.end.column++; use.range.end.column++;
} }
add_all_symbols_use(use, id, SymbolKind::Func); add_all_symbols(use, id, SymbolKind::Func);
} }
} }
for (const IndexVar& var : indexed.vars) { for (const IndexVar& var : indexed.vars) {
QueryVarId id = id_map.ToQuery(var.id); QueryVarId id = id_map.ToQuery(var.id);
if (var.def.spell) if (var.def.spell)
add_all_symbols_use(*var.def.spell, id, SymbolKind::Var); add_all_symbols(*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(*var.def.extent, id, SymbolKind::Var);
for (Use decl : var.declarations) { for (Use decl : var.declarations) {
add_all_symbols_use(decl, id, SymbolKind::Var); add_all_symbols(decl, id, SymbolKind::Var);
add_outline_use(decl, id, SymbolKind::Var); add_outline(decl, id, SymbolKind::Var);
} }
for (Use use : var.uses) for (Use use : var.uses)
add_all_symbols_use(use, id, SymbolKind::Var); add_all_symbols(use, id, SymbolKind::Var);
} }
std::sort(def.outline.begin(), def.outline.end(), std::sort(def.outline.begin(), def.outline.end(),
@ -434,8 +430,7 @@ QueryVarId IdMap::ToQuery(IndexVarId id) const {
} }
Use IdMap::ToQuery(Reference ref) const { Use IdMap::ToQuery(Reference ref) const {
Use ret(ref); Use ret(ref.range, ref.id, ref.kind, ref.role, primary_file);
ret.file = primary_file;
switch (ref.kind) { switch (ref.kind) {
case SymbolKind::Invalid: case SymbolKind::Invalid:
break; break;
@ -463,9 +458,7 @@ Use IdMap::ToQuery(Use use) const {
} }
Use IdMap::ToQuery(IndexFunc::Declaration decl) const { Use IdMap::ToQuery(IndexFunc::Declaration decl) const {
// TODO: expose more than just QueryLocation. return ToQuery(static_cast<Reference>(decl.spell));
return {decl.spelling, primary_file, SymbolKind::File, Role::Declaration,
primary_file};
} }
// ---------------------- // ----------------------
@ -995,12 +988,12 @@ TEST_SUITE("query") {
IndexFile previous("foo.cc", "<empty>"); IndexFile previous("foo.cc", "<empty>");
IndexFile current("foo.cc", "<empty>"); IndexFile current("foo.cc", "<empty>");
previous.Resolve(previous.ToTypeId(HashUsr("usr1"))) previous.Resolve(previous.ToTypeId(HashUsr("usr1")))->def.spell =
->def.spell = Use(Range(Position(1, 0)), Id<void>(), SymbolKind::File, Role::None); Use(Range(Position(1, 0)), {}, {}, {}, {});
previous.Resolve(previous.ToFuncId(HashUsr("usr2"))) previous.Resolve(previous.ToFuncId(HashUsr("usr2")))->def.spell =
->def.spell = Use(Range(Position(2, 0)), Id<void>(), SymbolKind::File, Role::None); Use(Range(Position(2, 0)), {}, {}, {}, {});
previous.Resolve(previous.ToVarId(HashUsr("usr3"))) previous.Resolve(previous.ToVarId(HashUsr("usr3")))->def.spell =
->def.spell = Use(Range(Position(3, 0)), Id<void>(), SymbolKind::File, Role::None); Use(Range(Position(3, 0)), {}, {}, {}, {});
IndexUpdate update = GetDelta(previous, current); IndexUpdate update = GetDelta(previous, current);
@ -1016,12 +1009,11 @@ TEST_SUITE("query") {
IndexFile current("foo.cc", "<empty>"); IndexFile current("foo.cc", "<empty>");
previous.Resolve(previous.ToTypeId(HashUsr("usr1"))) previous.Resolve(previous.ToTypeId(HashUsr("usr1")))
->uses.push_back(Reference{Range(Position(1, 0))}); ->uses.push_back(Use{Range(Position(1, 0)), {}, {}, {}, {}});
previous.Resolve(previous.ToFuncId(HashUsr("usr2"))) previous.Resolve(previous.ToFuncId(HashUsr("usr2")))
->uses.push_back(Use(Range(Position(2, 0)), Id<void>(0), ->uses.push_back(Use(Range(Position(2, 0)), {}, {}, {}, {}));
SymbolKind::Func, Role::None));
previous.Resolve(previous.ToVarId(HashUsr("usr3"))) previous.Resolve(previous.ToVarId(HashUsr("usr3")))
->uses.push_back(Reference{Range(Position(3, 0))}); ->uses.push_back(Use(Range(Position(3, 0)), {}, {}, {}, {}));
IndexUpdate update = GetDelta(previous, current); IndexUpdate update = GetDelta(previous, current);
@ -1037,10 +1029,8 @@ TEST_SUITE("query") {
IndexFunc* pf = previous.Resolve(previous.ToFuncId(HashUsr("usr"))); IndexFunc* pf = previous.Resolve(previous.ToFuncId(HashUsr("usr")));
IndexFunc* cf = current.Resolve(current.ToFuncId(HashUsr("usr"))); IndexFunc* cf = current.Resolve(current.ToFuncId(HashUsr("usr")));
pf->uses.push_back(Use(Range(Position(1, 0)), Id<void>(0), pf->uses.push_back(Use(Range(Position(1, 0)), {}, {}, {}, {}));
SymbolKind::Func, Role::None)); cf->uses.push_back(Use(Range(Position(2, 0)), {}, {}, {}, {}));
cf->uses.push_back(Use(Range(Position(2, 0)), Id<void>(0),
SymbolKind::Func, Role::None));
IndexUpdate update = GetDelta(previous, current); IndexUpdate update = GetDelta(previous, current);
@ -1062,8 +1052,8 @@ TEST_SUITE("query") {
IndexType* pt = previous.Resolve(previous.ToTypeId(HashUsr("usr"))); IndexType* pt = previous.Resolve(previous.ToTypeId(HashUsr("usr")));
IndexType* ct = current.Resolve(current.ToTypeId(HashUsr("usr"))); IndexType* ct = current.Resolve(current.ToTypeId(HashUsr("usr")));
pt->uses.push_back(Reference{Range(Position(1, 0))}); pt->uses.push_back(Use(Range(Position(1, 0)), {}, {}, {}, {}));
ct->uses.push_back(Reference{Range(Position(2, 0))}); ct->uses.push_back(Use(Range(Position(2, 0)), {}, {}, {}, {}));
IndexUpdate update = GetDelta(previous, current); IndexUpdate update = GetDelta(previous, current);
@ -1082,14 +1072,10 @@ TEST_SUITE("query") {
IndexFunc* pf = previous.Resolve(previous.ToFuncId(HashUsr("usr"))); IndexFunc* pf = previous.Resolve(previous.ToFuncId(HashUsr("usr")));
IndexFunc* cf = current.Resolve(current.ToFuncId(HashUsr("usr"))); IndexFunc* cf = current.Resolve(current.ToFuncId(HashUsr("usr")));
pf->uses.push_back(Use(Range(Position(1, 0)), Id<void>(0), pf->uses.push_back(Use(Range(Position(1, 0)), {}, {}, {}, {}));
SymbolKind::Func, Role::None)); pf->uses.push_back(Use(Range(Position(2, 0)), {}, {}, {}, {}));
pf->uses.push_back(Use(Range(Position(2, 0)), Id<void>(0), cf->uses.push_back(Use(Range(Position(4, 0)), {}, {}, {}, {}));
SymbolKind::Func, Role::None)); cf->uses.push_back(Use(Range(Position(5, 0)), {}, {}, {}, {}));
cf->uses.push_back(Use(Range(Position(4, 0)), Id<void>(0),
SymbolKind::Func, Role::None));
cf->uses.push_back(Use(Range(Position(5, 0)), Id<void>(0),
SymbolKind::Func, Role::None));
QueryDatabase db; QueryDatabase db;
IdMap previous_map(&db, previous.id_cache); IdMap previous_map(&db, previous.id_cache);

View File

@ -96,6 +96,7 @@ struct QueryFamily {
struct QueryFile { struct QueryFile {
struct Def { struct Def {
Id<QueryFile> file;
std::string path; std::string path;
std::vector<std::string> args; std::vector<std::string> args;
// Language identifier // Language identifier
@ -123,6 +124,7 @@ struct QueryFile {
} }
}; };
MAKE_REFLECT_STRUCT(QueryFile::Def, MAKE_REFLECT_STRUCT(QueryFile::Def,
file,
path, path,
args, args,
language, language,
@ -316,33 +318,6 @@ struct QueryDatabase {
Maybe<QueryFuncId> GetQueryFuncIdFromUsr(Usr usr); Maybe<QueryFuncId> GetQueryFuncIdFromUsr(Usr usr);
Maybe<QueryVarId> GetQueryVarIdFromUsr(Usr usr); Maybe<QueryVarId> GetQueryVarIdFromUsr(Usr usr);
Maybe<QueryFileId> GetFileId(SymbolIdx ref) {
switch (ref.kind) {
case SymbolKind::Invalid:
break;
case SymbolKind::File:
return QueryFileId(ref.id);
case SymbolKind::Func: {
const QueryFunc::Def* def = funcs[ref.id.id].AnyDef();
if (def)
return def->file;
break;
}
case SymbolKind::Type: {
const QueryType::Def* def = types[ref.id.id].AnyDef();
if (def)
return def->file;
break;
}
case SymbolKind::Var: {
const QueryVar::Def* def = vars[ref.id.id].AnyDef();
if (def)
return def->file;
break;
}
}
return QueryFileId();
}
QueryFile& GetFile(SymbolIdx ref) { QueryFile& GetFile(SymbolIdx ref) {
return files[ref.id.id]; return files[ref.id.id];
} }

View File

@ -1,7 +1,5 @@
#pragma once #pragma once
#include "query_utils.h"
#include "query.h" #include "query.h"
#include "working_files.h" #include "working_files.h"