aboutsummaryrefslogtreecommitdiff
path: root/crates/ide/src/diagnostics.rs
diff options
context:
space:
mode:
authorAleksey Kladov <[email protected]>2021-04-12 15:58:01 +0100
committerAleksey Kladov <[email protected]>2021-04-12 15:58:01 +0100
commit426d098bd6a032cb03e61d4b3d091caeaecbd4d0 (patch)
treeeb54a5d4e72a875b072af5f266673c6265057f3d /crates/ide/src/diagnostics.rs
parentcae920a1bb827726aa142e5c81da9e6b0ca38d97 (diff)
internal: prepare for lazy diagnostics
Diffstat (limited to 'crates/ide/src/diagnostics.rs')
-rw-r--r--crates/ide/src/diagnostics.rs83
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::{
25use text_edit::TextEdit; 25use text_edit::TextEdit;
26use unlinked_file::UnlinkedFile; 26use unlinked_file::UnlinkedFile;
27 27
28use crate::{FileId, Label, SourceChange}; 28use crate::{Assist, AssistId, AssistKind, FileId, Label, SourceChange};
29 29
30use self::fixes::DiagnosticWithFix; 30use 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)]
73pub 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
80impl 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)]
88pub enum Severity { 73pub 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
273fn 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)]
288mod tests { 285mod 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,