[llvm-branch-commits] [clang-tools-extra] 9c328e7 - [clangd] Add hover info for `this` expr
Sam McCall via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Tue Dec 15 01:01:35 PST 2020
Author: xndcn
Date: 2020-12-15T09:47:29+01:00
New Revision: 9c328e7afafd15795fed54e3b0c1c5bd4fa97dfa
URL: https://github.com/llvm/llvm-project/commit/9c328e7afafd15795fed54e3b0c1c5bd4fa97dfa
DIFF: https://github.com/llvm/llvm-project/commit/9c328e7afafd15795fed54e3b0c1c5bd4fa97dfa.diff
LOG: [clangd] Add hover info for `this` expr
How about add hover information for `this` expr?
It seems useful to show related information about the class for `this` expr sometimes.
Reviewed By: sammccall
Differential Revision: https://reviews.llvm.org/D92041
Added:
Modified:
clang-tools-extra/clangd/Hover.cpp
clang-tools-extra/clangd/unittests/HoverTests.cpp
Removed:
################################################################################
diff --git a/clang-tools-extra/clangd/Hover.cpp b/clang-tools-extra/clangd/Hover.cpp
index d599ccb557c28..e461c7c433645 100644
--- a/clang-tools-extra/clangd/Hover.cpp
+++ b/clang-tools-extra/clangd/Hover.cpp
@@ -552,7 +552,8 @@ HoverInfo getHoverContents(const NamedDecl *D, const SymbolIndex *Index) {
/// Generate a \p Hover object given the type \p T.
HoverInfo getHoverContents(QualType T, ASTContext &ASTCtx,
- const SymbolIndex *Index) {
+ const SymbolIndex *Index,
+ bool SuppressScope = false) {
HoverInfo HI;
if (const auto *D = T->getAsTagDecl()) {
@@ -566,6 +567,7 @@ HoverInfo getHoverContents(QualType T, ASTContext &ASTCtx,
// Builtin types
auto Policy = printingPolicyForDecls(ASTCtx.getPrintingPolicy());
Policy.SuppressTagKeyword = true;
+ Policy.SuppressScope = SuppressScope;
HI.Name = T.getAsString(Policy);
}
return HI;
@@ -628,15 +630,29 @@ llvm::StringLiteral getNameForExpr(const Expr *E) {
return llvm::StringLiteral("expression");
}
-// Generates hover info for evaluatable expressions.
+// Generates hover info for `this` and evaluatable expressions.
// FIXME: Support hover for literals (esp user-defined)
-llvm::Optional<HoverInfo> getHoverContents(const Expr *E, ParsedAST &AST) {
+llvm::Optional<HoverInfo> getHoverContents(const Expr *E, ParsedAST &AST,
+ const SymbolIndex *Index) {
// There's not much value in hovering over "42" and getting a hover card
// saying "42 is an int", similar for other literals.
if (isLiteral(E))
return llvm::None;
HoverInfo HI;
+ // For `this` expr we currently generate hover with pointee type.
+ if (const CXXThisExpr *CTE = dyn_cast<CXXThisExpr>(E)) {
+ QualType OriginThisType = CTE->getType()->getPointeeType();
+ QualType ClassType = declaredType(OriginThisType->getAsTagDecl());
+ // For partial specialization class, origin `this` pointee type will be
+ // parsed as `InjectedClassNameType`, which will ouput template arguments
+ // like "type-parameter-0-0". So we retrieve user written class type in this
+ // case.
+ QualType PrettyThisType = AST.getASTContext().getPointerType(
+ QualType(ClassType.getTypePtr(), OriginThisType.getCVRQualifiers()));
+ return getHoverContents(PrettyThisType, AST.getASTContext(), Index,
+ /*SuppressScope=*/true);
+ }
// For expressions we currently print the type and the value, iff it is
// evaluatable.
if (auto Val = printExprValue(E, AST.getASTContext())) {
@@ -861,7 +877,7 @@ llvm::Optional<HoverInfo> getHover(ParsedAST &AST, Position Pos,
HI->Value = printExprValue(N, AST.getASTContext());
maybeAddCalleeArgInfo(N, *HI, AST.getASTContext().getPrintingPolicy());
} else if (const Expr *E = N->ASTNode.get<Expr>()) {
- HI = getHoverContents(E, AST);
+ HI = getHoverContents(E, AST, Index);
}
// FIXME: support hovers for other nodes?
// - built-in types
diff --git a/clang-tools-extra/clangd/unittests/HoverTests.cpp b/clang-tools-extra/clangd/unittests/HoverTests.cpp
index fdebf0da67103..bac0e525664b2 100644
--- a/clang-tools-extra/clangd/unittests/HoverTests.cpp
+++ b/clang-tools-extra/clangd/unittests/HoverTests.cpp
@@ -2019,6 +2019,56 @@ TEST(Hover, All) {
HI.NamespaceScope = "";
HI.Definition = "@interface MYObject\n at end";
}},
+ {
+ R"cpp(// this expr
+ // comment
+ namespace ns {
+ class Foo {
+ Foo* bar() {
+ return [[t^his]];
+ }
+ };
+ }
+ )cpp",
+ [](HoverInfo &HI) { HI.Name = "Foo *"; }},
+ {
+ R"cpp(// this expr for template class
+ namespace ns {
+ template <typename T>
+ class Foo {
+ Foo* bar() const {
+ return [[t^his]];
+ }
+ };
+ }
+ )cpp",
+ [](HoverInfo &HI) { HI.Name = "const Foo<T> *"; }},
+ {
+ R"cpp(// this expr for specialization class
+ namespace ns {
+ template <typename T> class Foo {};
+ template <>
+ struct Foo<int> {
+ Foo* bar() {
+ return [[thi^s]];
+ }
+ };
+ }
+ )cpp",
+ [](HoverInfo &HI) { HI.Name = "Foo<int> *"; }},
+ {
+ R"cpp(// this expr for partial specialization struct
+ namespace ns {
+ template <typename T, typename F> struct Foo {};
+ template <typename F>
+ struct Foo<int, F> {
+ Foo* bar() const {
+ return [[thi^s]];
+ }
+ };
+ }
+ )cpp",
+ [](HoverInfo &HI) { HI.Name = "const Foo<int, F> *"; }},
};
// Create a tiny index, so tests above can verify documentation is fetched.
More information about the llvm-branch-commits
mailing list