summaryrefslogtreecommitdiff
path: root/unittests/Tooling/RefactoringCallbacksTest.cpp
diff options
context:
space:
mode:
authorEric Liu <ioeric@google.com>2017-05-10 07:48:45 +0000
committerEric Liu <ioeric@google.com>2017-05-10 07:48:45 +0000
commita2e82a51ce36b75787aad498c2c6cd24ca42982f (patch)
treeea7f9763ab358711971001e337920fe17482699a /unittests/Tooling/RefactoringCallbacksTest.cpp
parent327d010bc81cbf3656ac46faa24109c7c0f1f624 (diff)
downloadclang-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.cpp91
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