[cfe-commits] r129085 - in /cfe/trunk: include/clang/Rewrite/Rewriter.h lib/Rewrite/Rewriter.cpp
Argyrios Kyrtzidis
akyrtzi at gmail.com
Thu Apr 7 11:10:12 PDT 2011
Author: akirtzidis
Date: Thu Apr 7 13:10:12 2011
New Revision: 129085
URL: http://llvm.org/viewvc/llvm-project?rev=129085&view=rev
Log:
Enhance the Rewriter.
-Allow removing a line completely if it ends up empty
-Provide more control on what should be removed.
Modified:
cfe/trunk/include/clang/Rewrite/Rewriter.h
cfe/trunk/lib/Rewrite/Rewriter.cpp
Modified: cfe/trunk/include/clang/Rewrite/Rewriter.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Rewrite/Rewriter.h?rev=129085&r1=129084&r2=129085&view=diff
==============================================================================
--- cfe/trunk/include/clang/Rewrite/Rewriter.h (original)
+++ cfe/trunk/include/clang/Rewrite/Rewriter.h Thu Apr 7 13:10:12 2011
@@ -58,7 +58,8 @@
llvm::raw_ostream &write(llvm::raw_ostream &) const;
/// RemoveText - Remove the specified text.
- void RemoveText(unsigned OrigOffset, unsigned Size);
+ void RemoveText(unsigned OrigOffset, unsigned Size,
+ bool removeLineIfEmpty = false);
/// InsertText - Insert some text at the specified point, where the offset in
/// the buffer is specified relative to the original SourceBuffer. The
@@ -150,8 +151,11 @@
/// getRangeSize - Return the size in bytes of the specified range if they
/// are in the same file. If not, this returns -1.
- int getRangeSize(SourceRange Range) const;
- int getRangeSize(const CharSourceRange &Range) const;
+ /// If AfterInserts is true and if the beginning of range indicates a position
+ /// where text is inserted, the beginning of range will be after any inserted
+ /// text at the position.
+ int getRangeSize(SourceRange Range, bool AfterInserts = false) const;
+ int getRangeSize(const CharSourceRange &Range, bool AfterInserts=false) const;
/// getRewrittenText - Return the rewritten form of the text in the specified
/// range. If the start or end of the range was unrewritable or if they are
@@ -176,6 +180,10 @@
return InsertText(Loc, Str);
}
+ /// \brief Insert the specified string after the token in the
+ /// specified location.
+ bool InsertTextAfterToken(SourceLocation Loc, llvm::StringRef Str);
+
/// InsertText - Insert the specified string at the specified location in the
/// original buffer. This method returns true (and does nothing) if the input
/// location was not rewritable, false otherwise. Text is
@@ -186,7 +194,34 @@
}
/// RemoveText - Remove the specified text region.
- bool RemoveText(SourceLocation Start, unsigned Length);
+ bool RemoveText(SourceLocation Start, unsigned Length,
+ bool removeLineIfEmpty = false);
+
+ /// \brief Remove the specified text region.
+ ///
+ /// \param afterInserts if true the beginning of removal will be after any
+ /// inserted text at the position.
+ ///
+ /// \param removeLineIfEmpty if true and removing the text leaves a blank line
+ /// also remove the empty line.
+ bool RemoveText(CharSourceRange range, bool afterInserts = false,
+ bool removeLineIfEmpty = false) {
+ return RemoveText(range.getBegin(), getRangeSize(range, afterInserts),
+ removeLineIfEmpty);
+ }
+
+ /// \brief Remove the specified text region.
+ ///
+ /// \param afterInserts if true the beginning of removal will be after any
+ /// inserted text at the position.
+ ///
+ /// \param removeLineIfEmpty if true and removing the text leaves a blank line
+ /// also remove the empty line.
+ bool RemoveText(SourceRange range, bool afterInserts = false,
+ bool removeLineIfEmpty = false) {
+ return RemoveText(range.getBegin(), getRangeSize(range, afterInserts),
+ removeLineIfEmpty);
+ }
/// ReplaceText - This method replaces a range of characters in the input
/// buffer with a new string. This is effectively a combined "remove/insert"
@@ -194,6 +229,18 @@
bool ReplaceText(SourceLocation Start, unsigned OrigLength,
llvm::StringRef NewStr);
+ /// ReplaceText - This method replaces a range of characters in the input
+ /// buffer with a new string. This is effectively a combined "remove/insert"
+ /// operation.
+ bool ReplaceText(SourceRange range, llvm::StringRef NewStr) {
+ return ReplaceText(range.getBegin(), getRangeSize(range), NewStr);
+ }
+
+ /// ReplaceText - This method replaces a range of characters in the input
+ /// buffer with a new string. This is effectively a combined "remove/insert"
+ /// operation.
+ bool ReplaceText(SourceRange range, SourceRange replacementRange);
+
/// ReplaceStmt - This replaces a Stmt/Expr with another, using the pretty
/// printer to generate the replacement code. This returns true if the input
/// could not be rewritten, or false if successful.
Modified: cfe/trunk/lib/Rewrite/Rewriter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Rewrite/Rewriter.cpp?rev=129085&r1=129084&r2=129085&view=diff
==============================================================================
--- cfe/trunk/lib/Rewrite/Rewriter.cpp (original)
+++ cfe/trunk/lib/Rewrite/Rewriter.cpp Thu Apr 7 13:10:12 2011
@@ -26,7 +26,23 @@
return os;
}
-void RewriteBuffer::RemoveText(unsigned OrigOffset, unsigned Size) {
+/// \brief Return true if this character is non-new-line whitespace:
+/// ' ', '\t', '\f', '\v', '\r'.
+static inline bool isWhitespace(unsigned char c) {
+ switch (c) {
+ case ' ':
+ case '\t':
+ case '\f':
+ case '\v':
+ case '\r':
+ return true;
+ default:
+ return false;
+ }
+}
+
+void RewriteBuffer::RemoveText(unsigned OrigOffset, unsigned Size,
+ bool removeLineIfEmpty) {
// Nothing to remove, exit early.
if (Size == 0) return;
@@ -38,6 +54,34 @@
// Add a delta so that future changes are offset correctly.
AddReplaceDelta(OrigOffset, -Size);
+
+ if (removeLineIfEmpty) {
+ // Find the line that the remove occurred and if it is completely empty
+ // remove the line as well.
+
+ iterator curLineStart = begin();
+ unsigned curLineStartOffs = 0;
+ iterator posI = begin();
+ for (unsigned i = 0; i != RealOffset; ++i) {
+ if (*posI == '\n') {
+ curLineStart = posI;
+ ++curLineStart;
+ curLineStartOffs = i + 1;
+ }
+ ++posI;
+ }
+
+ unsigned lineSize = 0;
+ posI = curLineStart;
+ while (posI != end() && isWhitespace(*posI)) {
+ ++posI;
+ ++lineSize;
+ }
+ if (posI != end() && *posI == '\n') {
+ Buffer.erase(curLineStartOffs, lineSize + 1/* + '\n'*/);
+ AddReplaceDelta(curLineStartOffs, -(lineSize + 1/* + '\n'*/));
+ }
+ }
}
void RewriteBuffer::InsertText(unsigned OrigOffset, llvm::StringRef Str,
@@ -72,7 +116,8 @@
/// getRangeSize - Return the size in bytes of the specified range if they
/// are in the same file. If not, this returns -1.
-int Rewriter::getRangeSize(const CharSourceRange &Range) const {
+int Rewriter::getRangeSize(const CharSourceRange &Range,
+ bool AfterInserts) const {
if (!isRewritable(Range.getBegin()) ||
!isRewritable(Range.getEnd())) return -1;
@@ -92,7 +137,7 @@
if (I != RewriteBuffers.end()) {
const RewriteBuffer &RB = I->second;
EndOff = RB.getMappedOffset(EndOff, true);
- StartOff = RB.getMappedOffset(StartOff);
+ StartOff = RB.getMappedOffset(StartOff, AfterInserts);
}
@@ -104,8 +149,8 @@
return EndOff-StartOff;
}
-int Rewriter::getRangeSize(SourceRange Range) const {
- return getRangeSize(CharSourceRange::getTokenRange(Range));
+int Rewriter::getRangeSize(SourceRange Range, bool AfterInserts) const {
+ return getRangeSize(CharSourceRange::getTokenRange(Range), AfterInserts);
}
@@ -194,12 +239,22 @@
return false;
}
+bool Rewriter::InsertTextAfterToken(SourceLocation Loc, llvm::StringRef Str) {
+ if (!isRewritable(Loc)) return true;
+ FileID FID;
+ unsigned StartOffs = getLocationOffsetAndFileID(Loc, FID);
+ StartOffs += getRangeSize(SourceRange(Loc, Loc), /*AfterInserts*/true);
+ getEditBuffer(FID).InsertText(StartOffs, Str, /*InsertAfter*/true);
+ return false;
+}
+
/// RemoveText - Remove the specified text region.
-bool Rewriter::RemoveText(SourceLocation Start, unsigned Length) {
+bool Rewriter::RemoveText(SourceLocation Start, unsigned Length,
+ bool removeLineIfEmpty) {
if (!isRewritable(Start)) return true;
FileID FID;
unsigned StartOffs = getLocationOffsetAndFileID(Start, FID);
- getEditBuffer(FID).RemoveText(StartOffs, Length);
+ getEditBuffer(FID).RemoveText(StartOffs, Length, removeLineIfEmpty);
return false;
}
@@ -216,6 +271,20 @@
return false;
}
+bool Rewriter::ReplaceText(SourceRange range, SourceRange replacementRange) {
+ if (!isRewritable(range.getBegin())) return true;
+ if (!isRewritable(range.getEnd())) return true;
+ if (replacementRange.isInvalid()) return true;
+ SourceLocation start = range.getBegin();
+ unsigned origLength = getRangeSize(range);
+ unsigned newLength = getRangeSize(replacementRange);
+ FileID FID;
+ unsigned newOffs = getLocationOffsetAndFileID(replacementRange.getBegin(),
+ FID);
+ llvm::StringRef MB = SourceMgr->getBufferData(FID);
+ return ReplaceText(start, origLength, MB.substr(newOffs, newLength));
+}
+
/// ReplaceStmt - This replaces a Stmt/Expr with another, using the pretty
/// printer to generate the replacement code. This returns true if the input
/// could not be rewritten, or false if successful.
More information about the cfe-commits
mailing list