| //===- Commit.h - A unit of edits -------------------------------*- C++ -*-===// |
| // |
| // The LLVM Compiler Infrastructure |
| // |
| // This file is distributed under the University of Illinois Open Source |
| // License. See LICENSE.TXT for details. |
| // |
| //===----------------------------------------------------------------------===// |
| |
| #ifndef LLVM_CLANG_EDIT_COMMIT_H |
| #define LLVM_CLANG_EDIT_COMMIT_H |
| |
| #include "clang/Basic/LLVM.h" |
| #include "clang/Basic/SourceLocation.h" |
| #include "clang/Edit/FileOffset.h" |
| #include "llvm/ADT/SmallVector.h" |
| #include "llvm/ADT/StringRef.h" |
| #include "llvm/Support/Allocator.h" |
| |
| namespace clang { |
| |
| class LangOptions; |
| class PPConditionalDirectiveRecord; |
| class SourceManager; |
| |
| namespace edit { |
| |
| class EditedSource; |
| |
| class Commit { |
| public: |
| enum EditKind { |
| Act_Insert, |
| Act_InsertFromRange, |
| Act_Remove |
| }; |
| |
| struct Edit { |
| EditKind Kind; |
| StringRef Text; |
| SourceLocation OrigLoc; |
| FileOffset Offset; |
| FileOffset InsertFromRangeOffs; |
| unsigned Length; |
| bool BeforePrev; |
| |
| SourceLocation getFileLocation(SourceManager &SM) const; |
| CharSourceRange getFileRange(SourceManager &SM) const; |
| CharSourceRange getInsertFromRange(SourceManager &SM) const; |
| }; |
| |
| private: |
| const SourceManager &SourceMgr; |
| const LangOptions &LangOpts; |
| const PPConditionalDirectiveRecord *PPRec; |
| EditedSource *Editor = nullptr; |
| |
| bool IsCommitable = true; |
| SmallVector<Edit, 8> CachedEdits; |
| |
| llvm::BumpPtrAllocator StrAlloc; |
| |
| public: |
| explicit Commit(EditedSource &Editor); |
| Commit(const SourceManager &SM, const LangOptions &LangOpts, |
| const PPConditionalDirectiveRecord *PPRec = nullptr) |
| : SourceMgr(SM), LangOpts(LangOpts), PPRec(PPRec) {} |
| |
| bool isCommitable() const { return IsCommitable; } |
| |
| bool insert(SourceLocation loc, StringRef text, bool afterToken = false, |
| bool beforePreviousInsertions = false); |
| |
| bool insertAfterToken(SourceLocation loc, StringRef text, |
| bool beforePreviousInsertions = false) { |
| return insert(loc, text, /*afterToken=*/true, beforePreviousInsertions); |
| } |
| |
| bool insertBefore(SourceLocation loc, StringRef text) { |
| return insert(loc, text, /*afterToken=*/false, |
| /*beforePreviousInsertions=*/true); |
| } |
| |
| bool insertFromRange(SourceLocation loc, CharSourceRange range, |
| bool afterToken = false, |
| bool beforePreviousInsertions = false); |
| bool insertWrap(StringRef before, CharSourceRange range, StringRef after); |
| |
| bool remove(CharSourceRange range); |
| |
| bool replace(CharSourceRange range, StringRef text); |
| bool replaceWithInner(CharSourceRange range, CharSourceRange innerRange); |
| bool replaceText(SourceLocation loc, StringRef text, |
| StringRef replacementText); |
| |
| bool insertFromRange(SourceLocation loc, SourceRange TokenRange, |
| bool afterToken = false, |
| bool beforePreviousInsertions = false) { |
| return insertFromRange(loc, CharSourceRange::getTokenRange(TokenRange), |
| afterToken, beforePreviousInsertions); |
| } |
| |
| bool insertWrap(StringRef before, SourceRange TokenRange, StringRef after) { |
| return insertWrap(before, CharSourceRange::getTokenRange(TokenRange), after); |
| } |
| |
| bool remove(SourceRange TokenRange) { |
| return remove(CharSourceRange::getTokenRange(TokenRange)); |
| } |
| |
| bool replace(SourceRange TokenRange, StringRef text) { |
| return replace(CharSourceRange::getTokenRange(TokenRange), text); |
| } |
| |
| bool replaceWithInner(SourceRange TokenRange, SourceRange TokenInnerRange) { |
| return replaceWithInner(CharSourceRange::getTokenRange(TokenRange), |
| CharSourceRange::getTokenRange(TokenInnerRange)); |
| } |
| |
| using edit_iterator = SmallVectorImpl<Edit>::const_iterator; |
| |
| edit_iterator edit_begin() const { return CachedEdits.begin(); } |
| edit_iterator edit_end() const { return CachedEdits.end(); } |
| |
| private: |
| void addInsert(SourceLocation OrigLoc, |
| FileOffset Offs, StringRef text, bool beforePreviousInsertions); |
| void addInsertFromRange(SourceLocation OrigLoc, FileOffset Offs, |
| FileOffset RangeOffs, unsigned RangeLen, |
| bool beforePreviousInsertions); |
| void addRemove(SourceLocation OrigLoc, FileOffset Offs, unsigned Len); |
| |
| bool canInsert(SourceLocation loc, FileOffset &Offset); |
| bool canInsertAfterToken(SourceLocation loc, FileOffset &Offset, |
| SourceLocation &AfterLoc); |
| bool canInsertInOffset(SourceLocation OrigLoc, FileOffset Offs); |
| bool canRemoveRange(CharSourceRange range, FileOffset &Offs, unsigned &Len); |
| bool canReplaceText(SourceLocation loc, StringRef text, |
| FileOffset &Offs, unsigned &Len); |
| |
| void commitInsert(FileOffset offset, StringRef text, |
| bool beforePreviousInsertions); |
| void commitRemove(FileOffset offset, unsigned length); |
| |
| bool isAtStartOfMacroExpansion(SourceLocation loc, |
| SourceLocation *MacroBegin = nullptr) const; |
| bool isAtEndOfMacroExpansion(SourceLocation loc, |
| SourceLocation *MacroEnd = nullptr) const; |
| }; |
| |
| } // namespace edit |
| |
| } // namespace clang |
| |
| #endif // LLVM_CLANG_EDIT_COMMIT_H |