diff options
| author | Argyrios Kyrtzidis <akyrtzi@gmail.com> | 2011-04-07 18:10:12 +0000 | 
|---|---|---|
| committer | Argyrios Kyrtzidis <akyrtzi@gmail.com> | 2011-04-07 18:10:12 +0000 | 
| commit | 2f8165b685e7abd2c0788e5792802a56ddaf13ad (patch) | |
| tree | a10e66bd55ce8759a53f72fd4c3257be472d0643 /clang | |
| parent | 3fd80c1f1a720380501705b3d5f24c326a52c90b (diff) | |
| download | bcm5719-llvm-2f8165b685e7abd2c0788e5792802a56ddaf13ad.tar.gz bcm5719-llvm-2f8165b685e7abd2c0788e5792802a56ddaf13ad.zip  | |
Enhance the Rewriter.
-Allow removing a line completely if it ends up empty
-Provide more control on what should be removed.
llvm-svn: 129085
Diffstat (limited to 'clang')
| -rw-r--r-- | clang/include/clang/Rewrite/Rewriter.h | 55 | ||||
| -rw-r--r-- | clang/lib/Rewrite/Rewriter.cpp | 83 | 
2 files changed, 127 insertions, 11 deletions
diff --git a/clang/include/clang/Rewrite/Rewriter.h b/clang/include/clang/Rewrite/Rewriter.h index b3d4035628e..252f0baf890 100644 --- a/clang/include/clang/Rewrite/Rewriter.h +++ b/clang/include/clang/Rewrite/Rewriter.h @@ -58,7 +58,8 @@ public:    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 @@ public:    /// 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 @@ public:      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 @@ public:    }    /// 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 @@ public:    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. diff --git a/clang/lib/Rewrite/Rewriter.cpp b/clang/lib/Rewrite/Rewriter.cpp index 92e2b03f76f..c4b6757bacb 100644 --- a/clang/lib/Rewrite/Rewriter.cpp +++ b/clang/lib/Rewrite/Rewriter.cpp @@ -26,7 +26,23 @@ llvm::raw_ostream &RewriteBuffer::write(llvm::raw_ostream &os) const {    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 @@ void RewriteBuffer::RemoveText(unsigned OrigOffset, unsigned Size) {    // 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 @@ void RewriteBuffer::ReplaceText(unsigned OrigOffset, unsigned OrigLength,  /// 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 @@ int Rewriter::getRangeSize(const CharSourceRange &Range) const {    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 @@ int Rewriter::getRangeSize(const CharSourceRange &Range) const {    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 @@ bool Rewriter::InsertText(SourceLocation Loc, llvm::StringRef Str,    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 @@ bool Rewriter::ReplaceText(SourceLocation Start, unsigned OrigLength,    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.  | 

