|
|
|||
File indexing completed on 2026-05-10 08:37:11
0001 //===--- AtomicChange.h - AtomicChange class --------------------*- 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 AtomicChange which is used to create a set of source 0010 // changes, e.g. replacements and header insertions. 0011 // 0012 //===----------------------------------------------------------------------===// 0013 0014 #ifndef LLVM_CLANG_TOOLING_REFACTORING_ATOMICCHANGE_H 0015 #define LLVM_CLANG_TOOLING_REFACTORING_ATOMICCHANGE_H 0016 0017 #include "clang/Basic/SourceManager.h" 0018 #include "clang/Format/Format.h" 0019 #include "clang/Tooling/Core/Replacement.h" 0020 #include "llvm/ADT/Any.h" 0021 #include "llvm/ADT/StringRef.h" 0022 #include "llvm/Support/Error.h" 0023 0024 namespace clang { 0025 namespace tooling { 0026 0027 /// An atomic change is used to create and group a set of source edits, 0028 /// e.g. replacements or header insertions. Edits in an AtomicChange should be 0029 /// related, e.g. replacements for the same type reference and the corresponding 0030 /// header insertion/deletion. 0031 /// 0032 /// An AtomicChange is uniquely identified by a key and will either be fully 0033 /// applied or not applied at all. 0034 /// 0035 /// Calling setError on an AtomicChange stores the error message and marks it as 0036 /// bad, i.e. none of its source edits will be applied. 0037 class AtomicChange { 0038 public: 0039 /// Creates an atomic change around \p KeyPosition with the key being a 0040 /// concatenation of the file name and the offset of \p KeyPosition. 0041 /// \p KeyPosition should be the location of the key syntactical element that 0042 /// is being changed, e.g. the call to a refactored method. 0043 AtomicChange(const SourceManager &SM, SourceLocation KeyPosition); 0044 0045 AtomicChange(const SourceManager &SM, SourceLocation KeyPosition, 0046 llvm::Any Metadata); 0047 0048 /// Creates an atomic change for \p FilePath with a customized key. 0049 AtomicChange(llvm::StringRef FilePath, llvm::StringRef Key) 0050 : Key(Key), FilePath(FilePath) {} 0051 0052 AtomicChange(AtomicChange &&) = default; 0053 AtomicChange(const AtomicChange &) = default; 0054 0055 AtomicChange &operator=(AtomicChange &&) = default; 0056 AtomicChange &operator=(const AtomicChange &) = default; 0057 0058 bool operator==(const AtomicChange &Other) const; 0059 0060 /// Returns the atomic change as a YAML string. 0061 std::string toYAMLString(); 0062 0063 /// Converts a YAML-encoded automic change to AtomicChange. 0064 static AtomicChange convertFromYAML(llvm::StringRef YAMLContent); 0065 0066 /// Returns the key of this change, which is a concatenation of the 0067 /// file name and offset of the key position. 0068 const std::string &getKey() const { return Key; } 0069 0070 /// Returns the path of the file containing this atomic change. 0071 const std::string &getFilePath() const { return FilePath; } 0072 0073 /// If this change could not be created successfully, e.g. because of 0074 /// conflicts among replacements, use this to set an error description. 0075 /// Thereby, places that cannot be fixed automatically can be gathered when 0076 /// applying changes. 0077 void setError(llvm::StringRef Error) { this->Error = std::string(Error); } 0078 0079 /// Returns whether an error has been set on this list. 0080 bool hasError() const { return !Error.empty(); } 0081 0082 /// Returns the error message or an empty string if it does not exist. 0083 const std::string &getError() const { return Error; } 0084 0085 /// Adds a replacement that replaces the given Range with 0086 /// ReplacementText. 0087 /// \returns An llvm::Error carrying ReplacementError on error. 0088 llvm::Error replace(const SourceManager &SM, const CharSourceRange &Range, 0089 llvm::StringRef ReplacementText); 0090 0091 /// Adds a replacement that replaces range [Loc, Loc+Length) with 0092 /// \p Text. 0093 /// \returns An llvm::Error carrying ReplacementError on error. 0094 llvm::Error replace(const SourceManager &SM, SourceLocation Loc, 0095 unsigned Length, llvm::StringRef Text); 0096 0097 /// Adds a replacement that inserts \p Text at \p Loc. If this 0098 /// insertion conflicts with an existing insertion (at the same position), 0099 /// this will be inserted before/after the existing insertion depending on 0100 /// \p InsertAfter. Users should use `replace` with `Length=0` instead if they 0101 /// do not want conflict resolving by default. If the conflicting replacement 0102 /// is not an insertion, an error is returned. 0103 /// 0104 /// \returns An llvm::Error carrying ReplacementError on error. 0105 llvm::Error insert(const SourceManager &SM, SourceLocation Loc, 0106 llvm::StringRef Text, bool InsertAfter = true); 0107 0108 /// Adds a header into the file that contains the key position. 0109 /// Header can be in angle brackets or double quotation marks. By default 0110 /// (header is not quoted), header will be surrounded with double quotes. 0111 void addHeader(llvm::StringRef Header); 0112 0113 /// Removes a header from the file that contains the key position. 0114 void removeHeader(llvm::StringRef Header); 0115 0116 /// Returns a const reference to existing replacements. 0117 const Replacements &getReplacements() const { return Replaces; } 0118 0119 Replacements &getReplacements() { return Replaces; } 0120 0121 llvm::ArrayRef<std::string> getInsertedHeaders() const { 0122 return InsertedHeaders; 0123 } 0124 0125 llvm::ArrayRef<std::string> getRemovedHeaders() const { 0126 return RemovedHeaders; 0127 } 0128 0129 const llvm::Any &getMetadata() const { return Metadata; } 0130 0131 private: 0132 AtomicChange() {} 0133 0134 AtomicChange(std::string Key, std::string FilePath, std::string Error, 0135 std::vector<std::string> InsertedHeaders, 0136 std::vector<std::string> RemovedHeaders, 0137 clang::tooling::Replacements Replaces); 0138 0139 // This uniquely identifies an AtomicChange. 0140 std::string Key; 0141 std::string FilePath; 0142 std::string Error; 0143 std::vector<std::string> InsertedHeaders; 0144 std::vector<std::string> RemovedHeaders; 0145 tooling::Replacements Replaces; 0146 0147 // This field stores metadata which is ignored for the purposes of applying 0148 // edits to source, but may be useful for other consumers of AtomicChanges. In 0149 // particular, consumers can use this to direct how they want to consume each 0150 // edit. 0151 llvm::Any Metadata; 0152 }; 0153 0154 using AtomicChanges = std::vector<AtomicChange>; 0155 0156 // Defines specs for applying changes. 0157 struct ApplyChangesSpec { 0158 // If true, cleans up redundant/erroneous code around changed code with 0159 // clang-format's cleanup functionality, e.g. redundant commas around deleted 0160 // parameter or empty namespaces introduced by deletions. 0161 bool Cleanup = true; 0162 0163 format::FormatStyle Style = format::getNoStyle(); 0164 0165 // Options for selectively formatting changes with clang-format: 0166 // kAll: Format all changed lines. 0167 // kNone: Don't format anything. 0168 // kViolations: Format lines exceeding the `ColumnLimit` in `Style`. 0169 enum FormatOption { kAll, kNone, kViolations }; 0170 0171 FormatOption Format = kNone; 0172 }; 0173 0174 /// Applies all AtomicChanges in \p Changes to the \p Code. 0175 /// 0176 /// This completely ignores the file path in each change and replaces them with 0177 /// \p FilePath, i.e. callers are responsible for ensuring all changes are for 0178 /// the same file. 0179 /// 0180 /// \returns The changed code if all changes are applied successfully; 0181 /// otherwise, an llvm::Error carrying llvm::StringError is returned (the Error 0182 /// message can be converted to string with `llvm::toString()` and the 0183 /// error_code should be ignored). 0184 llvm::Expected<std::string> 0185 applyAtomicChanges(llvm::StringRef FilePath, llvm::StringRef Code, 0186 llvm::ArrayRef<AtomicChange> Changes, 0187 const ApplyChangesSpec &Spec); 0188 0189 } // end namespace tooling 0190 } // end namespace clang 0191 0192 #endif // LLVM_CLANG_TOOLING_REFACTORING_ATOMICCHANGE_H
| [ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
|
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |
|