aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_ide/src/diagnostics.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_ide/src/diagnostics.rs')
-rw-r--r--crates/ra_ide/src/diagnostics.rs127
1 files changed, 71 insertions, 56 deletions
diff --git a/crates/ra_ide/src/diagnostics.rs b/crates/ra_ide/src/diagnostics.rs
index a6b4c2c28..15dc50cf1 100644
--- a/crates/ra_ide/src/diagnostics.rs
+++ b/crates/ra_ide/src/diagnostics.rs
@@ -21,7 +21,7 @@ use ra_syntax::{
21}; 21};
22use ra_text_edit::{TextEdit, TextEditBuilder}; 22use ra_text_edit::{TextEdit, TextEditBuilder};
23 23
24use crate::{Diagnostic, FileId, FileSystemEdit, SourceChange, SourceFileEdit}; 24use crate::{Diagnostic, FileId, FileSystemEdit, Fix, SourceChange, SourceFileEdit};
25 25
26#[derive(Debug, Copy, Clone)] 26#[derive(Debug, Copy, Clone)]
27pub enum Severity { 27pub enum Severity {
@@ -63,8 +63,8 @@ pub(crate) fn diagnostics(db: &RootDatabase, file_id: FileId) -> Vec<Diagnostic>
63 .parent() 63 .parent()
64 .unwrap_or_else(|| RelativePath::new("")) 64 .unwrap_or_else(|| RelativePath::new(""))
65 .join(&d.candidate); 65 .join(&d.candidate);
66 let create_file = FileSystemEdit::CreateFile { source_root, path }; 66 let fix =
67 let fix = SourceChange::file_system_edit("create module", create_file); 67 Fix::new("Create module", FileSystemEdit::CreateFile { source_root, path }.into());
68 res.borrow_mut().push(Diagnostic { 68 res.borrow_mut().push(Diagnostic {
69 range: sema.diagnostics_range(d).range, 69 range: sema.diagnostics_range(d).range,
70 message: d.message(), 70 message: d.message(),
@@ -88,14 +88,12 @@ pub(crate) fn diagnostics(db: &RootDatabase, file_id: FileId) -> Vec<Diagnostic>
88 field_list = field_list.append_field(&field); 88 field_list = field_list.append_field(&field);
89 } 89 }
90 90
91 let mut builder = TextEditBuilder::default(); 91 let edit = {
92 algo::diff(&d.ast(db).syntax(), &field_list.syntax()).into_text_edit(&mut builder); 92 let mut builder = TextEditBuilder::default();
93 93 algo::diff(&d.ast(db).syntax(), &field_list.syntax()).into_text_edit(&mut builder);
94 Some(SourceChange::source_file_edit_from( 94 builder.finish()
95 "fill struct fields", 95 };
96 file_id, 96 Some(Fix::new("Fill struct fields", SourceFileEdit { file_id, edit }.into()))
97 builder.finish(),
98 ))
99 }; 97 };
100 98
101 res.borrow_mut().push(Diagnostic { 99 res.borrow_mut().push(Diagnostic {
@@ -117,7 +115,8 @@ pub(crate) fn diagnostics(db: &RootDatabase, file_id: FileId) -> Vec<Diagnostic>
117 let node = d.ast(db); 115 let node = d.ast(db);
118 let replacement = format!("Ok({})", node.syntax()); 116 let replacement = format!("Ok({})", node.syntax());
119 let edit = TextEdit::replace(node.syntax().text_range(), replacement); 117 let edit = TextEdit::replace(node.syntax().text_range(), replacement);
120 let fix = SourceChange::source_file_edit_from("wrap with ok", file_id, edit); 118 let source_change = SourceChange::source_file_edit_from(file_id, edit);
119 let fix = Fix::new("Wrap with ok", source_change);
121 res.borrow_mut().push(Diagnostic { 120 res.borrow_mut().push(Diagnostic {
122 range: sema.diagnostics_range(d).range, 121 range: sema.diagnostics_range(d).range,
123 message: d.message(), 122 message: d.message(),
@@ -154,9 +153,9 @@ fn check_unnecessary_braces_in_use_statement(
154 range, 153 range,
155 message: "Unnecessary braces in use statement".to_string(), 154 message: "Unnecessary braces in use statement".to_string(),
156 severity: Severity::WeakWarning, 155 severity: Severity::WeakWarning,
157 fix: Some(SourceChange::source_file_edit( 156 fix: Some(Fix::new(
158 "Remove unnecessary braces", 157 "Remove unnecessary braces",
159 SourceFileEdit { file_id, edit }, 158 SourceFileEdit { file_id, edit }.into(),
160 )), 159 )),
161 }); 160 });
162 } 161 }
@@ -198,9 +197,9 @@ fn check_struct_shorthand_initialization(
198 range: record_field.syntax().text_range(), 197 range: record_field.syntax().text_range(),
199 message: "Shorthand struct initialization".to_string(), 198 message: "Shorthand struct initialization".to_string(),
200 severity: Severity::WeakWarning, 199 severity: Severity::WeakWarning,
201 fix: Some(SourceChange::source_file_edit( 200 fix: Some(Fix::new(
202 "use struct shorthand initialization", 201 "Use struct shorthand initialization",
203 SourceFileEdit { file_id, edit }, 202 SourceFileEdit { file_id, edit }.into(),
204 )), 203 )),
205 }); 204 });
206 } 205 }
@@ -240,8 +239,12 @@ mod tests {
240 let diagnostic = 239 let diagnostic =
241 diagnostics.pop().unwrap_or_else(|| panic!("no diagnostics for:\n{}\n", before)); 240 diagnostics.pop().unwrap_or_else(|| panic!("no diagnostics for:\n{}\n", before));
242 let mut fix = diagnostic.fix.unwrap(); 241 let mut fix = diagnostic.fix.unwrap();
243 let edit = fix.source_file_edits.pop().unwrap().edit; 242 let edit = fix.source_change.source_file_edits.pop().unwrap().edit;
244 let actual = edit.apply(&before); 243 let actual = {
244 let mut actual = before.to_string();
245 edit.apply(&mut actual);
246 actual
247 };
245 assert_eq_text!(after, &actual); 248 assert_eq_text!(after, &actual);
246 } 249 }
247 250
@@ -254,9 +257,13 @@ mod tests {
254 let (analysis, file_position) = analysis_and_position(fixture); 257 let (analysis, file_position) = analysis_and_position(fixture);
255 let diagnostic = analysis.diagnostics(file_position.file_id).unwrap().pop().unwrap(); 258 let diagnostic = analysis.diagnostics(file_position.file_id).unwrap().pop().unwrap();
256 let mut fix = diagnostic.fix.unwrap(); 259 let mut fix = diagnostic.fix.unwrap();
257 let edit = fix.source_file_edits.pop().unwrap().edit; 260 let edit = fix.source_change.source_file_edits.pop().unwrap().edit;
258 let target_file_contents = analysis.file_text(file_position.file_id).unwrap(); 261 let target_file_contents = analysis.file_text(file_position.file_id).unwrap();
259 let actual = edit.apply(&target_file_contents); 262 let actual = {
263 let mut actual = target_file_contents.to_string();
264 edit.apply(&mut actual);
265 actual
266 };
260 267
261 // Strip indent and empty lines from `after`, to match the behaviour of 268 // Strip indent and empty lines from `after`, to match the behaviour of
262 // `parse_fixture` called from `analysis_and_position`. 269 // `parse_fixture` called from `analysis_and_position`.
@@ -287,8 +294,12 @@ mod tests {
287 let (analysis, file_id) = single_file(before); 294 let (analysis, file_id) = single_file(before);
288 let diagnostic = analysis.diagnostics(file_id).unwrap().pop().unwrap(); 295 let diagnostic = analysis.diagnostics(file_id).unwrap().pop().unwrap();
289 let mut fix = diagnostic.fix.unwrap(); 296 let mut fix = diagnostic.fix.unwrap();
290 let edit = fix.source_file_edits.pop().unwrap().edit; 297 let edit = fix.source_change.source_file_edits.pop().unwrap().edit;
291 let actual = edit.apply(&before); 298 let actual = {
299 let mut actual = before.to_string();
300 edit.apply(&mut actual);
301 actual
302 };
292 assert_eq_text!(after, &actual); 303 assert_eq_text!(after, &actual);
293 } 304 }
294 305
@@ -604,22 +615,24 @@ mod tests {
604 Diagnostic { 615 Diagnostic {
605 message: "unresolved module", 616 message: "unresolved module",
606 range: 0..8, 617 range: 0..8,
618 severity: Error,
607 fix: Some( 619 fix: Some(
608 SourceChange { 620 Fix {
609 label: "create module", 621 label: "Create module",
610 source_file_edits: [], 622 source_change: SourceChange {
611 file_system_edits: [ 623 source_file_edits: [],
612 CreateFile { 624 file_system_edits: [
613 source_root: SourceRootId( 625 CreateFile {
614 0, 626 source_root: SourceRootId(
615 ), 627 0,
616 path: "foo.rs", 628 ),
617 }, 629 path: "foo.rs",
618 ], 630 },
619 cursor_position: None, 631 ],
632 is_snippet: false,
633 },
620 }, 634 },
621 ), 635 ),
622 severity: Error,
623 }, 636 },
624 ] 637 ]
625 "###); 638 "###);
@@ -651,31 +664,33 @@ mod tests {
651 assert_debug_snapshot!(diagnostics, @r###" 664 assert_debug_snapshot!(diagnostics, @r###"
652 [ 665 [
653 Diagnostic { 666 Diagnostic {
654 message: "Missing structure fields:\n- b", 667 message: "Missing structure fields:\n- b\n",
655 range: 224..233, 668 range: 224..233,
669 severity: Error,
656 fix: Some( 670 fix: Some(
657 SourceChange { 671 Fix {
658 label: "fill struct fields", 672 label: "Fill struct fields",
659 source_file_edits: [ 673 source_change: SourceChange {
660 SourceFileEdit { 674 source_file_edits: [
661 file_id: FileId( 675 SourceFileEdit {
662 1, 676 file_id: FileId(
663 ), 677 1,
664 edit: TextEdit { 678 ),
665 atoms: [ 679 edit: TextEdit {
666 AtomTextEdit { 680 indels: [
667 delete: 3..9, 681 Indel {
668 insert: "{a:42, b: ()}", 682 insert: "{a:42, b: ()}",
669 }, 683 delete: 3..9,
670 ], 684 },
685 ],
686 },
671 }, 687 },
672 }, 688 ],
673 ], 689 file_system_edits: [],
674 file_system_edits: [], 690 is_snippet: false,
675 cursor_position: None, 691 },
676 }, 692 },
677 ), 693 ),
678 severity: Error,
679 }, 694 },
680 ] 695 ]
681 "###); 696 "###);