/Users/buildslave/jenkins/workspace/coverage/llvm-project/clang/lib/Tooling/Refactoring.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | //===--- Refactoring.cpp - Framework for clang refactoring tools ----------===// |
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 | | // Implements tools to support refactorings. |
10 | | // |
11 | | //===----------------------------------------------------------------------===// |
12 | | |
13 | | #include "clang/Tooling/Refactoring.h" |
14 | | #include "clang/Basic/DiagnosticOptions.h" |
15 | | #include "clang/Basic/FileManager.h" |
16 | | #include "clang/Basic/SourceManager.h" |
17 | | #include "clang/Format/Format.h" |
18 | | #include "clang/Frontend/TextDiagnosticPrinter.h" |
19 | | #include "clang/Lex/Lexer.h" |
20 | | #include "clang/Rewrite/Core/Rewriter.h" |
21 | | #include "llvm/Support/Path.h" |
22 | | #include "llvm/Support/raw_os_ostream.h" |
23 | | |
24 | | namespace clang { |
25 | | namespace tooling { |
26 | | |
27 | | RefactoringTool::RefactoringTool( |
28 | | const CompilationDatabase &Compilations, ArrayRef<std::string> SourcePaths, |
29 | | std::shared_ptr<PCHContainerOperations> PCHContainerOps) |
30 | 70 | : ClangTool(Compilations, SourcePaths, std::move(PCHContainerOps)) {} |
31 | | |
32 | 69 | std::map<std::string, Replacements> &RefactoringTool::getReplacements() { |
33 | 69 | return FileToReplaces; |
34 | 69 | } |
35 | | |
36 | 0 | int RefactoringTool::runAndSave(FrontendActionFactory *ActionFactory) { |
37 | 0 | if (int Result = run(ActionFactory)) { |
38 | 0 | return Result; |
39 | 0 | } |
40 | | |
41 | 0 | LangOptions DefaultLangOptions; |
42 | 0 | IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts = new DiagnosticOptions(); |
43 | 0 | TextDiagnosticPrinter DiagnosticPrinter(llvm::errs(), &*DiagOpts); |
44 | 0 | DiagnosticsEngine Diagnostics( |
45 | 0 | IntrusiveRefCntPtr<DiagnosticIDs>(new DiagnosticIDs()), |
46 | 0 | &*DiagOpts, &DiagnosticPrinter, false); |
47 | 0 | SourceManager Sources(Diagnostics, getFiles()); |
48 | 0 | Rewriter Rewrite(Sources, DefaultLangOptions); |
49 | |
|
50 | 0 | if (!applyAllReplacements(Rewrite)) { |
51 | 0 | llvm::errs() << "Skipped some replacements.\n"; |
52 | 0 | } |
53 | |
|
54 | 0 | return saveRewrittenFiles(Rewrite); |
55 | 0 | } |
56 | | |
57 | 69 | bool RefactoringTool::applyAllReplacements(Rewriter &Rewrite) { |
58 | 69 | bool Result = true; |
59 | 69 | for (const auto &Entry : groupReplacementsByFile( |
60 | 69 | Rewrite.getSourceMgr().getFileManager(), FileToReplaces)) |
61 | 68 | Result = tooling::applyAllReplacements(Entry.second, Rewrite) && Result; |
62 | 69 | return Result; |
63 | 69 | } |
64 | | |
65 | 0 | int RefactoringTool::saveRewrittenFiles(Rewriter &Rewrite) { |
66 | 0 | return Rewrite.overwriteChangedFiles() ? 1 : 0; |
67 | 0 | } |
68 | | |
69 | | bool formatAndApplyAllReplacements( |
70 | | const std::map<std::string, Replacements> &FileToReplaces, |
71 | 261 | Rewriter &Rewrite, StringRef Style) { |
72 | 261 | SourceManager &SM = Rewrite.getSourceMgr(); |
73 | 261 | FileManager &Files = SM.getFileManager(); |
74 | | |
75 | 261 | bool Result = true; |
76 | 261 | for (const auto &FileAndReplaces : groupReplacementsByFile( |
77 | 482 | Rewrite.getSourceMgr().getFileManager(), FileToReplaces)) { |
78 | 482 | const std::string &FilePath = FileAndReplaces.first; |
79 | 482 | auto &CurReplaces = FileAndReplaces.second; |
80 | | |
81 | 482 | const FileEntry *Entry = nullptr; |
82 | 482 | if (auto File = Files.getFile(FilePath)) |
83 | 482 | Entry = *File; |
84 | | |
85 | 482 | FileID ID = SM.getOrCreateFileID(Entry, SrcMgr::C_User); |
86 | 482 | StringRef Code = SM.getBufferData(ID); |
87 | | |
88 | 482 | auto CurStyle = format::getStyle(Style, FilePath, "LLVM"); |
89 | 482 | if (!CurStyle) { |
90 | 0 | llvm::errs() << llvm::toString(CurStyle.takeError()) << "\n"; |
91 | 0 | return false; |
92 | 0 | } |
93 | | |
94 | 482 | auto NewReplacements = |
95 | 482 | format::formatReplacements(Code, CurReplaces, *CurStyle); |
96 | 482 | if (!NewReplacements) { |
97 | 0 | llvm::errs() << llvm::toString(NewReplacements.takeError()) << "\n"; |
98 | 0 | return false; |
99 | 0 | } |
100 | 482 | Result = applyAllReplacements(*NewReplacements, Rewrite) && Result; |
101 | 482 | } |
102 | 261 | return Result; |
103 | 261 | } |
104 | | |
105 | | } // end namespace tooling |
106 | | } // end namespace clang |