Home | History | Annotate | Download | only in Core
      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;
     35   iterator begin() const { return Buffer.begin(); }
     36   iterator end() const { return Buffer.end(); }
     37   unsigned size() const { return Buffer.size(); }
     38 
     39   /// Initialize - Start this rewrite buffer out with a copy of the unmodified
     40   /// input buffer.
     41   void Initialize(const char *BufStart, const char *BufEnd) {
     42     Buffer.assign(BufStart, BufEnd);
     43   }
     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".
     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.
     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.
    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.
    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