[PATCH] D92977: [clangd] Improve hover and goToDefinition on auto and dectype
Sam McCall via Phabricator via cfe-commits
cfe-commits at lists.llvm.org
Fri Dec 11 01:30:40 PST 2020
sammccall added a comment.
Thanks for doing this! Go-to-def-on-auto has been bugging me, it'll be great to have it :-)
Overall the patch looks really solid, with nice tests. The one thing I'd suggest is splitting the two features (hover and go-to-def) into separate patches.
e.g. here, I'm not totally sure about the hover change yet, and want to think and get some input from others. But I don't want to delay the go-to-definition part. So I've left comments on the go-to-definition changes, and if you want to drop hover from this patch and upload it as a separate review, that'd be really helpful.
---
My concern with hover is mostly around consistency and clarity. In isolation, the new hover certainly looks better than the old one for structs (e.g. syntax highligthing!).
However now we have a different style for struct vs non-struct types, and it's not just a surface thing: for structs we show the declaration, but many types have no declaration to show. I'm not sure how you can show a hover for `auto = char *const*` or so that feels consistent with this one.
We should also consider consistency and clarity with different types of `auto`. Currently our hover for undeduced auto is just "auto", and our hover for auto params is a mess. It would be nice about this distinction, as when the same keyword has multiple meanings people can conflate them.
One solution would be to make `auto` the name, and the type the definition. This provides less information (but I suspect that information is often noise):
### deduced-type `auto`
---
struct cv::Ptr<cv::detail::ChannelsCompensator>
(For context, the `auto` hover was one of the first implemented. Later we went back and added some structure (type/name/definition/documentation) but the old `auto` hover was mostly shoehorned into this. So if we're going to change auto hover, we shuold consider trying to make it fit this schema, too)
================
Comment at: clang-tools-extra/clangd/XRefs.cpp:685
+
+ if (Tok.kind() == tok::kw_auto || Tok.kind() == tok::kw_decltype) {
+ if (auto Deduced = getDeducedType(AST.getASTContext(), Tok.location())) {
----------------
This deserves a high-level comment: // go-to-definition on auto should find the definition of the deduced type, if possible
================
Comment at: clang-tools-extra/clangd/XRefs.cpp:686
+ if (Tok.kind() == tok::kw_auto || Tok.kind() == tok::kw_decltype) {
+ if (auto Deduced = getDeducedType(AST.getASTContext(), Tok.location())) {
+ Deduced = Deduced->getNonReferenceType();
----------------
I think we should pull the contents of this if() into a function findSymbolForType or so.
LSP has a `textDocument/typeDefinition` request that could also make use of this logic.
(You don't need to implement that, and I'm very much in favor of having this `textDocument/definition` be the do-what-i-mean swiss army knife like this patch does. But I'd just like to factor this code with potential reuse in mind)
================
Comment at: clang-tools-extra/clangd/XRefs.cpp:689
+ const NamedDecl *D = Deduced->getTypePtr()->getAsTagDecl();
+ if (!D)
+ continue;
----------------
there are many other types we could resolve to a decl: TypedefType, TemplateTypeParmtype, ...
If we're only going to handle tag types, it deserves a FIXME comment.
But we do have a helper for this. Can you try calling `targetDecl(DynTypedNode::create(Deduced), DeclRelation::TemplatePattern | DeclRelation::Alias)` instead of `Deduced->getTypePtr()->getAsTagDecl()`?
That should handle more cases, at a minimum, this case sholud pass:
```
using [[T]] = int;
T x;
^auto y = x;
```
(I see you have a test case that aliases backed by tag types are resolved to the underlying tag decl, this change would offer the alias instead, which is more consistent with our current go-to-definition. You could also offer both by passing `DeclRelation::TemplatePattern | DeclRelation::Alias | DeclRelation::Underlying`... but I think we should value consistency here)
================
Comment at: clang-tools-extra/clangd/unittests/XRefsTests.cpp:669
+
+ R"cpp(// auto on template class with forward declared class
+ template<typename T> class [[Foo]] {};
----------------
There's a scalability problem with testing every corner of the C++ language (there are lots!) with every feature. Generally I prefer to cover some important/weird/bugfix cases here, but to cover as much as possible with unittests of the underlying functions.
In this case, that would mean
- moving tests that are about `auto` in different contexts to ASTTests.cpp (current test coverage there is poor).
- (assuming we can use `targetDecl()`) moving tests that are about which decl a type should resolve to to `FindTargetTests.cpp` - but current coverage there is pretty good so we can probably just drop many of them.
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D92977/new/
https://reviews.llvm.org/D92977
More information about the cfe-commits
mailing list