mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2024-11-27 07:31:28 +00:00
[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
This commit is contained in:
parent
a2eb07aa55
commit
9c328e7afa
@ -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
|
||||
|
@ -2019,6 +2019,56 @@ TEST(Hover, All) {
|
||||
HI.NamespaceScope = "";
|
||||
HI.Definition = "@interface MYObject\n@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.
|
||||
|
Loading…
Reference in New Issue
Block a user