Skip to content

Commit ffd0f11

Browse files
committed
[clangd] Improve type printing in hover
Summary: Do not include tag keywords when printing types for symbol names, as it will come from SymbolKind. Also suppress them while printing definitions to prevent them occuring in template arguments. Make use of `getAsString`, instead of `print` in all places to have a consistent style across the file. Reviewers: sammccall Subscribers: ilya-biryukov, MaskRay, jkorous, arphaman, usaxena95, cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D72450
1 parent 45c4b08 commit ffd0f11

File tree

2 files changed

+36
-15
lines changed

2 files changed

+36
-15
lines changed

clang-tools-extra/clangd/Hover.cpp

Lines changed: 9 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,13 @@
1616
#include "Selection.h"
1717
#include "SourceCode.h"
1818
#include "index/SymbolCollector.h"
19-
2019
#include "clang/AST/ASTContext.h"
2120
#include "clang/AST/ASTTypeTraits.h"
2221
#include "clang/AST/Decl.h"
2322
#include "clang/AST/DeclBase.h"
2423
#include "clang/AST/DeclTemplate.h"
2524
#include "clang/AST/PrettyPrinter.h"
25+
#include "clang/AST/Type.h"
2626
#include "clang/Index/IndexSymbol.h"
2727
#include "llvm/ADT/STLExtras.h"
2828
#include "llvm/ADT/SmallVector.h"
@@ -101,6 +101,7 @@ std::string printDefinition(const Decl *D) {
101101
printingPolicyForDecls(D->getASTContext().getPrintingPolicy());
102102
Policy.IncludeTagDefinition = false;
103103
Policy.SuppressTemplateArgsInCXXConstructors = true;
104+
Policy.SuppressTagKeyword = true;
104105
D->print(OS, Policy);
105106
OS.flush();
106107
return Definition;
@@ -233,9 +234,7 @@ void fillFunctionTypeAndParams(HoverInfo &HI, const Decl *D,
233234
HI.Parameters->emplace_back();
234235
auto &P = HI.Parameters->back();
235236
if (!PVD->getType().isNull()) {
236-
P.Type.emplace();
237-
llvm::raw_string_ostream OS(*P.Type);
238-
PVD->getType().print(OS, Policy);
237+
P.Type = PVD->getType().getAsString(Policy);
239238
} else {
240239
std::string Param;
241240
llvm::raw_string_ostream OS(Param);
@@ -344,13 +343,10 @@ HoverInfo getHoverContents(const NamedDecl *D, const SymbolIndex *Index) {
344343
}
345344

346345
// Fill in types and params.
347-
if (const FunctionDecl *FD = getUnderlyingFunction(D)) {
346+
if (const FunctionDecl *FD = getUnderlyingFunction(D))
348347
fillFunctionTypeAndParams(HI, D, FD, Policy);
349-
} else if (const auto *VD = dyn_cast<ValueDecl>(D)) {
350-
HI.Type.emplace();
351-
llvm::raw_string_ostream OS(*HI.Type);
352-
VD->getType().print(OS, Policy);
353-
}
348+
else if (const auto *VD = dyn_cast<ValueDecl>(D))
349+
HI.Type = VD->getType().getAsString(Policy);
354350

355351
// Fill in value with evaluated initializer if possible.
356352
if (const auto *Var = dyn_cast<VarDecl>(D)) {
@@ -380,9 +376,9 @@ HoverInfo getHoverContents(QualType T, ASTContext &ASTCtx,
380376
enhanceFromIndex(HI, *CommentD, Index);
381377
} else {
382378
// Builtin types
383-
llvm::raw_string_ostream OS(HI.Name);
384-
PrintingPolicy Policy = printingPolicyForDecls(ASTCtx.getPrintingPolicy());
385-
T.print(OS, Policy);
379+
auto Policy = printingPolicyForDecls(ASTCtx.getPrintingPolicy());
380+
Policy.SuppressTagKeyword = true;
381+
HI.Name = T.getAsString(Policy);
386382
}
387383
return HI;
388384
}

clang-tools-extra/clangd/unittests/HoverTests.cpp

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -446,7 +446,7 @@ class Foo {})cpp";
446446
[](HoverInfo &HI) {
447447
HI.Name = "x";
448448
HI.NamespaceScope = "";
449-
HI.Definition = "enum Color x = GREEN";
449+
HI.Definition = "Color x = GREEN";
450450
HI.Kind = index::SymbolKind::Variable;
451451
HI.Type = "enum Color";
452452
HI.Value = "GREEN (1)"; // Symbolic when hovering on an expression.
@@ -1427,7 +1427,7 @@ TEST(Hover, All) {
14271427
HI.NamespaceScope = "";
14281428
HI.LocalScope = "test::";
14291429
HI.Type = "struct Test &&";
1430-
HI.Definition = "struct Test &&test = {}";
1430+
HI.Definition = "Test &&test = {}";
14311431
HI.Value = "{}";
14321432
}},
14331433
{
@@ -1476,6 +1476,31 @@ TEST(Hover, All) {
14761476
HI.ReturnType = "int";
14771477
HI.Type = "int ()";
14781478
}},
1479+
{
1480+
R"cpp(// type of nested templates.
1481+
template <class T> struct cls {};
1482+
cls<cls<cls<int>>> [[fo^o]];
1483+
)cpp",
1484+
[](HoverInfo &HI) {
1485+
HI.Definition = "cls<cls<cls<int>>> foo";
1486+
HI.Kind = index::SymbolKind::Variable;
1487+
HI.NamespaceScope = "";
1488+
HI.Name = "foo";
1489+
HI.Type = "cls<cls<cls<int> > >";
1490+
HI.Value = "{}";
1491+
}},
1492+
{
1493+
R"cpp(// type of nested templates.
1494+
template <class T> struct cls {};
1495+
[[cl^s]]<cls<cls<int>>> foo;
1496+
)cpp",
1497+
[](HoverInfo &HI) {
1498+
HI.Definition = "template <> struct cls<cls<cls<int>>> {}";
1499+
HI.Kind = index::SymbolKind::Struct;
1500+
HI.NamespaceScope = "";
1501+
HI.Name = "cls<cls<cls<int> > >";
1502+
HI.Documentation = "type of nested templates.";
1503+
}},
14791504
};
14801505

14811506
// Create a tiny index, so tests above can verify documentation is fetched.

0 commit comments

Comments
 (0)