diff options
Diffstat (limited to 'crates/ra_ide/src')
-rw-r--r-- | crates/ra_ide/src/diagnostics.rs | 87 |
1 files changed, 50 insertions, 37 deletions
diff --git a/crates/ra_ide/src/diagnostics.rs b/crates/ra_ide/src/diagnostics.rs index 55593a8cb..043ce357b 100644 --- a/crates/ra_ide/src/diagnostics.rs +++ b/crates/ra_ide/src/diagnostics.rs | |||
@@ -62,12 +62,18 @@ pub(crate) fn diagnostics( | |||
62 | } | 62 | } |
63 | .into(), | 63 | .into(), |
64 | ); | 64 | ); |
65 | let fix = sema | ||
66 | .diagnostic_fix_source(d) | ||
67 | .map(|unresolved_module| unresolved_module.syntax().text_range()) | ||
68 | .map(|fix_range| (fix, fix_range)); | ||
69 | |||
65 | res.borrow_mut().push(Diagnostic { | 70 | res.borrow_mut().push(Diagnostic { |
66 | range: sema.diagnostics_presentation_range(d).range, | 71 | range: sema.diagnostics_presentation_range(d).range, |
67 | message: d.message(), | 72 | message: d.message(), |
68 | severity: Severity::Error, | 73 | severity: Severity::Error, |
69 | fix: Some((fix, sema.diagnostic_fix_source(d).syntax().text_range())), | 74 | fix, |
70 | }) | 75 | }); |
76 | Some(()) | ||
71 | }) | 77 | }) |
72 | .on::<hir::diagnostics::MissingFields, _>(|d| { | 78 | .on::<hir::diagnostics::MissingFields, _>(|d| { |
73 | // Note that although we could add a diagnostics to | 79 | // Note that although we could add a diagnostics to |
@@ -78,30 +84,29 @@ pub(crate) fn diagnostics( | |||
78 | let fix = if d.missed_fields.iter().any(|it| it.as_tuple_index().is_some()) { | 84 | let fix = if d.missed_fields.iter().any(|it| it.as_tuple_index().is_some()) { |
79 | None | 85 | None |
80 | } else { | 86 | } else { |
81 | let record_expr = sema.diagnostic_fix_source(d); | 87 | sema.diagnostic_fix_source(d) |
82 | if let Some(old_field_list) = record_expr.record_expr_field_list() { | 88 | .and_then(|record_expr| record_expr.record_expr_field_list()) |
83 | let mut new_field_list = old_field_list.clone(); | 89 | .map(|old_field_list| { |
84 | for f in d.missed_fields.iter() { | 90 | let mut new_field_list = old_field_list.clone(); |
85 | let field = make::record_expr_field( | 91 | for f in d.missed_fields.iter() { |
86 | make::name_ref(&f.to_string()), | 92 | let field = make::record_expr_field( |
87 | Some(make::expr_unit()), | 93 | make::name_ref(&f.to_string()), |
88 | ); | 94 | Some(make::expr_unit()), |
89 | new_field_list = new_field_list.append_field(&field); | 95 | ); |
90 | } | 96 | new_field_list = new_field_list.append_field(&field); |
91 | 97 | } | |
92 | let edit = { | 98 | |
93 | let mut builder = TextEditBuilder::default(); | 99 | let edit = { |
94 | algo::diff(&old_field_list.syntax(), &new_field_list.syntax()) | 100 | let mut builder = TextEditBuilder::default(); |
95 | .into_text_edit(&mut builder); | 101 | algo::diff(&old_field_list.syntax(), &new_field_list.syntax()) |
96 | builder.finish() | 102 | .into_text_edit(&mut builder); |
97 | }; | 103 | builder.finish() |
98 | Some(( | 104 | }; |
99 | Fix::new("Fill struct fields", SourceFileEdit { file_id, edit }.into()), | 105 | ( |
100 | sema.original_range(&old_field_list.syntax()).range, | 106 | Fix::new("Fill struct fields", SourceFileEdit { file_id, edit }.into()), |
101 | )) | 107 | sema.original_range(&old_field_list.syntax()).range, |
102 | } else { | 108 | ) |
103 | None | 109 | }) |
104 | } | ||
105 | }; | 110 | }; |
106 | 111 | ||
107 | res.borrow_mut().push(Diagnostic { | 112 | res.borrow_mut().push(Diagnostic { |
@@ -109,28 +114,36 @@ pub(crate) fn diagnostics( | |||
109 | message: d.message(), | 114 | message: d.message(), |
110 | severity: Severity::Error, | 115 | severity: Severity::Error, |
111 | fix, | 116 | fix, |
112 | }) | 117 | }); |
118 | Some(()) | ||
113 | }) | 119 | }) |
114 | .on::<hir::diagnostics::MissingOkInTailExpr, _>(|d| { | 120 | .on::<hir::diagnostics::MissingOkInTailExpr, _>(|d| { |
115 | let tail_expr = sema.diagnostic_fix_source(d); | 121 | let fix = sema.diagnostic_fix_source(d).map(|tail_expr| { |
116 | let tail_expr_range = tail_expr.syntax().text_range(); | 122 | let tail_expr_range = tail_expr.syntax().text_range(); |
117 | let edit = TextEdit::replace(tail_expr_range, format!("Ok({})", tail_expr.syntax())); | 123 | let edit = |
118 | let source_change = SourceFileEdit { file_id, edit }.into(); | 124 | TextEdit::replace(tail_expr_range, format!("Ok({})", tail_expr.syntax())); |
125 | let source_change = SourceFileEdit { file_id, edit }.into(); | ||
126 | (Fix::new("Wrap with ok", source_change), tail_expr_range) | ||
127 | }); | ||
128 | |||
119 | res.borrow_mut().push(Diagnostic { | 129 | res.borrow_mut().push(Diagnostic { |
120 | range: sema.diagnostics_presentation_range(d).range, | 130 | range: sema.diagnostics_presentation_range(d).range, |
121 | message: d.message(), | 131 | message: d.message(), |
122 | severity: Severity::Error, | 132 | severity: Severity::Error, |
123 | fix: Some((Fix::new("Wrap with ok", source_change), tail_expr_range)), | 133 | fix, |
124 | }) | 134 | }); |
135 | Some(()) | ||
125 | }) | 136 | }) |
126 | .on::<hir::diagnostics::NoSuchField, _>(|d| { | 137 | .on::<hir::diagnostics::NoSuchField, _>(|d| { |
127 | res.borrow_mut().push(Diagnostic { | 138 | res.borrow_mut().push(Diagnostic { |
128 | range: sema.diagnostics_presentation_range(d).range, | 139 | range: sema.diagnostics_presentation_range(d).range, |
129 | message: d.message(), | 140 | message: d.message(), |
130 | severity: Severity::Error, | 141 | severity: Severity::Error, |
131 | fix: missing_struct_field_fix(&sema, file_id, d) | 142 | fix: missing_struct_field_fix(&sema, file_id, d).and_then(|fix| { |
132 | .map(|fix| (fix, sema.diagnostic_fix_source(d).syntax().text_range())), | 143 | Some((fix, sema.diagnostic_fix_source(d)?.syntax().text_range())) |
133 | }) | 144 | }), |
145 | }); | ||
146 | Some(()) | ||
134 | }) | 147 | }) |
135 | // Only collect experimental diagnostics when they're enabled. | 148 | // Only collect experimental diagnostics when they're enabled. |
136 | .filter(|diag| !diag.is_experimental() || enable_experimental) | 149 | .filter(|diag| !diag.is_experimental() || enable_experimental) |
@@ -156,7 +169,7 @@ fn missing_struct_field_fix( | |||
156 | usage_file_id: FileId, | 169 | usage_file_id: FileId, |
157 | d: &hir::diagnostics::NoSuchField, | 170 | d: &hir::diagnostics::NoSuchField, |
158 | ) -> Option<Fix> { | 171 | ) -> Option<Fix> { |
159 | let record_expr_field = sema.diagnostic_fix_source(d); | 172 | let record_expr_field = sema.diagnostic_fix_source(d)?; |
160 | 173 | ||
161 | let record_lit = ast::RecordExpr::cast(record_expr_field.syntax().parent()?.parent()?)?; | 174 | let record_lit = ast::RecordExpr::cast(record_expr_field.syntax().parent()?.parent()?)?; |
162 | let def_id = sema.resolve_variant(record_lit)?; | 175 | let def_id = sema.resolve_variant(record_lit)?; |