]> granicus.if.org Git - clang/commitdiff
add a new Rewriter::getRewritenText method that returns the text for a range
authorChris Lattner <sabre@nondot.org>
Fri, 3 Oct 2008 23:31:16 +0000 (23:31 +0000)
committerChris Lattner <sabre@nondot.org>
Fri, 3 Oct 2008 23:31:16 +0000 (23:31 +0000)
that includes any edits in the range.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@57037 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Rewrite/Rewriter.h
lib/Rewrite/Rewriter.cpp

index 6176cfb2dd5c3df15277f5598523edfb704e03d3..9a579f12634d1d4df4c0f7c14212959d2c177bc3 100644 (file)
@@ -136,6 +136,11 @@ public:
   /// are in the same file.  If not, this returns -1.
   int getRangeSize(SourceRange Range) const;
   
+  /// getRewritenText - 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
+  /// in different buffers, this returns an empty string. 
+  std::string getRewritenText(SourceRange Range) const;
+  
   /// 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.
index f414e1c5f22a367adda5a76df262c0800d30b638..9235a91bef5368ccaf38be0c94fd96af36e74510 100644 (file)
@@ -97,6 +97,55 @@ int Rewriter::getRangeSize(SourceRange Range) const {
   return EndOff-StartOff;
 }
 
+/// getRewritenText - 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
+/// in different buffers, this returns an empty string. 
+///
+/// Note that this method is not particularly efficient.
+///
+std::string Rewriter::getRewritenText(SourceRange Range) const {
+  if (!isRewritable(Range.getBegin()) ||
+      !isRewritable(Range.getEnd()))
+    return "";
+  
+  unsigned StartOff, StartFileID;
+  unsigned EndOff  , EndFileID;
+  StartOff = getLocationOffsetAndFileID(Range.getBegin(), StartFileID);
+  EndOff   = getLocationOffsetAndFileID(Range.getEnd(), EndFileID);
+  
+  if (StartFileID != EndFileID)
+    return ""; // Start and end in different buffers.
+  
+  // If edits have been made to this buffer, the delta between the range may
+  // have changed.
+  std::map<unsigned, RewriteBuffer>::const_iterator I =
+    RewriteBuffers.find(StartFileID);
+  if (I == RewriteBuffers.end()) {
+    // If the buffer hasn't been rewritten, just return the text from the input.
+    const char *Ptr = SourceMgr->getCharacterData(Range.getBegin());
+    
+    // Adjust the end offset to the end of the last token, instead of being the
+    // start of the last token.
+    EndOff += Lexer::MeasureTokenLength(Range.getEnd(), *SourceMgr);
+    return std::string(Ptr, Ptr+EndOff-StartOff);
+  }
+  
+  const RewriteBuffer &RB = I->second;
+  EndOff = RB.getMappedOffset(EndOff, true);
+  StartOff = RB.getMappedOffset(StartOff);
+  
+  // Adjust the end offset to the end of the last token, instead of being the
+  // start of the last token.
+  EndOff += Lexer::MeasureTokenLength(Range.getEnd(), *SourceMgr);
+
+  // Advance the iterators to the right spot, yay for linear time algorithms.
+  RewriteBuffer::iterator Start = RB.begin();
+  std::advance(Start, StartOff);
+  RewriteBuffer::iterator End = Start;
+  std::advance(End, EndOff-StartOff);
+  
+  return std::string(Start, End);
+}
 
 unsigned Rewriter::getLocationOffsetAndFileID(SourceLocation Loc,
                                               unsigned &FileID) const {