If no range is given, return the translation unit AST.
This is useful for tooling operations that require e.g. the full path to
a node.
Details
- Reviewers
sammccall - Commits
- rG81dae18dff7f: [clangd] Allow AST request without range
Diff Detail
- Repository
- rG LLVM Github Monorepo
Event Timeline
Thanks! I'm not sure why range was required to start with, probably just lacking a use case.
Only real issue is I think we should update the signature on ClangdServer.
This is useful for tooling operations that require e.g. the full path to
a node.
This could be a fairly bulky/inefficient way of getting that though, for large files!
clang-tools-extra/clangd/ClangdServer.cpp | ||
---|---|---|
913 | I don't think it makes sense to give an empty range this special meaning. | |
clang-tools-extra/clangd/test/ast-no-range.test | ||
2 | We try to cover the features we can in gtests (here unittests/DumpASTTests.cpp) - could you add one? (Having a lit test too is reasonable as it tests the serialization of requests etc, but not essential) |
Is that an action point for me?
This is useful for tooling operations that require e.g. the full path to
a node.
This could be a fairly bulky/inefficient way of getting that though, for large files!
Right, though there are probably other good reasons to have access to the full AST.
For this particular example, it might make more sense to (optionally) provide the node's parent
or indeed the AST path, but I think both of these would be more intrusive code-wise.
clang-tools-extra/clangd/ClangdServer.cpp | ||
---|---|---|
895 | Ooh, there's a problem here... TraverseDecl(TranslationUnitDecl) is going to deserialize the whole preamble and try to return the AST for every decl in every included header. I think this should be observable in a unit test: if you set TestTU.Code and TestTU.HeaderCode, we want decls from the latter not to be visible in the dumped tree. Instead, dumpAST should call DumpVisitor.TraverseAST(), which runs over the TraversalScope forest (i.e. all the top-level decls of the current file). But we still need the TranslationUnitDecl in order to have a single root. Therefore I think we need this logic for "full tree" dumping: DumpVisitor.traverseNode("declaration", TUDecl, [&] { DumpVisitor.TraverseAST() }); I think it's OK to keep the dumpAST signature as-is (i.e. pass a DynTypedNode with TUDecl in it as you're doing now) and just override TraverseTranslationUnitDecl with this special case. However both dumpAST() and the callsite should have a comment saying that TranslationUnitDecl is safe/has these special semantics, as that's not typical in clangd. (The previous version of this patch had this problem too, it was just less obvious. Sorry for not catching it in the first round!) | |
clang-tools-extra/clangd/ClangdServer.h | ||
347–348 | Nit: we tend to pass Range etc by value rather than const ref. | |
clang-tools-extra/clangd/Protocol.h | ||
1728–1729 | nit: top-level->root | |
clang-tools-extra/clangd/unittests/DumpASTTests.cpp | ||
164 | as mentioned, this test should have decls in the header file too (HeaderCode, which is implicitly included) to make sure that we're not returning those |
Fantastic, thank you! Just a couple of nits.
Want me to land this for you?
clang-tools-extra/clangd/DumpAST.cpp | ||
---|---|---|
339 | The naming causes a bit of confusion over whether this is a (CRTP) override of a RecursiveASTVisitor method. (It's not, as that method is called TraverseTranslationUnitDecl). I'd suggest either:
| |
405 | this comment should rather go in the .h file |
Nit: we tend to pass Range etc by value rather than const ref.
I actually have no idea why! But probably best to be consistent and if we clean this up we can do it everywhere at once.