Haojian Wu | b7da0eb | 2017-03-10 10:30:14 +0000 | [diff] [blame] | 1 | //===-- ClangRenameTests.cpp - clang-rename unit tests --------------------===// |
| 2 | // |
Chandler Carruth | 2946cd7 | 2019-01-19 08:50:56 +0000 | [diff] [blame] | 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
| 4 | // See https://llvm.org/LICENSE.txt for license information. |
| 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
Haojian Wu | b7da0eb | 2017-03-10 10:30:14 +0000 | [diff] [blame] | 6 | // |
| 7 | //===----------------------------------------------------------------------===// |
| 8 | |
Argyrios Kyrtzidis | adc178e | 2018-09-03 16:26:36 +0000 | [diff] [blame] | 9 | #ifndef LLVM_CLANG_UNITTESTS_RENAME_CLANGRENAMETEST_H |
| 10 | #define LLVM_CLANG_UNITTESTS_RENAME_CLANGRENAMETEST_H |
| 11 | |
Haojian Wu | b7da0eb | 2017-03-10 10:30:14 +0000 | [diff] [blame] | 12 | #include "unittests/Tooling/RewriterTestContext.h" |
| 13 | #include "clang/ASTMatchers/ASTMatchFinder.h" |
| 14 | #include "clang/Basic/FileManager.h" |
| 15 | #include "clang/Basic/FileSystemOptions.h" |
Haojian Wu | b7da0eb | 2017-03-10 10:30:14 +0000 | [diff] [blame] | 16 | #include "clang/Format/Format.h" |
| 17 | #include "clang/Frontend/CompilerInstance.h" |
| 18 | #include "clang/Frontend/PCHContainerOperations.h" |
| 19 | #include "clang/Tooling/Refactoring.h" |
Alex Lorenz | 4abbd92 | 2017-06-30 16:36:09 +0000 | [diff] [blame] | 20 | #include "clang/Tooling/Refactoring/Rename/RenamingAction.h" |
| 21 | #include "clang/Tooling/Refactoring/Rename/USRFindingAction.h" |
Haojian Wu | b7da0eb | 2017-03-10 10:30:14 +0000 | [diff] [blame] | 22 | #include "clang/Tooling/Tooling.h" |
| 23 | #include "llvm/ADT/IntrusiveRefCntPtr.h" |
| 24 | #include "llvm/ADT/StringRef.h" |
| 25 | #include "llvm/Support/Format.h" |
| 26 | #include "llvm/Support/MemoryBuffer.h" |
Jonas Devlieghere | fc51490 | 2018-10-10 13:27:25 +0000 | [diff] [blame] | 27 | #include "llvm/Support/VirtualFileSystem.h" |
Haojian Wu | b7da0eb | 2017-03-10 10:30:14 +0000 | [diff] [blame] | 28 | #include "gtest/gtest.h" |
| 29 | #include <memory> |
| 30 | #include <string> |
| 31 | #include <vector> |
| 32 | |
| 33 | namespace clang { |
| 34 | namespace clang_rename { |
Haojian Wu | 74f823a | 2017-04-04 09:30:06 +0000 | [diff] [blame] | 35 | namespace test { |
Haojian Wu | b7da0eb | 2017-03-10 10:30:14 +0000 | [diff] [blame] | 36 | |
| 37 | struct Case { |
| 38 | std::string Before; |
| 39 | std::string After; |
Haojian Wu | 74f823a | 2017-04-04 09:30:06 +0000 | [diff] [blame] | 40 | std::string OldName; |
| 41 | std::string NewName; |
Haojian Wu | b7da0eb | 2017-03-10 10:30:14 +0000 | [diff] [blame] | 42 | }; |
| 43 | |
| 44 | class ClangRenameTest : public testing::Test, |
| 45 | public testing::WithParamInterface<Case> { |
| 46 | protected: |
Haojian Wu | 74f823a | 2017-04-04 09:30:06 +0000 | [diff] [blame] | 47 | void AppendToHeader(StringRef Code) { HeaderContent += Code.str(); } |
Haojian Wu | b7da0eb | 2017-03-10 10:30:14 +0000 | [diff] [blame] | 48 | |
| 49 | std::string runClangRenameOnCode(llvm::StringRef Code, |
| 50 | llvm::StringRef OldName, |
| 51 | llvm::StringRef NewName) { |
| 52 | std::string NewCode; |
| 53 | llvm::raw_string_ostream(NewCode) << llvm::format( |
| 54 | "#include \"%s\"\n%s", HeaderName.c_str(), Code.str().c_str()); |
| 55 | tooling::FileContentMappings FileContents = {{HeaderName, HeaderContent}, |
| 56 | {CCName, NewCode}}; |
| 57 | clang::RewriterTestContext Context; |
| 58 | Context.createInMemoryFile(HeaderName, HeaderContent); |
| 59 | clang::FileID InputFileID = Context.createInMemoryFile(CCName, NewCode); |
| 60 | |
Alex Lorenz | 4abbd92 | 2017-06-30 16:36:09 +0000 | [diff] [blame] | 61 | tooling::USRFindingAction FindingAction({}, {OldName}, false); |
Haojian Wu | b7da0eb | 2017-03-10 10:30:14 +0000 | [diff] [blame] | 62 | std::unique_ptr<tooling::FrontendActionFactory> USRFindingActionFactory = |
| 63 | tooling::newFrontendActionFactory(&FindingAction); |
| 64 | |
| 65 | if (!tooling::runToolOnCodeWithArgs( |
| 66 | USRFindingActionFactory->create(), NewCode, {"-std=c++11"}, CCName, |
| 67 | "clang-rename", std::make_shared<PCHContainerOperations>(), |
| 68 | FileContents)) |
| 69 | return ""; |
| 70 | |
| 71 | const std::vector<std::vector<std::string>> &USRList = |
| 72 | FindingAction.getUSRList(); |
Haojian Wu | b7da0eb | 2017-03-10 10:30:14 +0000 | [diff] [blame] | 73 | std::vector<std::string> NewNames = {NewName}; |
| 74 | std::map<std::string, tooling::Replacements> FileToReplacements; |
Alex Lorenz | 4abbd92 | 2017-06-30 16:36:09 +0000 | [diff] [blame] | 75 | tooling::QualifiedRenamingAction RenameAction(NewNames, USRList, |
| 76 | FileToReplacements); |
Haojian Wu | b7da0eb | 2017-03-10 10:30:14 +0000 | [diff] [blame] | 77 | auto RenameActionFactory = tooling::newFrontendActionFactory(&RenameAction); |
| 78 | if (!tooling::runToolOnCodeWithArgs( |
| 79 | RenameActionFactory->create(), NewCode, {"-std=c++11"}, CCName, |
| 80 | "clang-rename", std::make_shared<PCHContainerOperations>(), |
| 81 | FileContents)) |
| 82 | return ""; |
| 83 | |
| 84 | formatAndApplyAllReplacements(FileToReplacements, Context.Rewrite, "llvm"); |
| 85 | return Context.getRewrittenText(InputFileID); |
| 86 | } |
| 87 | |
| 88 | void CompareSnippets(StringRef Expected, StringRef Actual) { |
| 89 | std::string ExpectedCode; |
| 90 | llvm::raw_string_ostream(ExpectedCode) << llvm::format( |
| 91 | "#include \"%s\"\n%s", HeaderName.c_str(), Expected.str().c_str()); |
| 92 | EXPECT_EQ(format(ExpectedCode), format(Actual)); |
| 93 | } |
| 94 | |
| 95 | std::string format(llvm::StringRef Code) { |
| 96 | tooling::Replacements Replaces = format::reformat( |
| 97 | format::getLLVMStyle(), Code, {tooling::Range(0, Code.size())}); |
| 98 | auto ChangedCode = tooling::applyAllReplacements(Code, Replaces); |
| 99 | EXPECT_TRUE(static_cast<bool>(ChangedCode)); |
| 100 | if (!ChangedCode) { |
| 101 | llvm::errs() << llvm::toString(ChangedCode.takeError()); |
| 102 | return ""; |
| 103 | } |
| 104 | return *ChangedCode; |
| 105 | } |
| 106 | |
| 107 | std::string HeaderContent; |
| 108 | std::string HeaderName = "header.h"; |
| 109 | std::string CCName = "input.cc"; |
| 110 | }; |
| 111 | |
Haojian Wu | 74f823a | 2017-04-04 09:30:06 +0000 | [diff] [blame] | 112 | } // namespace test |
Haojian Wu | b7da0eb | 2017-03-10 10:30:14 +0000 | [diff] [blame] | 113 | } // namespace clang_rename |
| 114 | } // namesdpace clang |
Argyrios Kyrtzidis | adc178e | 2018-09-03 16:26:36 +0000 | [diff] [blame] | 115 | |
| 116 | #endif |