clang  14.0.0git
AtomicChange.h
Go to the documentation of this file.
1 //===--- AtomicChange.h - AtomicChange class --------------------*- 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 AtomicChange which is used to create a set of source
10 // changes, e.g. replacements and header insertions.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #ifndef LLVM_CLANG_TOOLING_REFACTOR_ATOMICCHANGE_H
15 #define LLVM_CLANG_TOOLING_REFACTOR_ATOMICCHANGE_H
16 
18 #include "clang/Format/Format.h"
20 #include "llvm/ADT/Any.h"
21 #include "llvm/ADT/StringRef.h"
22 #include "llvm/Support/Error.h"
23 
24 namespace clang {
25 namespace tooling {
26 
27 /// An atomic change is used to create and group a set of source edits,
28 /// e.g. replacements or header insertions. Edits in an AtomicChange should be
29 /// related, e.g. replacements for the same type reference and the corresponding
30 /// header insertion/deletion.
31 ///
32 /// An AtomicChange is uniquely identified by a key and will either be fully
33 /// applied or not applied at all.
34 ///
35 /// Calling setError on an AtomicChange stores the error message and marks it as
36 /// bad, i.e. none of its source edits will be applied.
37 class AtomicChange {
38 public:
39  /// Creates an atomic change around \p KeyPosition with the key being a
40  /// concatenation of the file name and the offset of \p KeyPosition.
41  /// \p KeyPosition should be the location of the key syntactical element that
42  /// is being changed, e.g. the call to a refactored method.
43  AtomicChange(const SourceManager &SM, SourceLocation KeyPosition);
44 
45  AtomicChange(const SourceManager &SM, SourceLocation KeyPosition,
46  llvm::Any Metadata);
47 
48  /// Creates an atomic change for \p FilePath with a customized key.
49  AtomicChange(llvm::StringRef FilePath, llvm::StringRef Key)
50  : Key(Key), FilePath(FilePath) {}
51 
52  AtomicChange(AtomicChange &&) = default;
53  AtomicChange(const AtomicChange &) = default;
54 
55  AtomicChange &operator=(AtomicChange &&) = default;
56  AtomicChange &operator=(const AtomicChange &) = default;
57 
58  bool operator==(const AtomicChange &Other) const;
59 
60  /// Returns the atomic change as a YAML string.
62 
63  /// Converts a YAML-encoded automic change to AtomicChange.
64  static AtomicChange convertFromYAML(llvm::StringRef YAMLContent);
65 
66  /// Returns the key of this change, which is a concatenation of the
67  /// file name and offset of the key position.
68  const std::string &getKey() const { return Key; }
69 
70  /// Returns the path of the file containing this atomic change.
71  const std::string &getFilePath() const { return FilePath; }
72 
73  /// If this change could not be created successfully, e.g. because of
74  /// conflicts among replacements, use this to set an error description.
75  /// Thereby, places that cannot be fixed automatically can be gathered when
76  /// applying changes.
77  void setError(llvm::StringRef Error) { this->Error = std::string(Error); }
78 
79  /// Returns whether an error has been set on this list.
80  bool hasError() const { return !Error.empty(); }
81 
82  /// Returns the error message or an empty string if it does not exist.
83  const std::string &getError() const { return Error; }
84 
85  /// Adds a replacement that replaces the given Range with
86  /// ReplacementText.
87  /// \returns An llvm::Error carrying ReplacementError on error.
88  llvm::Error replace(const SourceManager &SM, const CharSourceRange &Range,
89  llvm::StringRef ReplacementText);
90 
91  /// Adds a replacement that replaces range [Loc, Loc+Length) with
92  /// \p Text.
93  /// \returns An llvm::Error carrying ReplacementError on error.
94  llvm::Error replace(const SourceManager &SM, SourceLocation Loc,
95  unsigned Length, llvm::StringRef Text);
96 
97  /// Adds a replacement that inserts \p Text at \p Loc. If this
98  /// insertion conflicts with an existing insertion (at the same position),
99  /// this will be inserted before/after the existing insertion depending on
100  /// \p InsertAfter. Users should use `replace` with `Length=0` instead if they
101  /// do not want conflict resolving by default. If the conflicting replacement
102  /// is not an insertion, an error is returned.
103  ///
104  /// \returns An llvm::Error carrying ReplacementError on error.
105  llvm::Error insert(const SourceManager &SM, SourceLocation Loc,
106  llvm::StringRef Text, bool InsertAfter = true);
107 
108  /// Adds a header into the file that contains the key position.
109  /// Header can be in angle brackets or double quotation marks. By default
110  /// (header is not quoted), header will be surrounded with double quotes.
111  void addHeader(llvm::StringRef Header);
112 
113  /// Removes a header from the file that contains the key position.
114  void removeHeader(llvm::StringRef Header);
115 
116  /// Returns a const reference to existing replacements.
117  const Replacements &getReplacements() const { return Replaces; }
118 
120  return InsertedHeaders;
121  }
122 
124  return RemovedHeaders;
125  }
126 
127  const llvm::Any &getMetadata() const { return Metadata; }
128 
129 private:
130  AtomicChange() {}
131 
132  AtomicChange(std::string Key, std::string FilePath, std::string Error,
133  std::vector<std::string> InsertedHeaders,
134  std::vector<std::string> RemovedHeaders,
136 
137  // This uniquely identifies an AtomicChange.
138  std::string Key;
139  std::string FilePath;
140  std::string Error;
141  std::vector<std::string> InsertedHeaders;
142  std::vector<std::string> RemovedHeaders;
143  tooling::Replacements Replaces;
144 
145  // This field stores metadata which is ignored for the purposes of applying
146  // edits to source, but may be useful for other consumers of AtomicChanges. In
147  // particular, consumers can use this to direct how they want to consume each
148  // edit.
149  llvm::Any Metadata;
150 };
151 
152 using AtomicChanges = std::vector<AtomicChange>;
153 
154 // Defines specs for applying changes.
156  // If true, cleans up redundant/erroneous code around changed code with
157  // clang-format's cleanup functionality, e.g. redundant commas around deleted
158  // parameter or empty namespaces introduced by deletions.
159  bool Cleanup = true;
160 
162 
163  // Options for selectively formatting changes with clang-format:
164  // kAll: Format all changed lines.
165  // kNone: Don't format anything.
166  // kViolations: Format lines exceeding the `ColumnLimit` in `Style`.
168 
170 };
171 
172 /// Applies all AtomicChanges in \p Changes to the \p Code.
173 ///
174 /// This completely ignores the file path in each change and replaces them with
175 /// \p FilePath, i.e. callers are responsible for ensuring all changes are for
176 /// the same file.
177 ///
178 /// \returns The changed code if all changes are applied successfully;
179 /// otherwise, an llvm::Error carrying llvm::StringError is returned (the Error
180 /// message can be converted to string with `llvm::toString()` and the
181 /// error_code should be ignored).
183 applyAtomicChanges(llvm::StringRef FilePath, llvm::StringRef Code,
185  const ApplyChangesSpec &Spec);
186 
187 } // end namespace tooling
188 } // end namespace clang
189 
190 #endif // LLVM_CLANG_TOOLING_REFACTOR_ATOMICCHANGE_H
clang::tooling::AtomicChange::hasError
bool hasError() const
Returns whether an error has been set on this list.
Definition: AtomicChange.h:80
Error
llvm::Error Error
Definition: ByteCodeEmitter.cpp:20
string
string(SUBSTRING ${CMAKE_CURRENT_BINARY_DIR} 0 ${PATH_LIB_START} PATH_HEAD) string(SUBSTRING $
Definition: CMakeLists.txt:22
clang::tooling::AtomicChange::getError
const std::string & getError() const
Returns the error message or an empty string if it does not exist.
Definition: AtomicChange.h:83
clang::SourceLocation
Encodes a location in the source.
Definition: SourceLocation.h:88
clang::tooling::ApplyChangesSpec
Definition: AtomicChange.h:155
clang::tooling::AtomicChange::removeHeader
void removeHeader(llvm::StringRef Header)
Removes a header from the file that contains the key position.
Definition: AtomicChange.cpp:296
clang::tooling::Range
A source range independent of the SourceManager.
Definition: Replacement.h:44
clang::tooling::Replacements
Maintains a set of replacements that are conflict-free.
Definition: Replacement.h:209
clang::tooling::AtomicChange::replace
llvm::Error replace(const SourceManager &SM, const CharSourceRange &Range, llvm::StringRef ReplacementText)
Adds a replacement that replaces the given Range with ReplacementText.
Definition: AtomicChange.cpp:258
clang::tooling::AtomicChange
An atomic change is used to create and group a set of source edits, e.g.
Definition: AtomicChange.h:37
clang::format::FormatStyle
The FormatStyle is used to configure the formatting to follow specific guidelines.
Definition: Format.h:59
SourceManager.h
llvm::Expected
Definition: LLVM.h:41
Format.h
clang::SourceManager
This class handles loading and caching of source files into memory.
Definition: SourceManager.h:626
clang::tooling::AtomicChange::getKey
const std::string & getKey() const
Returns the key of this change, which is a concatenation of the file name and offset of the key posit...
Definition: AtomicChange.h:68
clang::tooling::AtomicChange::getInsertedHeaders
llvm::ArrayRef< std::string > getInsertedHeaders() const
Definition: AtomicChange.h:119
clang::tooling::AtomicChanges
std::vector< AtomicChange > AtomicChanges
Definition: AtomicChange.h:152
clang::tooling::AtomicChange::getRemovedHeaders
llvm::ArrayRef< std::string > getRemovedHeaders() const
Definition: AtomicChange.h:123
clang::tooling::AtomicChange::getMetadata
const llvm::Any & getMetadata() const
Definition: AtomicChange.h:127
clang::tooling::AtomicChange::addHeader
void addHeader(llvm::StringRef Header)
Adds a header into the file that contains the key position.
Definition: AtomicChange.cpp:292
clang::tooling::AtomicChange::operator=
AtomicChange & operator=(AtomicChange &&)=default
clang::tooling::ApplyChangesSpec::Cleanup
bool Cleanup
Definition: AtomicChange.h:159
clang::tooling::AtomicChange::toYAMLString
std::string toYAMLString()
Returns the atomic change as a YAML string.
Definition: AtomicChange.cpp:232
clang::tooling::ApplyChangesSpec::kViolations
@ kViolations
Definition: AtomicChange.h:167
clang::tooling::ApplyChangesSpec::FormatOption
FormatOption
Definition: AtomicChange.h:167
clang::tooling::AtomicChange::getFilePath
const std::string & getFilePath() const
Returns the path of the file containing this atomic change.
Definition: AtomicChange.h:71
clang::tooling::AtomicChange::getReplacements
const Replacements & getReplacements() const
Returns a const reference to existing replacements.
Definition: AtomicChange.h:117
Replacement.h
llvm::ArrayRef< std::string >
clang::CharSourceRange
Represents a character-granular source range.
Definition: SourceLocation.h:255
clang::tooling::AtomicChange::AtomicChange
AtomicChange(llvm::StringRef FilePath, llvm::StringRef Key)
Creates an atomic change for FilePath with a customized key.
Definition: AtomicChange.h:49
clang::tooling::AtomicChange::setError
void setError(llvm::StringRef Error)
If this change could not be created successfully, e.g.
Definition: AtomicChange.h:77
clang::tooling::applyAtomicChanges
llvm::Expected< std::string > applyAtomicChanges(llvm::StringRef FilePath, llvm::StringRef Code, llvm::ArrayRef< AtomicChange > Changes, const ApplyChangesSpec &Spec)
Applies all AtomicChanges in Changes to the Code.
Definition: AtomicChange.cpp:301
clang
Definition: CalledOnceCheck.h:17
Text
StringRef Text
Definition: Format.cpp:2334
clang::tooling::ApplyChangesSpec::kNone
@ kNone
Definition: AtomicChange.h:167
clang::format::getNoStyle
FormatStyle getNoStyle()
Returns style indicating formatting should be not applied at all.
Definition: Format.cpp:1513
clang::tooling::ApplyChangesSpec::Style
format::FormatStyle Style
Definition: AtomicChange.h:161
clang::tooling::AtomicChange::operator==
bool operator==(const AtomicChange &Other) const
Definition: AtomicChange.cpp:223
clang::tooling::ApplyChangesSpec::Format
FormatOption Format
Definition: AtomicChange.h:169
clang::tooling::ApplyChangesSpec::kAll
@ kAll
Definition: AtomicChange.h:167
SM
#define SM(sm)
Definition: Cuda.cpp:78
clang::tooling::AtomicChange::convertFromYAML
static AtomicChange convertFromYAML(llvm::StringRef YAMLContent)
Converts a YAML-encoded automic change to AtomicChange.
Definition: AtomicChange.cpp:242
clang::tooling::AtomicChange::insert
llvm::Error insert(const SourceManager &SM, SourceLocation Loc, llvm::StringRef Text, bool InsertAfter=true)
Adds a replacement that inserts Text at Loc.
Definition: AtomicChange.cpp:269