Clang Project

clang_source_code/unittests/Rename/ClangRenameTest.h
1//===-- ClangRenameTests.cpp - clang-rename unit tests --------------------===//
2//
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
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef LLVM_CLANG_UNITTESTS_RENAME_CLANGRENAMETEST_H
10#define LLVM_CLANG_UNITTESTS_RENAME_CLANGRENAMETEST_H
11
12#include "unittests/Tooling/RewriterTestContext.h"
13#include "clang/ASTMatchers/ASTMatchFinder.h"
14#include "clang/Basic/FileManager.h"
15#include "clang/Basic/FileSystemOptions.h"
16#include "clang/Format/Format.h"
17#include "clang/Frontend/CompilerInstance.h"
18#include "clang/Frontend/PCHContainerOperations.h"
19#include "clang/Tooling/Refactoring.h"
20#include "clang/Tooling/Refactoring/Rename/RenamingAction.h"
21#include "clang/Tooling/Refactoring/Rename/USRFindingAction.h"
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"
27#include "llvm/Support/VirtualFileSystem.h"
28#include "gtest/gtest.h"
29#include <memory>
30#include <string>
31#include <vector>
32
33namespace clang {
34namespace clang_rename {
35namespace test {
36
37struct Case {
38  std::string Before;
39  std::string After;
40  std::string OldName;
41  std::string NewName;
42};
43
44class ClangRenameTest : public testing::Test,
45                        public testing::WithParamInterface<Case> {
46protected:
47  void AppendToHeader(StringRef Code) { HeaderContent += Code.str(); }
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 = {{HeaderNameHeaderContent},
56                                                 {CCNameNewCode}};
57    clang::RewriterTestContext Context;
58    Context.createInMemoryFile(HeaderNameHeaderContent);
59    clang::FileID InputFileID = Context.createInMemoryFile(CCNameNewCode);
60
61    tooling::USRFindingAction FindingAction({}, {OldName}, false);
62    std::unique_ptr<tooling::FrontendActionFactoryUSRFindingActionFactory =
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();
73    std::vector<std::stringNewNames = {NewName};
74    std::map<std::stringtooling::ReplacementsFileToReplacements;
75    tooling::QualifiedRenamingAction RenameAction(NewNamesUSRList,
76                                                  FileToReplacements);
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(FileToReplacementsContext.Rewrite"llvm");
85    return Context.getRewrittenText(InputFileID);
86  }
87
88  void CompareSnippets(StringRef ExpectedStringRef 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
112// namespace test
113// namespace clang_rename
114// namesdpace clang
115
116#endif
117
clang::clang_rename::test::Case::Before
clang::clang_rename::test::Case::After
clang::clang_rename::test::Case::OldName
clang::clang_rename::test::Case::NewName
clang::clang_rename::test::ClangRenameTest::AppendToHeader
clang::clang_rename::test::ClangRenameTest::runClangRenameOnCode
clang::clang_rename::test::ClangRenameTest::CompareSnippets
clang::clang_rename::test::ClangRenameTest::format
clang::clang_rename::test::ClangRenameTest::HeaderContent
clang::clang_rename::test::ClangRenameTest::HeaderName
clang::clang_rename::test::ClangRenameTest::CCName