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