/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/tools/clang/include/clang/Rewrite/Core/Rewriter.h
Line | Count | Source (jump to first uncovered line) |
1 | | //===- Rewriter.h - Code rewriting interface --------------------*- 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 | | // This file defines the Rewriter class, which is used for code |
10 | | // transformations. |
11 | | // |
12 | | //===----------------------------------------------------------------------===// |
13 | | |
14 | | #ifndef LLVM_CLANG_REWRITE_CORE_REWRITER_H |
15 | | #define LLVM_CLANG_REWRITE_CORE_REWRITER_H |
16 | | |
17 | | #include "clang/Basic/LLVM.h" |
18 | | #include "clang/Basic/SourceLocation.h" |
19 | | #include "clang/Rewrite/Core/RewriteBuffer.h" |
20 | | #include "llvm/ADT/StringRef.h" |
21 | | #include <map> |
22 | | #include <string> |
23 | | |
24 | | namespace clang { |
25 | | |
26 | | class LangOptions; |
27 | | class SourceManager; |
28 | | |
29 | | /// Rewriter - This is the main interface to the rewrite buffers. Its primary |
30 | | /// job is to dispatch high-level requests to the low-level RewriteBuffers that |
31 | | /// are involved. |
32 | | class Rewriter { |
33 | | SourceManager *SourceMgr = nullptr; |
34 | | const LangOptions *LangOpts = nullptr; |
35 | | std::map<FileID, RewriteBuffer> RewriteBuffers; |
36 | | |
37 | | public: |
38 | | struct RewriteOptions { |
39 | | /// Given a source range, true to include previous inserts at the |
40 | | /// beginning of the range as part of the range itself (true by default). |
41 | | bool IncludeInsertsAtBeginOfRange = true; |
42 | | |
43 | | /// Given a source range, true to include previous inserts at the |
44 | | /// end of the range as part of the range itself (true by default). |
45 | | bool IncludeInsertsAtEndOfRange = true; |
46 | | |
47 | | /// If true and removing some text leaves a blank line |
48 | | /// also remove the empty line (false by default). |
49 | | bool RemoveLineIfEmpty = false; |
50 | | |
51 | 2.68k | RewriteOptions() {} |
52 | | }; |
53 | | |
54 | | using buffer_iterator = std::map<FileID, RewriteBuffer>::iterator; |
55 | | using const_buffer_iterator = std::map<FileID, RewriteBuffer>::const_iterator; |
56 | | |
57 | 168 | explicit Rewriter() = default; |
58 | | explicit Rewriter(SourceManager &SM, const LangOptions &LO) |
59 | 12.5k | : SourceMgr(&SM), LangOpts(&LO) {} |
60 | | |
61 | 168 | void setSourceMgr(SourceManager &SM, const LangOptions &LO) { |
62 | 168 | SourceMgr = &SM; |
63 | 168 | LangOpts = &LO; |
64 | 168 | } |
65 | | |
66 | 39.5k | SourceManager &getSourceMgr() const { return *SourceMgr; } |
67 | 708 | const LangOptions &getLangOpts() const { return *LangOpts; } |
68 | | |
69 | | /// isRewritable - Return true if this location is a raw file location, which |
70 | | /// is rewritable. Locations from macros, etc are not rewritable. |
71 | 50.0k | static bool isRewritable(SourceLocation Loc) { |
72 | 50.0k | return Loc.isFileID(); |
73 | 50.0k | } |
74 | | |
75 | | /// getRangeSize - Return the size in bytes of the specified range if they |
76 | | /// are in the same file. If not, this returns -1. |
77 | | int getRangeSize(SourceRange Range, |
78 | | RewriteOptions opts = RewriteOptions()) const; |
79 | | int getRangeSize(const CharSourceRange &Range, |
80 | | RewriteOptions opts = RewriteOptions()) const; |
81 | | |
82 | | /// getRewrittenText - Return the rewritten form of the text in the specified |
83 | | /// range. If the start or end of the range was unrewritable or if they are |
84 | | /// in different buffers, this returns an empty string. |
85 | | /// |
86 | | /// Note that this method is not particularly efficient. |
87 | | std::string getRewrittenText(SourceRange Range) const; |
88 | | |
89 | | /// InsertText - Insert the specified string at the specified location in the |
90 | | /// original buffer. This method returns true (and does nothing) if the input |
91 | | /// location was not rewritable, false otherwise. |
92 | | /// |
93 | | /// \param indentNewLines if true new lines in the string are indented |
94 | | /// using the indentation of the source line in position \p Loc. |
95 | | bool InsertText(SourceLocation Loc, StringRef Str, |
96 | | bool InsertAfter = true, bool indentNewLines = false); |
97 | | |
98 | | /// InsertTextAfter - Insert the specified string at the specified location in |
99 | | /// the original buffer. This method returns true (and does nothing) if |
100 | | /// the input location was not rewritable, false otherwise. Text is |
101 | | /// inserted after any other text that has been previously inserted |
102 | | /// at the some point (the default behavior for InsertText). |
103 | 90 | bool InsertTextAfter(SourceLocation Loc, StringRef Str) { |
104 | 90 | return InsertText(Loc, Str); |
105 | 90 | } |
106 | | |
107 | | /// Insert the specified string after the token in the |
108 | | /// specified location. |
109 | | bool InsertTextAfterToken(SourceLocation Loc, StringRef Str); |
110 | | |
111 | | /// InsertText - Insert the specified string at the specified location in the |
112 | | /// original buffer. This method returns true (and does nothing) if the input |
113 | | /// location was not rewritable, false otherwise. Text is |
114 | | /// inserted before any other text that has been previously inserted |
115 | | /// at the some point. |
116 | 707 | bool InsertTextBefore(SourceLocation Loc, StringRef Str) { |
117 | 707 | return InsertText(Loc, Str, false); |
118 | 707 | } |
119 | | |
120 | | /// RemoveText - Remove the specified text region. |
121 | | bool RemoveText(SourceLocation Start, unsigned Length, |
122 | | RewriteOptions opts = RewriteOptions()); |
123 | | |
124 | | /// Remove the specified text region. |
125 | | bool RemoveText(CharSourceRange range, |
126 | 402 | RewriteOptions opts = RewriteOptions()) { |
127 | 402 | return RemoveText(range.getBegin(), getRangeSize(range, opts), opts); |
128 | 402 | } |
129 | | |
130 | | /// Remove the specified text region. |
131 | 0 | bool RemoveText(SourceRange range, RewriteOptions opts = RewriteOptions()) { |
132 | 0 | return RemoveText(range.getBegin(), getRangeSize(range, opts), opts); |
133 | 0 | } |
134 | | |
135 | | /// ReplaceText - This method replaces a range of characters in the input |
136 | | /// buffer with a new string. This is effectively a combined "remove/insert" |
137 | | /// operation. |
138 | | bool ReplaceText(SourceLocation Start, unsigned OrigLength, |
139 | | StringRef NewStr); |
140 | | |
141 | | /// ReplaceText - This method replaces a range of characters in the input |
142 | | /// buffer with a new string. This is effectively a combined "remove/insert" |
143 | | /// operation. |
144 | 0 | bool ReplaceText(SourceRange range, StringRef NewStr) { |
145 | 0 | return ReplaceText(range.getBegin(), getRangeSize(range), NewStr); |
146 | 0 | } |
147 | | |
148 | | /// ReplaceText - This method replaces a range of characters in the input |
149 | | /// buffer with a new string. This is effectively a combined "remove/insert" |
150 | | /// operation. |
151 | | bool ReplaceText(SourceRange range, SourceRange replacementRange); |
152 | | |
153 | | /// Increase indentation for the lines between the given source range. |
154 | | /// To determine what the indentation should be, 'parentIndent' is used |
155 | | /// that should be at a source location with an indentation one degree |
156 | | /// lower than the given range. |
157 | | bool IncreaseIndentation(CharSourceRange range, SourceLocation parentIndent); |
158 | 0 | bool IncreaseIndentation(SourceRange range, SourceLocation parentIndent) { |
159 | 0 | return IncreaseIndentation(CharSourceRange::getTokenRange(range), |
160 | 0 | parentIndent); |
161 | 0 | } |
162 | | |
163 | | /// getEditBuffer - This is like getRewriteBufferFor, but always returns a |
164 | | /// buffer, and allows you to write on it directly. This is useful if you |
165 | | /// want efficient low-level access to apis for scribbling on one specific |
166 | | /// FileID's buffer. |
167 | | RewriteBuffer &getEditBuffer(FileID FID); |
168 | | |
169 | | /// getRewriteBufferFor - Return the rewrite buffer for the specified FileID. |
170 | | /// If no modification has been made to it, return null. |
171 | 261 | const RewriteBuffer *getRewriteBufferFor(FileID FID) const { |
172 | 261 | std::map<FileID, RewriteBuffer>::const_iterator I = |
173 | 261 | RewriteBuffers.find(FID); |
174 | 261 | return I == RewriteBuffers.end() ? nullptr0 : &I->second; |
175 | 261 | } |
176 | | |
177 | | // Iterators over rewrite buffers. |
178 | 161 | buffer_iterator buffer_begin() { return RewriteBuffers.begin(); } |
179 | 161 | buffer_iterator buffer_end() { return RewriteBuffers.end(); } |
180 | 0 | const_buffer_iterator buffer_begin() const { return RewriteBuffers.begin(); } |
181 | 0 | const_buffer_iterator buffer_end() const { return RewriteBuffers.end(); } |
182 | | |
183 | | /// overwriteChangedFiles - Save all changed files to disk. |
184 | | /// |
185 | | /// Returns true if any files were not saved successfully. |
186 | | /// Outputs diagnostics via the source manager's diagnostic engine |
187 | | /// in case of an error. |
188 | | bool overwriteChangedFiles(); |
189 | | |
190 | | private: |
191 | | unsigned getLocationOffsetAndFileID(SourceLocation Loc, FileID &FID) const; |
192 | | }; |
193 | | |
194 | | } // namespace clang |
195 | | |
196 | | #endif // LLVM_CLANG_REWRITE_CORE_REWRITER_H |