• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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/StringRef.h"
15 #include "llvm/ADT/SmallVector.h"
16 
17 namespace clang {
18   class LangOptions;
19   class PreprocessingRecord;
20 
21 namespace edit {
22   class EditedSource;
23 
24 class Commit {
25 public:
26   enum EditKind {
27     Act_Insert,
28     Act_InsertFromRange,
29     Act_Remove
30   };
31 
32   struct Edit {
33     EditKind Kind;
34     StringRef Text;
35     SourceLocation OrigLoc;
36     FileOffset Offset;
37     FileOffset InsertFromRangeOffs;
38     unsigned Length;
39     bool BeforePrev;
40 
41     SourceLocation getFileLocation(SourceManager &SM) const;
42     CharSourceRange getFileRange(SourceManager &SM) const;
43     CharSourceRange getInsertFromRange(SourceManager &SM) const;
44   };
45 
46 private:
47   const SourceManager &SourceMgr;
48   const LangOptions &LangOpts;
49   const PreprocessingRecord *PPRec;
50   EditedSource *Editor;
51 
52   bool IsCommitable;
53   SmallVector<Edit, 8> CachedEdits;
54 
55 public:
56   explicit Commit(EditedSource &Editor);
57   Commit(const SourceManager &SM, const LangOptions &LangOpts,
58          const PreprocessingRecord *PPRec = 0)
SourceMgr(SM)59     : SourceMgr(SM), LangOpts(LangOpts), PPRec(PPRec), Editor(0),
60       IsCommitable(true) { }
61 
isCommitable()62   bool isCommitable() const { return IsCommitable; }
63 
64   bool insert(SourceLocation loc, StringRef text, bool afterToken = false,
65               bool beforePreviousInsertions = false);
66   bool insertAfterToken(SourceLocation loc, StringRef text,
67                         bool beforePreviousInsertions = false) {
68     return insert(loc, text, /*afterToken=*/true, beforePreviousInsertions);
69   }
insertBefore(SourceLocation loc,StringRef text)70   bool insertBefore(SourceLocation loc, StringRef text) {
71     return insert(loc, text, /*afterToken=*/false,
72                   /*beforePreviousInsertions=*/true);
73   }
74   bool insertFromRange(SourceLocation loc, CharSourceRange range,
75                        bool afterToken = false,
76                        bool beforePreviousInsertions = false);
77   bool insertWrap(StringRef before, CharSourceRange range, StringRef after);
78 
79   bool remove(CharSourceRange range);
80 
81   bool replace(CharSourceRange range, StringRef text);
82   bool replaceWithInner(CharSourceRange range, CharSourceRange innerRange);
83   bool replaceText(SourceLocation loc, StringRef text,
84                    StringRef replacementText);
85 
86   bool insertFromRange(SourceLocation loc, SourceRange TokenRange,
87                        bool afterToken = false,
88                        bool beforePreviousInsertions = false) {
89     return insertFromRange(loc, CharSourceRange::getTokenRange(TokenRange),
90                            afterToken, beforePreviousInsertions);
91   }
insertWrap(StringRef before,SourceRange TokenRange,StringRef after)92   bool insertWrap(StringRef before, SourceRange TokenRange, StringRef after) {
93     return insertWrap(before, CharSourceRange::getTokenRange(TokenRange), after);
94   }
remove(SourceRange TokenRange)95   bool remove(SourceRange TokenRange) {
96     return remove(CharSourceRange::getTokenRange(TokenRange));
97   }
replace(SourceRange TokenRange,StringRef text)98   bool replace(SourceRange TokenRange, StringRef text) {
99     return replace(CharSourceRange::getTokenRange(TokenRange), text);
100   }
replaceWithInner(SourceRange TokenRange,SourceRange TokenInnerRange)101   bool replaceWithInner(SourceRange TokenRange, SourceRange TokenInnerRange) {
102     return replaceWithInner(CharSourceRange::getTokenRange(TokenRange),
103                             CharSourceRange::getTokenRange(TokenInnerRange));
104   }
105 
106   typedef SmallVector<Edit, 8>::const_iterator edit_iterator;
edit_begin()107   edit_iterator edit_begin() const { return CachedEdits.begin(); }
edit_end()108   edit_iterator edit_end() const { return CachedEdits.end(); }
109 
110 private:
111   void addInsert(SourceLocation OrigLoc,
112                 FileOffset Offs, StringRef text, bool beforePreviousInsertions);
113   void addInsertFromRange(SourceLocation OrigLoc, FileOffset Offs,
114                           FileOffset RangeOffs, unsigned RangeLen,
115                           bool beforePreviousInsertions);
116   void addRemove(SourceLocation OrigLoc, FileOffset Offs, unsigned Len);
117 
118   bool canInsert(SourceLocation loc, FileOffset &Offset);
119   bool canInsertAfterToken(SourceLocation loc, FileOffset &Offset,
120                            SourceLocation &AfterLoc);
121   bool canInsertInOffset(SourceLocation OrigLoc, FileOffset Offs);
122   bool canRemoveRange(CharSourceRange range, FileOffset &Offs, unsigned &Len);
123   bool canReplaceText(SourceLocation loc, StringRef text,
124                       FileOffset &Offs, unsigned &Len);
125 
126   void commitInsert(FileOffset offset, StringRef text,
127                     bool beforePreviousInsertions);
128   void commitRemove(FileOffset offset, unsigned length);
129 
130   bool isAtStartOfMacroExpansion(SourceLocation loc,
131                                  SourceLocation *MacroBegin = 0) const;
132   bool isAtEndOfMacroExpansion(SourceLocation loc,
133                                SourceLocation *MacroEnd = 0) const;
134 };
135 
136 }
137 
138 } // end namespace clang
139 
140 #endif
141