From 03b50ea3cc7a905a4c9b11560302d91a11201ff3 Mon Sep 17 00:00:00 2001 From: romix Date: Sat, 23 Dec 2017 18:22:22 -0800 Subject: [PATCH] Serialize decl comments and use them in GetHoverForSymbol --- src/clang_cursor.cc | 9 +++++--- src/clang_cursor.h | 6 +++++- src/indexer.cc | 10 +++++++++ src/indexer.h | 6 ++++++ src/messages/text_document_hover.cc | 33 ++++++++++++++++------------- src/query.cc | 3 +++ src/serializer.cc | 3 +++ 7 files changed, 51 insertions(+), 19 deletions(-) diff --git a/src/clang_cursor.cc b/src/clang_cursor.cc index ccb48bbe..be0de391 100644 --- a/src/clang_cursor.cc +++ b/src/clang_cursor.cc @@ -182,12 +182,15 @@ std::string ClangCursor::get_type_description() const { return ::ToString(clang_getTypeSpelling(type)); } -std::string ClangCursor::get_comments() const { +optional ClangCursor::get_comments() const { + return nullopt; + // TODO ClangCursor referenced = get_referenced(); if (referenced) + // Get unformatted comments. Returns multiple paragraphs. return ::ToString(clang_Cursor_getRawCommentText(referenced.cx_cursor)); - - return ""; + // Get formatted comments. Returns only the first paragraph. + return ::ToString(clang_Cursor_getBriefCommentText(referenced.cx_cursor)); } std::string ClangCursor::ToString() const { diff --git a/src/clang_cursor.h b/src/clang_cursor.h index f786519e..efbca7eb 100644 --- a/src/clang_cursor.h +++ b/src/clang_cursor.h @@ -1,10 +1,14 @@ #pragma once +#include + #include #include #include +using std::experimental::optional; + class ClangType { public: ClangType(); @@ -65,7 +69,7 @@ class ClangCursor { bool is_valid_kind() const; std::string get_type_description() const; - std::string get_comments() const; + optional get_comments() const; std::string ToString() const; diff --git a/src/indexer.cc b/src/indexer.cc index bff1d330..c497aec8 100644 --- a/src/indexer.cc +++ b/src/indexer.cc @@ -1012,6 +1012,7 @@ ClangCursor::VisitResult VisitMacroDefinitionAndExpansions(ClangCursor cursor, var_def->def.hover = "#define " + GetDocumentContentInRange(param->tu->cx_tu, cx_extent); var_def->def.cls = VarClass::Macro; + var_def->def.comments = cursor.get_comments(); var_def->def.definition_spelling = decl_loc_spelling; var_def->def.definition_extent = Resolve(cx_extent, nullptr); } @@ -1154,6 +1155,7 @@ void OnIndexDeclaration(CXClientData client_data, const CXIdxDeclInfo* decl) { // string. Shorten it to just "lambda". if (type_name.find("(lambda at") != std::string::npos) type_name = "lambda"; + var->def.comments = decl_cursor.get_comments(); { std::string qualified_name = @@ -1246,6 +1248,7 @@ void OnIndexDeclaration(CXClientData client_data, const CXIdxDeclInfo* decl) { IndexFuncId func_id = db->ToFuncId(decl_cursor_resolved.cx_cursor); IndexFunc* func = db->Resolve(func_id); + func->def.comments = decl_cursor.get_comments(); // We don't actually need to know the return type, but we need to mark it // as an interesting usage. @@ -1428,6 +1431,9 @@ void OnIndexDeclaration(CXClientData client_data, const CXIdxDeclInfo* decl) { type->def.detailed_name = ns->QualifiedName(decl->semanticContainer, type->def.short_name); + ClangCursor decl_cursor = decl->cursor; + type->def.comments = decl_cursor.get_comments(); + // For Typedef/CXXTypeAlias spanning a few lines, display the declaration // line, with spelling name replaced with qualified name. // TODO Think how to display multi-line declaration like `typedef struct { @@ -1481,6 +1487,8 @@ void OnIndexDeclaration(CXClientData client_data, const CXIdxDeclInfo* decl) { type->def.detailed_name = ns->QualifiedName(decl->semanticContainer, type->def.short_name); + ClangCursor decl_cursor = decl->cursor; + type->def.comments = decl_cursor.get_comments(); // } if (decl->isDefinition) { @@ -1594,6 +1602,8 @@ void OnIndexReference(CXClientData client_data, const CXIdxEntityRefInfo* ref) { clang_getTypeSpelling(clang_getCursorType(referenced.cx_cursor))); var->def.detailed_name = type_name + " " + var->def.short_name; var->def.cls = VarClass::Member; + ClangCursor decl_cursor = referenced; + var->def.comments = decl_cursor.get_comments(); UniqueAdd(var->uses, ResolveSpelling(referenced.cx_cursor)); AddDeclInitializerUsages(db, referenced.cx_cursor); // TODO Use proper semantic_container and lexical_container. diff --git a/src/indexer.h b/src/indexer.h index 692eb32a..a19ea82b 100644 --- a/src/indexer.h +++ b/src/indexer.h @@ -150,6 +150,7 @@ struct TypeDefDefinitionData { std::string short_name; std::string detailed_name; optional hover; + optional comments; // While a class/type can technically have a separate declaration/definition, // it doesn't really happen in practice. The declaration never contains @@ -201,6 +202,7 @@ void Reflect(TVisitor& visitor, REFLECT_MEMBER(short_name); REFLECT_MEMBER(detailed_name); REFLECT_MEMBER(hover); + REFLECT_MEMBER(comments); REFLECT_MEMBER(definition_spelling); REFLECT_MEMBER(definition_extent); REFLECT_MEMBER(alias_of); @@ -247,6 +249,7 @@ struct FuncDefDefinitionData { std::string short_name; std::string detailed_name; optional hover; + optional comments; optional definition_spelling; optional definition_extent; @@ -295,6 +298,7 @@ void Reflect( REFLECT_MEMBER(short_name); REFLECT_MEMBER(detailed_name); REFLECT_MEMBER(hover); + REFLECT_MEMBER(comments); REFLECT_MEMBER(definition_spelling); REFLECT_MEMBER(definition_extent); REFLECT_MEMBER(declaring_type); @@ -375,6 +379,7 @@ struct VarDefDefinitionData { std::string short_name; std::string detailed_name; optional hover; + optional comments; optional declaration; // TODO: definitions should be a list of ranges, since there can be more // than one - when?? @@ -419,6 +424,7 @@ void Reflect(TVisitor& visitor, REFLECT_MEMBER(short_name); REFLECT_MEMBER(detailed_name); REFLECT_MEMBER(hover); + REFLECT_MEMBER(comments); REFLECT_MEMBER(definition_spelling); REFLECT_MEMBER(definition_extent); REFLECT_MEMBER(variable_type); diff --git a/src/messages/text_document_hover.cc b/src/messages/text_document_hover.cc index 29217489..e4d9f839 100644 --- a/src/messages/text_document_hover.cc +++ b/src/messages/text_document_hover.cc @@ -3,33 +3,36 @@ namespace { +static std::string getHoverString(const optional& hover, + const optional& comments, + const std::string& detailed_name) { + // TODO: Properly format multi-line comments. + std::string ret; + if (comments) { + ret += *comments; + ret += '\n'; + } + return ret + hover.value_or(detailed_name); +} + std::string GetHoverForSymbol(QueryDatabase* db, const SymbolIdx& symbol) { switch (symbol.kind) { case SymbolKind::Type: { QueryType& type = db->types[symbol.idx]; - if (type.def) { - if (type.def->hover) - return *type.def->hover; - return type.def->detailed_name; - } + if (type.def) + return getHoverString(type.def->hover, type.def->comments, type.def->detailed_name); break; } case SymbolKind::Func: { QueryFunc& func = db->funcs[symbol.idx]; - if (func.def) { - if (func.def->hover) - return *func.def->hover; - return func.def->detailed_name; - } + if (func.def) + return getHoverString(func.def->hover, func.def->comments, func.def->detailed_name); break; } case SymbolKind::Var: { QueryVar& var = db->vars[symbol.idx]; - if (var.def) { - if (var.def->hover) - return *var.def->hover; - return var.def->detailed_name; - } + if (var.def) + return getHoverString(var.def->hover, var.def->comments, var.def->detailed_name); break; } case SymbolKind::File: diff --git a/src/query.cc b/src/query.cc index f842df14..de6afbfe 100644 --- a/src/query.cc +++ b/src/query.cc @@ -27,6 +27,7 @@ optional ToQuery(const IdMap& id_map, result.short_name = type.short_name; result.detailed_name = type.detailed_name; result.hover = type.hover; + result.comments = type.comments; result.definition_spelling = id_map.ToQuery(type.definition_spelling); result.definition_extent = id_map.ToQuery(type.definition_extent); result.alias_of = id_map.ToQuery(type.alias_of); @@ -46,6 +47,7 @@ optional ToQuery(const IdMap& id_map, result.short_name = func.short_name; result.detailed_name = func.detailed_name; result.hover = func.hover; + result.comments = func.comments; result.definition_spelling = id_map.ToQuery(func.definition_spelling); result.definition_extent = id_map.ToQuery(func.definition_extent); result.declaring_type = id_map.ToQuery(func.declaring_type); @@ -64,6 +66,7 @@ optional ToQuery(const IdMap& id_map, const IndexVar::Def& var) { result.short_name = var.short_name; result.detailed_name = var.detailed_name; result.hover = var.hover; + result.comments = var.comments; result.declaration = id_map.ToQuery(var.declaration); result.definition_spelling = id_map.ToQuery(var.definition_spelling); result.definition_extent = id_map.ToQuery(var.definition_extent); diff --git a/src/serializer.cc b/src/serializer.cc index adbcd78a..60b4c363 100644 --- a/src/serializer.cc +++ b/src/serializer.cc @@ -100,6 +100,7 @@ void Reflect(TVisitor& visitor, IndexType& value) { REFLECT_MEMBER2("short_name", value.def.short_name); REFLECT_MEMBER2("detailed_name", value.def.detailed_name); REFLECT_MEMBER2("hover", value.def.hover); + REFLECT_MEMBER2("comments", value.def.comments); REFLECT_MEMBER2("definition_spelling", value.def.definition_spelling); REFLECT_MEMBER2("definition_extent", value.def.definition_extent); REFLECT_MEMBER2("alias_of", value.def.alias_of); @@ -122,6 +123,7 @@ void Reflect(TVisitor& visitor, IndexFunc& value) { REFLECT_MEMBER2("short_name", value.def.short_name); REFLECT_MEMBER2("detailed_name", value.def.detailed_name); REFLECT_MEMBER2("hover", value.def.hover); + REFLECT_MEMBER2("comments", value.def.comments); REFLECT_MEMBER2("declarations", value.declarations); REFLECT_MEMBER2("definition_spelling", value.def.definition_spelling); REFLECT_MEMBER2("definition_extent", value.def.definition_extent); @@ -142,6 +144,7 @@ void Reflect(TVisitor& visitor, IndexVar& value) { REFLECT_MEMBER2("short_name", value.def.short_name); REFLECT_MEMBER2("detailed_name", value.def.detailed_name); REFLECT_MEMBER2("hover", value.def.hover); + REFLECT_MEMBER2("comments", value.def.comments); REFLECT_MEMBER2("declaration", value.def.declaration); REFLECT_MEMBER2("definition_spelling", value.def.definition_spelling); REFLECT_MEMBER2("definition_extent", value.def.definition_extent);