/usr/include/clang/Rewrite/Rewriter.h is in libclang-dev 3.0-6ubuntu3.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 | //===--- Rewriter.h - Code rewriting interface ------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file defines the Rewriter class, which is used for code
// transformations.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_REWRITER_H
#define LLVM_CLANG_REWRITER_H
#include "clang/Basic/SourceLocation.h"
#include "clang/Rewrite/DeltaTree.h"
#include "clang/Rewrite/RewriteRope.h"
#include "llvm/ADT/StringRef.h"
#include <cstring>
#include <map>
#include <string>
namespace clang {
class LangOptions;
class Rewriter;
class SourceManager;
class Stmt;
/// RewriteBuffer - As code is rewritten, SourceBuffer's from the original
/// input with modifications get a new RewriteBuffer associated with them. The
/// RewriteBuffer captures the modified text itself as well as information used
/// to map between SourceLocation's in the original input and offsets in the
/// RewriteBuffer. For example, if text is inserted into the buffer, any
/// locations after the insertion point have to be mapped.
class RewriteBuffer {
friend class Rewriter;
/// Deltas - Keep track of all the deltas in the source code due to insertions
/// and deletions.
DeltaTree Deltas;
/// Buffer - This is the actual buffer itself. Note that using a vector or
/// string is a horribly inefficient way to do this, we should use a rope
/// instead.
typedef RewriteRope BufferTy;
BufferTy Buffer;
public:
typedef BufferTy::const_iterator iterator;
iterator begin() const { return Buffer.begin(); }
iterator end() const { return Buffer.end(); }
unsigned size() const { return Buffer.size(); }
raw_ostream &write(raw_ostream &) const;
/// RemoveText - Remove the specified text.
void RemoveText(unsigned OrigOffset, unsigned Size,
bool removeLineIfEmpty = false);
/// InsertText - Insert some text at the specified point, where the offset in
/// the buffer is specified relative to the original SourceBuffer. The
/// text is inserted after the specified location.
///
void InsertText(unsigned OrigOffset, StringRef Str,
bool InsertAfter = true);
/// InsertTextBefore - Insert some text before the specified point, where the
/// offset in the buffer is specified relative to the original
/// SourceBuffer. The text is inserted before the specified location. This is
/// method is the same as InsertText with "InsertAfter == false".
void InsertTextBefore(unsigned OrigOffset, StringRef Str) {
InsertText(OrigOffset, Str, false);
}
/// InsertTextAfter - Insert some text at the specified point, where the
/// offset in the buffer is specified relative to the original SourceBuffer.
/// The text is inserted after the specified location.
void InsertTextAfter(unsigned OrigOffset, StringRef Str) {
InsertText(OrigOffset, Str);
}
/// ReplaceText - This method replaces a range of characters in the input
/// buffer with a new string. This is effectively a combined "remove/insert"
/// operation.
void ReplaceText(unsigned OrigOffset, unsigned OrigLength,
StringRef NewStr);
private: // Methods only usable by Rewriter.
/// Initialize - Start this rewrite buffer out with a copy of the unmodified
/// input buffer.
void Initialize(const char *BufStart, const char *BufEnd) {
Buffer.assign(BufStart, BufEnd);
}
/// getMappedOffset - Given an offset into the original SourceBuffer that this
/// RewriteBuffer is based on, map it into the offset space of the
/// RewriteBuffer. If AfterInserts is true and if the OrigOffset indicates a
/// position where text is inserted, the location returned will be after any
/// inserted text at the position.
unsigned getMappedOffset(unsigned OrigOffset,
bool AfterInserts = false) const{
return Deltas.getDeltaAt(2*OrigOffset+AfterInserts)+OrigOffset;
}
/// AddInsertDelta - When an insertion is made at a position, this
/// method is used to record that information.
void AddInsertDelta(unsigned OrigOffset, int Change) {
return Deltas.AddDelta(2*OrigOffset, Change);
}
/// AddReplaceDelta - When a replacement/deletion is made at a position, this
/// method is used to record that information.
void AddReplaceDelta(unsigned OrigOffset, int Change) {
return Deltas.AddDelta(2*OrigOffset+1, Change);
}
};
/// Rewriter - This is the main interface to the rewrite buffers. Its primary
/// job is to dispatch high-level requests to the low-level RewriteBuffers that
/// are involved.
class Rewriter {
SourceManager *SourceMgr;
const LangOptions *LangOpts;
std::map<FileID, RewriteBuffer> RewriteBuffers;
public:
struct RewriteOptions {
/// \brief Given a source range, true to include previous inserts at the
/// beginning of the range as part of the range itself (true by default).
bool IncludeInsertsAtBeginOfRange;
/// \brief Given a source range, true to include previous inserts at the
/// end of the range as part of the range itself (true by default).
bool IncludeInsertsAtEndOfRange;
/// \brief If true and removing some text leaves a blank line
/// also remove the empty line (false by default).
bool RemoveLineIfEmpty;
RewriteOptions()
: IncludeInsertsAtBeginOfRange(true),
IncludeInsertsAtEndOfRange(true),
RemoveLineIfEmpty(false) { }
};
typedef std::map<FileID, RewriteBuffer>::iterator buffer_iterator;
explicit Rewriter(SourceManager &SM, const LangOptions &LO)
: SourceMgr(&SM), LangOpts(&LO) {}
explicit Rewriter() : SourceMgr(0), LangOpts(0) {}
void setSourceMgr(SourceManager &SM, const LangOptions &LO) {
SourceMgr = &SM;
LangOpts = &LO;
}
SourceManager &getSourceMgr() const { return *SourceMgr; }
const LangOptions &getLangOpts() const { return *LangOpts; }
/// isRewritable - Return true if this location is a raw file location, which
/// is rewritable. Locations from macros, etc are not rewritable.
static bool isRewritable(SourceLocation Loc) {
return Loc.isFileID();
}
/// getRangeSize - Return the size in bytes of the specified range if they
/// are in the same file. If not, this returns -1.
int getRangeSize(SourceRange Range,
RewriteOptions opts = RewriteOptions()) const;
int getRangeSize(const CharSourceRange &Range,
RewriteOptions opts = RewriteOptions()) const;
/// getRewrittenText - 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 getRewrittenText(SourceRange Range) const;
/// InsertText - Insert the specified string at the specified location in the
/// original buffer. This method returns true (and does nothing) if the input
/// location was not rewritable, false otherwise.
///
/// \param indentNewLines if true new lines in the string are indented
/// using the indentation of the source line in position \arg Loc.
bool InsertText(SourceLocation Loc, StringRef Str,
bool InsertAfter = true, bool indentNewLines = false);
/// InsertTextAfter - Insert the specified string at the specified location in
/// the original buffer. This method returns true (and does nothing) if
/// the input location was not rewritable, false otherwise. Text is
/// inserted after any other text that has been previously inserted
/// at the some point (the default behavior for InsertText).
bool InsertTextAfter(SourceLocation Loc, StringRef Str) {
return InsertText(Loc, Str);
}
/// \brief Insert the specified string after the token in the
/// specified location.
bool InsertTextAfterToken(SourceLocation Loc, StringRef Str);
/// InsertText - Insert the specified string at the specified location in the
/// original buffer. This method returns true (and does nothing) if the input
/// location was not rewritable, false otherwise. Text is
/// inserted before any other text that has been previously inserted
/// at the some point.
bool InsertTextBefore(SourceLocation Loc, StringRef Str) {
return InsertText(Loc, Str, false);
}
/// RemoveText - Remove the specified text region.
bool RemoveText(SourceLocation Start, unsigned Length,
RewriteOptions opts = RewriteOptions());
/// \brief Remove the specified text region.
bool RemoveText(CharSourceRange range,
RewriteOptions opts = RewriteOptions()) {
return RemoveText(range.getBegin(), getRangeSize(range, opts), opts);
}
/// \brief Remove the specified text region.
bool RemoveText(SourceRange range, RewriteOptions opts = RewriteOptions()) {
return RemoveText(range.getBegin(), getRangeSize(range, opts), opts);
}
/// ReplaceText - This method replaces a range of characters in the input
/// buffer with a new string. This is effectively a combined "remove/insert"
/// operation.
bool ReplaceText(SourceLocation Start, unsigned OrigLength,
StringRef NewStr);
/// ReplaceText - This method replaces a range of characters in the input
/// buffer with a new string. This is effectively a combined "remove/insert"
/// operation.
bool ReplaceText(SourceRange range, StringRef NewStr) {
return ReplaceText(range.getBegin(), getRangeSize(range), NewStr);
}
/// ReplaceText - This method replaces a range of characters in the input
/// buffer with a new string. This is effectively a combined "remove/insert"
/// operation.
bool ReplaceText(SourceRange range, SourceRange replacementRange);
/// ReplaceStmt - This replaces a Stmt/Expr with another, using the pretty
/// printer to generate the replacement code. This returns true if the input
/// could not be rewritten, or false if successful.
bool ReplaceStmt(Stmt *From, Stmt *To);
/// \brief Increase indentation for the lines between the given source range.
/// To determine what the indentation should be, 'parentIndent' is used
/// that should be at a source location with an indentation one degree
/// lower than the given range.
bool IncreaseIndentation(CharSourceRange range, SourceLocation parentIndent);
bool IncreaseIndentation(SourceRange range, SourceLocation parentIndent) {
return IncreaseIndentation(CharSourceRange::getTokenRange(range),
parentIndent);
}
/// ConvertToString converts statement 'From' to a string using the
/// pretty printer.
std::string ConvertToString(Stmt *From);
/// getEditBuffer - This is like getRewriteBufferFor, but always returns a
/// buffer, and allows you to write on it directly. This is useful if you
/// want efficient low-level access to apis for scribbling on one specific
/// FileID's buffer.
RewriteBuffer &getEditBuffer(FileID FID);
/// getRewriteBufferFor - Return the rewrite buffer for the specified FileID.
/// If no modification has been made to it, return null.
const RewriteBuffer *getRewriteBufferFor(FileID FID) const {
std::map<FileID, RewriteBuffer>::const_iterator I =
RewriteBuffers.find(FID);
return I == RewriteBuffers.end() ? 0 : &I->second;
}
// Iterators over rewrite buffers.
buffer_iterator buffer_begin() { return RewriteBuffers.begin(); }
buffer_iterator buffer_end() { return RewriteBuffers.end(); }
private:
unsigned getLocationOffsetAndFileID(SourceLocation Loc, FileID &FID) const;
};
} // end namespace clang
#endif
|