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
This commit is contained in:
Fangrui Song 2018-01-27 20:25:14 -08:00
parent aeb63ce3ad
commit 5763201838
8 changed files with 61 additions and 80 deletions

View File

@ -45,19 +45,23 @@ MAKE_REFLECT_TYPE_PROXY(ClangSymbolKind,
std::underlying_type<ClangSymbolKind>::type); std::underlying_type<ClangSymbolKind>::type);
// clang/Basic/Specifiers.h clang::StorageClass // clang/Basic/Specifiers.h clang::StorageClass
enum class ClangStorageClass : uint8_t { enum class StorageClass : uint8_t {
// In |CX_StorageClass| but not in |clang::StorageClass| // 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. // These are legal on both functions and variables.
SC_None, // e.g. global functions/variables, local variables
SC_Extern, None,
SC_Static, Extern,
SC_PrivateExtern, Static,
// e.g. |__private_extern__ int a;|
PrivateExtern,
// These are only legal on variables. // These are only legal on variables.
SC_Auto, // e.g. explicit |auto int a;|
SC_Register Auto,
Register
}; };
MAKE_REFLECT_TYPE_PROXY(ClangStorageClass, MAKE_REFLECT_TYPE_PROXY(StorageClass,
std::underlying_type<ClangStorageClass>::type); std::underlying_type<StorageClass>::type);

View File

@ -110,26 +110,26 @@ ClangSymbolKind GetSymbolKind(CXIdxEntityKind kind) {
} }
} }
ClangStorageClass GetStorageClass(CX_StorageClass storage) { StorageClass GetStorageClass(CX_StorageClass storage) {
switch (storage) { switch (storage) {
case CX_SC_Invalid: case CX_SC_Invalid:
case CX_SC_OpenCLWorkGroupLocal: case CX_SC_OpenCLWorkGroupLocal:
return ClangStorageClass::SC_Invalid; return StorageClass::Invalid;
case CX_SC_None: case CX_SC_None:
return ClangStorageClass::SC_None; return StorageClass::None;
case CX_SC_Extern: case CX_SC_Extern:
return ClangStorageClass::SC_Extern; return StorageClass::Extern;
case CX_SC_Static: case CX_SC_Static:
return ClangStorageClass::SC_Static; return StorageClass::Static;
case CX_SC_PrivateExtern: case CX_SC_PrivateExtern:
return ClangStorageClass::SC_PrivateExtern; return StorageClass::PrivateExtern;
case CX_SC_Auto: case CX_SC_Auto:
return ClangStorageClass::SC_Auto; return StorageClass::Auto;
case CX_SC_Register: case CX_SC_Register:
return ClangStorageClass::SC_Register; return StorageClass::Register;
default: default:
assert(0); assert(0);
return ClangStorageClass::SC_Invalid; return StorageClass::Invalid;
} }
} }
@ -566,7 +566,7 @@ void OnIndexReference_Function(IndexFile* db,
// static // static
const int IndexFile::kCurrentVersion = 10; const int IndexFile::kCurrentVersion = 10;
const uint64_t IndexFile::kMessagePackMagic = 0x6371657279; const uint64_t IndexFile::kMessagePackMagic = 0x637175657279; // "cquery"
const int IndexFile::kMessagePackVersion = 0; const int IndexFile::kMessagePackVersion = 0;
IndexFile::IndexFile(const std::string& path, 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 // We don't need to assign declaring type multiple times if this variable
// has already been seen. // has already been seen.
// TODO: Refactor handlers so more things are under 'if if (decl->isDefinition && decl->semanticContainer) {
// (!decl->isRedeclaration)' if (IsFunctionCallContext(decl->semanticContainer->cursor.kind)) {
if (decl->isDefinition && IsTypeDefinition(decl->semanticContainer)) { IndexFuncId parent_func_id =
IndexTypeId declaring_type_id = db->ToFuncId(decl->semanticContainer->cursor);
db->ToTypeId(decl->semanticContainer->cursor); var->def.semantic_parent_kind = SymbolKind::Func;
IndexType* declaring_type_def = db->Resolve(declaring_type_id); var->def.semantic_parent_id = size_t(parent_func_id);
var->def.declaring_type = declaring_type_id; } else if (IsTypeDefinition(decl->semanticContainer)) {
declaring_type_def->def.vars.push_back(var_id); 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; break;

View File

@ -31,6 +31,11 @@ struct IndexVar;
using namespace std::experimental; 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 <typename T> template <typename T>
struct Id { struct Id {
size_t id; size_t id;
@ -253,7 +258,7 @@ struct FuncDefDefinitionData {
std::string short_name; std::string short_name;
std::string detailed_name; std::string detailed_name;
ClangSymbolKind kind = ClangSymbolKind::Unknown; ClangSymbolKind kind = ClangSymbolKind::Unknown;
ClangStorageClass storage = ClangStorageClass::SC_Invalid; StorageClass storage = StorageClass::Invalid;
optional<std::string> hover; optional<std::string> hover;
optional<std::string> comments; optional<std::string> comments;
optional<Range> definition_spelling; optional<Range> definition_spelling;
@ -369,8 +374,6 @@ struct VarDefDefinitionData {
// General metadata. // General metadata.
std::string short_name; std::string short_name;
std::string detailed_name; std::string detailed_name;
ClangSymbolKind kind = ClangSymbolKind::Unknown;
ClangStorageClass storage = ClangStorageClass::SC_Invalid;
optional<std::string> hover; optional<std::string> hover;
optional<std::string> comments; optional<std::string> comments;
// TODO: definitions should be a list of ranges, since there can be more // TODO: definitions should be a list of ranges, since there can be more
@ -381,15 +384,19 @@ struct VarDefDefinitionData {
// Type of the variable. // Type of the variable.
optional<TypeId> variable_type; optional<TypeId> variable_type;
// Type which declares this one. // Function/type which declares this one.
optional<TypeId> declaring_type; size_t semantic_parent_id = size_t(-1);
SymbolKind semantic_parent_kind = SymbolKind::Invalid;
// Function which declares this one. ClangSymbolKind kind = ClangSymbolKind::Unknown;
// TODO Accept other container types. // Note a variable may have instances of both |None| and |Extern|
optional<IndexFuncId> semantic_container; // (declaration).
StorageClass storage = StorageClass::Invalid;
// FIXME bool is_local() const {
bool is_local() const { return kind == ClangSymbolKind::Variable; } return kind == ClangSymbolKind::Parameter ||
kind == ClangSymbolKind::Variable;
}
bool is_macro() const { return kind == ClangSymbolKind::Macro; } bool is_macro() const { return kind == ClangSymbolKind::Macro; }
bool operator==( bool operator==(
@ -398,9 +405,7 @@ struct VarDefDefinitionData {
detailed_name == other.detailed_name && hover == other.hover && detailed_name == other.detailed_name && hover == other.hover &&
definition_spelling == other.definition_spelling && definition_spelling == other.definition_spelling &&
definition_extent == other.definition_extent && definition_extent == other.definition_extent &&
variable_type == other.variable_type && variable_type == other.variable_type && comments == other.comments;
declaring_type == other.declaring_type && hover == other.hover &&
comments == other.comments;
} }
bool operator!=( bool operator!=(
const VarDefDefinitionData<TypeId, FuncId, VarId, Range>& other) const { const VarDefDefinitionData<TypeId, FuncId, VarId, Range>& other) const {
@ -425,7 +430,6 @@ void Reflect(TVisitor& visitor,
REFLECT_MEMBER(definition_spelling); REFLECT_MEMBER(definition_spelling);
REFLECT_MEMBER(definition_extent); REFLECT_MEMBER(definition_extent);
REFLECT_MEMBER(variable_type); REFLECT_MEMBER(variable_type);
REFLECT_MEMBER(declaring_type);
REFLECT_MEMBER_END(); REFLECT_MEMBER_END();
} }

View File

@ -1082,15 +1082,10 @@ MAKE_REFLECT_STRUCT(Out_CquerySetInactiveRegion, jsonrpc, method, params);
struct Out_CqueryPublishSemanticHighlighting struct Out_CqueryPublishSemanticHighlighting
: public lsOutMessage<Out_CqueryPublishSemanticHighlighting> { : public lsOutMessage<Out_CqueryPublishSemanticHighlighting> {
enum class SymbolType { Type = 0, Function, Variable };
struct Symbol { struct Symbol {
int stableId = 0; int stableId = 0;
// TODO Deprecate |type| in favor of fine-grained |kind|.
SymbolType type = SymbolType::Type;
ClangSymbolKind kind; ClangSymbolKind kind;
ClangStorageClass storage; StorageClass storage;
// TODO Deprecate |isTypeMember| in favor of semantic container.
bool isTypeMember = false;
std::vector<lsRange> ranges; std::vector<lsRange> ranges;
}; };
struct Params { struct Params {
@ -1100,12 +1095,9 @@ struct Out_CqueryPublishSemanticHighlighting
std::string method = "$cquery/publishSemanticHighlighting"; std::string method = "$cquery/publishSemanticHighlighting";
Params params; Params params;
}; };
MAKE_REFLECT_TYPE_PROXY(Out_CqueryPublishSemanticHighlighting::SymbolType, int);
MAKE_REFLECT_STRUCT(Out_CqueryPublishSemanticHighlighting::Symbol, MAKE_REFLECT_STRUCT(Out_CqueryPublishSemanticHighlighting::Symbol,
type,
kind, kind,
storage, storage,
isTypeMember,
stableId, stableId,
ranges); ranges);
MAKE_REFLECT_STRUCT(Out_CqueryPublishSemanticHighlighting::Params, MAKE_REFLECT_STRUCT(Out_CqueryPublishSemanticHighlighting::Params,

View File

@ -103,20 +103,6 @@ void EmitSemanticHighlighting(QueryDatabase* db,
WorkingFile* working_file, WorkingFile* working_file,
QueryFile* file) { QueryFile* file) {
assert(file->def); 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 = auto semantic_cache_for_file =
semantic_cache->GetCacheForFile(file->def->path); semantic_cache->GetCacheForFile(file->def->path);
@ -125,9 +111,8 @@ void EmitSemanticHighlighting(QueryDatabase* db,
grouped_symbols; grouped_symbols;
for (SymbolRef sym : file->def->all_symbols) { for (SymbolRef sym : file->def->all_symbols) {
std::string detailed_name; std::string detailed_name;
bool is_type_member = false;
ClangSymbolKind kind = ClangSymbolKind::Unknown; ClangSymbolKind kind = ClangSymbolKind::Unknown;
ClangStorageClass storage = ClangStorageClass::SC_Invalid; StorageClass storage = StorageClass::Invalid;
// This switch statement also filters out symbols that are not highlighted. // This switch statement also filters out symbols that are not highlighted.
switch (sym.idx.kind) { switch (sym.idx.kind) {
case SymbolKind::Func: { case SymbolKind::Func: {
@ -137,7 +122,6 @@ void EmitSemanticHighlighting(QueryDatabase* db,
if (func->def->short_name.compare(0, 8, "operator") == 0) if (func->def->short_name.compare(0, 8, "operator") == 0)
continue; // applies to for loop continue; // applies to for loop
kind = func->def->kind; kind = func->def->kind;
is_type_member = func->def->declaring_type.has_value();
detailed_name = func->def->short_name; detailed_name = func->def->short_name;
// TODO We use cursor extent for lambda definition. Without the region // TODO We use cursor extent for lambda definition. Without the region
@ -164,7 +148,6 @@ void EmitSemanticHighlighting(QueryDatabase* db,
continue; // applies to for loop continue; // applies to for loop
kind = var->def->kind; kind = var->def->kind;
storage = var->def->storage; storage = var->def->storage;
is_type_member = var->def->declaring_type.has_value();
detailed_name = var->def->short_name; detailed_name = var->def->short_name;
break; break;
} }
@ -191,8 +174,6 @@ void EmitSemanticHighlighting(QueryDatabase* db,
semantic_cache_for_file->GetStableId(sym.idx.kind, detailed_name); semantic_cache_for_file->GetStableId(sym.idx.kind, detailed_name);
symbol.kind = kind; symbol.kind = kind;
symbol.storage = storage; symbol.storage = storage;
symbol.type = map_symbol_kind_to_symbol_type(sym.idx.kind);
symbol.isTypeMember = is_type_member;
symbol.ranges.push_back(*loc); symbol.ranges.push_back(*loc);
grouped_symbols[sym.idx] = symbol; grouped_symbols[sym.idx] = symbol;
} }

View File

@ -79,14 +79,15 @@ optional<QueryVar::Def> ToQuery(const IdMap& id_map, const IndexVar::Def& var) {
QueryVar::Def result; QueryVar::Def result;
result.short_name = var.short_name; result.short_name = var.short_name;
result.detailed_name = var.detailed_name; result.detailed_name = var.detailed_name;
result.kind = var.kind;
result.storage = var.storage;
result.hover = var.hover; result.hover = var.hover;
result.comments = var.comments; result.comments = var.comments;
result.definition_spelling = id_map.ToQuery(var.definition_spelling); result.definition_spelling = id_map.ToQuery(var.definition_spelling);
result.definition_extent = id_map.ToQuery(var.definition_extent); result.definition_extent = id_map.ToQuery(var.definition_extent);
result.variable_type = id_map.ToQuery(var.variable_type); 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; return result;
} }

View File

@ -48,11 +48,6 @@ struct QueryLocation {
MAKE_REFLECT_STRUCT(QueryLocation, path, range); MAKE_REFLECT_STRUCT(QueryLocation, path, range);
MAKE_HASHABLE(QueryLocation, t.path, t.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 { namespace std {
template <> template <>
struct hash<::SymbolKind> { struct hash<::SymbolKind> {

View File

@ -193,7 +193,6 @@ void Reflect(TVisitor& visitor, IndexVar& value) {
REFLECT_MEMBER2("definition_spelling", value.def.definition_spelling); REFLECT_MEMBER2("definition_spelling", value.def.definition_spelling);
REFLECT_MEMBER2("definition_extent", value.def.definition_extent); REFLECT_MEMBER2("definition_extent", value.def.definition_extent);
REFLECT_MEMBER2("variable_type", value.def.variable_type); REFLECT_MEMBER2("variable_type", value.def.variable_type);
REFLECT_MEMBER2("declaring_type", value.def.declaring_type);
REFLECT_MEMBER2("uses", value.uses); REFLECT_MEMBER2("uses", value.uses);
REFLECT_MEMBER_END(); REFLECT_MEMBER_END();
} }