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
17namespace clang {
18class Rewriter;
19} // namespace clang
20
21namespace llvm {
22
23class 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.
31class 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
40public:
41 using iterator = RewriteRope::const_iterator;
42
43 iterator begin() const { return Buffer.begin(); }
44 iterator end() const { return Buffer.end(); }
45 unsigned size() const { return Buffer.size(); }
46
47 /// Initialize - Start this rewrite buffer out with a copy of the unmodified
48 /// input buffer.
49 void Initialize(const char *BufStart, const char *BufEnd) {
50 Buffer.assign(Start: BufStart, End: BufEnd);
51 }
52 void Initialize(StringRef Input) { Initialize(BufStart: Input.begin(), BufEnd: 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".
77 void InsertTextBefore(unsigned OrigOffset, StringRef Str) {
78 InsertText(OrigOffset, Str, InsertAfter: 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.
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
94private:
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(FileIndex: 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.
107 void AddInsertDelta(unsigned OrigOffset, int Change) {
108 return Deltas.AddDelta(FileIndex: 2 * OrigOffset, Delta: Change);
109 }
110
111 /// AddReplaceDelta - When a replacement/deletion is made at a position, this
112 /// method is used to record that information.
113 void AddReplaceDelta(unsigned OrigOffset, int Change) {
114 return Deltas.AddDelta(FileIndex: 2 * OrigOffset + 1, Delta: Change);
115 }
116};
117
118} // namespace llvm
119
120#endif // LLVM_ADT_REWRITEBUFFER_H
121