22#include "llvm/ADT/SmallVector.h"
23#include "llvm/ADT/StringRef.h"
24#include "llvm/Support/Error.h"
25#include "llvm/Support/raw_ostream.h"
58 bool removeLineIfEmpty) {
60 if (Size == 0)
return;
62 unsigned RealOffset = getMappedOffset(OrigOffset,
true);
63 assert(RealOffset+Size <= Buffer.
size() &&
"Invalid location");
66 Buffer.
erase(RealOffset, Size);
69 AddReplaceDelta(OrigOffset, -Size);
71 if (removeLineIfEmpty) {
76 unsigned curLineStartOffs = 0;
78 for (
unsigned i = 0; i != RealOffset; ++i) {
82 curLineStartOffs = i + 1;
87 unsigned lineSize = 0;
93 if (posI !=
end() && *posI ==
'\n') {
94 Buffer.
erase(curLineStartOffs, lineSize + 1);
106 AddReplaceDelta(curLineStartOffs, -(lineSize + 1));
114 if (Str.empty())
return;
116 unsigned RealOffset = getMappedOffset(OrigOffset, InsertAfter);
117 Buffer.
insert(RealOffset, Str.begin(), Str.end());
120 AddInsertDelta(OrigOffset, Str.size());
128 unsigned RealOffset = getMappedOffset(OrigOffset,
true);
129 Buffer.
erase(RealOffset, OrigLength);
130 Buffer.
insert(RealOffset, NewStr.begin(), NewStr.end());
131 if (OrigLength != NewStr.size())
132 AddReplaceDelta(OrigOffset, NewStr.size() - OrigLength);
146 FileID StartFileID, EndFileID;
147 unsigned StartOff = getLocationOffsetAndFileID(Range.getBegin(), StartFileID);
148 unsigned EndOff = getLocationOffsetAndFileID(Range.getEnd(), EndFileID);
150 if (StartFileID != EndFileID)
155 std::map<FileID, RewriteBuffer>::const_iterator I =
156 RewriteBuffers.find(StartFileID);
157 if (I != RewriteBuffers.end()) {
165 if (Range.isTokenRange())
168 return EndOff-StartOff;
185 FileID StartFileID, EndFileID;
186 unsigned StartOff, EndOff;
187 StartOff = getLocationOffsetAndFileID(Range.getBegin(), StartFileID);
188 EndOff = getLocationOffsetAndFileID(Range.getEnd(), EndFileID);
190 if (StartFileID != EndFileID)
195 std::map<FileID, RewriteBuffer>::const_iterator I =
196 RewriteBuffers.find(StartFileID);
197 if (I == RewriteBuffers.end()) {
203 if (Range.isTokenRange())
206 return std::string(Ptr, Ptr+EndOff-StartOff);
210 EndOff = RB.getMappedOffset(EndOff,
true);
211 StartOff = RB.getMappedOffset(StartOff);
215 if (Range.isTokenRange())
220 std::advance(Start, StartOff);
222 assert(EndOff >= StartOff &&
"Invalid iteration distance");
223 std::advance(End, EndOff-StartOff);
225 return std::string(Start, End);
230 assert(Loc.
isValid() &&
"Invalid location");
238 std::map<FileID, RewriteBuffer>::iterator I =
239 RewriteBuffers.lower_bound(FID);
240 if (I != RewriteBuffers.end() && I->first == FID)
242 I = RewriteBuffers.insert(I, std::make_pair(FID,
RewriteBuffer()));
245 I->second.Initialize(MB.begin(), MB.end());
253 bool InsertAfter,
bool indentNewLines) {
256 unsigned StartOffs = getLocationOffsetAndFileID(Loc, FID);
259 if (indentNewLines && Str.contains(
'\n')) {
262 unsigned lineNo = SourceMgr->
getLineNumber(FID, StartOffs) - 1;
268 StringRef indentSpace;
270 unsigned i = lineOffs;
273 indentSpace = MB.substr(lineOffs, i-lineOffs);
277 Str.split(lines,
"\n");
279 for (
unsigned i = 0, e = lines.size(); i != e; ++i) {
280 indentedStr += lines[i];
283 indentedStr += indentSpace;
286 Str = indentedStr.str();
296 unsigned StartOffs = getLocationOffsetAndFileID(Loc, FID);
309 unsigned StartOffs = getLocationOffsetAndFileID(Start, FID);
321 unsigned StartOffs = getLocationOffsetAndFileID(Start, StartFileID);
330 if (replacementRange.
isInvalid())
return true;
335 unsigned newOffs = getLocationOffsetAndFileID(replacementRange.
getBegin(),
338 return ReplaceText(start, origLength, MB.substr(newOffs, newLength));
343 if (range.isInvalid())
return true;
348 FileID StartFileID, EndFileID, parentFileID;
349 unsigned StartOff, EndOff, parentOff;
351 StartOff = getLocationOffsetAndFileID(range.getBegin(), StartFileID);
352 EndOff = getLocationOffsetAndFileID(range.getEnd(), EndFileID);
353 parentOff = getLocationOffsetAndFileID(parentIndent, parentFileID);
355 if (StartFileID != EndFileID || StartFileID != parentFileID)
357 if (StartOff > EndOff)
363 unsigned parentLineNo = SourceMgr->
getLineNumber(FID, parentOff) - 1;
364 unsigned startLineNo = SourceMgr->
getLineNumber(FID, StartOff) - 1;
365 unsigned endLineNo = SourceMgr->
getLineNumber(FID, EndOff) - 1;
375 StringRef parentSpace, startSpace;
377 unsigned i = parentLineOffs;
380 parentSpace = MB.substr(parentLineOffs, i-parentLineOffs);
385 startSpace = MB.substr(startLineOffs, i-startLineOffs);
387 if (parentSpace.size() >= startSpace.size())
389 if (!startSpace.startswith(parentSpace))
392 StringRef indent = startSpace.substr(parentSpace.size());
396 for (
unsigned lineNo = startLineNo; lineNo <= endLineNo; ++lineNo) {
401 StringRef origIndent = MB.substr(offs, i-offs);
402 if (origIndent.startswith(startSpace))
410 bool AllWritten =
true;
412 unsigned OverwriteFailure =
Diag.getCustomDiagID(
418 if (
auto Error = llvm::writeToOutput(Path, [&](llvm::raw_ostream &OS) {
420 return llvm::Error::success();
422 Diag.Report(OverwriteFailure)
423 << Entry->
getName() << llvm::toString(std::move(Error));
Defines the Diagnostic-related interfaces.
Defines the Diagnostic IDs-related interfaces.
static DiagnosticBuilder Diag(DiagnosticsEngine *Diags, const LangOptions &Features, FullSourceLoc TokLoc, const char *TokBegin, const char *TokRangeBegin, const char *TokRangeEnd, unsigned DiagID)
Produce a diagnostic highlighting some portion of a literal.
static bool isWhitespaceExceptNL(unsigned char c)
Return true if this character is non-new-line whitespace: ' ', '\t', '\f', '\v', '\r'.
Defines the clang::SourceLocation class and associated facilities.
Defines the SourceManager interface.
__device__ __2f16 float c
Represents a character-granular source range.
static CharSourceRange getTokenRange(SourceRange R)
StringRef getName() const
The name of this FileEntry.
An opaque identifier used by SourceManager which refers to a source file (MemoryBuffer) along with it...
bool makeAbsolutePath(SmallVectorImpl< char > &Path) const
Makes Path absolute taking into account FileSystemOptions and the working directory option.
static unsigned MeasureTokenLength(SourceLocation Loc, const SourceManager &SM, const LangOptions &LangOpts)
MeasureTokenLength - Relex the token at the specified location and return its length in bytes in the ...
RewriteBuffer - As code is rewritten, SourceBuffer's from the original input with modifications get a...
void RemoveText(unsigned OrigOffset, unsigned Size, bool removeLineIfEmpty=false)
RemoveText - Remove the specified text.
raw_ostream & write(raw_ostream &Stream) const
Write to Stream the result of applying all changes to the original buffer.
void InsertText(unsigned OrigOffset, StringRef Str, bool InsertAfter=true)
InsertText - Insert some text at the specified point, where the offset in the buffer is specified rel...
void ReplaceText(unsigned OrigOffset, unsigned OrigLength, StringRef NewStr)
ReplaceText - This method replaces a range of characters in the input buffer with a new string.
void erase(unsigned Offset, unsigned NumBytes)
void insert(unsigned Offset, const char *Start, const char *End)
int getRangeSize(SourceRange Range, RewriteOptions opts=RewriteOptions()) const
getRangeSize - Return the size in bytes of the specified range if they are in the same file.
bool InsertText(SourceLocation Loc, StringRef Str, bool InsertAfter=true, bool indentNewLines=false)
InsertText - Insert the specified string at the specified location in the original buffer.
bool RemoveText(SourceLocation Start, unsigned Length, RewriteOptions opts=RewriteOptions())
RemoveText - Remove the specified text region.
static bool isRewritable(SourceLocation Loc)
isRewritable - Return true if this location is a raw file location, which is rewritable.
buffer_iterator buffer_end()
SourceManager & getSourceMgr() const
buffer_iterator buffer_begin()
std::map< FileID, RewriteBuffer >::iterator buffer_iterator
std::string getRewrittenText(CharSourceRange Range) const
getRewrittenText - Return the rewritten form of the text in the specified range.
bool IncreaseIndentation(CharSourceRange range, SourceLocation parentIndent)
Increase indentation for the lines between the given source range.
bool InsertTextAfterToken(SourceLocation Loc, StringRef Str)
Insert the specified string after the token in the specified location.
RewriteBuffer & getEditBuffer(FileID FID)
getEditBuffer - This is like getRewriteBufferFor, but always returns a buffer, and allows you to writ...
bool overwriteChangedFiles()
overwriteChangedFiles - Save all changed files to disk.
bool ReplaceText(SourceLocation Start, unsigned OrigLength, StringRef NewStr)
ReplaceText - This method replaces a range of characters in the input buffer with a new string.
RopePieceBTreeIterator - This class provides read-only forward iteration over bytes that are in a Rop...
Encodes a location in the source.
bool isValid() const
Return true if this is a valid SourceLocation object.
DiagnosticsEngine & getDiagnostics() const
OptionalFileEntryRef getFileEntryRefForID(FileID FID) const
Returns the FileEntryRef for the provided FileID.
StringRef getBufferData(FileID FID, bool *Invalid=nullptr) const
Return a StringRef to the source buffer data for the specified FileID.
FileManager & getFileManager() const
const char * getCharacterData(SourceLocation SL, bool *Invalid=nullptr) const
Return a pointer to the start of the specified location in the appropriate spelling MemoryBuffer.
unsigned getLineNumber(FileID FID, unsigned FilePos, bool *Invalid=nullptr) const
Given a SourceLocation, return the spelling line number for the position indicated.
std::pair< FileID, unsigned > getDecomposedLoc(SourceLocation Loc) const
Decompose the specified location into a raw FileID + Offset pair.
const SrcMgr::SLocEntry & getSLocEntry(FileID FID, bool *Invalid=nullptr) const
A trivial tuple used to represent a source range.
SourceLocation getBegin() const
One instance of this struct is kept for every file loaded or used.
LineOffsetMapping SourceLineCache
A bump pointer allocated array of offsets for each source line.
const ContentCache & getContentCache() const
const FileInfo & getFile() const
bool IncludeInsertsAtBeginOfRange
Given a source range, true to include previous inserts at the beginning of the range as part of the r...
bool IncludeInsertsAtEndOfRange
Given a source range, true to include previous inserts at the end of the range as part of the range i...
bool RemoveLineIfEmpty
If true and removing some text leaves a blank line also remove the empty line (false by default).