From 420e84329b42123bb6a7758dc149c182f1e17dc6 Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Sat, 10 Feb 2018 12:53:18 -0800 Subject: [PATCH] Derive SymbolRef,Use from Reference and add lexical container to func/var/type uses --- src/clang_cursor.cc | 4 + src/clang_cursor.h | 1 + src/indexer.cc | 309 +++++++++++------------ src/indexer.h | 63 ++++- src/messages/cquery_base.cc | 4 +- src/messages/cquery_call_tree.cc | 23 +- src/messages/cquery_callers.cc | 6 +- src/messages/cquery_derived.cc | 4 +- src/messages/cquery_vars.cc | 4 +- src/messages/text_document_code_lens.cc | 30 +-- src/messages/text_document_definition.cc | 12 +- src/messages/text_document_highlight.cc | 4 +- src/messages/text_document_references.cc | 4 +- src/messages/text_document_rename.cc | 8 +- src/query.cc | 152 ++++++----- src/query.h | 85 ++----- src/query_utils.cc | 68 +++-- src/query_utils.h | 32 ++- src/serializer.cc | 2 +- 19 files changed, 393 insertions(+), 422 deletions(-) diff --git a/src/clang_cursor.cc b/src/clang_cursor.cc index 0b10dbf7..5bf90641 100644 --- a/src/clang_cursor.cc +++ b/src/clang_cursor.cc @@ -194,6 +194,10 @@ ClangCursor ClangCursor::get_definition() const { return ClangCursor(clang_getCursorDefinition(cx_cursor)); } +ClangCursor ClangCursor::get_lexical_parent() const { + return ClangCursor(clang_getCursorLexicalParent(cx_cursor)); +} + ClangCursor ClangCursor::get_semantic_parent() const { return ClangCursor(clang_getCursorSemanticParent(cx_cursor)); } diff --git a/src/clang_cursor.h b/src/clang_cursor.h index 9f36d2a2..27691ab8 100644 --- a/src/clang_cursor.h +++ b/src/clang_cursor.h @@ -73,6 +73,7 @@ class ClangCursor { ClangCursor get_referenced() const; ClangCursor get_canonical() const; ClangCursor get_definition() const; + ClangCursor get_lexical_parent() const; ClangCursor get_semantic_parent() const; std::vector get_arguments() const; bool is_valid_kind() const; diff --git a/src/indexer.cc b/src/indexer.cc index 6fd32fe7..0efd329b 100644 --- a/src/indexer.cc +++ b/src/indexer.cc @@ -30,7 +30,7 @@ constexpr bool kIndexStdDeclarations = true; // display their declarations on hover. constexpr int kMaxLinesDisplayTypeAliasDeclarations = 3; -void AddFuncRef(std::vector* result, IndexFuncRef ref) { +void AddFuncUse(std::vector* result, Use ref) { if (!result->empty() && (*result)[result->size() - 1] == ref) return; result->push_back(ref); @@ -53,6 +53,30 @@ bool IsScopeSemanticContainer(CXCursorKind kind) { } } +SymbolKind GetSymbolKind(CXCursorKind kind) { + switch (kind) { + default: + return SymbolKind::Invalid; + + case CXCursor_FunctionDecl: + case CXCursor_CXXMethod: + case CXCursor_Constructor: + case CXCursor_Destructor: + case CXCursor_ConversionFunction: + case CXCursor_FunctionTemplate: + case CXCursor_OverloadedDeclRef: + case CXCursor_LambdaExpr: + return SymbolKind::Func; + + case CXCursor_Namespace: + case CXCursor_EnumDecl: + case CXCursor_UnionDecl: + case CXCursor_StructDecl: + case CXCursor_ClassDecl: + return SymbolKind::Type; + } +} + // Inverse of libclang/CXIndexDataConsumer.cpp getEntityKindFromSymbolKind ClangSymbolKind GetSymbolKind(CXIdxEntityKind kind) { switch (kind) { @@ -410,26 +434,6 @@ std::string GetDocumentContentInRange(CXTranslationUnit cx_tu, return result; } -bool IsFunctionCallContext(CXCursorKind kind) { - switch (kind) { - case CXCursor_FunctionDecl: - case CXCursor_CXXMethod: - case CXCursor_Constructor: - case CXCursor_Destructor: - case CXCursor_ConversionFunction: - case CXCursor_FunctionTemplate: - case CXCursor_OverloadedDeclRef: - // TODO: we need to test lambdas - case CXCursor_LambdaExpr: - return true; - - default: - break; - } - - return false; -} - void SetTypeName(IndexType* type, const ClangCursor& cursor, const CXIdxContainerInfo* container, @@ -581,23 +585,30 @@ void SetVarDetail(IndexVar* var, void OnIndexReference_Function(IndexFile* db, Range loc, - ClangCursor caller_cursor, + ClangCursor parent_cursor, IndexFuncId called_id, - IndexFunc* called, SymbolRole role) { - if (IsFunctionCallContext(caller_cursor.get_kind())) { - IndexFuncId caller_id = db->ToFuncId(caller_cursor.cx_cursor); - IndexFunc* caller = db->Resolve(caller_id); - // Calling db->ToFuncId invalidates the FuncDef* ptrs. - called = db->Resolve(called_id); - - AddFuncRef(&caller->def.callees, - IndexFuncRef(loc, Id(called->id), SymbolKind::Func, role)); - AddFuncRef(&called->callers, - IndexFuncRef(loc, Id(caller->id), SymbolKind::Func, role)); - } else { - AddFuncRef(&called->callers, - IndexFuncRef(loc, Id(), SymbolKind::Invalid, role)); + switch (GetSymbolKind(parent_cursor.get_kind())) { + case SymbolKind::Func: { + IndexFunc* parent = db->Resolve(db->ToFuncId(parent_cursor.cx_cursor)); + IndexFunc* called = db->Resolve(called_id); + parent->def.callees.push_back( + SymbolRef(loc, called->id, SymbolKind::Func, role)); + AddFuncUse(&called->uses, Use(loc, parent->id, SymbolKind::Func, role)); + break; + } + case SymbolKind::Type: { + IndexType* parent = db->Resolve(db->ToTypeId(parent_cursor.cx_cursor)); + IndexFunc* called = db->Resolve(called_id); + called = db->Resolve(called_id); + AddFuncUse(&called->uses, Use(loc, parent->id, SymbolKind::Type, role)); + break; + } + default: { + IndexFunc* called = db->Resolve(called_id); + AddFuncUse(&called->uses, Use(loc, Id(), SymbolKind::File, role)); + break; + } } } @@ -686,17 +697,55 @@ void UniqueAdd(std::vector& values, T value) { } // FIXME Reference: set id in call sites and remove this -void AddUse(std::vector& values, Range value) { - values.push_back(Reference{value, Id(), SymbolKind::Invalid, - SymbolRole::Reference}); +void AddUse(std::vector& values, Range value) { + values.push_back( + Use(value, Id(), SymbolKind::File, SymbolRole::Reference)); } -// FIXME Reference: set id in call sites and remove this -void UniqueAdd(std::vector& values, Range value) { - if (std::find_if(values.begin(), values.end(), [&](const Reference& ref) { - return ref.range == value; - }) == values.end()) - AddUse(values, value); +void AddUse(IndexFile* db, + std::vector& uses, + Range range, + ClangCursor parent, + SymbolRole role = SymbolRole::Reference) { + switch (GetSymbolKind(parent.get_kind())) { + default: + uses.push_back(Use(range, Id(), SymbolKind::File, role)); + break; + case SymbolKind::Func: + uses.push_back( + Use(range, db->ToFuncId(parent.cx_cursor), SymbolKind::Func, role)); + break; + case SymbolKind::Type: + uses.push_back( + Use(range, db->ToTypeId(parent.cx_cursor), SymbolKind::Type, role)); + break; + } +} + +CXCursor fromContainer(const CXIdxContainerInfo* parent) { + return parent ? parent->cursor : clang_getNullCursor(); +} + +void AddUseSpell(IndexFile* db, + std::vector& uses, + ClangCursor cursor) { + AddUse(db, uses, cursor.get_spelling_range(), + cursor.get_lexical_parent().cx_cursor, SymbolRole::Reference); +} + +template +void UniqueAddUse(IndexFile* db, std::vector& uses, Range range, Args&&... args) { + if (std::find_if(uses.begin(), uses.end(), + [&](Use use) { return use.range == range; }) == uses.end()) + AddUse(db, uses, range, std::forward(args)...); +} + +template +void UniqueAddUseSpell(IndexFile* db, std::vector& uses, ClangCursor cursor, Args&&... args) { + Range range = cursor.get_spelling_range(); + if (std::find_if(uses.begin(), uses.end(), + [&](Use use) { return use.range == range; }) == uses.end()) + AddUse(db, uses, range, cursor.get_lexical_parent().cx_cursor, std::forward(args)...); } IdCache::IdCache(const std::string& primary_file) @@ -840,17 +889,7 @@ bool IsGlobalContainer(const CXIdxContainerInfo* container) { bool IsTypeDefinition(const CXIdxContainerInfo* container) { if (!container) return false; - - switch (container->cursor.kind) { - case CXCursor_Namespace: - case CXCursor_EnumDecl: - case CXCursor_UnionDecl: - case CXCursor_StructDecl: - case CXCursor_ClassDecl: - return true; - default: - return false; - } + return GetSymbolKind(container->cursor.kind) == SymbolKind::Type; } struct VisitDeclForTypeUsageParam { @@ -886,7 +925,7 @@ void VisitDeclForTypeUsageVisitorHandler(ClangCursor cursor, IndexType* ref_type = db->Resolve(*param->toplevel_type); std::string name = cursor.get_referenced().get_spelling(); if (name == ref_type->def.ShortName()) { - UniqueAdd(ref_type->uses, cursor.get_spelling_range()); + UniqueAddUseSpell(db, ref_type->uses, cursor); param->toplevel_type = nullopt; return; } @@ -908,8 +947,7 @@ void VisitDeclForTypeUsageVisitorHandler(ClangCursor cursor, IndexType* ref_type_def = db->Resolve(ref_type_id); // TODO: Should we even be visiting this if the file is not from the main // def? Try adding assert on |loc| later. - Range loc = cursor.get_spelling_range(); - UniqueAdd(ref_type_def->uses, loc); + UniqueAddUseSpell(db, ref_type_def->uses, cursor); } ClangCursor::VisitResult VisitDeclForTypeUsageVisitor( @@ -1128,10 +1166,8 @@ ClangCursor::VisitResult AddDeclInitializerUsagesVisitor(ClangCursor cursor, if (ref_usr == "") break; - Range loc = cursor.get_spelling_range(); - IndexVarId ref_id = db->ToVarId(HashUsr(ref_usr)); - IndexVar* ref_def = db->Resolve(ref_id); - UniqueAdd(ref_def->uses, loc); + IndexVar* ref_var = db->Resolve(db->ToVarId(HashUsr(ref_usr))); + UniqueAddUseSpell(db, ref_var->uses, cursor); break; } @@ -1195,7 +1231,7 @@ ClangCursor::VisitResult VisitMacroDefinitionAndExpansions(ClangCursor cursor, var_def->def.definition_extent = ResolveCXSourceRange(cx_extent, nullptr); } else - UniqueAdd(var_def->uses, decl_loc_spelling); + UniqueAddUse(db, var_def->uses, decl_loc_spelling, parent); break; } @@ -1244,10 +1280,11 @@ ClangCursor::VisitResult TemplateVisitor(ClangCursor cursor, // seems no way to extract the spelling range of `type` and we do // not want to do subtraction here. // See https://github.com/jacobdufault/cquery/issues/252 - UniqueAdd(ref_type_index->uses, ref_cursor.get_extent()); + UniqueAddUse(db, ref_type_index->uses, ref_cursor.get_extent(), + ref_cursor.get_lexical_parent()); } } - UniqueAdd(ref_index->uses, cursor.get_spelling_range()); + UniqueAddUseSpell(db, ref_index->uses, cursor); } break; } @@ -1261,10 +1298,9 @@ ClangCursor::VisitResult TemplateVisitor(ClangCursor cursor, case CXCursor_FunctionDecl: case CXCursor_FunctionTemplate: { IndexFuncId called_id = db->ToFuncId(overloaded.get_usr_hash()); - IndexFunc* called = db->Resolve(called_id); OnIndexReference_Function(db, cursor.get_spelling_range(), - data->container, called_id, called, - SymbolRole::None); + data->container, called_id, + SymbolRole::CalledBy); break; } } @@ -1293,7 +1329,7 @@ ClangCursor::VisitResult TemplateVisitor(ClangCursor cursor, ref_index->def.short_name_size = ref_index->def.detailed_name.size(); ref_index->def.kind = ClangSymbolKind::Parameter; } - UniqueAdd(ref_index->uses, cursor.get_spelling_range()); + UniqueAddUseSpell(db, ref_index->uses, cursor); } break; } @@ -1319,7 +1355,7 @@ ClangCursor::VisitResult TemplateVisitor(ClangCursor cursor, ref_index->def.short_name_size = ref_index->def.detailed_name.size(); ref_index->def.kind = ClangSymbolKind::Parameter; } - UniqueAdd(ref_index->uses, cursor.get_spelling_range()); + UniqueAddUseSpell(db, ref_index->uses, cursor); } break; } @@ -1502,17 +1538,24 @@ void OnIndexDeclaration(CXClientData client_data, const CXIdxDeclInfo* decl) { // has already been seen. if (decl->isDefinition && decl->semanticContainer) { - if (IsFunctionCallContext(decl->semanticContainer->cursor.kind)) { - IndexFuncId parent_func_id = - db->ToFuncId(decl->semanticContainer->cursor); - var->def.parent_kind = SymbolKind::Func; - var->def.parent_id = Id(parent_func_id); - } else if (IsTypeDefinition(decl->semanticContainer)) { - IndexTypeId parent_type_id = - db->ToTypeId(decl->semanticContainer->cursor); - var->def.parent_kind = SymbolKind::Type; - var->def.parent_id = Id(parent_type_id); - db->Resolve(parent_type_id)->def.vars.push_back(var_id); + switch (GetSymbolKind(decl->semanticContainer->cursor.kind)) { + default: + break; + case SymbolKind::Func: { + IndexFuncId parent_func_id = + db->ToFuncId(decl->semanticContainer->cursor); + var->def.parent_kind = SymbolKind::Func; + var->def.parent_id = Id(parent_func_id); + break; + } + case SymbolKind::Type: { + IndexTypeId parent_type_id = + db->ToTypeId(decl->semanticContainer->cursor); + var->def.parent_kind = SymbolKind::Type; + var->def.parent_id = Id(parent_type_id); + db->Resolve(parent_type_id)->def.vars.push_back(var_id); + break; + } } } @@ -1632,13 +1675,10 @@ void OnIndexDeclaration(CXClientData client_data, const CXIdxDeclInfo* decl) { func->def.declaring_type = declaring_type_id; // Mark a type reference at the ctor/dtor location. - if (decl->entityInfo->kind == CXIdxEntity_CXXConstructor) - UniqueAdd(declaring_type_def->uses, decl_spelling); - if (decl->entityInfo->kind == CXIdxEntity_CXXDestructor) { - Range dtor_type_range = decl_spelling; - dtor_type_range.start.column += 1; // Don't count the leading ~ - UniqueAdd(declaring_type_def->uses, dtor_type_range); - } + if (decl->entityInfo->kind == CXIdxEntity_CXXConstructor + || decl->entityInfo->kind == CXIdxEntity_CXXDestructor) + UniqueAddUse(db, declaring_type_def->uses, decl_spelling, + fromContainer(decl->lexicalContainer)); // Add function to declaring type. UniqueAdd(declaring_type_def->def.funcs, func_id); @@ -1714,7 +1754,7 @@ void OnIndexDeclaration(CXClientData client_data, const CXIdxDeclInfo* decl) { } } - UniqueAdd(type->uses, spell); + UniqueAddUse(db, type->uses, spell, fromContainer(decl->lexicalContainer)); break; } @@ -1751,13 +1791,13 @@ void OnIndexDeclaration(CXClientData client_data, const CXIdxDeclInfo* decl) { if (!enum_type.is_fundamental()) { IndexType* int_type = db->Resolve(db->ToTypeId(enum_type.get_usr_hash())); - AddUse(int_type->uses, decl_spell); + AddUse(db, int_type->uses, decl_spell, fromContainer(decl->lexicalContainer)); // type is invalidated. type = db->Resolve(type_id); } } } else - UniqueAdd(type->uses, decl_spell); + UniqueAddUse(db, type->uses, decl_spell, fromContainer(decl->lexicalContainer)); switch (decl->entityInfo->templateKind) { default: @@ -1905,7 +1945,7 @@ void OnIndexReference(CXClientData client_data, const CXIdxEntityRefInfo* ref) { case CXIdxEntity_CXXNamespace: { ClangCursor referenced = ref->referencedEntity->cursor; IndexType* ns = db->Resolve(db->ToTypeId(referenced.get_usr_hash())); - AddUse(ns->uses, cursor.get_spelling_range()); + AddUse(db, ns->uses, cursor.get_spelling_range(), fromContainer(ref->container)); break; } @@ -1943,7 +1983,7 @@ void OnIndexReference(CXClientData client_data, const CXIdxEntityRefInfo* ref) { var->def.kind = ClangSymbolKind::Parameter; } } - UniqueAdd(var->uses, loc); + UniqueAddUse(db, var->uses, loc, fromContainer(ref->container), SymbolRole::Reference); break; } @@ -1999,8 +2039,9 @@ void OnIndexReference(CXClientData client_data, const CXIdxEntityRefInfo* ref) { CheckTypeDependentMemberRefExpr(&loc, ref_cursor, param, db); OnIndexReference_Function( - db, loc, ref->container->cursor, called_id, called, - is_implicit ? SymbolRole::Implicit : SymbolRole::None); + db, loc, ref->container->cursor, called_id, + SymbolRole::CalledBy | + (is_implicit ? SymbolRole::Implicit : SymbolRole::None)); // Checks if |str| starts with |start|. Ignores case. auto str_begin = [](const char* start, const char* str) { @@ -2040,9 +2081,9 @@ void OnIndexReference(CXClientData client_data, const CXIdxEntityRefInfo* ref) { param->ctors.TryFindConstructorUsr(ctor_type_usr, call_type_desc); if (ctor_usr) { IndexFunc* ctor = db->Resolve(db->ToFuncId(*ctor_usr)); - AddFuncRef(&ctor->callers, - IndexFuncRef(loc, Id(), SymbolKind::Invalid, - SymbolRole::Implicit)); + AddFuncUse(&ctor->uses, + Use(loc, Id(), SymbolKind::File, + SymbolRole::CalledBy | SymbolRole::Implicit)); } } } @@ -2078,7 +2119,7 @@ void OnIndexReference(CXClientData client_data, const CXIdxEntityRefInfo* ref) { // Foo f; // } // - UniqueAdd(ref_type->uses, ClangCursor(ref->cursor).get_spelling_range()); + UniqueAddUseSpell(db, ref_type->uses, ref->cursor); break; } @@ -2319,57 +2360,15 @@ std::string GetClangVersion() { return ToString(clang_getClangVersion()); } -void Reflect(Reader& visitor, IndexFuncRef& value) { - if (visitor.Format() == SerializeFormat::Json) { - std::string s = visitor.GetString(); - const char* str_value = s.c_str(); - if (str_value[0] == '~') { - value.role = SymbolRole::Implicit; - ++str_value; - } else - value.role = SymbolRole::None; - RawId id = atol(str_value); - const char* loc_string = strchr(str_value, '@') + 1; - - value.id = Id(id); - value.range = Range(loc_string); - } else { - Reflect(visitor, static_cast(value)); - } -} -void Reflect(Writer& visitor, IndexFuncRef& value) { - if (visitor.Format() == SerializeFormat::Json) { - std::string s; - if (value.role & SymbolRole::Implicit) - s += "~"; - - // id.id is unsigned, special case -1 value - if (value.id.HasValue()) - s += std::to_string(value.id.id); - else - s += "-1"; - - s += "@" + value.range.ToString(); - visitor.String(s.c_str()); - } else { - Reflect(visitor, static_cast(value)); - } -} - void Reflect(Reader& visitor, Reference& value) { if (visitor.Format() == SerializeFormat::Json) { - std::string s = visitor.GetString(); - value = Reference{}; - value.range = Range(s.c_str()); - auto sep = s.find('|'); - if (sep == std::string::npos) - value.role = SymbolRole::Reference; - else { - char* p = const_cast(s.c_str()) + sep; - value.role = SymbolRole(strtol(p + 1, &p, 10)); - value.kind = SymbolKind(strtol(p + 1, &p, 10)); - value.id = Id(strtol(p + 1, &p, 10)); - } + std::string t = visitor.GetString(); + char* s = const_cast(t.c_str()); + value.range = Range(s); + s = strchr(s, '|'); + value.id.id = RawId(strtol(s + 1, &s, 10)); + value.kind = static_cast(strtol(s + 1, &s, 10)); + value.role = static_cast(strtol(s + 1, &s, 10)); } else { Reflect(visitor, value.range); Reflect(visitor, value.id); @@ -2380,13 +2379,11 @@ void Reflect(Reader& visitor, Reference& value) { void Reflect(Writer& visitor, Reference& value) { if (visitor.Format() == SerializeFormat::Json) { std::string s = value.range.ToString(); - if (value.role != SymbolRole::Reference || - value.kind != SymbolKind::Invalid) { - s += '|' + std::to_string(uint8_t(value.role)); - s += '|' + std::to_string(uint8_t(value.kind)); - s += '|' + std::to_string(RawId(value.id)); - } - visitor.String(s.c_str()); + // RawId(-1) -> "-1" + s += '|' + std::to_string(static_cast::type>(value.id.id)); + s += '|' + std::to_string(int(value.kind)); + s += '|' + std::to_string(int(value.role)); + Reflect(visitor, s); } else { Reflect(visitor, value.range); Reflect(visitor, value.id); diff --git a/src/indexer.h b/src/indexer.h index af4cd57c..70ad751c 100644 --- a/src/indexer.h +++ b/src/indexer.h @@ -57,7 +57,16 @@ struct Id { // Invalid id. Id() : id(-1) {} explicit Id(RawId id) : id(id) {} - template + // Id -> Id or Id -> Id is allowed implicitly. + template ::value || + std::is_same::value, + bool>::type = false> + Id(Id o) : id(o.id) {} + template ::value || + std::is_same::value), + bool>::type = false> explicit Id(Id o) : id(o.id) {} // Needed for google::dense_hash_map. @@ -107,16 +116,45 @@ struct Reference { } }; -// NOTE: id can be -1 if the function call is not coming from a function. -struct IndexFuncRef : Reference { - // Constructors are unnecessary in C++17 p0017 - IndexFuncRef() = default; - IndexFuncRef(Range range, Id id, SymbolKind kind, SymbolRole role) +struct SymbolIdx { + RawId idx; + SymbolKind kind; + + bool operator==(const SymbolIdx& o) const { + return kind == o.kind && idx == o.idx; + } + bool operator!=(const SymbolIdx& o) const { return !(*this == o); } + bool operator<(const SymbolIdx& o) const { + if (kind != o.kind) + return kind < o.kind; + return idx < o.idx; + } +}; +MAKE_REFLECT_STRUCT(SymbolIdx, kind, idx); +MAKE_HASHABLE(SymbolIdx, t.kind, t.idx); + +// |id,kind| refer to the referenced entity. +struct SymbolRef : Reference { + SymbolRef() = default; + SymbolRef(Range range, Id id, SymbolKind kind, SymbolRole role) + : Reference{range, id, kind, role} {} + SymbolRef(Reference ref) : Reference(ref) {} + SymbolRef(SymbolIdx si) + : Reference{Range(), Id(si.idx), si.kind, SymbolRole::None} {} + + RawId Idx() const { return RawId(id); } + operator SymbolIdx() const { return SymbolIdx{Idx(), kind}; } +}; + +// Represents an occurrence of a variable/type, |id,kind| refer to the lexical +// parent. +struct Use : Reference { + Use() = default; + Use(Reference ref) : Reference(ref) {} + Use(Range range, Id id, SymbolKind kind, SymbolRole role) : Reference{range, id, kind, role} {} }; -void Reflect(Reader& visitor, IndexFuncRef& value); -void Reflect(Writer& visitor, IndexFuncRef& value); void Reflect(Reader& visitor, Reference& value); void Reflect(Writer& visitor, Reference& value); @@ -126,7 +164,6 @@ struct IndexFamily { using TypeId = Id; using VarId = Id; using Range = ::Range; - using FuncRef = IndexFuncRef; }; template @@ -218,7 +255,7 @@ struct IndexType { // Every usage, useful for things like renames. // NOTE: Do not insert directly! Use AddUsage instead. - std::vector uses; + std::vector uses; IndexType() {} // For serialization. IndexType(IndexTypeId id, Usr usr); @@ -243,7 +280,7 @@ struct FuncDefDefinitionData { std::vector locals; // Functions that this function calls. - std::vector callees; + std::vector callees; typename F::FileId file; // Type which declares this one (ie, it is a method) @@ -321,7 +358,7 @@ struct IndexFunc { // // To get all usages, also include the ranges inside of declarations and // def.definition_spelling. - std::vector callers; + std::vector uses; IndexFunc() {} // For serialization. IndexFunc(IndexFuncId id, Usr usr) : usr(usr), id(id) { @@ -416,7 +453,7 @@ struct IndexVar { std::vector declarations; // Usages. - std::vector uses; + std::vector uses; IndexVar() {} // For serialization. IndexVar(IndexVarId id, Usr usr) : usr(usr), id(id) { diff --git a/src/messages/cquery_base.cc b/src/messages/cquery_base.cc index 7c1fbb3f..4a7e64e1 100644 --- a/src/messages/cquery_base.cc +++ b/src/messages/cquery_base.cc @@ -38,13 +38,13 @@ struct CqueryBaseHandler : BaseMessageHandler { QueryType& type = db->GetType(sym); if (type.def) out.result = GetLsLocations(db, working_files, - ToReference(db, type.def->parents)); + ToUses(db, type.def->parents)); break; } else if (sym.kind == SymbolKind::Func) { QueryFunc& func = db->GetFunc(sym); if (func.def) out.result = GetLsLocations(db, working_files, - ToReference(db, func.def->base)); + ToUses(db, func.def->base)); break; } } diff --git a/src/messages/cquery_call_tree.cc b/src/messages/cquery_call_tree.cc index b277dec4..db210a12 100644 --- a/src/messages/cquery_call_tree.cc +++ b/src/messages/cquery_call_tree.cc @@ -105,11 +105,8 @@ std::vector BuildExpandCallTree( // std::endl; return; //} - if (caller.HasValue()) { - QueryFuncId func_id = caller.FuncId(); - if (!func_id.HasValue()) - return; - QueryFunc& call_func = db->funcs[func_id.id]; + if (caller.kind == SymbolKind::Func) { + QueryFunc& call_func = db->GetFunc(caller); if (!call_func.def) return; @@ -137,18 +134,16 @@ std::vector BuildExpandCallTree( GetCallersForAllBaseFunctions(db, root_func); std::vector derived_callers = GetCallersForAllDerivedFunctions(db, root_func); - result.reserve(root_func.callers.size() + base_callers.size() + + result.reserve(root_func.uses.size() + base_callers.size() + derived_callers.size()); - for (QueryFuncRef caller : root_func.callers) + for (QueryFuncRef caller : root_func.uses) handle_caller(caller, Out_CqueryCallTree::CallType::Direct); - for (QueryFuncRef caller : base_callers) { - // Do not show calls to the base function coming from this function. - if (caller.FuncId() == root) - continue; - - handle_caller(caller, Out_CqueryCallTree::CallType::Base); - } + for (QueryFuncRef caller : base_callers) + if (caller.kind == SymbolKind::Func && caller.id != Id(root)) { + // Do not show calls to the base function coming from this function. + handle_caller(caller, Out_CqueryCallTree::CallType::Base); + } for (QueryFuncRef caller : derived_callers) handle_caller(caller, Out_CqueryCallTree::CallType::Derived); diff --git a/src/messages/cquery_callers.cc b/src/messages/cquery_callers.cc index 58df39ee..8be078d1 100644 --- a/src/messages/cquery_callers.cc +++ b/src/messages/cquery_callers.cc @@ -27,10 +27,10 @@ struct CqueryCallersHandler : BaseMessageHandler { FindSymbolsAtLocation(working_file, file, request->params.position)) { if (sym.kind == SymbolKind::Func) { QueryFunc& func = db->GetFunc(sym); - std::vector uses = ToReference(db, func.callers); - for (QueryFuncRef func_ref : GetCallersForAllBaseFunctions(db, func)) + std::vector uses = func.uses; + for (Use func_ref : GetCallersForAllBaseFunctions(db, func)) uses.push_back(func_ref); - for (QueryFuncRef func_ref : GetCallersForAllDerivedFunctions(db, func)) + for (Use func_ref : GetCallersForAllDerivedFunctions(db, func)) uses.push_back(func_ref); out.result = GetLsLocations(db, working_files, uses); } diff --git a/src/messages/cquery_derived.cc b/src/messages/cquery_derived.cc index aaf1cfec..bc982278 100644 --- a/src/messages/cquery_derived.cc +++ b/src/messages/cquery_derived.cc @@ -37,12 +37,12 @@ struct CqueryDerivedHandler : BaseMessageHandler { if (sym.kind == SymbolKind::Type) { QueryType& type = db->GetType(sym); out.result = - GetLsLocations(db, working_files, ToReference(db, type.derived)); + GetLsLocations(db, working_files, ToUses(db, type.derived)); break; } else if (sym.kind == SymbolKind::Func) { QueryFunc& func = db->GetFunc(sym); out.result = - GetLsLocations(db, working_files, ToReference(db, func.derived)); + GetLsLocations(db, working_files, ToUses(db, func.derived)); break; } } diff --git a/src/messages/cquery_vars.cc b/src/messages/cquery_vars.cc index 079310cd..3e0430e2 100644 --- a/src/messages/cquery_vars.cc +++ b/src/messages/cquery_vars.cc @@ -38,8 +38,8 @@ struct CqueryVarsHandler : BaseMessageHandler { // fallthrough case SymbolKind::Type: { QueryType& type = db->types[idx]; - out.result = GetLsLocations(db, working_files, - ToReference(db, type.instances)); + out.result = + GetLsLocations(db, working_files, ToUses(db, type.instances)); break; } } diff --git a/src/messages/text_document_code_lens.cc b/src/messages/text_document_code_lens.cc index 4bb13570..a84a1ed4 100644 --- a/src/messages/text_document_code_lens.cc +++ b/src/messages/text_document_code_lens.cc @@ -85,7 +85,7 @@ void AddCodeLens(const char* singular, const char* plural, CommonCodeLensParams* common, SymbolRef loc, - const std::vector& uses, + const std::vector& uses, bool force_display) { TCodeLens code_lens; optional range = GetLsRange(common->working_file, loc.range); @@ -100,7 +100,7 @@ void AddCodeLens(const char* singular, // Add unique uses. std::unordered_set unique_uses; - for (const Reference& use : uses) { + for (Use use : uses) { optional location = GetLsLocation(common->db, common->working_files, use); if (!location) @@ -159,9 +159,9 @@ struct TextDocumentCodeLensHandler AddCodeLens("ref", "refs", &common, OffsetStartColumn(sym, 0), type.uses, true /*force_display*/); AddCodeLens("derived", "derived", &common, OffsetStartColumn(sym, 1), - ToReference(db, type.derived), false /*force_display*/); + ToUses(db, type.derived), false /*force_display*/); AddCodeLens("var", "vars", &common, OffsetStartColumn(sym, 2), - ToReference(db, type.instances), false /*force_display*/); + ToUses(db, type.instances), false /*force_display*/); break; } case SymbolKind::Func: { @@ -183,35 +183,33 @@ struct TextDocumentCodeLensHandler return SymbolRef(*def); }; - std::vector base_callers = + std::vector base_callers = GetCallersForAllBaseFunctions(db, func); - std::vector derived_callers = + std::vector derived_callers = GetCallersForAllDerivedFunctions(db, func); if (base_callers.empty() && derived_callers.empty()) { SymbolRef loc = try_ensure_spelling(sym); AddCodeLens("call", "calls", &common, - OffsetStartColumn(loc, offset++), - ToReference(db, func.callers), true /*force_display*/); + OffsetStartColumn(loc, offset++), func.uses, + true /*force_display*/); } else { SymbolRef loc = try_ensure_spelling(sym); AddCodeLens("direct call", "direct calls", &common, - OffsetStartColumn(loc, offset++), - ToReference(db, func.callers), false /*force_display*/); + OffsetStartColumn(loc, offset++), func.uses, + false /*force_display*/); if (!base_callers.empty()) AddCodeLens("base call", "base calls", &common, - OffsetStartColumn(loc, offset++), - ToReference(db, base_callers), + OffsetStartColumn(loc, offset++), base_callers, false /*force_display*/); if (!derived_callers.empty()) AddCodeLens("derived call", "derived calls", &common, - OffsetStartColumn(loc, offset++), - ToReference(db, derived_callers), + OffsetStartColumn(loc, offset++), derived_callers, false /*force_display*/); } AddCodeLens("derived", "derived", &common, OffsetStartColumn(sym, offset++), - ToReference(db, func.derived), false /*force_display*/); + ToUses(db, func.derived), false /*force_display*/); // "Base" if (func.def->base.size() == 1) { @@ -238,7 +236,7 @@ struct TextDocumentCodeLensHandler } } else { AddCodeLens("base", "base", &common, OffsetStartColumn(sym, 1), - ToReference(db, func.def->base), + ToUses(db, func.def->base), false /*force_display*/); } diff --git a/src/messages/text_document_definition.cc b/src/messages/text_document_definition.cc index 677c6012..83077a7a 100644 --- a/src/messages/text_document_definition.cc +++ b/src/messages/text_document_definition.cc @@ -23,17 +23,17 @@ struct Out_TextDocumentDefinition }; MAKE_REFLECT_STRUCT(Out_TextDocumentDefinition, jsonrpc, id, result); -std::vector GetGotoDefinitionTargets(QueryDatabase* db, - SymbolRef sym) { +std::vector GetGotoDefinitionTargets(QueryDatabase* db, + SymbolRef sym) { switch (sym.kind) { // Returns GetDeclarationsOfSymbolForGotoDefinition and // variable type definition. case SymbolKind::Var: { - std::vector ret = + std::vector ret = GetDeclarationsOfSymbolForGotoDefinition(db, sym); QueryVar& var = db->GetVar(sym); if (var.def && var.def->variable_type) { - std::vector types = GetDeclarationsOfSymbolForGotoDefinition( + std::vector types = GetDeclarationsOfSymbolForGotoDefinition( db, SymbolRef(Range(), Id(var.def->variable_type->id), SymbolKind::Type, SymbolRole::None)); ret.insert(ret.end(), types.begin(), types.end()); @@ -91,8 +91,8 @@ struct TextDocumentDefinitionHandler def_loc->range.Contains(target_line, target_column))) { // Goto declaration. - std::vector targets = GetGotoDefinitionTargets(db, sym); - for (Reference target : targets) { + std::vector targets = GetGotoDefinitionTargets(db, sym); + for (Use target : targets) { optional ls_target = GetLsLocation(db, working_files, target); if (ls_target) diff --git a/src/messages/text_document_highlight.cc b/src/messages/text_document_highlight.cc index ca2c90f6..88d8db6d 100644 --- a/src/messages/text_document_highlight.cc +++ b/src/messages/text_document_highlight.cc @@ -38,9 +38,9 @@ struct TextDocumentDocumentHighlightHandler for (SymbolRef sym : FindSymbolsAtLocation(working_file, file, request->params.position)) { // Found symbol. Return references to highlight. - std::vector uses = GetUsesOfSymbol(db, sym, true); + std::vector uses = GetUsesOfSymbol(db, sym, true); out.result.reserve(uses.size()); - for (Reference use : uses) { + for (Use use : uses) { if (db->GetFileId(use) != file_id) continue; diff --git a/src/messages/text_document_references.cc b/src/messages/text_document_references.cc index c3100436..31e9bcec 100644 --- a/src/messages/text_document_references.cc +++ b/src/messages/text_document_references.cc @@ -54,10 +54,10 @@ struct TextDocumentReferencesHandler for (const SymbolRef& sym : FindSymbolsAtLocation(working_file, file, request->params.position)) { // Found symbol. Return references. - std::vector uses = GetUsesOfSymbol( + std::vector uses = GetUsesOfSymbol( db, sym, request->params.context.includeDeclaration); out.result.reserve(uses.size()); - for (const Reference& use : uses) { + for (Use use : uses) { optional ls_location = GetLsLocation(db, working_files, use); if (ls_location) diff --git a/src/messages/text_document_rename.cc b/src/messages/text_document_rename.cc index ddbeb933..8915491d 100644 --- a/src/messages/text_document_rename.cc +++ b/src/messages/text_document_rename.cc @@ -6,17 +6,17 @@ namespace { lsWorkspaceEdit BuildWorkspaceEdit(QueryDatabase* db, WorkingFiles* working_files, - const std::vector& refs, + const std::vector& uses, const std::string& new_text) { std::unordered_map path_to_edit; - for (auto& ref : refs) { + for (Use use : uses) { optional ls_location = - GetLsLocation(db, working_files, ref); + GetLsLocation(db, working_files, use); if (!ls_location) continue; - QueryFileId file_id = db->GetFileId(ref); + QueryFileId file_id = db->GetFileId(use); if (path_to_edit.find(file_id) == path_to_edit.end()) { path_to_edit[file_id] = lsTextDocumentEdit(); diff --git a/src/query.cc b/src/query.cc index 37949939..4e66a994 100644 --- a/src/query.cc +++ b/src/query.cc @@ -285,7 +285,7 @@ QueryFile::DefUpdate BuildFileDefUpdate(const IdMap& id_map, const IndexFile& in SymbolRole::Declaration); add_outline(decl.spelling, id, SymbolKind::Func, SymbolRole::Declaration); } - for (const IndexFuncRef& caller : func.callers) { + for (Use caller : func.uses) { // Make ranges of implicit function calls larger (spanning one more column // to the left/right). This is hacky but useful. e.g. // textDocument/definition on the space/semicolon in `A a;` or `return @@ -432,30 +432,8 @@ IdMap::IdMap(QueryDatabase* query_db, const IdCache& local_ids) *GetQueryVarIdFromUsr(query_db, entry.second, true); } -Reference IdMap::ToQuery(Range range, SymbolRole role) const { - return Reference{range, Id(primary_file), SymbolKind:: File, role}; -} -Reference IdMap::ToQuery(Reference ref) const { - switch (ref.kind) { - case SymbolKind::Invalid: - case SymbolKind::File: - ref.kind = SymbolKind::File; - ref.id = Id(primary_file); - break; - case SymbolKind::Func: - ref.id = Id( - cached_func_ids_.find(IndexFuncId(ref.id))->second); - break; - case SymbolKind::Type: - ref.id = Id( - cached_type_ids_.find(IndexTypeId(ref.id))->second); - break; - case SymbolKind::Var: - ref.id = - Id(cached_var_ids_.find(IndexVarId(ref.id))->second); - break; - } - return ref; +Use IdMap::ToQuery(Range range, SymbolRole role) const { + return Use(range, primary_file, SymbolKind:: File, role); } QueryTypeId IdMap::ToQuery(IndexTypeId id) const { assert(cached_type_ids_.find(id) != cached_type_ids_.end()); @@ -471,29 +449,42 @@ QueryVarId IdMap::ToQuery(IndexVarId id) const { assert(cached_var_ids_.find(id) != cached_var_ids_.end()); return QueryVarId(cached_var_ids_.find(id)->second); } -QueryFuncRef IdMap::ToQuery(IndexFuncRef ref) const { - QueryFuncRef ret(ref.range, ref.id, ref.kind, ref.role); + +Use IdMap::ToQuery(Reference ref) const { switch (ref.kind) { - default: - break; - case SymbolKind::File: - ret.id = Id(primary_file); - break; - case SymbolKind::Func: - ret.id = Id(ToQuery(IndexFuncId(ref.id))); - break; - case SymbolKind::Type: - ret.id = Id(ToQuery(IndexTypeId(ref.id))); - break; + case SymbolKind::Invalid: + break; + case SymbolKind::File: + ref.id = primary_file; + break; + case SymbolKind::Func: + ref.id = ToQuery(IndexFuncId(ref.id)); + break; + case SymbolKind::Type: + ref.id = ToQuery(IndexTypeId(ref.id)); + break; + case SymbolKind::Var: + ref.id = ToQuery(IndexVarId(ref.id)); + break; } - return ret; + return ref; } -Reference IdMap::ToQuery(IndexFunc::Declaration decl) const { +SymbolRef IdMap::ToQuery(SymbolRef ref) const { + ref.Reference::operator=(ToQuery(static_cast(ref))); + return ref; +} +Use IdMap::ToQuery(Use use) const { + use.Reference::operator=(ToQuery(static_cast(use))); + return use; +} + +Use IdMap::ToQuery(IndexFunc::Declaration decl) const { // TODO: expose more than just QueryLocation. - return Reference{decl.spelling, Id(primary_file), SymbolKind::File, SymbolRole::Declaration}; + return Use(decl.spelling, primary_file, SymbolKind::File, + SymbolRole::Declaration); } -std::vector IdMap::ToQuery(const std::vector& a) const { - std::vector ret; +std::vector IdMap::ToQuery(const std::vector& a) const { + std::vector ret; ret.reserve(a.size()); for (auto& x : a) ret.push_back(ToQuery(x, SymbolRole::Reference)); @@ -610,7 +601,7 @@ IndexUpdate::IndexUpdate(const IdMap& previous_id_map, PROCESS_UPDATE_DIFF(QueryTypeId, types_derived, derived, QueryTypeId); PROCESS_UPDATE_DIFF(QueryTypeId, types_instances, instances, QueryVarId); - PROCESS_UPDATE_DIFF(QueryTypeId, types_uses, uses, Reference); + PROCESS_UPDATE_DIFF(QueryTypeId, types_uses, uses, Use); }); // Functions @@ -629,10 +620,10 @@ IndexUpdate::IndexUpdate(const IdMap& previous_id_map, funcs_derived.push_back(QueryFunc::DerivedUpdate( previous_id_map.ToQuery(func->id), {}, previous_id_map.ToQuery(func->derived))); - if (!func->callers.empty()) - funcs_callers.push_back(QueryFunc::CallersUpdate( + if (!func->uses.empty()) + funcs_uses.push_back(QueryFunc::UsesUpdate( previous_id_map.ToQuery(func->id), {}, - previous_id_map.ToQuery(func->callers))); + previous_id_map.ToQuery(func->uses))); } }, /*onAdded:*/ @@ -650,10 +641,10 @@ IndexUpdate::IndexUpdate(const IdMap& previous_id_map, funcs_derived.push_back( QueryFunc::DerivedUpdate(current_id_map.ToQuery(func->id), current_id_map.ToQuery(func->derived))); - if (!func->callers.empty()) - funcs_callers.push_back( - QueryFunc::CallersUpdate(current_id_map.ToQuery(func->id), - current_id_map.ToQuery(func->callers))); + if (!func->uses.empty()) + funcs_uses.push_back( + QueryFunc::UsesUpdate(current_id_map.ToQuery(func->id), + current_id_map.ToQuery(func->uses))); }, /*onFound:*/ [this, &previous_id_map, ¤t_id_map](IndexFunc* previous, @@ -670,9 +661,9 @@ IndexUpdate::IndexUpdate(const IdMap& previous_id_map, } PROCESS_UPDATE_DIFF(QueryFuncId, funcs_declarations, declarations, - Reference); + Use); PROCESS_UPDATE_DIFF(QueryFuncId, funcs_derived, derived, QueryFuncId); - PROCESS_UPDATE_DIFF(QueryFuncId, funcs_callers, callers, QueryFuncRef); + PROCESS_UPDATE_DIFF(QueryFuncId, funcs_uses, uses, Use); }); // Variables @@ -721,9 +712,8 @@ IndexUpdate::IndexUpdate(const IdMap& previous_id_map, vars_def_update.push_back(QueryVar::DefUpdate( current->usr, std::move(*current_remapped_def))); - PROCESS_UPDATE_DIFF(QueryVarId, vars_declarations, declarations, - Reference); - PROCESS_UPDATE_DIFF(QueryVarId, vars_uses, uses, Reference); + PROCESS_UPDATE_DIFF(QueryVarId, vars_declarations, declarations, Use); + PROCESS_UPDATE_DIFF(QueryVarId, vars_uses, uses, Use); }); #undef PROCESS_UPDATE_DIFF @@ -747,7 +737,7 @@ void IndexUpdate::Merge(IndexUpdate&& update) { INDEX_UPDATE_APPEND(funcs_def_update); INDEX_UPDATE_MERGE(funcs_declarations); INDEX_UPDATE_MERGE(funcs_derived); - INDEX_UPDATE_MERGE(funcs_callers); + INDEX_UPDATE_MERGE(funcs_uses); INDEX_UPDATE_APPEND(vars_removed); INDEX_UPDATE_APPEND(vars_def_update); @@ -864,7 +854,7 @@ void QueryDatabase::ApplyIndexUpdate(IndexUpdate* update) { ImportOrUpdate(std::move(update->funcs_def_update)); HANDLE_MERGEABLE(funcs_declarations, declarations, funcs); HANDLE_MERGEABLE(funcs_derived, derived, funcs); - HANDLE_MERGEABLE(funcs_callers, callers, funcs); + HANDLE_MERGEABLE(funcs_uses, uses, funcs); RemoveUsrs(SymbolKind::Var, update->vars_removed); ImportOrUpdate(std::move(update->vars_def_update)); @@ -1053,7 +1043,7 @@ TEST_SUITE("query") { previous.Resolve(previous.ToTypeId(HashUsr("usr1"))) ->uses.push_back(Reference{Range(Position(1, 0))}); previous.Resolve(previous.ToFuncId(HashUsr("usr2"))) - ->callers.push_back(IndexFuncRef(Range(Position(2, 0)), Id(0), + ->uses.push_back(Use(Range(Position(2, 0)), Id(0), SymbolKind::Func, SymbolRole::None)); previous.Resolve(previous.ToVarId(HashUsr("usr3"))) ->uses.push_back(Reference{Range(Position(3, 0))}); @@ -1072,21 +1062,21 @@ TEST_SUITE("query") { IndexFunc* pf = previous.Resolve(previous.ToFuncId(HashUsr("usr"))); IndexFunc* cf = current.Resolve(current.ToFuncId(HashUsr("usr"))); - pf->callers.push_back(IndexFuncRef(Range(Position(1, 0)), Id(0), + pf->uses.push_back(Use(Range(Position(1, 0)), Id(0), SymbolKind::Func, SymbolRole::None)); - cf->callers.push_back(IndexFuncRef(Range(Position(2, 0)), Id(0), + cf->uses.push_back(Use(Range(Position(2, 0)), Id(0), SymbolKind::Func, SymbolRole::None)); IndexUpdate update = GetDelta(previous, current); REQUIRE(update.funcs_removed == std::vector{}); - REQUIRE(update.funcs_callers.size() == 1); - REQUIRE(update.funcs_callers[0].id == QueryFuncId(0)); - REQUIRE(update.funcs_callers[0].to_remove.size() == 1); - REQUIRE(update.funcs_callers[0].to_remove[0].range == + REQUIRE(update.funcs_uses.size() == 1); + REQUIRE(update.funcs_uses[0].id == QueryFuncId(0)); + REQUIRE(update.funcs_uses[0].to_remove.size() == 1); + REQUIRE(update.funcs_uses[0].to_remove[0].range == Range(Position(1, 0))); - REQUIRE(update.funcs_callers[0].to_add.size() == 1); - REQUIRE(update.funcs_callers[0].to_add[0].range == + REQUIRE(update.funcs_uses[0].to_add.size() == 1); + REQUIRE(update.funcs_uses[0].to_add[0].range == Range(Position(2, 0))); } @@ -1117,14 +1107,14 @@ TEST_SUITE("query") { IndexFunc* pf = previous.Resolve(previous.ToFuncId(HashUsr("usr"))); IndexFunc* cf = current.Resolve(current.ToFuncId(HashUsr("usr"))); - pf->callers.push_back(IndexFuncRef(Range(Position(1, 0)), Id(0), - SymbolKind::Func, SymbolRole::None)); - pf->callers.push_back(IndexFuncRef(Range(Position(2, 0)), Id(0), - SymbolKind::Func, SymbolRole::None)); - cf->callers.push_back(IndexFuncRef(Range(Position(4, 0)), Id(0), - SymbolKind::Func, SymbolRole::None)); - cf->callers.push_back(IndexFuncRef(Range(Position(5, 0)), Id(0), - SymbolKind::Func, SymbolRole::None)); + pf->uses.push_back(Use(Range(Position(1, 0)), Id(0), + SymbolKind::Func, SymbolRole::None)); + pf->uses.push_back(Use(Range(Position(2, 0)), Id(0), + SymbolKind::Func, SymbolRole::None)); + cf->uses.push_back(Use(Range(Position(4, 0)), Id(0), + SymbolKind::Func, SymbolRole::None)); + cf->uses.push_back(Use(Range(Position(5, 0)), Id(0), + SymbolKind::Func, SymbolRole::None)); QueryDatabase db; IdMap previous_map(&db, previous.id_cache); @@ -1137,13 +1127,13 @@ TEST_SUITE("query") { &previous_map, ¤t_map, &previous, ¤t); db.ApplyIndexUpdate(&import_update); - REQUIRE(db.funcs[0].callers.size() == 2); - REQUIRE(db.funcs[0].callers[0].range == Range(Position(1, 0))); - REQUIRE(db.funcs[0].callers[1].range == Range(Position(2, 0))); + REQUIRE(db.funcs[0].uses.size() == 2); + REQUIRE(db.funcs[0].uses[0].range == Range(Position(1, 0))); + REQUIRE(db.funcs[0].uses[1].range == Range(Position(2, 0))); db.ApplyIndexUpdate(&delta_update); - REQUIRE(db.funcs[0].callers.size() == 2); - REQUIRE(db.funcs[0].callers[0].range == Range(Position(4, 0))); - REQUIRE(db.funcs[0].callers[1].range == Range(Position(5, 0))); + REQUIRE(db.funcs[0].uses.size() == 2); + REQUIRE(db.funcs[0].uses[0].range == Range(Position(4, 0))); + REQUIRE(db.funcs[0].uses[1].range == Range(Position(5, 0))); } } diff --git a/src/query.h b/src/query.h index 3b64bc05..e14b127c 100644 --- a/src/query.h +++ b/src/query.h @@ -20,46 +20,7 @@ using QueryVarId = Id; struct IdMap; -struct SymbolIdx { - RawId idx; - SymbolKind kind; - - bool operator==(const SymbolIdx& o) const { - return kind == o.kind && idx == o.idx; - } - bool operator!=(const SymbolIdx& o) const { return !(*this == o); } - bool operator<(const SymbolIdx& o) const { - if (kind != o.kind) - return kind < o.kind; - return idx < o.idx; - } -}; -MAKE_REFLECT_STRUCT(SymbolIdx, kind, idx); -MAKE_HASHABLE(SymbolIdx, t.kind, t.idx); - -struct SymbolRef : Reference { - SymbolRef() = default; - SymbolRef(Range range, Id id, SymbolKind kind, SymbolRole role) - : Reference{range, id, kind, role} {} - SymbolRef(Reference ref) : Reference(ref) {} - SymbolRef(SymbolIdx si) - : Reference{Range(), Id(si.idx), si.kind, SymbolRole::None} {} - - RawId Idx() const { return RawId(id); } - operator SymbolIdx() const { return SymbolIdx{Idx(), kind, }; } -}; - -struct QueryFuncRef : Reference { - QueryFuncRef() = default; - QueryFuncRef(Range range, Id id, SymbolKind kind, SymbolRole role) - : Reference{range, id, kind, role} {} - - QueryFuncId FuncId() const { - if (kind == SymbolKind::Func) - return QueryFuncId(id); - return QueryFuncId(); - } -}; +using QueryFuncRef = Use; // There are two sources of reindex updates: the (single) definition of a // symbol has changed, or one of many users of the symbol has changed. @@ -132,7 +93,6 @@ struct QueryFamily { using TypeId = Id; using VarId = Id; using Range = Reference; - using FuncRef = QueryFuncRef; }; struct QueryFile { @@ -175,14 +135,14 @@ struct QueryType { using DefUpdate = WithUsr; using DerivedUpdate = MergeableUpdate; using InstancesUpdate = MergeableUpdate; - using UsesUpdate = MergeableUpdate; + using UsesUpdate = MergeableUpdate; Usr usr; Maybe> symbol_idx; optional def; std::vector derived; std::vector instances; - std::vector uses; + std::vector uses; explicit QueryType(const Usr& usr) : usr(usr) {} }; @@ -190,16 +150,16 @@ struct QueryType { struct QueryFunc { using Def = FuncDefDefinitionData; using DefUpdate = WithUsr; - using DeclarationsUpdate = MergeableUpdate; + using DeclarationsUpdate = MergeableUpdate; using DerivedUpdate = MergeableUpdate; - using CallersUpdate = MergeableUpdate; + using UsesUpdate = MergeableUpdate; Usr usr; Maybe> symbol_idx; optional def; - std::vector declarations; + std::vector declarations; std::vector derived; - std::vector callers; + std::vector uses; explicit QueryFunc(const Usr& usr) : usr(usr) {} }; @@ -207,14 +167,14 @@ struct QueryFunc { struct QueryVar { using Def = VarDefDefinitionData; using DefUpdate = WithUsr; - using DeclarationsUpdate = MergeableUpdate; - using UsesUpdate = MergeableUpdate; + using DeclarationsUpdate = MergeableUpdate; + using UsesUpdate = MergeableUpdate; Usr usr; Maybe> symbol_idx; optional def; - std::vector declarations; - std::vector uses; + std::vector declarations; + std::vector uses; explicit QueryVar(const Usr& usr) : usr(usr) {} }; @@ -250,7 +210,7 @@ struct IndexUpdate { std::vector funcs_def_update; std::vector funcs_declarations; std::vector funcs_derived; - std::vector funcs_callers; + std::vector funcs_uses; // Variable updates. std::vector vars_removed; @@ -279,7 +239,7 @@ MAKE_REFLECT_STRUCT(IndexUpdate, funcs_def_update, funcs_declarations, funcs_derived, - funcs_callers, + funcs_uses, vars_removed, vars_def_update, vars_declarations, @@ -379,10 +339,10 @@ template <> struct IndexToQuery { using type = QueryFileId; }; template <> struct IndexToQuery { using type = QueryFuncId; }; template <> struct IndexToQuery { using type = QueryTypeId; }; template <> struct IndexToQuery { using type = QueryVarId; }; -template <> struct IndexToQuery { using type = QueryFuncRef; }; -template <> struct IndexToQuery { using type = Reference; }; -template <> struct IndexToQuery { using type = Reference; }; -template <> struct IndexToQuery { using type = Reference; }; +template <> struct IndexToQuery { using type = Use; }; +template <> struct IndexToQuery { using type = SymbolRef; }; +template <> struct IndexToQuery { using type = Use; }; +template <> struct IndexToQuery { using type = Use; }; template struct IndexToQuery> { using type = optional::type>; }; @@ -399,13 +359,14 @@ struct IdMap { // FIXME Too verbose // clang-format off - Reference ToQuery(Range range, SymbolRole role) const; - Reference ToQuery(Reference ref) const; QueryTypeId ToQuery(IndexTypeId id) const; QueryFuncId ToQuery(IndexFuncId id) const; QueryVarId ToQuery(IndexVarId id) const; - QueryFuncRef ToQuery(IndexFuncRef ref) const; - Reference ToQuery(IndexFunc::Declaration decl) const; + SymbolRef ToQuery(SymbolRef ref) const; + Use ToQuery(Range range, SymbolRole role) const; + Use ToQuery(Reference ref) const; + Use ToQuery(Use ref) const; + Use ToQuery(IndexFunc::Declaration decl) const; template Maybe::type> ToQuery(Maybe id) const { if (!id) @@ -420,7 +381,7 @@ struct IdMap { ret.push_back(ToQuery(x)); return ret; } - std::vector ToQuery(const std::vector& a) const; + std::vector ToQuery(const std::vector& a) const; // clang-format on diff --git a/src/query_utils.cc b/src/query_utils.cc index f919e706..a1853dae 100644 --- a/src/query_utils.cc +++ b/src/query_utils.cc @@ -119,18 +119,9 @@ Maybe GetDeclarationFileForSymbol(QueryDatabase* db, return nullopt; } -std::vector ToReference(QueryDatabase* db, - const std::vector& refs) { - std::vector ret; - ret.reserve(refs.size()); - for (auto& ref : refs) - ret.push_back(ref); - return ret; -} - -std::vector ToReference(QueryDatabase* db, - const std::vector& ids) { - std::vector ret; +std::vector ToUses(QueryDatabase* db, + const std::vector& ids) { + std::vector ret; ret.reserve(ids.size()); for (auto id : ids) { QueryFunc& func = db->funcs[id.id]; @@ -142,9 +133,9 @@ std::vector ToReference(QueryDatabase* db, return ret; } -std::vector ToReference(QueryDatabase* db, - const std::vector& ids) { - std::vector ret; +std::vector ToUses(QueryDatabase* db, + const std::vector& ids) { + std::vector ret; ret.reserve(ids.size()); for (auto id : ids) { QueryType& type = db->types[id.id]; @@ -154,9 +145,8 @@ std::vector ToReference(QueryDatabase* db, return ret; } -std::vector ToReference(QueryDatabase* db, - const std::vector& ids) { - std::vector ret; +std::vector ToUses(QueryDatabase* db, const std::vector& ids) { + std::vector ret; ret.reserve(ids.size()); for (auto id : ids) { QueryVar& var = db->vars[id.id]; @@ -168,13 +158,13 @@ std::vector ToReference(QueryDatabase* db, return ret; } -std::vector GetUsesOfSymbol(QueryDatabase* db, - SymbolRef sym, - bool include_decl) { +std::vector GetUsesOfSymbol(QueryDatabase* db, + SymbolRef sym, + bool include_decl) { switch (sym.kind) { case SymbolKind::Type: { QueryType& type = db->types[sym.Idx()]; - std::vector ret = type.uses; + std::vector ret = type.uses; if (include_decl && type.def && type.def->definition_spelling) ret.push_back(*type.def->definition_spelling); return ret; @@ -182,7 +172,7 @@ std::vector GetUsesOfSymbol(QueryDatabase* db, case SymbolKind::Func: { // TODO: the vector allocation could be avoided. QueryFunc& func = db->funcs[sym.Idx()]; - std::vector ret = ToReference(db, func.callers); + std::vector ret = func.uses; if (include_decl) { AddRange(&ret, func.declarations); if (func.def && func.def->definition_spelling) @@ -192,7 +182,7 @@ std::vector GetUsesOfSymbol(QueryDatabase* db, } case SymbolKind::Var: { QueryVar& var = db->vars[sym.Idx()]; - std::vector ret = var.uses; + std::vector ret = var.uses; if (include_decl) { if (var.def && var.def->definition_spelling) ret.push_back(*var.def->definition_spelling); @@ -208,7 +198,7 @@ std::vector GetUsesOfSymbol(QueryDatabase* db, } } -std::vector GetDeclarationsOfSymbolForGotoDefinition( +std::vector GetDeclarationsOfSymbolForGotoDefinition( QueryDatabase* db, SymbolRef sym) { switch (sym.kind) { @@ -238,7 +228,7 @@ std::vector GetDeclarationsOfSymbolForGotoDefinition( bool HasCallersOnSelfOrBaseOrDerived(QueryDatabase* db, QueryFunc& root) { // Check self. - if (!root.callers.empty()) + if (!root.uses.empty()) return true; // Check for base calls. @@ -249,7 +239,7 @@ bool HasCallersOnSelfOrBaseOrDerived(QueryDatabase* db, QueryFunc& root) { while (!queue.empty()) { QueryFunc& func = *queue.front(); queue.pop(); - if (!func.callers.empty()) + if (!func.uses.empty()) return true; if (func.def) EachWithGen(db->funcs, func.def->base, [&](QueryFunc& func1) { @@ -264,7 +254,7 @@ bool HasCallersOnSelfOrBaseOrDerived(QueryDatabase* db, QueryFunc& root) { while (!queue.empty()) { QueryFunc& func = *queue.front(); queue.pop(); - if (!func.callers.empty()) + if (!func.uses.empty()) return true; EachWithGen(db->funcs, func.derived, [&](QueryFunc& func1) { queue.push(&func1); @@ -274,9 +264,9 @@ bool HasCallersOnSelfOrBaseOrDerived(QueryDatabase* db, QueryFunc& root) { return false; } -std::vector GetCallersForAllBaseFunctions(QueryDatabase* db, - QueryFunc& root) { - std::vector callers; +std::vector GetCallersForAllBaseFunctions(QueryDatabase* db, + QueryFunc& root) { + std::vector callers; if (!root.def) return callers; @@ -288,7 +278,7 @@ std::vector GetCallersForAllBaseFunctions(QueryDatabase* db, QueryFunc& func = *queue.front(); queue.pop(); - AddRange(&callers, func.callers); + AddRange(&callers, func.uses); if (func.def) EachWithGen(db->funcs, func.def->base, [&](QueryFunc& func1) { queue.push(&func1); @@ -298,9 +288,9 @@ std::vector GetCallersForAllBaseFunctions(QueryDatabase* db, return callers; } -std::vector GetCallersForAllDerivedFunctions(QueryDatabase* db, - QueryFunc& root) { - std::vector callers; +std::vector GetCallersForAllDerivedFunctions(QueryDatabase* db, + QueryFunc& root) { + std::vector callers; std::queue queue; EachWithGen(db->funcs, root.derived, [&](QueryFunc& func) { @@ -314,7 +304,7 @@ std::vector GetCallersForAllDerivedFunctions(QueryDatabase* db, EachWithGen(db->funcs, func.derived, [&](QueryFunc& func1) { queue.push(&func1); }); - AddRange(&callers, func.callers); + AddRange(&callers, func.uses); } return callers; @@ -403,11 +393,11 @@ optional GetLsLocation(QueryDatabase* db, std::vector GetLsLocations( QueryDatabase* db, WorkingFiles* working_files, - const std::vector& refs) { + const std::vector& uses) { std::unordered_set unique_locations; - for (Reference ref : refs) { + for (Use use : uses) { optional location = - GetLsLocation(db, working_files, ref); + GetLsLocation(db, working_files, use); if (!location) continue; unique_locations.insert(*location); diff --git a/src/query_utils.h b/src/query_utils.h index f73ba439..213607b1 100644 --- a/src/query_utils.h +++ b/src/query_utils.h @@ -15,27 +15,25 @@ Maybe GetDefinitionExtentOfSymbol(QueryDatabase* db, SymbolRef sym); Maybe GetDeclarationFileForSymbol(QueryDatabase* db, SymbolRef sym); -std::vector ToReference(QueryDatabase* db, - const std::vector& refs); -std::vector ToReference(QueryDatabase* db, - const std::vector& ids); -std::vector ToReference(QueryDatabase* db, - const std::vector& ids); -std::vector ToReference(QueryDatabase* db, - const std::vector& ids); +std::vector ToUses(QueryDatabase* db, + const std::vector& ids); +std::vector ToUses(QueryDatabase* db, + const std::vector& ids); +std::vector ToUses(QueryDatabase* db, + const std::vector& ids); -std::vector GetUsesOfSymbol(QueryDatabase* db, - SymbolRef sym, - bool include_decl); -std::vector GetDeclarationsOfSymbolForGotoDefinition( +std::vector GetUsesOfSymbol(QueryDatabase* db, + SymbolRef sym, + bool include_decl); +std::vector GetDeclarationsOfSymbolForGotoDefinition( QueryDatabase* db, SymbolRef sym); bool HasCallersOnSelfOrBaseOrDerived(QueryDatabase* db, QueryFunc& root); -std::vector GetCallersForAllBaseFunctions(QueryDatabase* db, - QueryFunc& root); -std::vector GetCallersForAllDerivedFunctions(QueryDatabase* db, - QueryFunc& root); +std::vector GetCallersForAllBaseFunctions(QueryDatabase* db, + QueryFunc& root); +std::vector GetCallersForAllDerivedFunctions(QueryDatabase* db, + QueryFunc& root); optional GetLsPosition(WorkingFile* working_file, const Position& position); optional GetLsRange(WorkingFile* working_file, const Range& location); @@ -50,7 +48,7 @@ optional GetLsLocation(QueryDatabase* db, std::vector GetLsLocations( QueryDatabase* db, WorkingFiles* working_files, - const std::vector& refs); + const std::vector& refs); // Returns a symbol. The symbol will have *NOT* have a location assigned. optional GetSymbolInfo(QueryDatabase* db, WorkingFiles* working_files, diff --git a/src/serializer.cc b/src/serializer.cc index 74bfb948..48d77e01 100644 --- a/src/serializer.cc +++ b/src/serializer.cc @@ -240,7 +240,7 @@ void Reflect(TVisitor& visitor, IndexFunc& value) { REFLECT_MEMBER2("base", value.def.base); REFLECT_MEMBER2("derived", value.derived); REFLECT_MEMBER2("locals", value.def.locals); - REFLECT_MEMBER2("callers", value.callers); + REFLECT_MEMBER2("uses", value.uses); REFLECT_MEMBER2("callees", value.def.callees); REFLECT_MEMBER_END(); }