1234287Sdim//===----- Commit.h - A unit of edits ---------------------------*- C++ -*-===// 2234287Sdim// 3234287Sdim// The LLVM Compiler Infrastructure 4234287Sdim// 5234287Sdim// This file is distributed under the University of Illinois Open Source 6234287Sdim// License. See LICENSE.TXT for details. 7234287Sdim// 8234287Sdim//===----------------------------------------------------------------------===// 9234287Sdim 10234287Sdim#ifndef LLVM_CLANG_EDIT_COMMIT_H 11234287Sdim#define LLVM_CLANG_EDIT_COMMIT_H 12234287Sdim 13234287Sdim#include "clang/Edit/FileOffset.h" 14252723Sdim#include "llvm/ADT/SmallVector.h" 15234287Sdim#include "llvm/ADT/StringRef.h" 16263509Sdim#include "llvm/Support/Allocator.h" 17234287Sdim 18234287Sdimnamespace clang { 19234287Sdim class LangOptions; 20252723Sdim class PPConditionalDirectiveRecord; 21234287Sdim 22234287Sdimnamespace edit { 23234287Sdim class EditedSource; 24234287Sdim 25234287Sdimclass Commit { 26234287Sdimpublic: 27234287Sdim enum EditKind { 28234287Sdim Act_Insert, 29234287Sdim Act_InsertFromRange, 30234287Sdim Act_Remove 31234287Sdim }; 32234287Sdim 33234287Sdim struct Edit { 34234287Sdim EditKind Kind; 35234287Sdim StringRef Text; 36234287Sdim SourceLocation OrigLoc; 37234287Sdim FileOffset Offset; 38234287Sdim FileOffset InsertFromRangeOffs; 39234287Sdim unsigned Length; 40234287Sdim bool BeforePrev; 41234287Sdim 42234287Sdim SourceLocation getFileLocation(SourceManager &SM) const; 43234287Sdim CharSourceRange getFileRange(SourceManager &SM) const; 44234287Sdim CharSourceRange getInsertFromRange(SourceManager &SM) const; 45234287Sdim }; 46234287Sdim 47234287Sdimprivate: 48234287Sdim const SourceManager &SourceMgr; 49234287Sdim const LangOptions &LangOpts; 50252723Sdim const PPConditionalDirectiveRecord *PPRec; 51234287Sdim EditedSource *Editor; 52263509Sdim 53263509Sdim const bool ForceCommitInSystemHeader; 54234287Sdim bool IsCommitable; 55234287Sdim SmallVector<Edit, 8> CachedEdits; 56263509Sdim 57263509Sdim llvm::BumpPtrAllocator StrAlloc; 58234287Sdim 59234287Sdimpublic: 60234287Sdim explicit Commit(EditedSource &Editor); 61234287Sdim Commit(const SourceManager &SM, const LangOptions &LangOpts, 62252723Sdim const PPConditionalDirectiveRecord *PPRec = 0) 63234287Sdim : SourceMgr(SM), LangOpts(LangOpts), PPRec(PPRec), Editor(0), 64263509Sdim ForceCommitInSystemHeader(true), IsCommitable(true) { } 65234287Sdim 66234287Sdim bool isCommitable() const { return IsCommitable; } 67234287Sdim 68234287Sdim bool insert(SourceLocation loc, StringRef text, bool afterToken = false, 69234287Sdim bool beforePreviousInsertions = false); 70234287Sdim bool insertAfterToken(SourceLocation loc, StringRef text, 71234287Sdim bool beforePreviousInsertions = false) { 72234287Sdim return insert(loc, text, /*afterToken=*/true, beforePreviousInsertions); 73234287Sdim } 74234287Sdim bool insertBefore(SourceLocation loc, StringRef text) { 75234287Sdim return insert(loc, text, /*afterToken=*/false, 76234287Sdim /*beforePreviousInsertions=*/true); 77234287Sdim } 78234287Sdim bool insertFromRange(SourceLocation loc, CharSourceRange range, 79234287Sdim bool afterToken = false, 80234287Sdim bool beforePreviousInsertions = false); 81234287Sdim bool insertWrap(StringRef before, CharSourceRange range, StringRef after); 82234287Sdim 83234287Sdim bool remove(CharSourceRange range); 84234287Sdim 85234287Sdim bool replace(CharSourceRange range, StringRef text); 86234287Sdim bool replaceWithInner(CharSourceRange range, CharSourceRange innerRange); 87234287Sdim bool replaceText(SourceLocation loc, StringRef text, 88234287Sdim StringRef replacementText); 89234287Sdim 90234287Sdim bool insertFromRange(SourceLocation loc, SourceRange TokenRange, 91234287Sdim bool afterToken = false, 92234287Sdim bool beforePreviousInsertions = false) { 93234287Sdim return insertFromRange(loc, CharSourceRange::getTokenRange(TokenRange), 94234287Sdim afterToken, beforePreviousInsertions); 95234287Sdim } 96234287Sdim bool insertWrap(StringRef before, SourceRange TokenRange, StringRef after) { 97234287Sdim return insertWrap(before, CharSourceRange::getTokenRange(TokenRange), after); 98234287Sdim } 99234287Sdim bool remove(SourceRange TokenRange) { 100234287Sdim return remove(CharSourceRange::getTokenRange(TokenRange)); 101234287Sdim } 102234287Sdim bool replace(SourceRange TokenRange, StringRef text) { 103234287Sdim return replace(CharSourceRange::getTokenRange(TokenRange), text); 104234287Sdim } 105234287Sdim bool replaceWithInner(SourceRange TokenRange, SourceRange TokenInnerRange) { 106234287Sdim return replaceWithInner(CharSourceRange::getTokenRange(TokenRange), 107234287Sdim CharSourceRange::getTokenRange(TokenInnerRange)); 108234287Sdim } 109234287Sdim 110263509Sdim typedef SmallVectorImpl<Edit>::const_iterator edit_iterator; 111234287Sdim edit_iterator edit_begin() const { return CachedEdits.begin(); } 112234287Sdim edit_iterator edit_end() const { return CachedEdits.end(); } 113234287Sdim 114234287Sdimprivate: 115234287Sdim void addInsert(SourceLocation OrigLoc, 116234287Sdim FileOffset Offs, StringRef text, bool beforePreviousInsertions); 117234287Sdim void addInsertFromRange(SourceLocation OrigLoc, FileOffset Offs, 118234287Sdim FileOffset RangeOffs, unsigned RangeLen, 119234287Sdim bool beforePreviousInsertions); 120234287Sdim void addRemove(SourceLocation OrigLoc, FileOffset Offs, unsigned Len); 121234287Sdim 122234287Sdim bool canInsert(SourceLocation loc, FileOffset &Offset); 123234287Sdim bool canInsertAfterToken(SourceLocation loc, FileOffset &Offset, 124234287Sdim SourceLocation &AfterLoc); 125234287Sdim bool canInsertInOffset(SourceLocation OrigLoc, FileOffset Offs); 126234287Sdim bool canRemoveRange(CharSourceRange range, FileOffset &Offs, unsigned &Len); 127234287Sdim bool canReplaceText(SourceLocation loc, StringRef text, 128234287Sdim FileOffset &Offs, unsigned &Len); 129234287Sdim 130234287Sdim void commitInsert(FileOffset offset, StringRef text, 131234287Sdim bool beforePreviousInsertions); 132234287Sdim void commitRemove(FileOffset offset, unsigned length); 133234287Sdim 134234287Sdim bool isAtStartOfMacroExpansion(SourceLocation loc, 135234287Sdim SourceLocation *MacroBegin = 0) const; 136234287Sdim bool isAtEndOfMacroExpansion(SourceLocation loc, 137234287Sdim SourceLocation *MacroEnd = 0) const; 138263509Sdim 139263509Sdim StringRef copyString(StringRef str) { 140263509Sdim char *buf = StrAlloc.Allocate<char>(str.size()); 141263509Sdim std::memcpy(buf, str.data(), str.size()); 142263509Sdim return StringRef(buf, str.size()); 143263509Sdim } 144234287Sdim}; 145234287Sdim 146234287Sdim} 147234287Sdim 148234287Sdim} // end namespace clang 149234287Sdim 150234287Sdim#endif 151