diff options
author | Aleksey Kladov <[email protected]> | 2021-04-12 15:58:01 +0100 |
---|---|---|
committer | Aleksey Kladov <[email protected]> | 2021-04-12 15:58:01 +0100 |
commit | 426d098bd6a032cb03e61d4b3d091caeaecbd4d0 (patch) | |
tree | eb54a5d4e72a875b072af5f266673c6265057f3d /crates/ide/src/diagnostics.rs | |
parent | cae920a1bb827726aa142e5c81da9e6b0ca38d97 (diff) |
internal: prepare for lazy diagnostics
Diffstat (limited to 'crates/ide/src/diagnostics.rs')
-rw-r--r-- | crates/ide/src/diagnostics.rs | 83 |
1 files changed, 44 insertions, 39 deletions
diff --git a/crates/ide/src/diagnostics.rs b/crates/ide/src/diagnostics.rs index 0ace80a1e..4f0b4a62e 100644 --- a/crates/ide/src/diagnostics.rs +++ b/crates/ide/src/diagnostics.rs | |||
@@ -25,7 +25,7 @@ use syntax::{ | |||
25 | use text_edit::TextEdit; | 25 | use text_edit::TextEdit; |
26 | use unlinked_file::UnlinkedFile; | 26 | use unlinked_file::UnlinkedFile; |
27 | 27 | ||
28 | use crate::{FileId, Label, SourceChange}; | 28 | use crate::{Assist, AssistId, AssistKind, FileId, Label, SourceChange}; |
29 | 29 | ||
30 | use self::fixes::DiagnosticWithFix; | 30 | use self::fixes::DiagnosticWithFix; |
31 | 31 | ||
@@ -35,7 +35,7 @@ pub struct Diagnostic { | |||
35 | pub message: String, | 35 | pub message: String, |
36 | pub range: TextRange, | 36 | pub range: TextRange, |
37 | pub severity: Severity, | 37 | pub severity: Severity, |
38 | pub fix: Option<Fix>, | 38 | pub fix: Option<Assist>, |
39 | pub unused: bool, | 39 | pub unused: bool, |
40 | pub code: Option<DiagnosticCode>, | 40 | pub code: Option<DiagnosticCode>, |
41 | } | 41 | } |
@@ -56,7 +56,7 @@ impl Diagnostic { | |||
56 | } | 56 | } |
57 | } | 57 | } |
58 | 58 | ||
59 | fn with_fix(self, fix: Option<Fix>) -> Self { | 59 | fn with_fix(self, fix: Option<Assist>) -> Self { |
60 | Self { fix, ..self } | 60 | Self { fix, ..self } |
61 | } | 61 | } |
62 | 62 | ||
@@ -69,21 +69,6 @@ impl Diagnostic { | |||
69 | } | 69 | } |
70 | } | 70 | } |
71 | 71 | ||
72 | #[derive(Debug)] | ||
73 | pub struct Fix { | ||
74 | pub label: Label, | ||
75 | pub source_change: SourceChange, | ||
76 | /// Allows to trigger the fix only when the caret is in the range given | ||
77 | pub fix_trigger_range: TextRange, | ||
78 | } | ||
79 | |||
80 | impl Fix { | ||
81 | fn new(label: &str, source_change: SourceChange, fix_trigger_range: TextRange) -> Self { | ||
82 | let label = Label::new(label); | ||
83 | Self { label, source_change, fix_trigger_range } | ||
84 | } | ||
85 | } | ||
86 | |||
87 | #[derive(Debug, Copy, Clone)] | 72 | #[derive(Debug, Copy, Clone)] |
88 | pub enum Severity { | 73 | pub enum Severity { |
89 | Error, | 74 | Error, |
@@ -261,7 +246,8 @@ fn check_unnecessary_braces_in_use_statement( | |||
261 | 246 | ||
262 | acc.push( | 247 | acc.push( |
263 | Diagnostic::hint(use_range, "Unnecessary braces in use statement".to_string()) | 248 | Diagnostic::hint(use_range, "Unnecessary braces in use statement".to_string()) |
264 | .with_fix(Some(Fix::new( | 249 | .with_fix(Some(fix( |
250 | "remove_braces", | ||
265 | "Remove unnecessary braces", | 251 | "Remove unnecessary braces", |
266 | SourceChange::from_text_edit(file_id, edit), | 252 | SourceChange::from_text_edit(file_id, edit), |
267 | use_range, | 253 | use_range, |
@@ -284,6 +270,17 @@ fn text_edit_for_remove_unnecessary_braces_with_self_in_use_statement( | |||
284 | None | 270 | None |
285 | } | 271 | } |
286 | 272 | ||
273 | fn fix(id: &'static str, label: &str, source_change: SourceChange, target: TextRange) -> Assist { | ||
274 | assert!(!id.contains(' ')); | ||
275 | Assist { | ||
276 | id: AssistId(id, AssistKind::QuickFix), | ||
277 | label: Label::new(label), | ||
278 | group: None, | ||
279 | target, | ||
280 | source_change: Some(source_change), | ||
281 | } | ||
282 | } | ||
283 | |||
287 | #[cfg(test)] | 284 | #[cfg(test)] |
288 | mod tests { | 285 | mod tests { |
289 | use expect_test::{expect, Expect}; | 286 | use expect_test::{expect, Expect}; |
@@ -308,10 +305,11 @@ mod tests { | |||
308 | .unwrap(); | 305 | .unwrap(); |
309 | let fix = diagnostic.fix.unwrap(); | 306 | let fix = diagnostic.fix.unwrap(); |
310 | let actual = { | 307 | let actual = { |
311 | let file_id = *fix.source_change.source_file_edits.keys().next().unwrap(); | 308 | let source_change = fix.source_change.unwrap(); |
309 | let file_id = *source_change.source_file_edits.keys().next().unwrap(); | ||
312 | let mut actual = analysis.file_text(file_id).unwrap().to_string(); | 310 | let mut actual = analysis.file_text(file_id).unwrap().to_string(); |
313 | 311 | ||
314 | for edit in fix.source_change.source_file_edits.values() { | 312 | for edit in source_change.source_file_edits.values() { |
315 | edit.apply(&mut actual); | 313 | edit.apply(&mut actual); |
316 | } | 314 | } |
317 | actual | 315 | actual |
@@ -319,9 +317,9 @@ mod tests { | |||
319 | 317 | ||
320 | assert_eq_text!(&after, &actual); | 318 | assert_eq_text!(&after, &actual); |
321 | assert!( | 319 | assert!( |
322 | fix.fix_trigger_range.contains_inclusive(file_position.offset), | 320 | fix.target.contains_inclusive(file_position.offset), |
323 | "diagnostic fix range {:?} does not touch cursor position {:?}", | 321 | "diagnostic fix range {:?} does not touch cursor position {:?}", |
324 | fix.fix_trigger_range, | 322 | fix.target, |
325 | file_position.offset | 323 | file_position.offset |
326 | ); | 324 | ); |
327 | } | 325 | } |
@@ -665,24 +663,31 @@ fn test_fn() { | |||
665 | range: 0..8, | 663 | range: 0..8, |
666 | severity: Error, | 664 | severity: Error, |
667 | fix: Some( | 665 | fix: Some( |
668 | Fix { | 666 | Assist { |
667 | id: AssistId( | ||
668 | "create_module", | ||
669 | QuickFix, | ||
670 | ), | ||
669 | label: "Create module", | 671 | label: "Create module", |
670 | source_change: SourceChange { | 672 | group: None, |
671 | source_file_edits: {}, | 673 | target: 0..8, |
672 | file_system_edits: [ | 674 | source_change: Some( |
673 | CreateFile { | 675 | SourceChange { |
674 | dst: AnchoredPathBuf { | 676 | source_file_edits: {}, |
675 | anchor: FileId( | 677 | file_system_edits: [ |
676 | 0, | 678 | CreateFile { |
677 | ), | 679 | dst: AnchoredPathBuf { |
678 | path: "foo.rs", | 680 | anchor: FileId( |
681 | 0, | ||
682 | ), | ||
683 | path: "foo.rs", | ||
684 | }, | ||
685 | initial_contents: "", | ||
679 | }, | 686 | }, |
680 | initial_contents: "", | 687 | ], |
681 | }, | 688 | is_snippet: false, |
682 | ], | 689 | }, |
683 | is_snippet: false, | 690 | ), |
684 | }, | ||
685 | fix_trigger_range: 0..8, | ||
686 | }, | 691 | }, |
687 | ), | 692 | ), |
688 | unused: false, | 693 | unused: false, |