diff options
author | Chris Lattner <sabre@nondot.org> | 2008-10-03 23:31:16 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2008-10-03 23:31:16 +0000 |
commit | b5cd09a2bf1509167a2e7a46bdd0316812a93335 (patch) | |
tree | 8a0e2b81d76090e2aebc744600ef645a4bfaf4e1 /lib/Rewrite/Rewriter.cpp | |
parent | 94ede6e443726affff31c1666a8ed57e6bd4d674 (diff) |
add a new Rewriter::getRewritenText method that returns the text for a range
that includes any edits in the range.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@57037 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Rewrite/Rewriter.cpp')
-rw-r--r-- | lib/Rewrite/Rewriter.cpp | 49 |
1 files changed, 49 insertions, 0 deletions
diff --git a/lib/Rewrite/Rewriter.cpp b/lib/Rewrite/Rewriter.cpp index f414e1c5f2..9235a91bef 100644 --- a/lib/Rewrite/Rewriter.cpp +++ b/lib/Rewrite/Rewriter.cpp @@ -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 { |