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