ilia@18415
|
1 |
Index: include/clang/Tooling/Core/Diagnostics.h
|
ilia@18415
|
2 |
===================================================================
|
ilia@18415
|
3 |
--- include/clang/Tooling/Core/Diagnostics.h (revision 278390)
|
ilia@18415
|
4 |
+++ include/clang/Tooling/Core/Diagnostics.h (working copy)
|
ilia@18415
|
5 |
@@ -1,254 +1,54 @@
|
ilia@18415
|
6 |
-//===--- Replacement.h - Framework for clang refactoring tools --*- C++ -*-===//
|
ilia@18415
|
7 |
-//
|
ilia@18415
|
8 |
-// The LLVM Compiler Infrastructure
|
ilia@18415
|
9 |
-//
|
ilia@18415
|
10 |
-// This file is distributed under the University of Illinois Open Source
|
ilia@18415
|
11 |
-// License. See LICENSE.TXT for details.
|
ilia@18415
|
12 |
-//
|
ilia@18415
|
13 |
-//===----------------------------------------------------------------------===//
|
ilia@18415
|
14 |
-//
|
ilia@18415
|
15 |
-// Classes supporting refactorings that span multiple translation units.
|
ilia@18415
|
16 |
-// While single translation unit refactorings are supported via the Rewriter,
|
ilia@18415
|
17 |
-// when refactoring multiple translation units changes must be stored in a
|
ilia@18415
|
18 |
-// SourceManager independent form, duplicate changes need to be removed, and
|
ilia@18415
|
19 |
-// all changes must be applied at once at the end of the refactoring so that
|
ilia@18415
|
20 |
-// the code is always parseable.
|
ilia@18415
|
21 |
-//
|
ilia@18415
|
22 |
-//===----------------------------------------------------------------------===//
|
ilia@18415
|
23 |
-
|
ilia@18415
|
24 |
-#ifndef LLVM_CLANG_TOOLING_CORE_REPLACEMENT_H
|
ilia@18415
|
25 |
-#define LLVM_CLANG_TOOLING_CORE_REPLACEMENT_H
|
ilia@18415
|
26 |
-
|
ilia@18415
|
27 |
-#include "clang/Basic/LangOptions.h"
|
ilia@18415
|
28 |
-#include "clang/Basic/SourceLocation.h"
|
ilia@18415
|
29 |
-#include "llvm/ADT/StringRef.h"
|
ilia@18415
|
30 |
-#include "llvm/Support/Error.h"
|
ilia@18415
|
31 |
-#include <map>
|
ilia@18415
|
32 |
-#include <set>
|
ilia@18415
|
33 |
+#ifndef LLVM_CLANG_TOOLING_CORE_DIAGNOSTICS_H
|
ilia@18415
|
34 |
+#define LLVM_CLANG_TOOLING_CORE_DIAGNOSTICS_H
|
ilia@18415
|
35 |
+#include "clang/Basic/Diagnostic.h"
|
ilia@18415
|
36 |
+#include "llvm/ADT/SmallVector.h"
|
ilia@18415
|
37 |
+#include "Replacement.h"
|
ilia@18415
|
38 |
#include <string>
|
ilia@18415
|
39 |
-#include <vector>
|
ilia@18415
|
40 |
-
|
ilia@18415
|
41 |
namespace clang {
|
ilia@18415
|
42 |
+ namespace tooling {
|
ilia@18415
|
43 |
|
ilia@18415
|
44 |
-class Rewriter;
|
ilia@18415
|
45 |
+ struct DiagnosticsMessage {
|
ilia@18415
|
46 |
+ DiagnosticsMessage(StringRef Message = "");
|
ilia@18415
|
47 |
+ DiagnosticsMessage(StringRef Message, const SourceManager &Sources,
|
ilia@18415
|
48 |
+ SourceLocation Loc);
|
ilia@18415
|
49 |
+ std::string Message;
|
ilia@18415
|
50 |
+ std::string FilePath;
|
ilia@18415
|
51 |
+ unsigned FileOffset;
|
ilia@18415
|
52 |
+ };
|
ilia@18415
|
53 |
|
ilia@18415
|
54 |
-namespace tooling {
|
ilia@18415
|
55 |
+ struct Diagnostics {
|
ilia@18415
|
56 |
|
ilia@18415
|
57 |
-/// \brief A source range independent of the \c SourceManager.
|
ilia@18415
|
58 |
-class Range {
|
ilia@18415
|
59 |
-public:
|
ilia@18415
|
60 |
- Range() : Offset(0), Length(0) {}
|
ilia@18415
|
61 |
- Range(unsigned Offset, unsigned Length) : Offset(Offset), Length(Length) {}
|
ilia@18415
|
62 |
+ enum Level {
|
ilia@18415
|
63 |
+ Warning = DiagnosticsEngine::Warning,
|
ilia@18415
|
64 |
+ Error = DiagnosticsEngine::Error
|
ilia@18415
|
65 |
+ };
|
ilia@18415
|
66 |
|
ilia@18415
|
67 |
- /// \brief Accessors.
|
ilia@18415
|
68 |
- /// @{
|
ilia@18415
|
69 |
- unsigned getOffset() const { return Offset; }
|
ilia@18415
|
70 |
- unsigned getLength() const { return Length; }
|
ilia@18415
|
71 |
- /// @}
|
ilia@18415
|
72 |
+ Diagnostics();
|
ilia@18415
|
73 |
+ Diagnostics(StringRef CheckName, Level DiagLevel, bool IsWarningAsError,
|
ilia@18415
|
74 |
+ StringRef BuildDirectory);
|
ilia@18415
|
75 |
+ std::string CheckName;
|
ilia@18415
|
76 |
+ DiagnosticsMessage Message;
|
ilia@18415
|
77 |
+ tooling::Replacements Fix;
|
ilia@18415
|
78 |
+ SmallVector<DiagnosticsMessage, 1> Notes;
|
ilia@18415
|
79 |
|
ilia@18415
|
80 |
- /// \name Range Predicates
|
ilia@18415
|
81 |
- /// @{
|
ilia@18415
|
82 |
- /// \brief Whether this range overlaps with \p RHS or not.
|
ilia@18415
|
83 |
- bool overlapsWith(Range RHS) const {
|
ilia@18415
|
84 |
- return Offset + Length > RHS.Offset && Offset < RHS.Offset + RHS.Length;
|
ilia@18415
|
85 |
- }
|
ilia@18415
|
86 |
+ // A build directory of the diagnostic source file.
|
ilia@18415
|
87 |
+ //
|
ilia@18415
|
88 |
+ // It's an absolute path which is `directory` field of the source file in
|
ilia@18415
|
89 |
+ // compilation database. If users don't specify the compilation database
|
ilia@18415
|
90 |
+ // directory, it is the current directory where clang-tidy runs.
|
ilia@18415
|
91 |
+ //
|
ilia@18415
|
92 |
+ // Note: it is empty in unittest.
|
ilia@18415
|
93 |
+ std::string BuildDirectory;
|
ilia@18415
|
94 |
|
ilia@18415
|
95 |
- /// \brief Whether this range contains \p RHS or not.
|
ilia@18415
|
96 |
- bool contains(Range RHS) const {
|
ilia@18415
|
97 |
- return RHS.Offset >= Offset &&
|
ilia@18415
|
98 |
- (RHS.Offset + RHS.Length) <= (Offset + Length);
|
ilia@18415
|
99 |
- }
|
ilia@18415
|
100 |
+ Level DiagLevel;
|
ilia@18415
|
101 |
+ bool IsWarningAsError;
|
ilia@18415
|
102 |
+ };
|
ilia@18415
|
103 |
|
ilia@18415
|
104 |
- /// \brief Whether this range equals to \p RHS or not.
|
ilia@18415
|
105 |
- bool operator==(const Range &RHS) const {
|
ilia@18415
|
106 |
- return Offset == RHS.getOffset() && Length == RHS.getLength();
|
ilia@18415
|
107 |
- }
|
ilia@18415
|
108 |
- /// @}
|
ilia@18415
|
109 |
-
|
ilia@18415
|
110 |
-private:
|
ilia@18415
|
111 |
- unsigned Offset;
|
ilia@18415
|
112 |
- unsigned Length;
|
ilia@18415
|
113 |
-};
|
ilia@18415
|
114 |
-
|
ilia@18415
|
115 |
-/// \brief A text replacement.
|
ilia@18415
|
116 |
-///
|
ilia@18415
|
117 |
-/// Represents a SourceManager independent replacement of a range of text in a
|
ilia@18415
|
118 |
-/// specific file.
|
ilia@18415
|
119 |
-class Replacement {
|
ilia@18415
|
120 |
-public:
|
ilia@18415
|
121 |
- /// \brief Creates an invalid (not applicable) replacement.
|
ilia@18415
|
122 |
- Replacement();
|
ilia@18415
|
123 |
-
|
ilia@18415
|
124 |
- /// \brief Creates a replacement of the range [Offset, Offset+Length) in
|
ilia@18415
|
125 |
- /// FilePath with ReplacementText.
|
ilia@18415
|
126 |
- ///
|
ilia@18415
|
127 |
- /// \param FilePath A source file accessible via a SourceManager.
|
ilia@18415
|
128 |
- /// \param Offset The byte offset of the start of the range in the file.
|
ilia@18415
|
129 |
- /// \param Length The length of the range in bytes.
|
ilia@18415
|
130 |
- Replacement(StringRef FilePath, unsigned Offset, unsigned Length,
|
ilia@18415
|
131 |
- StringRef ReplacementText);
|
ilia@18415
|
132 |
-
|
ilia@18415
|
133 |
- /// \brief Creates a Replacement of the range [Start, Start+Length) with
|
ilia@18415
|
134 |
- /// ReplacementText.
|
ilia@18415
|
135 |
- Replacement(const SourceManager &Sources, SourceLocation Start,
|
ilia@18415
|
136 |
- unsigned Length, StringRef ReplacementText);
|
ilia@18415
|
137 |
-
|
ilia@18415
|
138 |
- /// \brief Creates a Replacement of the given range with ReplacementText.
|
ilia@18415
|
139 |
- Replacement(const SourceManager &Sources, const CharSourceRange &Range,
|
ilia@18415
|
140 |
- StringRef ReplacementText,
|
ilia@18415
|
141 |
- const LangOptions &LangOpts = LangOptions());
|
ilia@18415
|
142 |
-
|
ilia@18415
|
143 |
- /// \brief Creates a Replacement of the node with ReplacementText.
|
ilia@18415
|
144 |
- template <typename Node>
|
ilia@18415
|
145 |
- Replacement(const SourceManager &Sources, const Node &NodeToReplace,
|
ilia@18415
|
146 |
- StringRef ReplacementText,
|
ilia@18415
|
147 |
- const LangOptions &LangOpts = LangOptions());
|
ilia@18415
|
148 |
-
|
ilia@18415
|
149 |
- /// \brief Returns whether this replacement can be applied to a file.
|
ilia@18415
|
150 |
- ///
|
ilia@18415
|
151 |
- /// Only replacements that are in a valid file can be applied.
|
ilia@18415
|
152 |
- bool isApplicable() const;
|
ilia@18415
|
153 |
-
|
ilia@18415
|
154 |
- /// \brief Accessors.
|
ilia@18415
|
155 |
- /// @{
|
ilia@18415
|
156 |
- StringRef getFilePath() const { return FilePath; }
|
ilia@18415
|
157 |
- unsigned getOffset() const { return ReplacementRange.getOffset(); }
|
ilia@18415
|
158 |
- unsigned getLength() const { return ReplacementRange.getLength(); }
|
ilia@18415
|
159 |
- StringRef getReplacementText() const { return ReplacementText; }
|
ilia@18415
|
160 |
- /// @}
|
ilia@18415
|
161 |
-
|
ilia@18415
|
162 |
- /// \brief Applies the replacement on the Rewriter.
|
ilia@18415
|
163 |
- bool apply(Rewriter &Rewrite) const;
|
ilia@18415
|
164 |
-
|
ilia@18415
|
165 |
- /// \brief Returns a human readable string representation.
|
ilia@18415
|
166 |
- std::string toString() const;
|
ilia@18415
|
167 |
-
|
ilia@18415
|
168 |
- private:
|
ilia@18415
|
169 |
- void setFromSourceLocation(const SourceManager &Sources,
|
ilia@18415
|
170 |
- SourceLocation Start, unsigned Length,
|
ilia@18415
|
171 |
- StringRef ReplacementText);
|
ilia@18415
|
172 |
- void setFromSourceRange(const SourceManager &Sources,
|
ilia@18415
|
173 |
- const CharSourceRange &Range,
|
ilia@18415
|
174 |
- StringRef ReplacementText,
|
ilia@18415
|
175 |
- const LangOptions &LangOpts);
|
ilia@18415
|
176 |
-
|
ilia@18415
|
177 |
- std::string FilePath;
|
ilia@18415
|
178 |
- Range ReplacementRange;
|
ilia@18415
|
179 |
- std::string ReplacementText;
|
ilia@18415
|
180 |
-};
|
ilia@18415
|
181 |
-
|
ilia@18415
|
182 |
-/// \brief Less-than operator between two Replacements.
|
ilia@18415
|
183 |
-bool operator<(const Replacement &LHS, const Replacement &RHS);
|
ilia@18415
|
184 |
-
|
ilia@18415
|
185 |
-/// \brief Equal-to operator between two Replacements.
|
ilia@18415
|
186 |
-bool operator==(const Replacement &LHS, const Replacement &RHS);
|
ilia@18415
|
187 |
-
|
ilia@18415
|
188 |
-/// \brief A set of Replacements.
|
ilia@18415
|
189 |
-/// FIXME: Change to a vector and deduplicate in the RefactoringTool.
|
ilia@18415
|
190 |
-typedef std::set<Replacement> Replacements;
|
ilia@18415
|
191 |
-
|
ilia@18415
|
192 |
-/// \brief Apply all replacements in \p Replaces to the Rewriter \p Rewrite.
|
ilia@18415
|
193 |
-///
|
ilia@18415
|
194 |
-/// Replacement applications happen independently of the success of
|
ilia@18415
|
195 |
-/// other applications.
|
ilia@18415
|
196 |
-///
|
ilia@18415
|
197 |
-/// \returns true if all replacements apply. false otherwise.
|
ilia@18415
|
198 |
-bool applyAllReplacements(const Replacements &Replaces, Rewriter &Rewrite);
|
ilia@18415
|
199 |
-
|
ilia@18415
|
200 |
-/// \brief Apply all replacements in \p Replaces to the Rewriter \p Rewrite.
|
ilia@18415
|
201 |
-///
|
ilia@18415
|
202 |
-/// Replacement applications happen independently of the success of
|
ilia@18415
|
203 |
-/// other applications.
|
ilia@18415
|
204 |
-///
|
ilia@18415
|
205 |
-/// \returns true if all replacements apply. false otherwise.
|
ilia@18415
|
206 |
-bool applyAllReplacements(const std::vector<Replacement> &Replaces,
|
ilia@18415
|
207 |
- Rewriter &Rewrite);
|
ilia@18415
|
208 |
-
|
ilia@18415
|
209 |
-/// \brief Applies all replacements in \p Replaces to \p Code.
|
ilia@18415
|
210 |
-///
|
ilia@18415
|
211 |
-/// This completely ignores the path stored in each replacement. If all
|
ilia@18415
|
212 |
-/// replacements are applied successfully, this returns the code with
|
ilia@18415
|
213 |
-/// replacements applied; otherwise, an llvm::Error carrying llvm::StringError
|
ilia@18415
|
214 |
-/// is returned (the Error message can be converted to string using
|
ilia@18415
|
215 |
-/// `llvm::toString()` and 'std::error_code` in the `Error` should be ignored).
|
ilia@18415
|
216 |
-llvm::Expected<std::string> applyAllReplacements(StringRef Code,
|
ilia@18415
|
217 |
- const Replacements &Replaces);
|
ilia@18415
|
218 |
-
|
ilia@18415
|
219 |
-/// \brief Calculates how a code \p Position is shifted when \p Replaces are
|
ilia@18415
|
220 |
-/// applied.
|
ilia@18415
|
221 |
-unsigned shiftedCodePosition(const Replacements& Replaces, unsigned Position);
|
ilia@18415
|
222 |
-
|
ilia@18415
|
223 |
-/// \brief Calculates how a code \p Position is shifted when \p Replaces are
|
ilia@18415
|
224 |
-/// applied.
|
ilia@18415
|
225 |
-///
|
ilia@18415
|
226 |
-/// \pre Replaces[i].getOffset() <= Replaces[i+1].getOffset().
|
ilia@18415
|
227 |
-unsigned shiftedCodePosition(const std::vector<Replacement> &Replaces,
|
ilia@18415
|
228 |
- unsigned Position);
|
ilia@18415
|
229 |
-
|
ilia@18415
|
230 |
-/// \brief Removes duplicate Replacements and reports if Replacements conflict
|
ilia@18415
|
231 |
-/// with one another. All Replacements are assumed to be in the same file.
|
ilia@18415
|
232 |
-///
|
ilia@18415
|
233 |
-/// \post Replaces[i].getOffset() <= Replaces[i+1].getOffset().
|
ilia@18415
|
234 |
-///
|
ilia@18415
|
235 |
-/// This function sorts \p Replaces so that conflicts can be reported simply by
|
ilia@18415
|
236 |
-/// offset into \p Replaces and number of elements in the conflict.
|
ilia@18415
|
237 |
-void deduplicate(std::vector<Replacement> &Replaces,
|
ilia@18415
|
238 |
- std::vector<Range> &Conflicts);
|
ilia@18415
|
239 |
-
|
ilia@18415
|
240 |
-/// \brief Collection of Replacements generated from a single translation unit.
|
ilia@18415
|
241 |
-struct TranslationUnitReplacements {
|
ilia@18415
|
242 |
- /// Name of the main source for the translation unit.
|
ilia@18415
|
243 |
- std::string MainSourceFile;
|
ilia@18415
|
244 |
-
|
ilia@18415
|
245 |
- /// A freeform chunk of text to describe the context of the replacements.
|
ilia@18415
|
246 |
- /// Will be printed, for example, when detecting conflicts during replacement
|
ilia@18415
|
247 |
- /// deduplication.
|
ilia@18415
|
248 |
- std::string Context;
|
ilia@18415
|
249 |
-
|
ilia@18415
|
250 |
- std::vector<Replacement> Replacements;
|
ilia@18415
|
251 |
-};
|
ilia@18415
|
252 |
-
|
ilia@18415
|
253 |
-/// \brief Calculates the ranges in a single file that are affected by the
|
ilia@18415
|
254 |
-/// Replacements. Overlapping ranges will be merged.
|
ilia@18415
|
255 |
-///
|
ilia@18415
|
256 |
-/// \pre Replacements must be for the same file.
|
ilia@18415
|
257 |
-///
|
ilia@18415
|
258 |
-/// \returns a non-overlapping and sorted ranges.
|
ilia@18415
|
259 |
-std::vector<Range> calculateChangedRanges(const Replacements &Replaces);
|
ilia@18415
|
260 |
-
|
ilia@18415
|
261 |
-/// \brief Calculates the new ranges after \p Replaces are applied. These
|
ilia@18415
|
262 |
-/// include both the original \p Ranges and the affected ranges of \p Replaces
|
ilia@18415
|
263 |
-/// in the new code.
|
ilia@18415
|
264 |
-///
|
ilia@18415
|
265 |
-/// \pre Replacements must be for the same file.
|
ilia@18415
|
266 |
-///
|
ilia@18415
|
267 |
-/// \return The new ranges after \p Replaces are applied. The new ranges will be
|
ilia@18415
|
268 |
-/// sorted and non-overlapping.
|
ilia@18415
|
269 |
-std::vector<Range>
|
ilia@18415
|
270 |
-calculateRangesAfterReplacements(const Replacements &Replaces,
|
ilia@18415
|
271 |
- const std::vector<Range> &Ranges);
|
ilia@18415
|
272 |
-
|
ilia@18415
|
273 |
-/// \brief Groups a random set of replacements by file path. Replacements
|
ilia@18415
|
274 |
-/// related to the same file entry are put into the same vector.
|
ilia@18415
|
275 |
-std::map<std::string, Replacements>
|
ilia@18415
|
276 |
-groupReplacementsByFile(const Replacements &Replaces);
|
ilia@18415
|
277 |
-
|
ilia@18415
|
278 |
-/// \brief Merges two sets of replacements with the second set referring to the
|
ilia@18415
|
279 |
-/// code after applying the first set. Within both 'First' and 'Second',
|
ilia@18415
|
280 |
-/// replacements must not overlap.
|
ilia@18415
|
281 |
-Replacements mergeReplacements(const Replacements &First,
|
ilia@18415
|
282 |
- const Replacements &Second);
|
ilia@18415
|
283 |
-
|
ilia@18415
|
284 |
-template <typename Node>
|
ilia@18415
|
285 |
-Replacement::Replacement(const SourceManager &Sources,
|
ilia@18415
|
286 |
- const Node &NodeToReplace, StringRef ReplacementText,
|
ilia@18415
|
287 |
- const LangOptions &LangOpts) {
|
ilia@18415
|
288 |
- const CharSourceRange Range =
|
ilia@18415
|
289 |
- CharSourceRange::getTokenRange(NodeToReplace->getSourceRange());
|
ilia@18415
|
290 |
- setFromSourceRange(Sources, Range, ReplacementText, LangOpts);
|
ilia@18415
|
291 |
+ struct TranslationUnitDiagnostics {
|
ilia@18415
|
292 |
+ std::string MainSourceFile;
|
ilia@18415
|
293 |
+ std::string Context;
|
ilia@18415
|
294 |
+ std::vector<Diagnostics> Diags;
|
ilia@18415
|
295 |
+ };
|
ilia@18415
|
296 |
+ }
|
ilia@18415
|
297 |
}
|
ilia@18415
|
298 |
-
|
ilia@18415
|
299 |
-} // end namespace tooling
|
ilia@18415
|
300 |
-} // end namespace clang
|
ilia@18415
|
301 |
-
|
ilia@18415
|
302 |
-#endif // LLVM_CLANG_TOOLING_CORE_REPLACEMENT_H
|
ilia@18415
|
303 |
+#endif
|
ilia@18415
|
304 |
\ No newline at end of file
|
ilia@18415
|
305 |
Index: lib/Tooling/Core/CMakeLists.txt
|
ilia@18415
|
306 |
===================================================================
|
ilia@18415
|
307 |
--- lib/Tooling/Core/CMakeLists.txt (revision 278390)
|
ilia@18415
|
308 |
+++ lib/Tooling/Core/CMakeLists.txt (working copy)
|
ilia@18415
|
309 |
@@ -3,6 +3,7 @@
|
ilia@18415
|
310 |
add_clang_library(clangToolingCore
|
ilia@18415
|
311 |
Lookup.cpp
|
ilia@18415
|
312 |
Replacement.cpp
|
ilia@18415
|
313 |
+ Diagnostics.cpp
|
ilia@18415
|
314 |
QualTypeNames.cpp
|
ilia@18415
|
315 |
|
ilia@18415
|
316 |
LINK_LIBS
|
ilia@18415
|
317 |
Index: lib/Tooling/Core/Diagnostics.cpp
|
ilia@18415
|
318 |
===================================================================
|
ilia@18415
|
319 |
--- lib/Tooling/Core/Diagnostics.cpp (revision 278390)
|
ilia@18415
|
320 |
+++ lib/Tooling/Core/Diagnostics.cpp (working copy)
|
ilia@18415
|
321 |
@@ -1,113 +1,30 @@
|
ilia@18415
|
322 |
-//===--- Lookup.cpp - Framework for clang refactoring tools ---------------===//
|
ilia@18415
|
323 |
-//
|
ilia@18415
|
324 |
-// The LLVM Compiler Infrastructure
|
ilia@18415
|
325 |
-//
|
ilia@18415
|
326 |
-// This file is distributed under the University of Illinois Open Source
|
ilia@18415
|
327 |
-// License. See LICENSE.TXT for details.
|
ilia@18415
|
328 |
-//
|
ilia@18415
|
329 |
-//===----------------------------------------------------------------------===//
|
ilia@18415
|
330 |
-//
|
ilia@18415
|
331 |
-// This file defines helper methods for clang tools performing name lookup.
|
ilia@18415
|
332 |
-//
|
ilia@18415
|
333 |
-//===----------------------------------------------------------------------===//
|
ilia@18415
|
334 |
+#include "clang/Tooling/Core/Diagnostics.h"
|
ilia@18415
|
335 |
+#include "clang/Basic/SourceManager.h"
|
ilia@18415
|
336 |
+namespace clang {
|
ilia@18415
|
337 |
+ namespace tooling {
|
ilia@18415
|
338 |
|
ilia@18415
|
339 |
-#include "clang/Tooling/Core/Lookup.h"
|
ilia@18415
|
340 |
-#include "clang/AST/Decl.h"
|
ilia@18415
|
341 |
-using namespace clang;
|
ilia@18415
|
342 |
-using namespace clang::tooling;
|
ilia@18415
|
343 |
+ DiagnosticsMessage::DiagnosticsMessage(StringRef Message)
|
ilia@18415
|
344 |
+ : Message(Message), FileOffset(0) {
|
ilia@18415
|
345 |
+ }
|
ilia@18415
|
346 |
|
ilia@18415
|
347 |
-static bool isInsideDifferentNamespaceWithSameName(const DeclContext *DeclA,
|
ilia@18415
|
348 |
- const DeclContext *DeclB) {
|
ilia@18415
|
349 |
- while (true) {
|
ilia@18415
|
350 |
- // Look past non-namespaces on DeclA.
|
ilia@18415
|
351 |
- while (DeclA && !isa<NamespaceDecl>(DeclA))
|
ilia@18415
|
352 |
- DeclA = DeclA->getParent();
|
ilia@18415
|
353 |
+ DiagnosticsMessage::DiagnosticsMessage(StringRef Message,
|
ilia@18415
|
354 |
+ const SourceManager &Sources,
|
ilia@18415
|
355 |
+ SourceLocation Loc)
|
ilia@18415
|
356 |
+ : Message(Message) {
|
ilia@18415
|
357 |
+ assert(Loc.isValid() && Loc.isFileID());
|
ilia@18415
|
358 |
+ FilePath = Sources.getFilename(Loc);
|
ilia@18415
|
359 |
+ FileOffset = Sources.getFileOffset(Loc);
|
ilia@18415
|
360 |
+ }
|
ilia@18415
|
361 |
|
ilia@18415
|
362 |
- // Look past non-namespaces on DeclB.
|
ilia@18415
|
363 |
- while (DeclB && !isa<NamespaceDecl>(DeclB))
|
ilia@18415
|
364 |
- DeclB = DeclB->getParent();
|
ilia@18415
|
365 |
+ Diagnostics::Diagnostics() {
|
ilia@18415
|
366 |
+ }
|
ilia@18415
|
367 |
|
ilia@18415
|
368 |
- // We hit the root, no namespace collision.
|
ilia@18415
|
369 |
- if (!DeclA || !DeclB)
|
ilia@18415
|
370 |
- return false;
|
ilia@18415
|
371 |
-
|
ilia@18415
|
372 |
- // Literally the same namespace, not a collision.
|
ilia@18415
|
373 |
- if (DeclA == DeclB)
|
ilia@18415
|
374 |
- return false;
|
ilia@18415
|
375 |
-
|
ilia@18415
|
376 |
- // Now check the names. If they match we have a different namespace with the
|
ilia@18415
|
377 |
- // same name.
|
ilia@18415
|
378 |
- if (cast<NamespaceDecl>(DeclA)->getDeclName() ==
|
ilia@18415
|
379 |
- cast<NamespaceDecl>(DeclB)->getDeclName())
|
ilia@18415
|
380 |
- return true;
|
ilia@18415
|
381 |
-
|
ilia@18415
|
382 |
- DeclA = DeclA->getParent();
|
ilia@18415
|
383 |
- DeclB = DeclB->getParent();
|
ilia@18415
|
384 |
- }
|
ilia@18415
|
385 |
-}
|
ilia@18415
|
386 |
-
|
ilia@18415
|
387 |
-static StringRef getBestNamespaceSubstr(const DeclContext *DeclA,
|
ilia@18415
|
388 |
- StringRef NewName,
|
ilia@18415
|
389 |
- bool HadLeadingColonColon) {
|
ilia@18415
|
390 |
- while (true) {
|
ilia@18415
|
391 |
- while (DeclA && !isa<NamespaceDecl>(DeclA))
|
ilia@18415
|
392 |
- DeclA = DeclA->getParent();
|
ilia@18415
|
393 |
-
|
ilia@18415
|
394 |
- // Fully qualified it is! Leave :: in place if it's there already.
|
ilia@18415
|
395 |
- if (!DeclA)
|
ilia@18415
|
396 |
- return HadLeadingColonColon ? NewName : NewName.substr(2);
|
ilia@18415
|
397 |
-
|
ilia@18415
|
398 |
- // Otherwise strip off redundant namespace qualifications from the new name.
|
ilia@18415
|
399 |
- // We use the fully qualified name of the namespace and remove that part
|
ilia@18415
|
400 |
- // from NewName if it has an identical prefix.
|
ilia@18415
|
401 |
- std::string NS =
|
ilia@18415
|
402 |
- "::" + cast<NamespaceDecl>(DeclA)->getQualifiedNameAsString() + "::";
|
ilia@18415
|
403 |
- if (NewName.startswith(NS))
|
ilia@18415
|
404 |
- return NewName.substr(NS.size());
|
ilia@18415
|
405 |
-
|
ilia@18415
|
406 |
- // No match yet. Strip of a namespace from the end of the chain and try
|
ilia@18415
|
407 |
- // again. This allows to get optimal qualifications even if the old and new
|
ilia@18415
|
408 |
- // decl only share common namespaces at a higher level.
|
ilia@18415
|
409 |
- DeclA = DeclA->getParent();
|
ilia@18415
|
410 |
- }
|
ilia@18415
|
411 |
-}
|
ilia@18415
|
412 |
-
|
ilia@18415
|
413 |
-/// Check if the name specifier begins with a written "::".
|
ilia@18415
|
414 |
-static bool isFullyQualified(const NestedNameSpecifier *NNS) {
|
ilia@18415
|
415 |
- while (NNS) {
|
ilia@18415
|
416 |
- if (NNS->getKind() == NestedNameSpecifier::Global)
|
ilia@18415
|
417 |
- return true;
|
ilia@18415
|
418 |
- NNS = NNS->getPrefix();
|
ilia@18415
|
419 |
- }
|
ilia@18415
|
420 |
- return false;
|
ilia@18415
|
421 |
-}
|
ilia@18415
|
422 |
-
|
ilia@18415
|
423 |
-std::string tooling::replaceNestedName(const NestedNameSpecifier *Use,
|
ilia@18415
|
424 |
- const DeclContext *UseContext,
|
ilia@18415
|
425 |
- const NamedDecl *FromDecl,
|
ilia@18415
|
426 |
- StringRef ReplacementString) {
|
ilia@18415
|
427 |
- assert(ReplacementString.startswith("::") &&
|
ilia@18415
|
428 |
- "Expected fully-qualified name!");
|
ilia@18415
|
429 |
-
|
ilia@18415
|
430 |
- // We can do a raw name replacement when we are not inside the namespace for
|
ilia@18415
|
431 |
- // the original function and it is not in the global namespace. The
|
ilia@18415
|
432 |
- // assumption is that outside the original namespace we must have a using
|
ilia@18415
|
433 |
- // statement that makes this work out and that other parts of this refactor
|
ilia@18415
|
434 |
- // will automatically fix using statements to point to the new function
|
ilia@18415
|
435 |
- const bool class_name_only = !Use;
|
ilia@18415
|
436 |
- const bool in_global_namespace =
|
ilia@18415
|
437 |
- isa<TranslationUnitDecl>(FromDecl->getDeclContext());
|
ilia@18415
|
438 |
- if (class_name_only && !in_global_namespace &&
|
ilia@18415
|
439 |
- !isInsideDifferentNamespaceWithSameName(FromDecl->getDeclContext(),
|
ilia@18415
|
440 |
- UseContext)) {
|
ilia@18415
|
441 |
- auto Pos = ReplacementString.rfind("::");
|
ilia@18415
|
442 |
- return Pos != StringRef::npos ? ReplacementString.substr(Pos + 2)
|
ilia@18415
|
443 |
- : ReplacementString;
|
ilia@18415
|
444 |
- }
|
ilia@18415
|
445 |
- // We did not match this because of a using statement, so we will need to
|
ilia@18415
|
446 |
- // figure out how good a namespace match we have with our destination type.
|
ilia@18415
|
447 |
- // We work backwards (from most specific possible namespace to least
|
ilia@18415
|
448 |
- // specific).
|
ilia@18415
|
449 |
- return getBestNamespaceSubstr(UseContext, ReplacementString,
|
ilia@18415
|
450 |
- isFullyQualified(Use));
|
ilia@18415
|
451 |
-}
|
ilia@18415
|
452 |
+ Diagnostics::Diagnostics(StringRef CheckName,
|
ilia@18415
|
453 |
+ Diagnostics::Level DiagLevel,
|
ilia@18415
|
454 |
+ bool IsWarningAsError,
|
ilia@18415
|
455 |
+ StringRef BuildDirectory)
|
ilia@18415
|
456 |
+ : CheckName(CheckName), BuildDirectory(BuildDirectory), DiagLevel(DiagLevel),
|
ilia@18415
|
457 |
+ IsWarningAsError(IsWarningAsError) {
|
ilia@18415
|
458 |
+ }
|
ilia@18415
|
459 |
+ }
|
ilia@18415
|
460 |
+}
|
ilia@18415
|
461 |
\ No newline at end of file
|