1234287Sdim//===----- Commit.h - A unit of edits ---------------------------*- C++ -*-===//
2234287Sdim//
3234287Sdim//                     The LLVM Compiler Infrastructure
4234287Sdim//
5234287Sdim// This file is distributed under the University of Illinois Open Source
6234287Sdim// License. See LICENSE.TXT for details.
7234287Sdim//
8234287Sdim//===----------------------------------------------------------------------===//
9234287Sdim
10234287Sdim#ifndef LLVM_CLANG_EDIT_COMMIT_H
11234287Sdim#define LLVM_CLANG_EDIT_COMMIT_H
12234287Sdim
13234287Sdim#include "clang/Edit/FileOffset.h"
14249423Sdim#include "llvm/ADT/SmallVector.h"
15234287Sdim#include "llvm/ADT/StringRef.h"
16234287Sdim
17234287Sdimnamespace clang {
18234287Sdim  class LangOptions;
19249423Sdim  class PPConditionalDirectiveRecord;
20234287Sdim
21234287Sdimnamespace edit {
22234287Sdim  class EditedSource;
23234287Sdim
24234287Sdimclass Commit {
25234287Sdimpublic:
26234287Sdim  enum EditKind {
27234287Sdim    Act_Insert,
28234287Sdim    Act_InsertFromRange,
29234287Sdim    Act_Remove
30234287Sdim  };
31234287Sdim
32234287Sdim  struct Edit {
33234287Sdim    EditKind Kind;
34234287Sdim    StringRef Text;
35234287Sdim    SourceLocation OrigLoc;
36234287Sdim    FileOffset Offset;
37234287Sdim    FileOffset InsertFromRangeOffs;
38234287Sdim    unsigned Length;
39234287Sdim    bool BeforePrev;
40234287Sdim
41234287Sdim    SourceLocation getFileLocation(SourceManager &SM) const;
42234287Sdim    CharSourceRange getFileRange(SourceManager &SM) const;
43234287Sdim    CharSourceRange getInsertFromRange(SourceManager &SM) const;
44234287Sdim  };
45234287Sdim
46234287Sdimprivate:
47234287Sdim  const SourceManager &SourceMgr;
48234287Sdim  const LangOptions &LangOpts;
49249423Sdim  const PPConditionalDirectiveRecord *PPRec;
50234287Sdim  EditedSource *Editor;
51234287Sdim
52234287Sdim  bool IsCommitable;
53234287Sdim  SmallVector<Edit, 8> CachedEdits;
54234287Sdim
55234287Sdimpublic:
56234287Sdim  explicit Commit(EditedSource &Editor);
57234287Sdim  Commit(const SourceManager &SM, const LangOptions &LangOpts,
58249423Sdim         const PPConditionalDirectiveRecord *PPRec = 0)
59234287Sdim    : SourceMgr(SM), LangOpts(LangOpts), PPRec(PPRec), Editor(0),
60234287Sdim      IsCommitable(true) { }
61234287Sdim
62234287Sdim  bool isCommitable() const { return IsCommitable; }
63234287Sdim
64234287Sdim  bool insert(SourceLocation loc, StringRef text, bool afterToken = false,
65234287Sdim              bool beforePreviousInsertions = false);
66234287Sdim  bool insertAfterToken(SourceLocation loc, StringRef text,
67234287Sdim                        bool beforePreviousInsertions = false) {
68234287Sdim    return insert(loc, text, /*afterToken=*/true, beforePreviousInsertions);
69234287Sdim  }
70234287Sdim  bool insertBefore(SourceLocation loc, StringRef text) {
71234287Sdim    return insert(loc, text, /*afterToken=*/false,
72234287Sdim                  /*beforePreviousInsertions=*/true);
73234287Sdim  }
74234287Sdim  bool insertFromRange(SourceLocation loc, CharSourceRange range,
75234287Sdim                       bool afterToken = false,
76234287Sdim                       bool beforePreviousInsertions = false);
77234287Sdim  bool insertWrap(StringRef before, CharSourceRange range, StringRef after);
78234287Sdim
79234287Sdim  bool remove(CharSourceRange range);
80234287Sdim
81234287Sdim  bool replace(CharSourceRange range, StringRef text);
82234287Sdim  bool replaceWithInner(CharSourceRange range, CharSourceRange innerRange);
83234287Sdim  bool replaceText(SourceLocation loc, StringRef text,
84234287Sdim                   StringRef replacementText);
85234287Sdim
86234287Sdim  bool insertFromRange(SourceLocation loc, SourceRange TokenRange,
87234287Sdim                       bool afterToken = false,
88234287Sdim                       bool beforePreviousInsertions = false) {
89234287Sdim    return insertFromRange(loc, CharSourceRange::getTokenRange(TokenRange),
90234287Sdim                           afterToken, beforePreviousInsertions);
91234287Sdim  }
92234287Sdim  bool insertWrap(StringRef before, SourceRange TokenRange, StringRef after) {
93234287Sdim    return insertWrap(before, CharSourceRange::getTokenRange(TokenRange), after);
94234287Sdim  }
95234287Sdim  bool remove(SourceRange TokenRange) {
96234287Sdim    return remove(CharSourceRange::getTokenRange(TokenRange));
97234287Sdim  }
98234287Sdim  bool replace(SourceRange TokenRange, StringRef text) {
99234287Sdim    return replace(CharSourceRange::getTokenRange(TokenRange), text);
100234287Sdim  }
101234287Sdim  bool replaceWithInner(SourceRange TokenRange, SourceRange TokenInnerRange) {
102234287Sdim    return replaceWithInner(CharSourceRange::getTokenRange(TokenRange),
103234287Sdim                            CharSourceRange::getTokenRange(TokenInnerRange));
104234287Sdim  }
105234287Sdim
106234287Sdim  typedef SmallVector<Edit, 8>::const_iterator edit_iterator;
107234287Sdim  edit_iterator edit_begin() const { return CachedEdits.begin(); }
108234287Sdim  edit_iterator edit_end() const { return CachedEdits.end(); }
109234287Sdim
110234287Sdimprivate:
111234287Sdim  void addInsert(SourceLocation OrigLoc,
112234287Sdim                FileOffset Offs, StringRef text, bool beforePreviousInsertions);
113234287Sdim  void addInsertFromRange(SourceLocation OrigLoc, FileOffset Offs,
114234287Sdim                          FileOffset RangeOffs, unsigned RangeLen,
115234287Sdim                          bool beforePreviousInsertions);
116234287Sdim  void addRemove(SourceLocation OrigLoc, FileOffset Offs, unsigned Len);
117234287Sdim
118234287Sdim  bool canInsert(SourceLocation loc, FileOffset &Offset);
119234287Sdim  bool canInsertAfterToken(SourceLocation loc, FileOffset &Offset,
120234287Sdim                           SourceLocation &AfterLoc);
121234287Sdim  bool canInsertInOffset(SourceLocation OrigLoc, FileOffset Offs);
122234287Sdim  bool canRemoveRange(CharSourceRange range, FileOffset &Offs, unsigned &Len);
123234287Sdim  bool canReplaceText(SourceLocation loc, StringRef text,
124234287Sdim                      FileOffset &Offs, unsigned &Len);
125234287Sdim
126234287Sdim  void commitInsert(FileOffset offset, StringRef text,
127234287Sdim                    bool beforePreviousInsertions);
128234287Sdim  void commitRemove(FileOffset offset, unsigned length);
129234287Sdim
130234287Sdim  bool isAtStartOfMacroExpansion(SourceLocation loc,
131234287Sdim                                 SourceLocation *MacroBegin = 0) const;
132234287Sdim  bool isAtEndOfMacroExpansion(SourceLocation loc,
133234287Sdim                               SourceLocation *MacroEnd = 0) const;
134234287Sdim};
135234287Sdim
136234287Sdim}
137234287Sdim
138234287Sdim} // end namespace clang
139234287Sdim
140234287Sdim#endif
141