diff options
author | 2020-08-03 14:31:31 +0000 | |
---|---|---|
committer | 2020-08-03 14:31:31 +0000 | |
commit | e5dd70708596ae51455a0ffa086a00c5b29f8583 (patch) | |
tree | 5d676f27b570bacf71e786c3b5cff3e6f6679b59 /gnu/llvm/clang/unittests/Tooling/RefactoringCallbacksTest.cpp | |
parent | Import LLVM 10.0.0 release including clang, lld and lldb. (diff) | |
download | wireguard-openbsd-e5dd70708596ae51455a0ffa086a00c5b29f8583.tar.xz wireguard-openbsd-e5dd70708596ae51455a0ffa086a00c5b29f8583.zip |
Import LLVM 10.0.0 release including clang, lld and lldb.
ok hackroom
tested by plenty
Diffstat (limited to 'gnu/llvm/clang/unittests/Tooling/RefactoringCallbacksTest.cpp')
-rw-r--r-- | gnu/llvm/clang/unittests/Tooling/RefactoringCallbacksTest.cpp | 152 |
1 files changed, 152 insertions, 0 deletions
diff --git a/gnu/llvm/clang/unittests/Tooling/RefactoringCallbacksTest.cpp b/gnu/llvm/clang/unittests/Tooling/RefactoringCallbacksTest.cpp new file mode 100644 index 00000000000..4a883c38c85 --- /dev/null +++ b/gnu/llvm/clang/unittests/Tooling/RefactoringCallbacksTest.cpp @@ -0,0 +1,152 @@ +//===- unittest/Tooling/RefactoringCallbacksTest.cpp ----------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "RewriterTestContext.h" +#include "clang/ASTMatchers/ASTMatchFinder.h" +#include "clang/ASTMatchers/ASTMatchers.h" +#include "clang/Tooling/RefactoringCallbacks.h" +#include "gtest/gtest.h" + +namespace clang { +namespace tooling { + +using namespace ast_matchers; + +template <typename T> +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)); + ASSERT_TRUE(tooling::runToolOnCode(Factory->create(), Code)) + << "Parsing error in \"" << Code << "\""; + RewriterTestContext Context; + FileID ID = Context.createInMemoryFile("input.cc", Code); + EXPECT_TRUE(tooling::applyAllReplacements(FileToReplace["input.cc"], + Context.Rewrite)); + EXPECT_EQ(Expected, Context.getRewrittenText(ID)); +} + +TEST(RefactoringCallbacksTest, ReplacesStmtsWithString) { + std::string Code = "void f() { int i = 1; }"; + std::string Expected = "void f() { ; }"; + ReplaceStmtWithText Callback("id", ";"); + expectRewritten(Code, Expected, declStmt().bind("id"), Callback); +} + +TEST(RefactoringCallbacksTest, ReplacesStmtsInCalledMacros) { + std::string Code = "#define A void f() { int i = 1; }\nA"; + std::string Expected = "#define A void f() { ; }\nA"; + ReplaceStmtWithText Callback("id", ";"); + expectRewritten(Code, Expected, declStmt().bind("id"), Callback); +} + +TEST(RefactoringCallbacksTest, IgnoresStmtsInUncalledMacros) { + std::string Code = "#define A void f() { int i = 1; }"; + std::string Expected = "#define A void f() { int i = 1; }"; + ReplaceStmtWithText Callback("id", ";"); + expectRewritten(Code, Expected, declStmt().bind("id"), Callback); +} + +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, expr(integerLiteral()).bind("id"), 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, + conditionalOperator(hasCondition(cxxBoolLiteral(equals(false))), + hasFalseExpression(expr().bind("should-be"))) + .bind("always-false"), + Callback); +} + +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, + ifStmt(hasCondition(implicitCastExpr(hasSourceExpression( + declRefExpr(to(varDecl(hasName("a")))))))) + .bind("id"), + Callback); +} + +TEST(RefactoringCallbacksTest, RemovesEntireIfOnEmptyElse) { + std::string Code = "void f() { if (false) int i = 0; }"; + std::string Expected = "void f() { }"; + ReplaceIfStmtWithItsBody Callback("id", false); + expectRewritten( + Code, Expected, + ifStmt(hasCondition(cxxBoolLiteral(equals(false)))).bind("id"), 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, declStmt().bind("id"), **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, + varDecl(hasInitializer(expr().bind("init"))).bind("decl"), + **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, + varDecl(hasInitializer(expr().bind("init"))).bind("decl"), + **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 |