1*67e74705SXin Li //===- unittest/Tooling/RefactoringCallbacksTest.cpp ----------------------===//
2*67e74705SXin Li //
3*67e74705SXin Li // The LLVM Compiler Infrastructure
4*67e74705SXin Li //
5*67e74705SXin Li // This file is distributed under the University of Illinois Open Source
6*67e74705SXin Li // License. See LICENSE.TXT for details.
7*67e74705SXin Li //
8*67e74705SXin Li //===----------------------------------------------------------------------===//
9*67e74705SXin Li
10*67e74705SXin Li #include "clang/Tooling/RefactoringCallbacks.h"
11*67e74705SXin Li #include "RewriterTestContext.h"
12*67e74705SXin Li #include "clang/ASTMatchers/ASTMatchFinder.h"
13*67e74705SXin Li #include "clang/ASTMatchers/ASTMatchers.h"
14*67e74705SXin Li #include "gtest/gtest.h"
15*67e74705SXin Li
16*67e74705SXin Li namespace clang {
17*67e74705SXin Li namespace tooling {
18*67e74705SXin Li
19*67e74705SXin Li using namespace ast_matchers;
20*67e74705SXin Li
21*67e74705SXin Li template <typename T>
expectRewritten(const std::string & Code,const std::string & Expected,const T & AMatcher,RefactoringCallback & Callback)22*67e74705SXin Li void expectRewritten(const std::string &Code,
23*67e74705SXin Li const std::string &Expected,
24*67e74705SXin Li const T &AMatcher,
25*67e74705SXin Li RefactoringCallback &Callback) {
26*67e74705SXin Li MatchFinder Finder;
27*67e74705SXin Li Finder.addMatcher(AMatcher, &Callback);
28*67e74705SXin Li std::unique_ptr<tooling::FrontendActionFactory> Factory(
29*67e74705SXin Li tooling::newFrontendActionFactory(&Finder));
30*67e74705SXin Li ASSERT_TRUE(tooling::runToolOnCode(Factory->create(), Code))
31*67e74705SXin Li << "Parsing error in \"" << Code << "\"";
32*67e74705SXin Li RewriterTestContext Context;
33*67e74705SXin Li FileID ID = Context.createInMemoryFile("input.cc", Code);
34*67e74705SXin Li EXPECT_TRUE(tooling::applyAllReplacements(Callback.getReplacements(),
35*67e74705SXin Li Context.Rewrite));
36*67e74705SXin Li EXPECT_EQ(Expected, Context.getRewrittenText(ID));
37*67e74705SXin Li }
38*67e74705SXin Li
TEST(RefactoringCallbacksTest,ReplacesStmtsWithString)39*67e74705SXin Li TEST(RefactoringCallbacksTest, ReplacesStmtsWithString) {
40*67e74705SXin Li std::string Code = "void f() { int i = 1; }";
41*67e74705SXin Li std::string Expected = "void f() { ; }";
42*67e74705SXin Li ReplaceStmtWithText Callback("id", ";");
43*67e74705SXin Li expectRewritten(Code, Expected, id("id", declStmt()), Callback);
44*67e74705SXin Li }
45*67e74705SXin Li
TEST(RefactoringCallbacksTest,ReplacesStmtsInCalledMacros)46*67e74705SXin Li TEST(RefactoringCallbacksTest, ReplacesStmtsInCalledMacros) {
47*67e74705SXin Li std::string Code = "#define A void f() { int i = 1; }\nA";
48*67e74705SXin Li std::string Expected = "#define A void f() { ; }\nA";
49*67e74705SXin Li ReplaceStmtWithText Callback("id", ";");
50*67e74705SXin Li expectRewritten(Code, Expected, id("id", declStmt()), Callback);
51*67e74705SXin Li }
52*67e74705SXin Li
TEST(RefactoringCallbacksTest,IgnoresStmtsInUncalledMacros)53*67e74705SXin Li TEST(RefactoringCallbacksTest, IgnoresStmtsInUncalledMacros) {
54*67e74705SXin Li std::string Code = "#define A void f() { int i = 1; }";
55*67e74705SXin Li std::string Expected = "#define A void f() { int i = 1; }";
56*67e74705SXin Li ReplaceStmtWithText Callback("id", ";");
57*67e74705SXin Li expectRewritten(Code, Expected, id("id", declStmt()), Callback);
58*67e74705SXin Li }
59*67e74705SXin Li
TEST(RefactoringCallbacksTest,ReplacesInteger)60*67e74705SXin Li TEST(RefactoringCallbacksTest, ReplacesInteger) {
61*67e74705SXin Li std::string Code = "void f() { int i = 1; }";
62*67e74705SXin Li std::string Expected = "void f() { int i = 2; }";
63*67e74705SXin Li ReplaceStmtWithText Callback("id", "2");
64*67e74705SXin Li expectRewritten(Code, Expected, id("id", expr(integerLiteral())),
65*67e74705SXin Li Callback);
66*67e74705SXin Li }
67*67e74705SXin Li
TEST(RefactoringCallbacksTest,ReplacesStmtWithStmt)68*67e74705SXin Li TEST(RefactoringCallbacksTest, ReplacesStmtWithStmt) {
69*67e74705SXin Li std::string Code = "void f() { int i = false ? 1 : i * 2; }";
70*67e74705SXin Li std::string Expected = "void f() { int i = i * 2; }";
71*67e74705SXin Li ReplaceStmtWithStmt Callback("always-false", "should-be");
72*67e74705SXin Li expectRewritten(Code, Expected,
73*67e74705SXin Li id("always-false", conditionalOperator(
74*67e74705SXin Li hasCondition(cxxBoolLiteral(equals(false))),
75*67e74705SXin Li hasFalseExpression(id("should-be", expr())))),
76*67e74705SXin Li Callback);
77*67e74705SXin Li }
78*67e74705SXin Li
TEST(RefactoringCallbacksTest,ReplacesIfStmt)79*67e74705SXin Li TEST(RefactoringCallbacksTest, ReplacesIfStmt) {
80*67e74705SXin Li std::string Code = "bool a; void f() { if (a) f(); else a = true; }";
81*67e74705SXin Li std::string Expected = "bool a; void f() { f(); }";
82*67e74705SXin Li ReplaceIfStmtWithItsBody Callback("id", true);
83*67e74705SXin Li expectRewritten(Code, Expected,
84*67e74705SXin Li id("id", ifStmt(
85*67e74705SXin Li hasCondition(implicitCastExpr(hasSourceExpression(
86*67e74705SXin Li declRefExpr(to(varDecl(hasName("a"))))))))),
87*67e74705SXin Li Callback);
88*67e74705SXin Li }
89*67e74705SXin Li
TEST(RefactoringCallbacksTest,RemovesEntireIfOnEmptyElse)90*67e74705SXin Li TEST(RefactoringCallbacksTest, RemovesEntireIfOnEmptyElse) {
91*67e74705SXin Li std::string Code = "void f() { if (false) int i = 0; }";
92*67e74705SXin Li std::string Expected = "void f() { }";
93*67e74705SXin Li ReplaceIfStmtWithItsBody Callback("id", false);
94*67e74705SXin Li expectRewritten(Code, Expected,
95*67e74705SXin Li id("id", ifStmt(hasCondition(cxxBoolLiteral(equals(false))))),
96*67e74705SXin Li Callback);
97*67e74705SXin Li }
98*67e74705SXin Li
99*67e74705SXin Li } // end namespace ast_matchers
100*67e74705SXin Li } // end namespace clang
101