diff options
author | Yitzhak Mandelbaum <yitzhakm@google.com> | 2020-05-26 22:59:08 -0400 |
---|---|---|
committer | Yitzhak Mandelbaum <yitzhakm@google.com> | 2020-05-28 11:42:07 -0400 |
commit | ce5780b88c6e2f3303afd266e5e29c1badd9eb3b (patch) | |
tree | 07eda3e7cf4d545fb9edb72e625892b856963581 /clang/unittests/Tooling/TransformerTest.cpp | |
parent | db52a4901096f035b6cda832c4bf4c6ce2ede2f9 (diff) | |
download | llvm-ce5780b88c6e2f3303afd266e5e29c1badd9eb3b.zip llvm-ce5780b88c6e2f3303afd266e5e29c1badd9eb3b.tar.gz llvm-ce5780b88c6e2f3303afd266e5e29c1badd9eb3b.tar.bz2 |
[libTooling] Fix Transformer to work with ambient traversal kinds.
Summary:
`RewriteRule`'s `applyFirst` was brittle with respect to the default setting of the
`TraversalKind`. This patch builds awareness of traversal kinds directly into
rewrite rules so that they are insensitive to any changes in defaults.
Reviewers: steveire, gribozavr
Subscribers: hokein, cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D80606
Diffstat (limited to 'clang/unittests/Tooling/TransformerTest.cpp')
-rw-r--r-- | clang/unittests/Tooling/TransformerTest.cpp | 53 |
1 files changed, 53 insertions, 0 deletions
diff --git a/clang/unittests/Tooling/TransformerTest.cpp b/clang/unittests/Tooling/TransformerTest.cpp index c8c6db0..d19f747 100644 --- a/clang/unittests/Tooling/TransformerTest.cpp +++ b/clang/unittests/Tooling/TransformerTest.cpp @@ -571,6 +571,59 @@ TEST_F(TransformerTest, OrderedRuleMultipleKinds) { testRule(Rule, Input, Expected); } +// Verifies that a rule with a top-level matcher for an implicit node (like +// `implicitCastExpr`) does not change the code, when the AST traversal skips +// implicit nodes. In this test, only the rule with the explicit-node matcher +// will fire. +TEST_F(TransformerTest, OrderedRuleImplicitIgnored) { + std::string Input = R"cc( + void f1(); + int f2(); + void call_f1() { f1(); } + float call_f2() { return f2(); } + )cc"; + std::string Expected = R"cc( + void f1(); + int f2(); + void call_f1() { REPLACE_F1; } + float call_f2() { return f2(); } + )cc"; + + RewriteRule ReplaceF1 = + makeRule(callExpr(callee(functionDecl(hasName("f1")))), + changeTo(cat("REPLACE_F1"))); + RewriteRule ReplaceF2 = + makeRule(implicitCastExpr(hasSourceExpression(callExpr())), + changeTo(cat("REPLACE_F2"))); + testRule(applyFirst({ReplaceF1, ReplaceF2}), Input, Expected); +} + +// Verifies that explicitly setting the traversal kind fixes the problem in the +// previous test. +TEST_F(TransformerTest, OrderedRuleImplicitMatched) { + std::string Input = R"cc( + void f1(); + int f2(); + void call_f1() { f1(); } + float call_f2() { return f2(); } + )cc"; + std::string Expected = R"cc( + void f1(); + int f2(); + void call_f1() { REPLACE_F1; } + float call_f2() { return REPLACE_F2; } + )cc"; + + RewriteRule ReplaceF1 = makeRule( + traverse(clang::TK_AsIs, callExpr(callee(functionDecl(hasName("f1"))))), + changeTo(cat("REPLACE_F1"))); + RewriteRule ReplaceF2 = + makeRule(traverse(clang::TK_AsIs, + implicitCastExpr(hasSourceExpression(callExpr()))), + changeTo(cat("REPLACE_F2"))); + testRule(applyFirst({ReplaceF1, ReplaceF2}), Input, Expected); +} + // // Negative tests (where we expect no transformation to occur). // |