[PATCH] D49840: [AST] Add MatchFinder::matchSubtree
Manuel Klimek via cfe-commits
cfe-commits at lists.llvm.org
Fri Jul 27 01:45:31 PDT 2018
On Fri, Jul 27, 2018 at 10:39 AM Gabor Marton via Phabricator <
reviews at reviews.llvm.org> wrote:
> martong added a comment.
>
> > MatchFinder::match allows you to match a node. Wrapping your matcher
> code with:
> > auto m = <my cool matcher>;
> > ast_matchers::match(anyOf(m, hashDescendant(m)), node, context);
>
> Okay, I understand and accept that.
> However, I consider that a different level of abstraction.
> `ast_matchers::match` uses `internal::CollectMatchesCallback` in its
> implementation. If I already have my own custom MatchCallback implemented
> then there is no way to achieve the desired behavior.
>
> For example, in `ASTImporter` tests we use the following customized
> callback class:
>
> enum class DeclMatcherKind { First, Last };
>
> // Matcher class to retrieve the first/last matched node under a given
> AST.
> template <typename NodeType, DeclMatcherKind MatcherKind>
> class DeclMatcher : public MatchFinder::MatchCallback {
> NodeType *Node = nullptr;
> void run(const MatchFinder::MatchResult &Result) override {
> if ((MatcherKind == DeclMatcherKind::First && Node == nullptr) ||
> MatcherKind == DeclMatcherKind::Last) {
> Node = const_cast<NodeType
> *>(Result.Nodes.getNodeAs<NodeType>(""));
> }
> }
> public:
> // Returns the first/last matched node under the tree rooted in `D`.
> template <typename MatcherType>
> NodeType *match(const Decl *D, const MatcherType &AMatcher) {
> MatchFinder Finder;
> Finder.addMatcher(AMatcher.bind(""), this);
> Finder.matchAST(D->getASTContext());
> assert(Node);
> return Node;
> }
> };
> template <typename NodeType>
> using LastDeclMatcher = DeclMatcher<NodeType, DeclMatcherKind::Last>;
> template <typename NodeType>
> using FirstDeclMatcher = DeclMatcher<NodeType, DeclMatcherKind::First>;
>
> And this is how we use it in the tests:
>
> Decl *FromTU = getTuDecl("void f(); void f(); void f();", Lang_CXX);
> auto Pattern = functionDecl(hasName("f"));
> auto *D0 = FirstDeclMatcher<FunctionDecl>().match(FromTU, Pattern);
> auto *D2 = LastDeclMatcher<FunctionDecl>().match(FromTU, Pattern);
>
> At this point we would like to extend this `DeclMatcher` to be able to
> match a subtree, and be able to start the traverse from a specific `Decl`,
> something like this :
>
> auto *DV = FirsDeclMatcher<VarDecl>().match(D2, SomeOtherPattern);
>
> Currently, I don't see how we could do this extension without the proposed
> `matchSubtree`.
> (Perhaps, we could refactor our `DeclMatcher` to not use a customized
> MatchCallback, rather use `ast_matchers::match`, but that sounds like a bad
> workaround to me.)
>
> Hope this makes the the goal of this patch cleaner.
>
Finder.match also has an overload that takes the node. Can you wrap
"Pattern" above in the anyOf(hasDescendant(...), ...) and match on the node
instead of the full AST?
>
>
> Repository:
> rC Clang
>
> https://reviews.llvm.org/D49840
>
>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20180727/3246a389/attachment-0001.html>
More information about the cfe-commits
mailing list