]>
Commit | Line | Data |
---|---|---|
223e47cc LB |
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) | |
59 | : SourceMgr(SM), LangOpts(LangOpts), PPRec(PPRec), Editor(0), | |
60 | IsCommitable(true) { } | |
61 | ||
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 | } | |
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 | } | |
92 | bool insertWrap(StringRef before, SourceRange TokenRange, StringRef after) { | |
93 | return insertWrap(before, CharSourceRange::getTokenRange(TokenRange), after); | |
94 | } | |
95 | bool remove(SourceRange TokenRange) { | |
96 | return remove(CharSourceRange::getTokenRange(TokenRange)); | |
97 | } | |
98 | bool replace(SourceRange TokenRange, StringRef text) { | |
99 | return replace(CharSourceRange::getTokenRange(TokenRange), text); | |
100 | } | |
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; | |
107 | edit_iterator edit_begin() const { return CachedEdits.begin(); } | |
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 |