Clang Project

clang_source_code/include/clang/Rewrite/Core/Rewriter.h
1//===- Rewriter.h - Code rewriting interface --------------------*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9//  This file defines the Rewriter class, which is used for code
10//  transformations.
11//
12//===----------------------------------------------------------------------===//
13
14#ifndef LLVM_CLANG_REWRITE_CORE_REWRITER_H
15#define LLVM_CLANG_REWRITE_CORE_REWRITER_H
16
17#include "clang/Basic/LLVM.h"
18#include "clang/Basic/SourceLocation.h"
19#include "clang/Rewrite/Core/RewriteBuffer.h"
20#include "llvm/ADT/StringRef.h"
21#include <map>
22#include <string>
23
24namespace clang {
25
26class LangOptions;
27class SourceManager;
28
29/// Rewriter - This is the main interface to the rewrite buffers.  Its primary
30/// job is to dispatch high-level requests to the low-level RewriteBuffers that
31/// are involved.
32class Rewriter {
33  SourceManager *SourceMgr = nullptr;
34  const LangOptions *LangOpts = nullptr;
35  std::map<FileIDRewriteBufferRewriteBuffers;
36
37public:
38  struct RewriteOptions {
39    /// Given a source range, true to include previous inserts at the
40    /// beginning of the range as part of the range itself (true by default).
41    bool IncludeInsertsAtBeginOfRange = true;
42
43    /// Given a source range, true to include previous inserts at the
44    /// end of the range as part of the range itself (true by default).
45    bool IncludeInsertsAtEndOfRange = true;
46
47    /// If true and removing some text leaves a blank line
48    /// also remove the empty line (false by default).
49    bool RemoveLineIfEmpty = false;
50
51    RewriteOptions() {}
52  };
53
54  using buffer_iterator = std::map<FileIDRewriteBuffer>::iterator;
55  using const_buffer_iterator = std::map<FileIDRewriteBuffer>::const_iterator;
56
57  explicit Rewriter() = default;
58  explicit Rewriter(SourceManager &SMconst LangOptions &LO)
59      : SourceMgr(&SM), LangOpts(&LO) {}
60
61  void setSourceMgr(SourceManager &SMconst LangOptions &LO) {
62    SourceMgr = &SM;
63    LangOpts = &LO;
64  }
65
66  SourceManager &getSourceMgr() const { return *SourceMgr; }
67  const LangOptions &getLangOpts() const { return *LangOpts; }
68
69  /// isRewritable - Return true if this location is a raw file location, which
70  /// is rewritable.  Locations from macros, etc are not rewritable.
71  static bool isRewritable(SourceLocation Loc) {
72    return Loc.isFileID();
73  }
74
75  /// getRangeSize - Return the size in bytes of the specified range if they
76  /// are in the same file.  If not, this returns -1.
77  int getRangeSize(SourceRange Range,
78                   RewriteOptions opts = RewriteOptions()) const;
79  int getRangeSize(const CharSourceRange &Range,
80                   RewriteOptions opts = RewriteOptions()) const;
81
82  /// getRewrittenText - Return the rewritten form of the text in the specified
83  /// range.  If the start or end of the range was unrewritable or if they are
84  /// in different buffers, this returns an empty string.
85  ///
86  /// Note that this method is not particularly efficient.
87  std::string getRewrittenText(SourceRange Rangeconst;
88
89  /// InsertText - Insert the specified string at the specified location in the
90  /// original buffer.  This method returns true (and does nothing) if the input
91  /// location was not rewritable, false otherwise.
92  ///
93  /// \param indentNewLines if true new lines in the string are indented
94  /// using the indentation of the source line in position \p Loc.
95  bool InsertText(SourceLocation LocStringRef Str,
96                  bool InsertAfter = truebool indentNewLines = false);
97
98  /// InsertTextAfter - Insert the specified string at the specified location in
99  ///  the original buffer.  This method returns true (and does nothing) if
100  ///  the input location was not rewritable, false otherwise.  Text is
101  ///  inserted after any other text that has been previously inserted
102  ///  at the some point (the default behavior for InsertText).
103  bool InsertTextAfter(SourceLocation LocStringRef Str) {
104    return InsertText(Loc, Str);
105  }
106
107  /// Insert the specified string after the token in the
108  /// specified location.
109  bool InsertTextAfterToken(SourceLocation LocStringRef Str);
110
111  /// InsertText - Insert the specified string at the specified location in the
112  /// original buffer.  This method returns true (and does nothing) if the input
113  /// location was not rewritable, false otherwise.  Text is
114  /// inserted before any other text that has been previously inserted
115  /// at the some point.
116  bool InsertTextBefore(SourceLocation LocStringRef Str) {
117    return InsertText(Loc, Str, false);
118  }
119
120  /// RemoveText - Remove the specified text region.
121  bool RemoveText(SourceLocation Startunsigned Length,
122                  RewriteOptions opts = RewriteOptions());
123
124  /// Remove the specified text region.
125  bool RemoveText(CharSourceRange range,
126                  RewriteOptions opts = RewriteOptions()) {
127    return RemoveText(range.getBegin(), getRangeSize(rangeopts), opts);
128  }
129
130  /// Remove the specified text region.
131  bool RemoveText(SourceRange rangeRewriteOptions opts = RewriteOptions()) {
132    return RemoveText(range.getBegin(), getRangeSize(rangeopts), opts);
133  }
134
135  /// ReplaceText - This method replaces a range of characters in the input
136  /// buffer with a new string.  This is effectively a combined "remove/insert"
137  /// operation.
138  bool ReplaceText(SourceLocation Startunsigned OrigLength,
139                   StringRef NewStr);
140
141  /// ReplaceText - This method replaces a range of characters in the input
142  /// buffer with a new string.  This is effectively a combined "remove/insert"
143  /// operation.
144  bool ReplaceText(SourceRange rangeStringRef NewStr) {
145    return ReplaceText(range.getBegin(), getRangeSize(range), NewStr);
146  }
147
148  /// ReplaceText - This method replaces a range of characters in the input
149  /// buffer with a new string.  This is effectively a combined "remove/insert"
150  /// operation.
151  bool ReplaceText(SourceRange rangeSourceRange replacementRange);
152
153  /// Increase indentation for the lines between the given source range.
154  /// To determine what the indentation should be, 'parentIndent' is used
155  /// that should be at a source location with an indentation one degree
156  /// lower than the given range.
157  bool IncreaseIndentation(CharSourceRange rangeSourceLocation parentIndent);
158  bool IncreaseIndentation(SourceRange rangeSourceLocation parentIndent) {
159    return IncreaseIndentation(CharSourceRange::getTokenRange(range),
160                               parentIndent);
161  }
162
163  /// getEditBuffer - This is like getRewriteBufferFor, but always returns a
164  /// buffer, and allows you to write on it directly.  This is useful if you
165  /// want efficient low-level access to apis for scribbling on one specific
166  /// FileID's buffer.
167  RewriteBuffer &getEditBuffer(FileID FID);
168
169  /// getRewriteBufferFor - Return the rewrite buffer for the specified FileID.
170  /// If no modification has been made to it, return null.
171  const RewriteBuffer *getRewriteBufferFor(FileID FIDconst {
172    std::map<FileIDRewriteBuffer>::const_iterator I =
173      RewriteBuffers.find(FID);
174    return I == RewriteBuffers.end() ? nullptr : &I->second;
175  }
176
177  // Iterators over rewrite buffers.
178  buffer_iterator buffer_begin() { return RewriteBuffers.begin(); }
179  buffer_iterator buffer_end() { return RewriteBuffers.end(); }
180  const_buffer_iterator buffer_begin() const { return RewriteBuffers.begin(); }
181  const_buffer_iterator buffer_end() const { return RewriteBuffers.end(); }
182
183  /// overwriteChangedFiles - Save all changed files to disk.
184  ///
185  /// Returns true if any files were not saved successfully.
186  /// Outputs diagnostics via the source manager's diagnostic engine
187  /// in case of an error.
188  bool overwriteChangedFiles();
189
190private:
191  unsigned getLocationOffsetAndFileID(SourceLocation LocFileID &FIDconst;
192};
193
194// namespace clang
195
196#endif // LLVM_CLANG_REWRITE_CORE_REWRITER_H
197
clang::Rewriter::SourceMgr
clang::Rewriter::LangOpts
clang::Rewriter::RewriteBuffers
clang::Rewriter::RewriteOptions
clang::Rewriter::RewriteOptions::IncludeInsertsAtBeginOfRange
clang::Rewriter::RewriteOptions::IncludeInsertsAtEndOfRange
clang::Rewriter::RewriteOptions::RemoveLineIfEmpty
clang::Rewriter::setSourceMgr
clang::Rewriter::getSourceMgr
clang::Rewriter::getLangOpts
clang::Rewriter::isRewritable
clang::Rewriter::getRangeSize
clang::Rewriter::getRangeSize
clang::Rewriter::getRewrittenText
clang::Rewriter::InsertText
clang::Rewriter::InsertTextAfter
clang::Rewriter::InsertTextAfterToken
clang::Rewriter::InsertTextBefore
clang::Rewriter::RemoveText
clang::Rewriter::RemoveText
clang::Rewriter::RemoveText
clang::Rewriter::ReplaceText
clang::Rewriter::ReplaceText
clang::Rewriter::ReplaceText
clang::Rewriter::IncreaseIndentation
clang::Rewriter::IncreaseIndentation
clang::Rewriter::getEditBuffer
clang::Rewriter::getRewriteBufferFor
clang::Rewriter::buffer_begin
clang::Rewriter::buffer_end
clang::Rewriter::buffer_begin
clang::Rewriter::buffer_end
clang::Rewriter::overwriteChangedFiles
clang::Rewriter::getLocationOffsetAndFileID