From 5763201838dd9054f56ad5f2fbc65f92b9dcbea1 Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Sat, 27 Jan 2018 20:25:14 -0800 Subject: [PATCH] Remove is_type_member & VarDefDefinitionData::declaring_type Rename ClangStorageClass to StorageClass Add semantic_parent & semantic_parent_kind (but not serialized yet) Move query.h SymbolKind to indexer.h SymbolKind and make it uint8_t --- src/clang_symbol_kind.h | 24 +++++++++++++---------- src/indexer.cc | 41 ++++++++++++++++++++++----------------- src/indexer.h | 32 +++++++++++++++++------------- src/language_server_api.h | 10 +--------- src/message_handler.cc | 21 +------------------- src/query.cc | 7 ++++--- src/query.h | 5 ----- src/serializer.cc | 1 - 8 files changed, 61 insertions(+), 80 deletions(-) diff --git a/src/clang_symbol_kind.h b/src/clang_symbol_kind.h index c9dcc95e..6fe6837c 100644 --- a/src/clang_symbol_kind.h +++ b/src/clang_symbol_kind.h @@ -45,19 +45,23 @@ MAKE_REFLECT_TYPE_PROXY(ClangSymbolKind, std::underlying_type::type); // clang/Basic/Specifiers.h clang::StorageClass -enum class ClangStorageClass : uint8_t { +enum class StorageClass : uint8_t { // In |CX_StorageClass| but not in |clang::StorageClass| - SC_Invalid, + // e.g. non-type template parameters + Invalid, // These are legal on both functions and variables. - SC_None, - SC_Extern, - SC_Static, - SC_PrivateExtern, + // e.g. global functions/variables, local variables + None, + Extern, + Static, + // e.g. |__private_extern__ int a;| + PrivateExtern, // These are only legal on variables. - SC_Auto, - SC_Register + // e.g. explicit |auto int a;| + Auto, + Register }; -MAKE_REFLECT_TYPE_PROXY(ClangStorageClass, - std::underlying_type::type); +MAKE_REFLECT_TYPE_PROXY(StorageClass, + std::underlying_type::type); diff --git a/src/indexer.cc b/src/indexer.cc index df11bbba..db7242aa 100644 --- a/src/indexer.cc +++ b/src/indexer.cc @@ -110,26 +110,26 @@ ClangSymbolKind GetSymbolKind(CXIdxEntityKind kind) { } } -ClangStorageClass GetStorageClass(CX_StorageClass storage) { +StorageClass GetStorageClass(CX_StorageClass storage) { switch (storage) { case CX_SC_Invalid: case CX_SC_OpenCLWorkGroupLocal: - return ClangStorageClass::SC_Invalid; + return StorageClass::Invalid; case CX_SC_None: - return ClangStorageClass::SC_None; + return StorageClass::None; case CX_SC_Extern: - return ClangStorageClass::SC_Extern; + return StorageClass::Extern; case CX_SC_Static: - return ClangStorageClass::SC_Static; + return StorageClass::Static; case CX_SC_PrivateExtern: - return ClangStorageClass::SC_PrivateExtern; + return StorageClass::PrivateExtern; case CX_SC_Auto: - return ClangStorageClass::SC_Auto; + return StorageClass::Auto; case CX_SC_Register: - return ClangStorageClass::SC_Register; + return StorageClass::Register; default: assert(0); - return ClangStorageClass::SC_Invalid; + return StorageClass::Invalid; } } @@ -566,7 +566,7 @@ void OnIndexReference_Function(IndexFile* db, // static const int IndexFile::kCurrentVersion = 10; -const uint64_t IndexFile::kMessagePackMagic = 0x6371657279; +const uint64_t IndexFile::kMessagePackMagic = 0x637175657279; // "cquery" const int IndexFile::kMessagePackVersion = 0; IndexFile::IndexFile(const std::string& path, @@ -1454,14 +1454,19 @@ void OnIndexDeclaration(CXClientData client_data, const CXIdxDeclInfo* decl) { // We don't need to assign declaring type multiple times if this variable // has already been seen. - // TODO: Refactor handlers so more things are under 'if - // (!decl->isRedeclaration)' - if (decl->isDefinition && IsTypeDefinition(decl->semanticContainer)) { - IndexTypeId declaring_type_id = - db->ToTypeId(decl->semanticContainer->cursor); - IndexType* declaring_type_def = db->Resolve(declaring_type_id); - var->def.declaring_type = declaring_type_id; - declaring_type_def->def.vars.push_back(var_id); + if (decl->isDefinition && decl->semanticContainer) { + if (IsFunctionCallContext(decl->semanticContainer->cursor.kind)) { + IndexFuncId parent_func_id = + db->ToFuncId(decl->semanticContainer->cursor); + var->def.semantic_parent_kind = SymbolKind::Func; + var->def.semantic_parent_id = size_t(parent_func_id); + } else if (IsTypeDefinition(decl->semanticContainer)) { + IndexTypeId parent_type_id = + db->ToTypeId(decl->semanticContainer->cursor); + var->def.semantic_parent_kind = SymbolKind::Type; + var->def.semantic_parent_id = size_t(parent_type_id); + db->Resolve(parent_type_id)->def.vars.push_back(var_id); + } } break; diff --git a/src/indexer.h b/src/indexer.h index cd1d6929..9b212a4d 100644 --- a/src/indexer.h +++ b/src/indexer.h @@ -31,6 +31,11 @@ struct IndexVar; using namespace std::experimental; +// The order matters. In FindSymbolsAtLocation, we want Var/Func ordered in +// front of others. +enum class SymbolKind : uint8_t { Invalid, File, Type, Func, Var }; +MAKE_REFLECT_TYPE_PROXY(SymbolKind, uint8_t); + template struct Id { size_t id; @@ -253,7 +258,7 @@ struct FuncDefDefinitionData { std::string short_name; std::string detailed_name; ClangSymbolKind kind = ClangSymbolKind::Unknown; - ClangStorageClass storage = ClangStorageClass::SC_Invalid; + StorageClass storage = StorageClass::Invalid; optional hover; optional comments; optional definition_spelling; @@ -369,8 +374,6 @@ struct VarDefDefinitionData { // General metadata. std::string short_name; std::string detailed_name; - ClangSymbolKind kind = ClangSymbolKind::Unknown; - ClangStorageClass storage = ClangStorageClass::SC_Invalid; optional hover; optional comments; // TODO: definitions should be a list of ranges, since there can be more @@ -381,15 +384,19 @@ struct VarDefDefinitionData { // Type of the variable. optional variable_type; - // Type which declares this one. - optional declaring_type; + // Function/type which declares this one. + size_t semantic_parent_id = size_t(-1); + SymbolKind semantic_parent_kind = SymbolKind::Invalid; - // Function which declares this one. - // TODO Accept other container types. - optional semantic_container; + ClangSymbolKind kind = ClangSymbolKind::Unknown; + // Note a variable may have instances of both |None| and |Extern| + // (declaration). + StorageClass storage = StorageClass::Invalid; - // FIXME - bool is_local() const { return kind == ClangSymbolKind::Variable; } + bool is_local() const { + return kind == ClangSymbolKind::Parameter || + kind == ClangSymbolKind::Variable; + } bool is_macro() const { return kind == ClangSymbolKind::Macro; } bool operator==( @@ -398,9 +405,7 @@ struct VarDefDefinitionData { detailed_name == other.detailed_name && hover == other.hover && definition_spelling == other.definition_spelling && definition_extent == other.definition_extent && - variable_type == other.variable_type && - declaring_type == other.declaring_type && hover == other.hover && - comments == other.comments; + variable_type == other.variable_type && comments == other.comments; } bool operator!=( const VarDefDefinitionData& other) const { @@ -425,7 +430,6 @@ void Reflect(TVisitor& visitor, REFLECT_MEMBER(definition_spelling); REFLECT_MEMBER(definition_extent); REFLECT_MEMBER(variable_type); - REFLECT_MEMBER(declaring_type); REFLECT_MEMBER_END(); } diff --git a/src/language_server_api.h b/src/language_server_api.h index 062dcdcf..0b068fcb 100644 --- a/src/language_server_api.h +++ b/src/language_server_api.h @@ -1082,15 +1082,10 @@ MAKE_REFLECT_STRUCT(Out_CquerySetInactiveRegion, jsonrpc, method, params); struct Out_CqueryPublishSemanticHighlighting : public lsOutMessage { - enum class SymbolType { Type = 0, Function, Variable }; struct Symbol { int stableId = 0; - // TODO Deprecate |type| in favor of fine-grained |kind|. - SymbolType type = SymbolType::Type; ClangSymbolKind kind; - ClangStorageClass storage; - // TODO Deprecate |isTypeMember| in favor of semantic container. - bool isTypeMember = false; + StorageClass storage; std::vector ranges; }; struct Params { @@ -1100,12 +1095,9 @@ struct Out_CqueryPublishSemanticHighlighting std::string method = "$cquery/publishSemanticHighlighting"; Params params; }; -MAKE_REFLECT_TYPE_PROXY(Out_CqueryPublishSemanticHighlighting::SymbolType, int); MAKE_REFLECT_STRUCT(Out_CqueryPublishSemanticHighlighting::Symbol, - type, kind, storage, - isTypeMember, stableId, ranges); MAKE_REFLECT_STRUCT(Out_CqueryPublishSemanticHighlighting::Params, diff --git a/src/message_handler.cc b/src/message_handler.cc index fe458a14..311d98a7 100644 --- a/src/message_handler.cc +++ b/src/message_handler.cc @@ -103,20 +103,6 @@ void EmitSemanticHighlighting(QueryDatabase* db, WorkingFile* working_file, QueryFile* file) { assert(file->def); - auto map_symbol_kind_to_symbol_type = [](SymbolKind kind) { - switch (kind) { - case SymbolKind::Type: - return Out_CqueryPublishSemanticHighlighting::SymbolType::Type; - case SymbolKind::Func: - return Out_CqueryPublishSemanticHighlighting::SymbolType::Function; - case SymbolKind::Var: - return Out_CqueryPublishSemanticHighlighting::SymbolType::Variable; - default: - assert(false); - return Out_CqueryPublishSemanticHighlighting::SymbolType::Variable; - } - }; - auto semantic_cache_for_file = semantic_cache->GetCacheForFile(file->def->path); @@ -125,9 +111,8 @@ void EmitSemanticHighlighting(QueryDatabase* db, grouped_symbols; for (SymbolRef sym : file->def->all_symbols) { std::string detailed_name; - bool is_type_member = false; ClangSymbolKind kind = ClangSymbolKind::Unknown; - ClangStorageClass storage = ClangStorageClass::SC_Invalid; + StorageClass storage = StorageClass::Invalid; // This switch statement also filters out symbols that are not highlighted. switch (sym.idx.kind) { case SymbolKind::Func: { @@ -137,7 +122,6 @@ void EmitSemanticHighlighting(QueryDatabase* db, if (func->def->short_name.compare(0, 8, "operator") == 0) continue; // applies to for loop kind = func->def->kind; - is_type_member = func->def->declaring_type.has_value(); detailed_name = func->def->short_name; // TODO We use cursor extent for lambda definition. Without the region @@ -164,7 +148,6 @@ void EmitSemanticHighlighting(QueryDatabase* db, continue; // applies to for loop kind = var->def->kind; storage = var->def->storage; - is_type_member = var->def->declaring_type.has_value(); detailed_name = var->def->short_name; break; } @@ -191,8 +174,6 @@ void EmitSemanticHighlighting(QueryDatabase* db, semantic_cache_for_file->GetStableId(sym.idx.kind, detailed_name); symbol.kind = kind; symbol.storage = storage; - symbol.type = map_symbol_kind_to_symbol_type(sym.idx.kind); - symbol.isTypeMember = is_type_member; symbol.ranges.push_back(*loc); grouped_symbols[sym.idx] = symbol; } diff --git a/src/query.cc b/src/query.cc index ea4aaa8b..18824fa4 100644 --- a/src/query.cc +++ b/src/query.cc @@ -79,14 +79,15 @@ optional ToQuery(const IdMap& id_map, const IndexVar::Def& var) { QueryVar::Def result; result.short_name = var.short_name; result.detailed_name = var.detailed_name; - result.kind = var.kind; - result.storage = var.storage; result.hover = var.hover; result.comments = var.comments; result.definition_spelling = id_map.ToQuery(var.definition_spelling); result.definition_extent = id_map.ToQuery(var.definition_extent); result.variable_type = id_map.ToQuery(var.variable_type); - result.declaring_type = id_map.ToQuery(var.declaring_type); + result.semantic_parent_id = var.semantic_parent_id; + result.semantic_parent_kind = var.semantic_parent_kind; + result.kind = var.kind; + result.storage = var.storage; return result; } diff --git a/src/query.h b/src/query.h index d2e4e69f..6833cc88 100644 --- a/src/query.h +++ b/src/query.h @@ -48,11 +48,6 @@ struct QueryLocation { MAKE_REFLECT_STRUCT(QueryLocation, path, range); MAKE_HASHABLE(QueryLocation, t.path, t.range); -// The order matters. In FindSymbolsAtLocation, we want Var/Func ordered in -// front of others. -enum class SymbolKind : int { Invalid, File, Type, Func, Var }; -MAKE_REFLECT_TYPE_PROXY(SymbolKind, int); - namespace std { template <> struct hash<::SymbolKind> { diff --git a/src/serializer.cc b/src/serializer.cc index e0c485ba..27e5b334 100644 --- a/src/serializer.cc +++ b/src/serializer.cc @@ -193,7 +193,6 @@ void Reflect(TVisitor& visitor, IndexVar& value) { REFLECT_MEMBER2("definition_spelling", value.def.definition_spelling); REFLECT_MEMBER2("definition_extent", value.def.definition_extent); REFLECT_MEMBER2("variable_type", value.def.variable_type); - REFLECT_MEMBER2("declaring_type", value.def.declaring_type); REFLECT_MEMBER2("uses", value.uses); REFLECT_MEMBER_END(); }