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