1
1
//! Library for applying diagnostic suggestions to source code.
2
2
//!
3
- //! This is a low-level library. You pass it the JSON output from `rustc`, and
4
- //! you can then use it to apply suggestions to in-memory strings. This
5
- //! library doesn't execute commands, or read or write from the filesystem.
3
+ //! This is a low-level library. You pass it the [ JSON output] from `rustc`,
4
+ //! and you can then use it to apply suggestions to in-memory strings.
5
+ //! This library doesn't execute commands, or read or write from the filesystem.
6
6
//!
7
7
//! If you are looking for the [`cargo fix`] implementation, the core of it is
8
8
//! located in [`cargo::ops::fix`].
9
9
//!
10
10
//! [`cargo fix`]: https://doc.rust-lang.org/cargo/commands/cargo-fix.html
11
11
//! [`cargo::ops::fix`]: https://github.com/rust-lang/cargo/blob/master/src/cargo/ops/fix.rs
12
+ //! [JSON output]: diagnostics
12
13
//!
13
14
//! The general outline of how to use this library is:
14
15
//!
15
16
//! 1. Call `rustc` and collect the JSON data.
16
17
//! 2. Pass the json data to [`get_suggestions_from_json`].
17
18
//! 3. Create a [`CodeFix`] with the source of a file to modify.
18
19
//! 4. Call [`CodeFix::apply`] to apply a change.
19
- //! 5. Write the source back to disk.
20
+ //! 5. Call [`CodeFix::finish`] to get the result and write it back to disk.
20
21
21
22
use std:: collections:: HashSet ;
22
23
use std:: ops:: Range ;
@@ -27,12 +28,20 @@ pub mod diagnostics;
27
28
use crate :: diagnostics:: { Diagnostic , DiagnosticSpan } ;
28
29
mod replace;
29
30
31
+ /// A filter to control which suggestion should be applied.
30
32
#[ derive( Debug , Clone , Copy ) ]
31
33
pub enum Filter {
34
+ /// For [`diagnostics::Applicability::MachineApplicable`] only.
32
35
MachineApplicableOnly ,
36
+ /// Everything is included. YOLO!
33
37
Everything ,
34
38
}
35
39
40
+ /// Collects code [`Suggestion`]s from one or more compiler diagnostic lines.
41
+ ///
42
+ /// Fails if any of diagnostic line `input` is not a valid [`Diagnostic`] JSON.
43
+ ///
44
+ /// * `only` --- only diagnostics with a set of error codes (e.g. `E0005`) would be collected.
36
45
pub fn get_suggestions_from_json < S : :: std:: hash:: BuildHasher > (
37
46
input : & str ,
38
47
only : & HashSet < String , S > ,
@@ -70,20 +79,24 @@ impl std::fmt::Display for LineRange {
70
79
}
71
80
}
72
81
73
- #[ derive( Debug , Clone , Hash , PartialEq , Eq ) ]
74
82
/// An error/warning and possible solutions for fixing it
83
+ #[ derive( Debug , Clone , Hash , PartialEq , Eq ) ]
75
84
pub struct Suggestion {
76
85
pub message : String ,
77
86
pub snippets : Vec < Snippet > ,
78
87
pub solutions : Vec < Solution > ,
79
88
}
80
89
90
+ /// Solution to a diagnostic item.
81
91
#[ derive( Debug , Clone , Hash , PartialEq , Eq ) ]
82
92
pub struct Solution {
93
+ /// The error message of the diagnostic item.
83
94
pub message : String ,
95
+ /// Possible solutions to fix the error.
84
96
pub replacements : Vec < Replacement > ,
85
97
}
86
98
99
+ /// Represents code that will get replaced.
87
100
#[ derive( Debug , Clone , Hash , PartialEq , Eq ) ]
88
101
pub struct Snippet {
89
102
pub file_name : String ,
@@ -95,12 +108,16 @@ pub struct Snippet {
95
108
pub text : ( String , String , String ) ,
96
109
}
97
110
111
+ /// Represents a replacement of a `snippet`.
98
112
#[ derive( Debug , Clone , Hash , PartialEq , Eq ) ]
99
113
pub struct Replacement {
114
+ /// Code snippet that gets replaced.
100
115
pub snippet : Snippet ,
116
+ /// The replacement of the snippet.
101
117
pub replacement : String ,
102
118
}
103
119
120
+ /// Parses a [`Snippet`] from a diagnostic span item.
104
121
fn parse_snippet ( span : & DiagnosticSpan ) -> Option < Snippet > {
105
122
// unindent the snippet
106
123
let indent = span
@@ -168,6 +185,7 @@ fn parse_snippet(span: &DiagnosticSpan) -> Option<Snippet> {
168
185
} )
169
186
}
170
187
188
+ /// Converts a [`DiagnosticSpan`] into a [`Replacement`].
171
189
fn collect_span ( span : & DiagnosticSpan ) -> Option < Replacement > {
172
190
let snippet = parse_snippet ( span) ?;
173
191
let replacement = span. suggested_replacement . clone ( ) ?;
@@ -177,6 +195,9 @@ fn collect_span(span: &DiagnosticSpan) -> Option<Replacement> {
177
195
} )
178
196
}
179
197
198
+ /// Collects code [`Suggestion`]s from a single compiler diagnostic line.
199
+ ///
200
+ /// * `only` --- only diagnostics with a set of error codes (e.g. `E0005`) would be collected.
180
201
pub fn collect_suggestions < S : :: std:: hash:: BuildHasher > (
181
202
diagnostic : & Diagnostic ,
182
203
only : & HashSet < String , S > ,
@@ -237,17 +258,26 @@ pub fn collect_suggestions<S: ::std::hash::BuildHasher>(
237
258
}
238
259
}
239
260
261
+ /// Represents a code fix. This doesn't write to disks but is only in memory.
262
+ ///
263
+ /// The general way to use this is:
264
+ ///
265
+ /// 1. Feeds the source of a file to [`CodeFix::new`].
266
+ /// 2. Calls [`CodeFix::apply`] to apply suggestions to the source code.
267
+ /// 3. Calls [`CodeFix::finish`] to get the "fixed" code.
240
268
pub struct CodeFix {
241
269
data : replace:: Data ,
242
270
}
243
271
244
272
impl CodeFix {
273
+ /// Creates a `CodeFix` with the source of a file to modify.
245
274
pub fn new ( s : & str ) -> CodeFix {
246
275
CodeFix {
247
276
data : replace:: Data :: new ( s. as_bytes ( ) ) ,
248
277
}
249
278
}
250
279
280
+ /// Applies a suggestion to the code.
251
281
pub fn apply ( & mut self , suggestion : & Suggestion ) -> Result < ( ) , Error > {
252
282
for sol in & suggestion. solutions {
253
283
for r in & sol. replacements {
@@ -258,11 +288,13 @@ impl CodeFix {
258
288
Ok ( ( ) )
259
289
}
260
290
291
+ /// Gets the result of the "fixed" code.
261
292
pub fn finish ( & self ) -> Result < String , Error > {
262
293
Ok ( String :: from_utf8 ( self . data . to_vec ( ) ) ?)
263
294
}
264
295
}
265
296
297
+ /// Applies multiple `suggestions` to the given `code`.
266
298
pub fn apply_suggestions ( code : & str , suggestions : & [ Suggestion ] ) -> Result < String , Error > {
267
299
let mut fix = CodeFix :: new ( code) ;
268
300
for suggestion in suggestions. iter ( ) . rev ( ) {
0 commit comments