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