Commit.h revision 6badc76787dc9480fd7c21d3eb75aab79d2df3f5
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 18namespace clang { 19 class LangOptions; 20 class PPConditionalDirectiveRecord; 21 22namespace edit { 23 class EditedSource; 24 25class Commit { 26public: 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 47private: 48 const SourceManager &SourceMgr; 49 const LangOptions &LangOpts; 50 const PPConditionalDirectiveRecord *PPRec; 51 EditedSource *Editor; 52 53 const bool ForceCommitInSystemHeader; 54 bool IsCommitable; 55 SmallVector<Edit, 8> CachedEdits; 56 57 llvm::BumpPtrAllocator StrAlloc; 58 59public: 60 explicit Commit(EditedSource &Editor); 61 Commit(const SourceManager &SM, const LangOptions &LangOpts, 62 const PPConditionalDirectiveRecord *PPRec = 0) 63 : SourceMgr(SM), LangOpts(LangOpts), PPRec(PPRec), Editor(0), 64 ForceCommitInSystemHeader(true), IsCommitable(true) { } 65 66 bool isCommitable() const { return IsCommitable; } 67 68 bool insert(SourceLocation loc, StringRef text, bool afterToken = false, 69 bool beforePreviousInsertions = false); 70 bool insertAfterToken(SourceLocation loc, StringRef text, 71 bool beforePreviousInsertions = false) { 72 return insert(loc, text, /*afterToken=*/true, beforePreviousInsertions); 73 } 74 bool insertBefore(SourceLocation loc, StringRef text) { 75 return insert(loc, text, /*afterToken=*/false, 76 /*beforePreviousInsertions=*/true); 77 } 78 bool insertFromRange(SourceLocation loc, CharSourceRange range, 79 bool afterToken = false, 80 bool beforePreviousInsertions = false); 81 bool insertWrap(StringRef before, CharSourceRange range, StringRef after); 82 83 bool remove(CharSourceRange range); 84 85 bool replace(CharSourceRange range, StringRef text); 86 bool replaceWithInner(CharSourceRange range, CharSourceRange innerRange); 87 bool replaceText(SourceLocation loc, StringRef text, 88 StringRef replacementText); 89 90 bool insertFromRange(SourceLocation loc, SourceRange TokenRange, 91 bool afterToken = false, 92 bool beforePreviousInsertions = false) { 93 return insertFromRange(loc, CharSourceRange::getTokenRange(TokenRange), 94 afterToken, beforePreviousInsertions); 95 } 96 bool insertWrap(StringRef before, SourceRange TokenRange, StringRef after) { 97 return insertWrap(before, CharSourceRange::getTokenRange(TokenRange), after); 98 } 99 bool remove(SourceRange TokenRange) { 100 return remove(CharSourceRange::getTokenRange(TokenRange)); 101 } 102 bool replace(SourceRange TokenRange, StringRef text) { 103 return replace(CharSourceRange::getTokenRange(TokenRange), text); 104 } 105 bool replaceWithInner(SourceRange TokenRange, SourceRange TokenInnerRange) { 106 return replaceWithInner(CharSourceRange::getTokenRange(TokenRange), 107 CharSourceRange::getTokenRange(TokenInnerRange)); 108 } 109 110 typedef SmallVectorImpl<Edit>::const_iterator edit_iterator; 111 edit_iterator edit_begin() const { return CachedEdits.begin(); } 112 edit_iterator edit_end() const { return CachedEdits.end(); } 113 114private: 115 void addInsert(SourceLocation OrigLoc, 116 FileOffset Offs, StringRef text, bool beforePreviousInsertions); 117 void addInsertFromRange(SourceLocation OrigLoc, FileOffset Offs, 118 FileOffset RangeOffs, unsigned RangeLen, 119 bool beforePreviousInsertions); 120 void addRemove(SourceLocation OrigLoc, FileOffset Offs, unsigned Len); 121 122 bool canInsert(SourceLocation loc, FileOffset &Offset); 123 bool canInsertAfterToken(SourceLocation loc, FileOffset &Offset, 124 SourceLocation &AfterLoc); 125 bool canInsertInOffset(SourceLocation OrigLoc, FileOffset Offs); 126 bool canRemoveRange(CharSourceRange range, FileOffset &Offs, unsigned &Len); 127 bool canReplaceText(SourceLocation loc, StringRef text, 128 FileOffset &Offs, unsigned &Len); 129 130 void commitInsert(FileOffset offset, StringRef text, 131 bool beforePreviousInsertions); 132 void commitRemove(FileOffset offset, unsigned length); 133 134 bool isAtStartOfMacroExpansion(SourceLocation loc, 135 SourceLocation *MacroBegin = 0) const; 136 bool isAtEndOfMacroExpansion(SourceLocation loc, 137 SourceLocation *MacroEnd = 0) const; 138 139 StringRef copyString(StringRef str) { 140 char *buf = StrAlloc.Allocate<char>(str.size()); 141 std::memcpy(buf, str.data(), str.size()); 142 return StringRef(buf, str.size()); 143 } 144}; 145 146} 147 148} // end namespace clang 149 150#endif 151