16 using namespace clang;
39 : SourceMgr(Editor.getSourceManager()), LangOpts(Editor.getLangOpts()),
40 PPRec(Editor.getPPCondDirectiveRecord()),
41 Editor(&Editor), IsCommitable(
true) { }
44 bool afterToken,
bool beforePreviousInsertions) {
49 if ((!afterToken && !canInsert(loc, Offs)) ||
50 ( afterToken && !canInsertAfterToken(loc, Offs, loc))) {
55 addInsert(loc, Offs, text, beforePreviousInsertions);
61 bool afterToken,
bool beforePreviousInsertions) {
64 if (!canRemoveRange(range, RangeOffs, RangeLen)) {
70 if ((!afterToken && !canInsert(loc, Offs)) ||
71 ( afterToken && !canInsertAfterToken(loc, Offs, loc))) {
82 addInsertFromRange(loc, Offs, RangeOffs, RangeLen, beforePreviousInsertions);
89 if (!canRemoveRange(range, Offs, Len)) {
94 addRemove(range.
getBegin(), Offs, Len);
102 bool commitableAfter;
108 return commitableBefore && commitableAfter;
113 return remove(range);
117 if (!canInsert(range.
getBegin(), Offs) || !canRemoveRange(range, Offs, Len)) {
118 IsCommitable =
false;
122 addRemove(range.
getBegin(), Offs, Len);
131 if (!canRemoveRange(range, OuterBegin, OuterLen)) {
132 IsCommitable =
false;
138 if (!canRemoveRange(replacementRange, InnerBegin, InnerLen)) {
139 IsCommitable =
false;
146 InnerBegin < OuterBegin ||
147 InnerBegin > OuterEnd ||
148 InnerEnd > OuterEnd) {
149 IsCommitable =
false;
155 addRemove(replacementRange.
getEnd(),
161 StringRef replacementText) {
162 if (text.empty() || replacementText.empty())
167 if (!canReplaceText(loc, replacementText, Offs, Len)) {
168 IsCommitable =
false;
172 addRemove(loc, Offs, Len);
173 addInsert(loc, Offs, text,
false);
178 bool beforePreviousInsertions) {
184 data.OrigLoc = OrigLoc;
186 data.Text = copyString(text);
187 data.BeforePrev = beforePreviousInsertions;
188 CachedEdits.push_back(data);
193 bool beforePreviousInsertions) {
199 data.OrigLoc = OrigLoc;
201 data.InsertFromRangeOffs = RangeOffs;
202 data.Length = RangeLen;
203 data.BeforePrev = beforePreviousInsertions;
204 CachedEdits.push_back(data);
214 data.OrigLoc = OrigLoc;
217 CachedEdits.push_back(data);
225 isAtStartOfMacroExpansion(loc, &loc);
232 if (!isAtStartOfMacroExpansion(loc, &loc))
239 if (locInfo.first.isInvalid())
241 offs =
FileOffset(locInfo.first, locInfo.second);
242 return canInsertInOffset(loc, offs);
256 isAtEndOfMacroExpansion(loc, &loc);
263 if (!isAtEndOfMacroExpansion(loc, &loc))
274 if (locInfo.first.isInvalid())
276 offs =
FileOffset(locInfo.first, locInfo.second);
277 return canInsertInOffset(loc, offs);
281 for (
unsigned i = 0, e = CachedEdits.size(); i != e; ++i) {
282 Edit &act = CachedEdits[i];
284 if (act.Offset.getFID() == Offs.
getFID() &&
285 Offs > act.Offset && Offs < act.Offset.
getWithOffset(act.Length))
313 if (beginInfo.first != endInfo.first ||
314 beginInfo.second > endInfo.second)
317 Offs =
FileOffset(beginInfo.first, beginInfo.second);
318 Len = endInfo.second - beginInfo.second;
324 assert(!text.empty());
326 if (!canInsert(loc, Offs))
330 bool invalidTemp =
false;
336 return file.substr(Offs.
getOffset()).startswith(text);
bool remove(CharSourceRange range)
SourceLocation getBegin() const
SourceLocation getImmediateSpellingLoc(SourceLocation Loc) const
Given a SourceLocation object, return the spelling location referenced by the ID. ...
SourceLocation getSpellingLoc(SourceLocation Loc) const
Given a SourceLocation object, return the spelling location referenced by the ID. ...
bool insertWrap(StringRef before, CharSourceRange range, StringRef after)
Defines the SourceManager interface.
bool insertAfterToken(SourceLocation loc, StringRef text, bool beforePreviousInsertions=false)
bool insertFromRange(SourceLocation loc, CharSourceRange range, bool afterToken=false, bool beforePreviousInsertions=false)
static bool isAtStartOfMacroExpansion(SourceLocation loc, const SourceManager &SM, const LangOptions &LangOpts, SourceLocation *MacroBegin=nullptr)
Returns true if the given MacroID location points at the first token of the macro expansion...
bool rangeIntersectsConditionalDirective(SourceRange Range) const
Returns true if the given range intersects with a conditional directive. if a #if/#endif block is ful...
unsigned getOffset() const
FileOffset getWithOffset(unsigned offset) const
bool insert(SourceLocation loc, StringRef text, bool afterToken=false, bool beforePreviousInsertions=false)
StringRef getBufferData(FileID FID, bool *Invalid=nullptr) const
Return a StringRef to the source buffer data for the specified FileID.
bool replace(CharSourceRange range, StringRef text)
SourceLocation getLocWithOffset(int Offset) const
Return a source location with the specified offset from this SourceLocation.
static bool isAtEndOfMacroExpansion(SourceLocation loc, const SourceManager &SM, const LangOptions &LangOpts, SourceLocation *MacroEnd=nullptr)
Returns true if the given MacroID location points at the last token of the macro expansion.
static SourceLocation getLocForEndOfToken(SourceLocation Loc, unsigned Offset, const SourceManager &SM, const LangOptions &LangOpts)
Computes the source location just past the end of the token at this source location.
Represents a character-granular source range.
SourceLocation getEnd() const
static unsigned MeasureTokenLength(SourceLocation Loc, const SourceManager &SM, const LangOptions &LangOpts)
bool isInSystemHeader(SourceLocation Loc) const
Returns if a SourceLocation is in a system header.
CharSourceRange getInsertFromRange(SourceManager &SM) const
static CharSourceRange getCharRange(SourceRange R)
const SourceRange & getAsRange() const
bool isTokenRange() const
Return true if the end of this range specifies the start of the last token. Return false if the end o...
bool areInDifferentConditionalDirectiveRegion(SourceLocation LHS, SourceLocation RHS) const
Returns true if the given locations are in different regions, separated by conditional directive bloc...
Encodes a location in the source. The SourceManager can decode this to get at the full include stack...
CharSourceRange getFileRange(SourceManager &SM) const
static CharSourceRange makeFileCharRange(CharSourceRange Range, const SourceManager &SM, const LangOptions &LangOpts)
Accepts a range and returns a character range with file locations.
bool replaceText(SourceLocation loc, StringRef text, StringRef replacementText)
Commit(EditedSource &Editor)
SourceLocation getFileLocation(SourceManager &SM) const
bool canInsertInOffset(SourceLocation OrigLoc, FileOffset Offs)
bool replaceWithInner(CharSourceRange range, CharSourceRange innerRange)
SourceLocation getLocForStartOfFile(FileID FID) const
Return the source location corresponding to the first byte of the specified file. ...
std::pair< FileID, unsigned > getDecomposedLoc(SourceLocation Loc) const
Decompose the specified location into a raw FileID + Offset pair.
This class handles loading and caching of source files into memory.
bool isMacroArgExpansion(SourceLocation Loc) const
Tests whether the given source location represents a macro argument's expansion into the function-lik...