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"
31 using namespace clang;
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())
222 assert(EndOff >= StartOff &&
"Invalid iteration distance");
225 return std::string(Start,
End);
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.starts_with(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.starts_with(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)
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 ParseState advance(ParseState S, size_t N)
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()
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.
SourceManager & getSourceMgr() const
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
const SrcMgr::SLocEntry & getSLocEntry(FileID FID, bool *Invalid=nullptr) 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.
A trivial tuple used to represent a source range.
SourceLocation getEnd() const
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
std::string toString(const til::SExpr *E)
The JSON file list parser is used to communicate input to InstallAPI.
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).