1 //===--- RewriteBuffer.h - Buffer rewriting interface -----------*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 #ifndef LLVM_CLANG_REWRITE_CORE_REWRITEBUFFER_H 11 #define LLVM_CLANG_REWRITE_CORE_REWRITEBUFFER_H 12 13 #include "clang/Basic/LLVM.h" 14 #include "clang/Rewrite/Core/DeltaTree.h" 15 #include "clang/Rewrite/Core/RewriteRope.h" 16 #include "llvm/ADT/StringRef.h" 17 18 namespace clang { 19 class Rewriter; 20 21 /// RewriteBuffer - As code is rewritten, SourceBuffer's from the original 22 /// input with modifications get a new RewriteBuffer associated with them. The 23 /// RewriteBuffer captures the modified text itself as well as information used 24 /// to map between SourceLocation's in the original input and offsets in the 25 /// RewriteBuffer. For example, if text is inserted into the buffer, any 26 /// locations after the insertion point have to be mapped. 27 class RewriteBuffer { 28 friend class Rewriter; 29 /// Deltas - Keep track of all the deltas in the source code due to insertions 30 /// and deletions. 31 DeltaTree Deltas; 32 RewriteRope Buffer; 33 public: 34 typedef RewriteRope::const_iterator iterator; begin()35 iterator begin() const { return Buffer.begin(); } end()36 iterator end() const { return Buffer.end(); } size()37 unsigned size() const { return Buffer.size(); } 38 39 /// Initialize - Start this rewrite buffer out with a copy of the unmodified 40 /// input buffer. Initialize(const char * BufStart,const char * BufEnd)41 void Initialize(const char *BufStart, const char *BufEnd) { 42 Buffer.assign(BufStart, BufEnd); 43 } Initialize(StringRef Input)44 void Initialize(StringRef Input) { 45 Initialize(Input.begin(), Input.end()); 46 } 47 48 /// \brief Write to \p Stream the result of applying all changes to the 49 /// original buffer. 50 /// Note that it isn't safe to use this function to overwrite memory mapped 51 /// files in-place (PR17960). Consider using a higher-level utility such as 52 /// Rewriter::overwriteChangedFiles() instead. 53 /// 54 /// The original buffer is not actually changed. 55 raw_ostream &write(raw_ostream &Stream) const; 56 57 /// RemoveText - Remove the specified text. 58 void RemoveText(unsigned OrigOffset, unsigned Size, 59 bool removeLineIfEmpty = false); 60 61 /// InsertText - Insert some text at the specified point, where the offset in 62 /// the buffer is specified relative to the original SourceBuffer. The 63 /// text is inserted after the specified location. 64 /// 65 void InsertText(unsigned OrigOffset, StringRef Str, 66 bool InsertAfter = true); 67 68 69 /// InsertTextBefore - Insert some text before the specified point, where the 70 /// offset in the buffer is specified relative to the original 71 /// SourceBuffer. The text is inserted before the specified location. This is 72 /// method is the same as InsertText with "InsertAfter == false". InsertTextBefore(unsigned OrigOffset,StringRef Str)73 void InsertTextBefore(unsigned OrigOffset, StringRef Str) { 74 InsertText(OrigOffset, Str, false); 75 } 76 77 /// InsertTextAfter - Insert some text at the specified point, where the 78 /// offset in the buffer is specified relative to the original SourceBuffer. 79 /// The text is inserted after the specified location. InsertTextAfter(unsigned OrigOffset,StringRef Str)80 void InsertTextAfter(unsigned OrigOffset, StringRef Str) { 81 InsertText(OrigOffset, Str); 82 } 83 84 /// ReplaceText - This method replaces a range of characters in the input 85 /// buffer with a new string. This is effectively a combined "remove/insert" 86 /// operation. 87 void ReplaceText(unsigned OrigOffset, unsigned OrigLength, 88 StringRef NewStr); 89 90 private: // Methods only usable by Rewriter. 91 92 /// getMappedOffset - Given an offset into the original SourceBuffer that this 93 /// RewriteBuffer is based on, map it into the offset space of the 94 /// RewriteBuffer. If AfterInserts is true and if the OrigOffset indicates a 95 /// position where text is inserted, the location returned will be after any 96 /// inserted text at the position. 97 unsigned getMappedOffset(unsigned OrigOffset, 98 bool AfterInserts = false) const{ 99 return Deltas.getDeltaAt(2*OrigOffset+AfterInserts)+OrigOffset; 100 } 101 102 /// AddInsertDelta - When an insertion is made at a position, this 103 /// method is used to record that information. AddInsertDelta(unsigned OrigOffset,int Change)104 void AddInsertDelta(unsigned OrigOffset, int Change) { 105 return Deltas.AddDelta(2*OrigOffset, Change); 106 } 107 108 /// AddReplaceDelta - When a replacement/deletion is made at a position, this 109 /// method is used to record that information. AddReplaceDelta(unsigned OrigOffset,int Change)110 void AddReplaceDelta(unsigned OrigOffset, int Change) { 111 return Deltas.AddDelta(2*OrigOffset+1, Change); 112 } 113 }; 114 115 } // end namespace clang 116 117 #endif 118