aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_ide/src
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_ide/src')
-rw-r--r--crates/ra_ide/src/diagnostics.rs139
1 files changed, 71 insertions, 68 deletions
diff --git a/crates/ra_ide/src/diagnostics.rs b/crates/ra_ide/src/diagnostics.rs
index e029af0dc..8e715faa4 100644
--- a/crates/ra_ide/src/diagnostics.rs
+++ b/crates/ra_ide/src/diagnostics.rs
@@ -7,7 +7,7 @@
7use std::cell::RefCell; 7use std::cell::RefCell;
8 8
9use hir::{ 9use hir::{
10 diagnostics::{AstDiagnostic, Diagnostic as _, DiagnosticSink}, 10 diagnostics::{AstDiagnostic, Diagnostic as _, DiagnosticSinkBuilder},
11 HasSource, HirDisplay, Semantics, VariantDef, 11 HasSource, HirDisplay, Semantics, VariantDef,
12}; 12};
13use itertools::Itertools; 13use itertools::Itertools;
@@ -48,79 +48,82 @@ pub(crate) fn diagnostics(db: &RootDatabase, file_id: FileId) -> Vec<Diagnostic>
48 check_struct_shorthand_initialization(&mut res, file_id, &node); 48 check_struct_shorthand_initialization(&mut res, file_id, &node);
49 } 49 }
50 let res = RefCell::new(res); 50 let res = RefCell::new(res);
51 let mut sink = DiagnosticSink::new(|d| { 51 let mut sink = DiagnosticSinkBuilder::new()
52 res.borrow_mut().push(Diagnostic { 52 .on::<hir::diagnostics::UnresolvedModule, _>(|d| {
53 message: d.message(), 53 let original_file = d.source().file_id.original_file(db);
54 range: sema.diagnostics_range(d).range, 54 let fix = Fix::new(
55 severity: Severity::Error, 55 "Create module",
56 fix: None, 56 FileSystemEdit::CreateFile { anchor: original_file, dst: d.candidate.clone() }
57 .into(),
58 );
59 res.borrow_mut().push(Diagnostic {
60 range: sema.diagnostics_range(d).range,
61 message: d.message(),
62 severity: Severity::Error,
63 fix: Some(fix),
64 })
57 }) 65 })
58 }) 66 .on::<hir::diagnostics::MissingFields, _>(|d| {
59 .on::<hir::diagnostics::UnresolvedModule, _>(|d| { 67 // Note that although we could add a diagnostics to
60 let original_file = d.source().file_id.original_file(db); 68 // fill the missing tuple field, e.g :
61 let fix = Fix::new( 69 // `struct A(usize);`
62 "Create module", 70 // `let a = A { 0: () }`
63 FileSystemEdit::CreateFile { anchor: original_file, dst: d.candidate.clone() }.into(), 71 // but it is uncommon usage and it should not be encouraged.
64 ); 72 let fix = if d.missed_fields.iter().any(|it| it.as_tuple_index().is_some()) {
65 res.borrow_mut().push(Diagnostic { 73 None
66 range: sema.diagnostics_range(d).range, 74 } else {
67 message: d.message(), 75 let mut field_list = d.ast(db);
68 severity: Severity::Error, 76 for f in d.missed_fields.iter() {
69 fix: Some(fix), 77 let field =
70 }) 78 make::record_field(make::name_ref(&f.to_string()), Some(make::expr_unit()));
71 }) 79 field_list = field_list.append_field(&field);
72 .on::<hir::diagnostics::MissingFields, _>(|d| { 80 }
73 // Note that although we could add a diagnostics to 81
74 // fill the missing tuple field, e.g : 82 let edit = {
75 // `struct A(usize);` 83 let mut builder = TextEditBuilder::default();
76 // `let a = A { 0: () }` 84 algo::diff(&d.ast(db).syntax(), &field_list.syntax())
77 // but it is uncommon usage and it should not be encouraged. 85 .into_text_edit(&mut builder);
78 let fix = if d.missed_fields.iter().any(|it| it.as_tuple_index().is_some()) { 86 builder.finish()
79 None 87 };
80 } else { 88 Some(Fix::new("Fill struct fields", SourceFileEdit { file_id, edit }.into()))
81 let mut field_list = d.ast(db);
82 for f in d.missed_fields.iter() {
83 let field =
84 make::record_field(make::name_ref(&f.to_string()), Some(make::expr_unit()));
85 field_list = field_list.append_field(&field);
86 }
87
88 let edit = {
89 let mut builder = TextEditBuilder::default();
90 algo::diff(&d.ast(db).syntax(), &field_list.syntax()).into_text_edit(&mut builder);
91 builder.finish()
92 }; 89 };
93 Some(Fix::new("Fill struct fields", SourceFileEdit { file_id, edit }.into()))
94 };
95 90
96 res.borrow_mut().push(Diagnostic { 91 res.borrow_mut().push(Diagnostic {
97 range: sema.diagnostics_range(d).range, 92 range: sema.diagnostics_range(d).range,
98 message: d.message(), 93 message: d.message(),
99 severity: Severity::Error, 94 severity: Severity::Error,
100 fix, 95 fix,
96 })
101 }) 97 })
102 }) 98 .on::<hir::diagnostics::MissingOkInTailExpr, _>(|d| {
103 .on::<hir::diagnostics::MissingOkInTailExpr, _>(|d| { 99 let node = d.ast(db);
104 let node = d.ast(db); 100 let replacement = format!("Ok({})", node.syntax());
105 let replacement = format!("Ok({})", node.syntax()); 101 let edit = TextEdit::replace(node.syntax().text_range(), replacement);
106 let edit = TextEdit::replace(node.syntax().text_range(), replacement); 102 let source_change = SourceFileEdit { file_id, edit }.into();
107 let source_change = SourceFileEdit { file_id, edit }.into(); 103 let fix = Fix::new("Wrap with ok", source_change);
108 let fix = Fix::new("Wrap with ok", source_change); 104 res.borrow_mut().push(Diagnostic {
109 res.borrow_mut().push(Diagnostic { 105 range: sema.diagnostics_range(d).range,
110 range: sema.diagnostics_range(d).range, 106 message: d.message(),
111 message: d.message(), 107 severity: Severity::Error,
112 severity: Severity::Error, 108 fix: Some(fix),
113 fix: Some(fix), 109 })
114 }) 110 })
115 }) 111 .on::<hir::diagnostics::NoSuchField, _>(|d| {
116 .on::<hir::diagnostics::NoSuchField, _>(|d| { 112 res.borrow_mut().push(Diagnostic {
117 res.borrow_mut().push(Diagnostic { 113 range: sema.diagnostics_range(d).range,
118 range: sema.diagnostics_range(d).range, 114 message: d.message(),
119 message: d.message(), 115 severity: Severity::Error,
120 severity: Severity::Error, 116 fix: missing_struct_field_fix(&sema, file_id, d),
121 fix: missing_struct_field_fix(&sema, file_id, d), 117 })
122 }) 118 })
123 }); 119 .build(|d| {
120 res.borrow_mut().push(Diagnostic {
121 message: d.message(),
122 range: sema.diagnostics_range(d).range,
123 severity: Severity::Error,
124 fix: None,
125 })
126 });
124 127
125 if let Some(m) = sema.to_module_def(file_id) { 128 if let Some(m) = sema.to_module_def(file_id) {
126 m.diagnostics(db, &mut sink); 129 m.diagnostics(db, &mut sink);