|
|
|||
File indexing completed on 2026-05-10 08:36:59
0001 //===- Rewriter.h - Code rewriting interface --------------------*- C++ -*-===// 0002 // 0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 0004 // See https://llvm.org/LICENSE.txt for license information. 0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 0006 // 0007 //===----------------------------------------------------------------------===// 0008 // 0009 // This file defines the Rewriter class, which is used for code 0010 // transformations. 0011 // 0012 //===----------------------------------------------------------------------===// 0013 0014 #ifndef LLVM_CLANG_REWRITE_CORE_REWRITER_H 0015 #define LLVM_CLANG_REWRITE_CORE_REWRITER_H 0016 0017 #include "clang/Basic/LLVM.h" 0018 #include "clang/Basic/SourceLocation.h" 0019 #include "llvm/ADT/RewriteBuffer.h" 0020 #include "llvm/ADT/StringRef.h" 0021 #include <map> 0022 #include <string> 0023 0024 namespace clang { 0025 0026 class LangOptions; 0027 class SourceManager; 0028 0029 /// Rewriter - This is the main interface to the rewrite buffers. Its primary 0030 /// job is to dispatch high-level requests to the low-level RewriteBuffers that 0031 /// are involved. 0032 class Rewriter { 0033 SourceManager *SourceMgr = nullptr; 0034 const LangOptions *LangOpts = nullptr; 0035 std::map<FileID, llvm::RewriteBuffer> RewriteBuffers; 0036 0037 public: 0038 struct RewriteOptions { 0039 /// Given a source range, true to include previous inserts at the 0040 /// beginning of the range as part of the range itself (true by default). 0041 bool IncludeInsertsAtBeginOfRange = true; 0042 0043 /// Given a source range, true to include previous inserts at the 0044 /// end of the range as part of the range itself (true by default). 0045 bool IncludeInsertsAtEndOfRange = true; 0046 0047 /// If true and removing some text leaves a blank line 0048 /// also remove the empty line (false by default). 0049 /// 0050 /// FIXME: This sometimes corrupts the file's rewrite buffer due to 0051 /// incorrect indexing in the implementation (see the FIXME in 0052 /// llvm::RewriteBuffer::RemoveText). Moreover, it's inefficient because 0053 /// it must scan the buffer from the beginning to find the start of the 0054 /// line. When feasible, it's better for the caller to check for a blank 0055 /// line and then, if found, expand the removal range to include it. 0056 /// Checking for a blank line is easy if, for example, the caller can 0057 /// guarantee this is the first edit of a line. In that case, it can just 0058 /// scan before and after the removal range until the next newline or 0059 /// begin/end of the input. 0060 bool RemoveLineIfEmpty = false; 0061 0062 RewriteOptions() {} 0063 }; 0064 0065 using buffer_iterator = std::map<FileID, llvm::RewriteBuffer>::iterator; 0066 using const_buffer_iterator = 0067 std::map<FileID, llvm::RewriteBuffer>::const_iterator; 0068 0069 explicit Rewriter() = default; 0070 explicit Rewriter(SourceManager &SM, const LangOptions &LO) 0071 : SourceMgr(&SM), LangOpts(&LO) {} 0072 0073 void setSourceMgr(SourceManager &SM, const LangOptions &LO) { 0074 SourceMgr = &SM; 0075 LangOpts = &LO; 0076 } 0077 0078 SourceManager &getSourceMgr() const { return *SourceMgr; } 0079 const LangOptions &getLangOpts() const { return *LangOpts; } 0080 0081 /// isRewritable - Return true if this location is a raw file location, which 0082 /// is rewritable. Locations from macros, etc are not rewritable. 0083 static bool isRewritable(SourceLocation Loc) { 0084 return Loc.isFileID(); 0085 } 0086 0087 /// getRangeSize - Return the size in bytes of the specified range if they 0088 /// are in the same file. If not, this returns -1. 0089 int getRangeSize(SourceRange Range, 0090 RewriteOptions opts = RewriteOptions()) const; 0091 int getRangeSize(const CharSourceRange &Range, 0092 RewriteOptions opts = RewriteOptions()) const; 0093 0094 /// getRewrittenText - Return the rewritten form of the text in the specified 0095 /// range. If the start or end of the range was unrewritable or if they are 0096 /// in different buffers, this returns an empty string. 0097 /// 0098 /// Note that this method is not particularly efficient. 0099 std::string getRewrittenText(CharSourceRange Range) const; 0100 0101 /// getRewrittenText - Return the rewritten form of the text in the specified 0102 /// range. If the start or end of the range was unrewritable or if they are 0103 /// in different buffers, this returns an empty string. 0104 /// 0105 /// Note that this method is not particularly efficient. 0106 std::string getRewrittenText(SourceRange Range) const { 0107 return getRewrittenText(CharSourceRange::getTokenRange(Range)); 0108 } 0109 0110 /// InsertText - Insert the specified string at the specified location in the 0111 /// original buffer. This method returns true (and does nothing) if the input 0112 /// location was not rewritable, false otherwise. 0113 /// 0114 /// \param indentNewLines if true new lines in the string are indented 0115 /// using the indentation of the source line in position \p Loc. 0116 bool InsertText(SourceLocation Loc, StringRef Str, 0117 bool InsertAfter = true, bool indentNewLines = false); 0118 0119 /// InsertTextAfter - Insert the specified string at the specified location in 0120 /// the original buffer. This method returns true (and does nothing) if 0121 /// the input location was not rewritable, false otherwise. Text is 0122 /// inserted after any other text that has been previously inserted 0123 /// at the some point (the default behavior for InsertText). 0124 bool InsertTextAfter(SourceLocation Loc, StringRef Str) { 0125 return InsertText(Loc, Str); 0126 } 0127 0128 /// Insert the specified string after the token in the 0129 /// specified location. 0130 bool InsertTextAfterToken(SourceLocation Loc, StringRef Str); 0131 0132 /// InsertText - Insert the specified string at the specified location in the 0133 /// original buffer. This method returns true (and does nothing) if the input 0134 /// location was not rewritable, false otherwise. Text is 0135 /// inserted before any other text that has been previously inserted 0136 /// at the some point. 0137 bool InsertTextBefore(SourceLocation Loc, StringRef Str) { 0138 return InsertText(Loc, Str, false); 0139 } 0140 0141 /// RemoveText - Remove the specified text region. 0142 bool RemoveText(SourceLocation Start, unsigned Length, 0143 RewriteOptions opts = RewriteOptions()); 0144 0145 /// Remove the specified text region. 0146 bool RemoveText(CharSourceRange range, 0147 RewriteOptions opts = RewriteOptions()) { 0148 return RemoveText(range.getBegin(), getRangeSize(range, opts), opts); 0149 } 0150 0151 /// Remove the specified text region. 0152 bool RemoveText(SourceRange range, RewriteOptions opts = RewriteOptions()) { 0153 return RemoveText(range.getBegin(), getRangeSize(range, opts), opts); 0154 } 0155 0156 /// ReplaceText - This method replaces a range of characters in the input 0157 /// buffer with a new string. This is effectively a combined "remove/insert" 0158 /// operation. 0159 bool ReplaceText(SourceLocation Start, unsigned OrigLength, 0160 StringRef NewStr); 0161 0162 /// ReplaceText - This method replaces a range of characters in the input 0163 /// buffer with a new string. This is effectively a combined "remove/insert" 0164 /// operation. 0165 bool ReplaceText(CharSourceRange range, StringRef NewStr) { 0166 return ReplaceText(range.getBegin(), getRangeSize(range), NewStr); 0167 } 0168 0169 /// ReplaceText - This method replaces a range of characters in the input 0170 /// buffer with a new string. This is effectively a combined "remove/insert" 0171 /// operation. 0172 bool ReplaceText(SourceRange range, StringRef NewStr) { 0173 return ReplaceText(range.getBegin(), getRangeSize(range), NewStr); 0174 } 0175 0176 /// ReplaceText - This method replaces a range of characters in the input 0177 /// buffer with a new string. This is effectively a combined "remove/insert" 0178 /// operation. 0179 bool ReplaceText(SourceRange range, SourceRange replacementRange); 0180 0181 /// Increase indentation for the lines between the given source range. 0182 /// To determine what the indentation should be, 'parentIndent' is used 0183 /// that should be at a source location with an indentation one degree 0184 /// lower than the given range. 0185 bool IncreaseIndentation(CharSourceRange range, SourceLocation parentIndent); 0186 bool IncreaseIndentation(SourceRange range, SourceLocation parentIndent) { 0187 return IncreaseIndentation(CharSourceRange::getTokenRange(range), 0188 parentIndent); 0189 } 0190 0191 /// getEditBuffer - This is like getRewriteBufferFor, but always returns a 0192 /// buffer, and allows you to write on it directly. This is useful if you 0193 /// want efficient low-level access to apis for scribbling on one specific 0194 /// FileID's buffer. 0195 llvm::RewriteBuffer &getEditBuffer(FileID FID); 0196 0197 /// getRewriteBufferFor - Return the rewrite buffer for the specified FileID. 0198 /// If no modification has been made to it, return null. 0199 const llvm::RewriteBuffer *getRewriteBufferFor(FileID FID) const { 0200 std::map<FileID, llvm::RewriteBuffer>::const_iterator I = 0201 RewriteBuffers.find(FID); 0202 return I == RewriteBuffers.end() ? nullptr : &I->second; 0203 } 0204 0205 // Iterators over rewrite buffers. 0206 buffer_iterator buffer_begin() { return RewriteBuffers.begin(); } 0207 buffer_iterator buffer_end() { return RewriteBuffers.end(); } 0208 const_buffer_iterator buffer_begin() const { return RewriteBuffers.begin(); } 0209 const_buffer_iterator buffer_end() const { return RewriteBuffers.end(); } 0210 0211 /// overwriteChangedFiles - Save all changed files to disk. 0212 /// 0213 /// Returns true if any files were not saved successfully. 0214 /// Outputs diagnostics via the source manager's diagnostic engine 0215 /// in case of an error. 0216 bool overwriteChangedFiles(); 0217 0218 private: 0219 unsigned getLocationOffsetAndFileID(SourceLocation Loc, FileID &FID) const; 0220 }; 0221 0222 } // namespace clang 0223 0224 #endif // LLVM_CLANG_REWRITE_CORE_REWRITER_H
| [ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
|
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |
|