1 //===--- AtomicChange.h - AtomicChange class --------------------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file defines AtomicChange which is used to create a set of source
11 // changes, e.g. replacements and header insertions.
13 //===----------------------------------------------------------------------===//
15 #ifndef LLVM_CLANG_TOOLING_REFACTOR_ATOMICCHANGE_H
16 #define LLVM_CLANG_TOOLING_REFACTOR_ATOMICCHANGE_H
18 #include "clang/Basic/SourceManager.h"
19 #include "clang/Tooling/Core/Replacement.h"
20 #include "llvm/ADT/StringRef.h"
21 #include "llvm/Support/Error.h"
26 /// \brief An atomic change is used to create and group a set of source edits,
27 /// e.g. replacements or header insertions. Edits in an AtomicChange should be
28 /// related, e.g. replacements for the same type reference and the corresponding
29 /// header insertion/deletion.
31 /// An AtomicChange is uniquely identified by a key and will either be fully
32 /// applied or not applied at all.
34 /// Calling setError on an AtomicChange stores the error message and marks it as
35 /// bad, i.e. none of its source edits will be applied.
38 /// \brief Creates an atomic change around \p KeyPosition with the key being a
39 /// concatenation of the file name and the offset of \p KeyPosition.
40 /// \p KeyPosition should be the location of the key syntactical element that
41 /// is being changed, e.g. the call to a refactored method.
42 AtomicChange(const SourceManager &SM, SourceLocation KeyPosition);
44 /// \brief Creates an atomic change for \p FilePath with a customized key.
45 AtomicChange(llvm::StringRef FilePath, llvm::StringRef Key)
46 : Key(Key), FilePath(FilePath) {}
48 /// \brief Returns the atomic change as a YAML string.
49 std::string toYAMLString();
51 /// \brief Converts a YAML-encoded automic change to AtomicChange.
52 static AtomicChange convertFromYAML(llvm::StringRef YAMLContent);
54 /// \brief Returns the key of this change, which is a concatenation of the
55 /// file name and offset of the key position.
56 const std::string &getKey() const { return Key; }
58 /// \brief Returns the path of the file containing this atomic change.
59 const std::string &getFilePath() const { return FilePath; }
61 /// \brief If this change could not be created successfully, e.g. because of
62 /// conflicts among replacements, use this to set an error description.
63 /// Thereby, places that cannot be fixed automatically can be gathered when
65 void setError(llvm::StringRef Error) { this->Error = Error; }
67 /// \brief Returns whether an error has been set on this list.
68 bool hasError() const { return !Error.empty(); }
70 /// \brief Returns the error message or an empty string if it does not exist.
71 const std::string &getError() const { return Error; }
73 /// \brief Adds a replacement that replaces the given Range with
75 /// \returns An llvm::Error carrying ReplacementError on error.
76 llvm::Error replace(const SourceManager &SM, const CharSourceRange &Range,
77 llvm::StringRef ReplacementText);
79 /// \brief Adds a replacement that replaces range [Loc, Loc+Length) with
81 /// \returns An llvm::Error carrying ReplacementError on error.
82 llvm::Error replace(const SourceManager &SM, SourceLocation Loc,
83 unsigned Length, llvm::StringRef Text);
85 /// \brief Adds a replacement that inserts \p Text at \p Loc. If this
86 /// insertion conflicts with an existing insertion (at the same position),
87 /// this will be inserted before/after the existing insertion depending on
88 /// \p InsertAfter. Users should use `replace` with `Length=0` instead if they
89 /// do not want conflict resolving by default. If the conflicting replacement
90 /// is not an insertion, an error is returned.
92 /// \returns An llvm::Error carrying ReplacementError on error.
93 llvm::Error insert(const SourceManager &SM, SourceLocation Loc,
94 llvm::StringRef Text, bool InsertAfter = true);
96 /// \brief Adds a header into the file that contains the key position.
97 /// Header can be in angle brackets or double quotation marks. By default
98 /// (header is not quoted), header will be surrounded with double quotes.
99 void addHeader(llvm::StringRef Header);
101 /// \brief Removes a header from the file that contains the key position.
102 void removeHeader(llvm::StringRef Header);
104 /// \brief Returns a const reference to existing replacements.
105 const Replacements &getReplacements() const { return Replaces; }
107 llvm::ArrayRef<std::string> getInsertedHeaders() const {
108 return InsertedHeaders;
111 llvm::ArrayRef<std::string> getRemovedHeaders() const {
112 return RemovedHeaders;
118 AtomicChange(std::string Key, std::string FilePath, std::string Error,
119 std::vector<std::string> InsertedHeaders,
120 std::vector<std::string> RemovedHeaders,
121 clang::tooling::Replacements Replaces);
123 // This uniquely identifies an AtomicChange.
125 std::string FilePath;
127 std::vector<std::string> InsertedHeaders;
128 std::vector<std::string> RemovedHeaders;
129 tooling::Replacements Replaces;
132 } // end namespace tooling
133 } // end namespace clang
135 #endif // LLVM_CLANG_TOOLING_REFACTOR_ATOMICCHANGE_H