1 | //===-- ApplyReplacements.h - Deduplicate and apply replacements -- C++ -*-===// |
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 | /// \file |
10 | /// This file provides the interface for deduplicating, detecting |
11 | /// conflicts in, and applying collections of Replacements. |
12 | /// |
13 | //===----------------------------------------------------------------------===// |
14 | |
15 | #ifndef LLVM_CLANG_APPLYREPLACEMENTS_H |
16 | #define LLVM_CLANG_APPLYREPLACEMENTS_H |
17 | |
18 | #include "clang/Tooling/Core/Diagnostic.h" |
19 | #include "clang/Tooling/Refactoring.h" |
20 | #include "clang/Tooling/Refactoring/AtomicChange.h" |
21 | #include "llvm/ADT/StringMap.h" |
22 | #include "llvm/ADT/StringRef.h" |
23 | #include <string> |
24 | #include <system_error> |
25 | #include <vector> |
26 | |
27 | namespace clang { |
28 | |
29 | class DiagnosticsEngine; |
30 | |
31 | namespace replace { |
32 | |
33 | /// Collection of TranslationUnitReplacements. |
34 | typedef std::vector<clang::tooling::TranslationUnitReplacements> TUReplacements; |
35 | |
36 | /// Collection of TranslationUnitReplacement files. |
37 | typedef std::vector<std::string> TUReplacementFiles; |
38 | |
39 | /// Collection of TranslationUniDiagnostics. |
40 | typedef std::vector<clang::tooling::TranslationUnitDiagnostics> TUDiagnostics; |
41 | |
42 | /// Map mapping file name to a set of AtomicChange targeting that file. |
43 | using FileToChangesMap = |
44 | llvm::DenseMap<clang::FileEntryRef, std::vector<tooling::AtomicChange>>; |
45 | |
46 | /// Recursively descends through a directory structure rooted at \p |
47 | /// Directory and attempts to deserialize *.yaml files as |
48 | /// TranslationUnitReplacements. All docs that successfully deserialize are |
49 | /// added to \p TUs. |
50 | /// |
51 | /// Directories starting with '.' are ignored during traversal. |
52 | /// |
53 | /// \param[in] Directory Directory to begin search for serialized |
54 | /// TranslationUnitReplacements or TranslationUnitDiagnostics. |
55 | /// \param[out] TUs Collection of all found and deserialized |
56 | /// TranslationUnitReplacements or TranslationUnitDiagnostics. |
57 | /// \param[out] TUFiles Collection of all TranslationUnitReplacement or |
58 | /// TranslationUnitDiagnostics files found in \c Directory. |
59 | /// \param[in] Diagnostics DiagnosticsEngine used for error output. |
60 | /// |
61 | /// \returns An error_code indicating success or failure in navigating the |
62 | /// directory structure. |
63 | template <typename TranslationUnits> |
64 | std::error_code collectReplacementsFromDirectory( |
65 | const llvm::StringRef Directory, TranslationUnits &TUs, |
66 | TUReplacementFiles &TUFiles, |
67 | clang::DiagnosticsEngine &Diagnostics) = delete; |
68 | |
69 | template <> |
70 | std::error_code collectReplacementsFromDirectory( |
71 | const llvm::StringRef Directory, TUReplacements &TUs, |
72 | TUReplacementFiles &TUFiles, clang::DiagnosticsEngine &Diagnostics); |
73 | |
74 | template <> |
75 | std::error_code collectReplacementsFromDirectory( |
76 | const llvm::StringRef Directory, TUDiagnostics &TUs, |
77 | TUReplacementFiles &TUFiles, clang::DiagnosticsEngine &Diagnostics); |
78 | |
79 | /// Deduplicate, check for conflicts, and extract all Replacements stored |
80 | /// in \c TUs. Conflicting replacements are skipped. |
81 | /// |
82 | /// \post For all (key,value) in FileChanges, value[i].getOffset() <= |
83 | /// value[i+1].getOffset(). |
84 | /// |
85 | /// \param[in] TUs Collection of TranslationUnitReplacements or |
86 | /// TranslationUnitDiagnostics to merge, deduplicate, and test for conflicts. |
87 | /// \param[out] FileChanges Container grouping all changes by the |
88 | /// file they target. Only non conflicting replacements are kept into |
89 | /// FileChanges. |
90 | /// \param[in] SM SourceManager required for conflict reporting. |
91 | /// |
92 | /// \returns \parblock |
93 | /// \li true If all changes were converted successfully. |
94 | /// \li false If there were conflicts. |
95 | bool mergeAndDeduplicate(const TUReplacements &TUs, const TUDiagnostics &TUDs, |
96 | FileToChangesMap &FileChanges, |
97 | clang::SourceManager &SM, |
98 | bool IgnoreInsertConflict = false); |
99 | |
100 | /// Apply \c AtomicChange on File and rewrite it. |
101 | /// |
102 | /// \param[in] File Path of the file where to apply AtomicChange. |
103 | /// \param[in] Changes to apply. |
104 | /// \param[in] Spec For code cleanup and formatting. |
105 | /// \param[in] Diagnostics DiagnosticsEngine used for error output. |
106 | /// |
107 | /// \returns The changed code if all changes are applied successfully; |
108 | /// otherwise, an llvm::Error carrying llvm::StringError or an error_code. |
109 | llvm::Expected<std::string> |
110 | applyChanges(StringRef File, const std::vector<tooling::AtomicChange> &Changes, |
111 | const tooling::ApplyChangesSpec &Spec, |
112 | DiagnosticsEngine &Diagnostics); |
113 | |
114 | /// Delete the replacement files. |
115 | /// |
116 | /// \param[in] Files Replacement files to delete. |
117 | /// \param[in] Diagnostics DiagnosticsEngine used for error output. |
118 | /// |
119 | /// \returns \parblock |
120 | /// \li true If all files have been deleted successfully. |
121 | /// \li false If at least one or more failures occur when deleting |
122 | /// files. |
123 | bool deleteReplacementFiles(const TUReplacementFiles &Files, |
124 | clang::DiagnosticsEngine &Diagnostics); |
125 | |
126 | } // end namespace replace |
127 | } // end namespace clang |
128 | |
129 | #endif // LLVM_CLANG_APPLYREPLACEMENTS_H |
130 | |