diff options
author | Eric Liu <ioeric@google.com> | 2017-05-10 07:48:45 +0000 |
---|---|---|
committer | Eric Liu <ioeric@google.com> | 2017-05-10 07:48:45 +0000 |
commit | a2e82a51ce36b75787aad498c2c6cd24ca42982f (patch) | |
tree | ea7f9763ab358711971001e337920fe17482699a /unittests/Tooling/RefactoringCallbacksTest.cpp | |
parent | 327d010bc81cbf3656ac46faa24109c7c0f1f624 (diff) | |
download | clang-a2e82a51ce36b75787aad498c2c6cd24ca42982f.tar.gz |
Add ASTMatchRefactorer and ReplaceNodeWithTemplate to RefactoringCallbacks
Summary: This is the first change as part of developing a clang-query based search and replace tool.
Reviewers: klimek, bkramer, ioeric, sbenza, jbangert
Reviewed By: ioeric, jbangert
Subscribers: sbenza, ioeric, cfe-commits
Patch by Julian Bangert!
Differential Revision: https://reviews.llvm.org/D29621
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@302624 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'unittests/Tooling/RefactoringCallbacksTest.cpp')
-rw-r--r-- | unittests/Tooling/RefactoringCallbacksTest.cpp | 91 |
1 files changed, 72 insertions, 19 deletions
diff --git a/unittests/Tooling/RefactoringCallbacksTest.cpp b/unittests/Tooling/RefactoringCallbacksTest.cpp index ad8aa8f98f..e226522a70 100644 --- a/unittests/Tooling/RefactoringCallbacksTest.cpp +++ b/unittests/Tooling/RefactoringCallbacksTest.cpp @@ -7,10 +7,10 @@ // //===----------------------------------------------------------------------===// -#include "clang/Tooling/RefactoringCallbacks.h" #include "RewriterTestContext.h" #include "clang/ASTMatchers/ASTMatchFinder.h" #include "clang/ASTMatchers/ASTMatchers.h" +#include "clang/Tooling/RefactoringCallbacks.h" #include "gtest/gtest.h" namespace clang { @@ -19,11 +19,10 @@ namespace tooling { using namespace ast_matchers; template <typename T> -void expectRewritten(const std::string &Code, - const std::string &Expected, - const T &AMatcher, - RefactoringCallback &Callback) { - MatchFinder Finder; +void expectRewritten(const std::string &Code, const std::string &Expected, + const T &AMatcher, RefactoringCallback &Callback) { + std::map<std::string, Replacements> FileToReplace; + ASTMatchRefactorer Finder(FileToReplace); Finder.addMatcher(AMatcher, &Callback); std::unique_ptr<tooling::FrontendActionFactory> Factory( tooling::newFrontendActionFactory(&Finder)); @@ -31,7 +30,7 @@ void expectRewritten(const std::string &Code, << "Parsing error in \"" << Code << "\""; RewriterTestContext Context; FileID ID = Context.createInMemoryFile("input.cc", Code); - EXPECT_TRUE(tooling::applyAllReplacements(Callback.getReplacements(), + EXPECT_TRUE(tooling::applyAllReplacements(FileToReplace["input.cc"], Context.Rewrite)); EXPECT_EQ(Expected, Context.getRewrittenText(ID)); } @@ -61,18 +60,18 @@ TEST(RefactoringCallbacksTest, ReplacesInteger) { std::string Code = "void f() { int i = 1; }"; std::string Expected = "void f() { int i = 2; }"; ReplaceStmtWithText Callback("id", "2"); - expectRewritten(Code, Expected, id("id", expr(integerLiteral())), - Callback); + expectRewritten(Code, Expected, id("id", expr(integerLiteral())), Callback); } TEST(RefactoringCallbacksTest, ReplacesStmtWithStmt) { std::string Code = "void f() { int i = false ? 1 : i * 2; }"; std::string Expected = "void f() { int i = i * 2; }"; ReplaceStmtWithStmt Callback("always-false", "should-be"); - expectRewritten(Code, Expected, - id("always-false", conditionalOperator( - hasCondition(cxxBoolLiteral(equals(false))), - hasFalseExpression(id("should-be", expr())))), + expectRewritten( + Code, Expected, + id("always-false", + conditionalOperator(hasCondition(cxxBoolLiteral(equals(false))), + hasFalseExpression(id("should-be", expr())))), Callback); } @@ -80,10 +79,10 @@ TEST(RefactoringCallbacksTest, ReplacesIfStmt) { std::string Code = "bool a; void f() { if (a) f(); else a = true; }"; std::string Expected = "bool a; void f() { f(); }"; ReplaceIfStmtWithItsBody Callback("id", true); - expectRewritten(Code, Expected, - id("id", ifStmt( - hasCondition(implicitCastExpr(hasSourceExpression( - declRefExpr(to(varDecl(hasName("a"))))))))), + expectRewritten( + Code, Expected, + id("id", ifStmt(hasCondition(implicitCastExpr(hasSourceExpression( + declRefExpr(to(varDecl(hasName("a"))))))))), Callback); } @@ -92,9 +91,63 @@ TEST(RefactoringCallbacksTest, RemovesEntireIfOnEmptyElse) { std::string Expected = "void f() { }"; ReplaceIfStmtWithItsBody Callback("id", false); expectRewritten(Code, Expected, - id("id", ifStmt(hasCondition(cxxBoolLiteral(equals(false))))), - Callback); + id("id", ifStmt(hasCondition(cxxBoolLiteral(equals(false))))), + Callback); } +TEST(RefactoringCallbacksTest, TemplateJustText) { + std::string Code = "void f() { int i = 1; }"; + std::string Expected = "void f() { FOO }"; + auto Callback = ReplaceNodeWithTemplate::create("id", "FOO"); + EXPECT_FALSE(Callback.takeError()); + expectRewritten(Code, Expected, id("id", declStmt()), **Callback); +} + +TEST(RefactoringCallbacksTest, TemplateSimpleSubst) { + std::string Code = "void f() { int i = 1; }"; + std::string Expected = "void f() { long x = 1; }"; + auto Callback = ReplaceNodeWithTemplate::create("decl", "long x = ${init}"); + EXPECT_FALSE(Callback.takeError()); + expectRewritten(Code, Expected, + id("decl", varDecl(hasInitializer(id("init", expr())))), + **Callback); +} + +TEST(RefactoringCallbacksTest, TemplateLiteral) { + std::string Code = "void f() { int i = 1; }"; + std::string Expected = "void f() { string x = \"$-1\"; }"; + auto Callback = ReplaceNodeWithTemplate::create("decl", + "string x = \"$$-${init}\""); + EXPECT_FALSE(Callback.takeError()); + expectRewritten(Code, Expected, + id("decl", varDecl(hasInitializer(id("init", expr())))), + **Callback); +} + +static void ExpectStringError(const std::string &Expected, + llvm::Error E) { + std::string Found; + handleAllErrors(std::move(E), [&](const llvm::StringError &SE) { + llvm::raw_string_ostream Stream(Found); + SE.log(Stream); + }); + EXPECT_EQ(Expected, Found); +} + +TEST(RefactoringCallbacksTest, TemplateUnterminated) { + auto Callback = ReplaceNodeWithTemplate::create("decl", + "string x = \"$$-${init\""); + ExpectStringError("Unterminated ${...} in replacement template near ${init\"", + Callback.takeError()); +} + +TEST(RefactoringCallbacksTest, TemplateUnknownDollar) { + auto Callback = ReplaceNodeWithTemplate::create("decl", + "string x = \"$<"); + ExpectStringError("Invalid $ in replacement template near $<", + Callback.takeError()); +} + + } // end namespace ast_matchers } // end namespace clang |