clang API Documentation
00001 //===----- Commit.h - A unit of edits ---------------------------*- C++ -*-===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 00010 #ifndef LLVM_CLANG_EDIT_COMMIT_H 00011 #define LLVM_CLANG_EDIT_COMMIT_H 00012 00013 #include "clang/Edit/FileOffset.h" 00014 #include "llvm/ADT/SmallVector.h" 00015 #include "llvm/ADT/StringRef.h" 00016 #include "llvm/Support/Allocator.h" 00017 00018 namespace clang { 00019 class LangOptions; 00020 class PPConditionalDirectiveRecord; 00021 00022 namespace edit { 00023 class EditedSource; 00024 00025 class Commit { 00026 public: 00027 enum EditKind { 00028 Act_Insert, 00029 Act_InsertFromRange, 00030 Act_Remove 00031 }; 00032 00033 struct Edit { 00034 EditKind Kind; 00035 StringRef Text; 00036 SourceLocation OrigLoc; 00037 FileOffset Offset; 00038 FileOffset InsertFromRangeOffs; 00039 unsigned Length; 00040 bool BeforePrev; 00041 00042 SourceLocation getFileLocation(SourceManager &SM) const; 00043 CharSourceRange getFileRange(SourceManager &SM) const; 00044 CharSourceRange getInsertFromRange(SourceManager &SM) const; 00045 }; 00046 00047 private: 00048 const SourceManager &SourceMgr; 00049 const LangOptions &LangOpts; 00050 const PPConditionalDirectiveRecord *PPRec; 00051 EditedSource *Editor; 00052 00053 bool IsCommitable; 00054 SmallVector<Edit, 8> CachedEdits; 00055 00056 llvm::BumpPtrAllocator StrAlloc; 00057 00058 public: 00059 explicit Commit(EditedSource &Editor); 00060 Commit(const SourceManager &SM, const LangOptions &LangOpts, 00061 const PPConditionalDirectiveRecord *PPRec = nullptr) 00062 : SourceMgr(SM), LangOpts(LangOpts), PPRec(PPRec), Editor(nullptr), 00063 IsCommitable(true) { } 00064 00065 bool isCommitable() const { return IsCommitable; } 00066 00067 bool insert(SourceLocation loc, StringRef text, bool afterToken = false, 00068 bool beforePreviousInsertions = false); 00069 bool insertAfterToken(SourceLocation loc, StringRef text, 00070 bool beforePreviousInsertions = false) { 00071 return insert(loc, text, /*afterToken=*/true, beforePreviousInsertions); 00072 } 00073 bool insertBefore(SourceLocation loc, StringRef text) { 00074 return insert(loc, text, /*afterToken=*/false, 00075 /*beforePreviousInsertions=*/true); 00076 } 00077 bool insertFromRange(SourceLocation loc, CharSourceRange range, 00078 bool afterToken = false, 00079 bool beforePreviousInsertions = false); 00080 bool insertWrap(StringRef before, CharSourceRange range, StringRef after); 00081 00082 bool remove(CharSourceRange range); 00083 00084 bool replace(CharSourceRange range, StringRef text); 00085 bool replaceWithInner(CharSourceRange range, CharSourceRange innerRange); 00086 bool replaceText(SourceLocation loc, StringRef text, 00087 StringRef replacementText); 00088 00089 bool insertFromRange(SourceLocation loc, SourceRange TokenRange, 00090 bool afterToken = false, 00091 bool beforePreviousInsertions = false) { 00092 return insertFromRange(loc, CharSourceRange::getTokenRange(TokenRange), 00093 afterToken, beforePreviousInsertions); 00094 } 00095 bool insertWrap(StringRef before, SourceRange TokenRange, StringRef after) { 00096 return insertWrap(before, CharSourceRange::getTokenRange(TokenRange), after); 00097 } 00098 bool remove(SourceRange TokenRange) { 00099 return remove(CharSourceRange::getTokenRange(TokenRange)); 00100 } 00101 bool replace(SourceRange TokenRange, StringRef text) { 00102 return replace(CharSourceRange::getTokenRange(TokenRange), text); 00103 } 00104 bool replaceWithInner(SourceRange TokenRange, SourceRange TokenInnerRange) { 00105 return replaceWithInner(CharSourceRange::getTokenRange(TokenRange), 00106 CharSourceRange::getTokenRange(TokenInnerRange)); 00107 } 00108 00109 typedef SmallVectorImpl<Edit>::const_iterator edit_iterator; 00110 edit_iterator edit_begin() const { return CachedEdits.begin(); } 00111 edit_iterator edit_end() const { return CachedEdits.end(); } 00112 00113 private: 00114 void addInsert(SourceLocation OrigLoc, 00115 FileOffset Offs, StringRef text, bool beforePreviousInsertions); 00116 void addInsertFromRange(SourceLocation OrigLoc, FileOffset Offs, 00117 FileOffset RangeOffs, unsigned RangeLen, 00118 bool beforePreviousInsertions); 00119 void addRemove(SourceLocation OrigLoc, FileOffset Offs, unsigned Len); 00120 00121 bool canInsert(SourceLocation loc, FileOffset &Offset); 00122 bool canInsertAfterToken(SourceLocation loc, FileOffset &Offset, 00123 SourceLocation &AfterLoc); 00124 bool canInsertInOffset(SourceLocation OrigLoc, FileOffset Offs); 00125 bool canRemoveRange(CharSourceRange range, FileOffset &Offs, unsigned &Len); 00126 bool canReplaceText(SourceLocation loc, StringRef text, 00127 FileOffset &Offs, unsigned &Len); 00128 00129 void commitInsert(FileOffset offset, StringRef text, 00130 bool beforePreviousInsertions); 00131 void commitRemove(FileOffset offset, unsigned length); 00132 00133 bool isAtStartOfMacroExpansion(SourceLocation loc, 00134 SourceLocation *MacroBegin = nullptr) const; 00135 bool isAtEndOfMacroExpansion(SourceLocation loc, 00136 SourceLocation *MacroEnd = nullptr) const; 00137 00138 StringRef copyString(StringRef str) { 00139 char *buf = StrAlloc.Allocate<char>(str.size()); 00140 std::memcpy(buf, str.data(), str.size()); 00141 return StringRef(buf, str.size()); 00142 } 00143 }; 00144 00145 } 00146 00147 } // end namespace clang 00148 00149 #endif