clang API Documentation

Commit.h
Go to the documentation of this file.
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