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