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/StringRef.h" 15 #include "llvm/ADT/SmallVector.h" 16 17 namespace clang { 18 class LangOptions; 19 class PreprocessingRecord; 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 PreprocessingRecord *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 PreprocessingRecord *PPRec = 0) SourceMgr(SM)59 : SourceMgr(SM), LangOpts(LangOpts), PPRec(PPRec), Editor(0), 60 IsCommitable(true) { } 61 isCommitable()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 } insertBefore(SourceLocation loc,StringRef text)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 } insertWrap(StringRef before,SourceRange TokenRange,StringRef after)92 bool insertWrap(StringRef before, SourceRange TokenRange, StringRef after) { 93 return insertWrap(before, CharSourceRange::getTokenRange(TokenRange), after); 94 } remove(SourceRange TokenRange)95 bool remove(SourceRange TokenRange) { 96 return remove(CharSourceRange::getTokenRange(TokenRange)); 97 } replace(SourceRange TokenRange,StringRef text)98 bool replace(SourceRange TokenRange, StringRef text) { 99 return replace(CharSourceRange::getTokenRange(TokenRange), text); 100 } replaceWithInner(SourceRange TokenRange,SourceRange TokenInnerRange)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; edit_begin()107 edit_iterator edit_begin() const { return CachedEdits.begin(); } edit_end()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