20#include "llvm/ADT/RewriteBuffer.h"
21#include "llvm/ADT/RewriteRope.h"
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"
32using llvm::RewriteBuffer;
41 return c ==
' ' ||
c ==
'\t' ||
c ==
'\f' ||
c ==
'\v' ||
c ==
'\r';
51 FileID StartFileID, EndFileID;
52 unsigned StartOff = getLocationOffsetAndFileID(
Range.
getBegin(), StartFileID);
53 unsigned EndOff = getLocationOffsetAndFileID(
Range.
getEnd(), EndFileID);
55 if (StartFileID != EndFileID)
60 std::map<FileID, RewriteBuffer>::const_iterator I =
61 RewriteBuffers.find(StartFileID);
62 if (I != RewriteBuffers.end()) {
63 const RewriteBuffer &RB = I->second;
70 if (
Range.isTokenRange())
73 return EndOff-StartOff;
90 FileID StartFileID, EndFileID;
91 unsigned StartOff, EndOff;
92 StartOff = getLocationOffsetAndFileID(
Range.
getBegin(), StartFileID);
93 EndOff = getLocationOffsetAndFileID(
Range.
getEnd(), EndFileID);
95 if (StartFileID != EndFileID)
100 std::map<FileID, RewriteBuffer>::const_iterator I =
101 RewriteBuffers.find(StartFileID);
102 if (I == RewriteBuffers.end()) {
108 if (
Range.isTokenRange())
111 return std::string(Ptr, Ptr+EndOff-StartOff);
114 const RewriteBuffer &RB = I->second;
115 EndOff = RB.getMappedOffset(EndOff,
true);
116 StartOff = RB.getMappedOffset(StartOff);
120 if (
Range.isTokenRange())
124 RewriteBuffer::iterator Start = RB.begin();
125 std::advance(Start, StartOff);
126 RewriteBuffer::iterator End = Start;
127 assert(EndOff >= StartOff &&
"Invalid iteration distance");
128 std::advance(End, EndOff-StartOff);
130 return std::string(Start, End);
143 std::map<FileID, RewriteBuffer>::iterator I =
144 RewriteBuffers.lower_bound(FID);
145 if (I != RewriteBuffers.end() && I->first == FID)
147 I = RewriteBuffers.insert(I, std::make_pair(FID, RewriteBuffer()));
150 I->second.Initialize(MB.begin(), MB.end());
158 bool InsertAfter,
bool indentNewLines) {
161 unsigned StartOffs = getLocationOffsetAndFileID(
Loc, FID);
164 if (indentNewLines && Str.contains(
'\n')) {
167 unsigned lineNo = SourceMgr->
getLineNumber(FID, StartOffs) - 1;
173 StringRef indentSpace;
175 unsigned i = lineOffs;
178 indentSpace = MB.substr(lineOffs, i-lineOffs);
182 Str.split(lines,
"\n");
184 for (
unsigned i = 0, e = lines.size(); i != e; ++i) {
185 indentedStr += lines[i];
188 indentedStr += indentSpace;
191 Str = indentedStr.str();
201 unsigned StartOffs = getLocationOffsetAndFileID(
Loc, FID);
214 unsigned StartOffs = getLocationOffsetAndFileID(Start, FID);
226 unsigned StartOffs = getLocationOffsetAndFileID(Start, StartFileID);
228 getEditBuffer(StartFileID).ReplaceText(StartOffs, OrigLength, NewStr);
235 if (replacementRange.
isInvalid())
return true;
240 unsigned newOffs = getLocationOffsetAndFileID(replacementRange.
getBegin(),
243 return ReplaceText(start, origLength, MB.substr(newOffs, newLength));
248 if (range.isInvalid())
return true;
253 FileID StartFileID, EndFileID, parentFileID;
254 unsigned StartOff, EndOff, parentOff;
256 StartOff = getLocationOffsetAndFileID(range.getBegin(), StartFileID);
257 EndOff = getLocationOffsetAndFileID(range.getEnd(), EndFileID);
258 parentOff = getLocationOffsetAndFileID(parentIndent, parentFileID);
260 if (StartFileID != EndFileID || StartFileID != parentFileID)
262 if (StartOff > EndOff)
268 unsigned parentLineNo = SourceMgr->
getLineNumber(FID, parentOff) - 1;
269 unsigned startLineNo = SourceMgr->
getLineNumber(FID, StartOff) - 1;
270 unsigned endLineNo = SourceMgr->
getLineNumber(FID, EndOff) - 1;
280 StringRef parentSpace, startSpace;
282 unsigned i = parentLineOffs;
285 parentSpace = MB.substr(parentLineOffs, i-parentLineOffs);
290 startSpace = MB.substr(startLineOffs, i-startLineOffs);
292 if (parentSpace.size() >= startSpace.size())
294 if (!startSpace.starts_with(parentSpace))
297 StringRef indent = startSpace.substr(parentSpace.size());
301 for (
unsigned lineNo = startLineNo; lineNo <= endLineNo; ++lineNo) {
306 StringRef origIndent = MB.substr(offs, i-offs);
307 if (origIndent.starts_with(startSpace))
308 RB.InsertText(offs, indent,
false);
315 bool AllWritten =
true;
317 unsigned OverwriteFailure =
Diag.getCustomDiagID(
323 if (
auto Error = llvm::writeToOutput(
Path, [&](llvm::raw_ostream &OS) {
325 return llvm::Error::success();
327 Diag.Report(OverwriteFailure)
328 << 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 ...
std::map< FileID, llvm::RewriteBuffer >::iterator buffer_iterator
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::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.
llvm::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.
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 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
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).