Home | History | Annotate | Download | only in Edit
      1 //===----- Commit.h - A unit of edits ---------------------------*- 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_EDIT_COMMIT_H
     11 #define LLVM_CLANG_EDIT_COMMIT_H
     12 
     13 #include "clang/Edit/FileOffset.h"
     14 #include "llvm/ADT/SmallVector.h"
     15 #include "llvm/ADT/StringRef.h"
     16 #include "llvm/Support/Allocator.h"
     17 
     18 namespace clang {
     19   class LangOptions;
     20   class PPConditionalDirectiveRecord;
     21 
     22 namespace edit {
     23   class EditedSource;
     24 
     25 class Commit {
     26 public:
     27   enum EditKind {
     28     Act_Insert,
     29     Act_InsertFromRange,
     30     Act_Remove
     31   };
     32 
     33   struct Edit {
     34     EditKind Kind;
     35     StringRef Text;
     36     SourceLocation OrigLoc;
     37     FileOffset Offset;
     38     FileOffset InsertFromRangeOffs;
     39     unsigned Length;
     40     bool BeforePrev;
     41 
     42     SourceLocation getFileLocation(SourceManager &SM) const;
     43     CharSourceRange getFileRange(SourceManager &SM) const;
     44     CharSourceRange getInsertFromRange(SourceManager &SM) const;
     45   };
     46 
     47 private:
     48   const SourceManager &SourceMgr;
     49   const LangOptions &LangOpts;
     50   const PPConditionalDirectiveRecord *PPRec;
     51   EditedSource *Editor;
     52 
     53   bool IsCommitable;
     54   SmallVector<Edit, 8> CachedEdits;
     55 
     56   llvm::BumpPtrAllocator StrAlloc;
     57 
     58 public:
     59   explicit Commit(EditedSource &Editor);
     60   Commit(const SourceManager &SM, const LangOptions &LangOpts,
     61          const PPConditionalDirectiveRecord *PPRec = 0)
     62     : SourceMgr(SM), LangOpts(LangOpts), PPRec(PPRec), Editor(0),
     63       IsCommitable(true) { }
     64 
     65   bool isCommitable() const { return IsCommitable; }
     66 
     67   bool insert(SourceLocation loc, StringRef text, bool afterToken = false,
     68               bool beforePreviousInsertions = false);
     69   bool insertAfterToken(SourceLocation loc, StringRef text,
     70                         bool beforePreviousInsertions = false) {
     71     return insert(loc, text, /*afterToken=*/true, beforePreviousInsertions);
     72   }
     73   bool insertBefore(SourceLocation loc, StringRef text) {
     74     return insert(loc, text, /*afterToken=*/false,
     75                   /*beforePreviousInsertions=*/true);
     76   }
     77   bool insertFromRange(SourceLocation loc, CharSourceRange range,
     78                        bool afterToken = false,
     79                        bool beforePreviousInsertions = false);
     80   bool insertWrap(StringRef before, CharSourceRange range, StringRef after);
     81 
     82   bool remove(CharSourceRange range);
     83 
     84   bool replace(CharSourceRange range, StringRef text);
     85   bool replaceWithInner(CharSourceRange range, CharSourceRange innerRange);
     86   bool replaceText(SourceLocation loc, StringRef text,
     87                    StringRef replacementText);
     88 
     89   bool insertFromRange(SourceLocation loc, SourceRange TokenRange,
     90                        bool afterToken = false,
     91                        bool beforePreviousInsertions = false) {
     92     return insertFromRange(loc, CharSourceRange::getTokenRange(TokenRange),
     93                            afterToken, beforePreviousInsertions);
     94   }
     95   bool insertWrap(StringRef before, SourceRange TokenRange, StringRef after) {
     96     return insertWrap(before, CharSourceRange::getTokenRange(TokenRange), after);
     97   }
     98   bool remove(SourceRange TokenRange) {
     99     return remove(CharSourceRange::getTokenRange(TokenRange));
    100   }
    101   bool replace(SourceRange TokenRange, StringRef text) {
    102     return replace(CharSourceRange::getTokenRange(TokenRange), text);
    103   }
    104   bool replaceWithInner(SourceRange TokenRange, SourceRange TokenInnerRange) {
    105     return replaceWithInner(CharSourceRange::getTokenRange(TokenRange),
    106                             CharSourceRange::getTokenRange(TokenInnerRange));
    107   }
    108 
    109   typedef SmallVectorImpl<Edit>::const_iterator edit_iterator;
    110   edit_iterator edit_begin() const { return CachedEdits.begin(); }
    111   edit_iterator edit_end() const { return CachedEdits.end(); }
    112 
    113 private:
    114   void addInsert(SourceLocation OrigLoc,
    115                 FileOffset Offs, StringRef text, bool beforePreviousInsertions);
    116   void addInsertFromRange(SourceLocation OrigLoc, FileOffset Offs,
    117                           FileOffset RangeOffs, unsigned RangeLen,
    118                           bool beforePreviousInsertions);
    119   void addRemove(SourceLocation OrigLoc, FileOffset Offs, unsigned Len);
    120 
    121   bool canInsert(SourceLocation loc, FileOffset &Offset);
    122   bool canInsertAfterToken(SourceLocation loc, FileOffset &Offset,
    123                            SourceLocation &AfterLoc);
    124   bool canInsertInOffset(SourceLocation OrigLoc, FileOffset Offs);
    125   bool canRemoveRange(CharSourceRange range, FileOffset &Offs, unsigned &Len);
    126   bool canReplaceText(SourceLocation loc, StringRef text,
    127                       FileOffset &Offs, unsigned &Len);
    128 
    129   void commitInsert(FileOffset offset, StringRef text,
    130                     bool beforePreviousInsertions);
    131   void commitRemove(FileOffset offset, unsigned length);
    132 
    133   bool isAtStartOfMacroExpansion(SourceLocation loc,
    134                                  SourceLocation *MacroBegin = 0) const;
    135   bool isAtEndOfMacroExpansion(SourceLocation loc,
    136                                SourceLocation *MacroEnd = 0) const;
    137 
    138   StringRef copyString(StringRef str) {
    139     char *buf = StrAlloc.Allocate<char>(str.size());
    140     std::memcpy(buf, str.data(), str.size());
    141     return StringRef(buf, str.size());
    142   }
    143 };
    144 
    145 }
    146 
    147 } // end namespace clang
    148 
    149 #endif
    150