diff options
Diffstat (limited to 'crates/ide/src/diagnostics.rs')
-rw-r--r-- | crates/ide/src/diagnostics.rs | 64 |
1 files changed, 64 insertions, 0 deletions
diff --git a/crates/ide/src/diagnostics.rs b/crates/ide/src/diagnostics.rs index f5d627b6e..71ab98c1f 100644 --- a/crates/ide/src/diagnostics.rs +++ b/crates/ide/src/diagnostics.rs | |||
@@ -96,6 +96,9 @@ pub(crate) fn diagnostics( | |||
96 | .on::<hir::diagnostics::NoSuchField, _>(|d| { | 96 | .on::<hir::diagnostics::NoSuchField, _>(|d| { |
97 | res.borrow_mut().push(diagnostic_with_fix(d, &sema)); | 97 | res.borrow_mut().push(diagnostic_with_fix(d, &sema)); |
98 | }) | 98 | }) |
99 | .on::<hir::diagnostics::IncorrectCase, _>(|d| { | ||
100 | res.borrow_mut().push(warning_with_fix(d, &sema)); | ||
101 | }) | ||
99 | // Only collect experimental diagnostics when they're enabled. | 102 | // Only collect experimental diagnostics when they're enabled. |
100 | .filter(|diag| !(diag.is_experimental() && config.disable_experimental)) | 103 | .filter(|diag| !(diag.is_experimental() && config.disable_experimental)) |
101 | .filter(|diag| !config.disabled.contains(diag.code().as_str())); | 104 | .filter(|diag| !config.disabled.contains(diag.code().as_str())); |
@@ -130,6 +133,16 @@ fn diagnostic_with_fix<D: DiagnosticWithFix>(d: &D, sema: &Semantics<RootDatabas | |||
130 | } | 133 | } |
131 | } | 134 | } |
132 | 135 | ||
136 | fn warning_with_fix<D: DiagnosticWithFix>(d: &D, sema: &Semantics<RootDatabase>) -> Diagnostic { | ||
137 | Diagnostic { | ||
138 | // name: Some(d.name().into()), | ||
139 | range: sema.diagnostics_display_range(d).range, | ||
140 | message: d.message(), | ||
141 | severity: Severity::WeakWarning, | ||
142 | fix: d.fix(&sema), | ||
143 | } | ||
144 | } | ||
145 | |||
133 | fn check_unnecessary_braces_in_use_statement( | 146 | fn check_unnecessary_braces_in_use_statement( |
134 | acc: &mut Vec<Diagnostic>, | 147 | acc: &mut Vec<Diagnostic>, |
135 | file_id: FileId, | 148 | file_id: FileId, |
@@ -253,6 +266,37 @@ mod tests { | |||
253 | ); | 266 | ); |
254 | } | 267 | } |
255 | 268 | ||
269 | /// Similar to `check_fix`, but applies all the available fixes. | ||
270 | fn check_fixes(ra_fixture_before: &str, ra_fixture_after: &str) { | ||
271 | let after = trim_indent(ra_fixture_after); | ||
272 | |||
273 | let (analysis, file_position) = fixture::position(ra_fixture_before); | ||
274 | let diagnostic = analysis | ||
275 | .diagnostics(&DiagnosticsConfig::default(), file_position.file_id) | ||
276 | .unwrap() | ||
277 | .pop() | ||
278 | .unwrap(); | ||
279 | let fix = diagnostic.fix.unwrap(); | ||
280 | let target_file_contents = analysis.file_text(file_position.file_id).unwrap(); | ||
281 | let actual = { | ||
282 | let mut actual = target_file_contents.to_string(); | ||
283 | // Go from the last one to the first one, so that ranges won't be affected by previous edits. | ||
284 | for edit in fix.source_change.source_file_edits.iter().rev() { | ||
285 | edit.edit.apply(&mut actual); | ||
286 | } | ||
287 | actual | ||
288 | }; | ||
289 | |||
290 | assert_eq_text!(&after, &actual); | ||
291 | assert!( | ||
292 | fix.fix_trigger_range.start() <= file_position.offset | ||
293 | && fix.fix_trigger_range.end() >= file_position.offset, | ||
294 | "diagnostic fix range {:?} does not touch cursor position {:?}", | ||
295 | fix.fix_trigger_range, | ||
296 | file_position.offset | ||
297 | ); | ||
298 | } | ||
299 | |||
256 | /// Checks that a diagnostic applies to the file containing the `<|>` cursor marker | 300 | /// Checks that a diagnostic applies to the file containing the `<|>` cursor marker |
257 | /// which has a fix that can apply to other files. | 301 | /// which has a fix that can apply to other files. |
258 | fn check_apply_diagnostic_fix_in_other_file(ra_fixture_before: &str, ra_fixture_after: &str) { | 302 | fn check_apply_diagnostic_fix_in_other_file(ra_fixture_before: &str, ra_fixture_after: &str) { |
@@ -790,4 +834,24 @@ struct Foo { | |||
790 | let diagnostics = analysis.diagnostics(&DiagnosticsConfig::default(), file_id).unwrap(); | 834 | let diagnostics = analysis.diagnostics(&DiagnosticsConfig::default(), file_id).unwrap(); |
791 | assert!(!diagnostics.is_empty()); | 835 | assert!(!diagnostics.is_empty()); |
792 | } | 836 | } |
837 | |||
838 | #[test] | ||
839 | fn test_rename_incorrect_case() { | ||
840 | check_fixes( | ||
841 | r#" | ||
842 | pub struct test_struct<|> { one: i32 } | ||
843 | |||
844 | pub fn some_fn(val: test_struct) -> test_struct { | ||
845 | test_struct { one: val.one + 1 } | ||
846 | } | ||
847 | "#, | ||
848 | r#" | ||
849 | pub struct TestStruct { one: i32 } | ||
850 | |||
851 | pub fn some_fn(val: TestStruct) -> TestStruct { | ||
852 | TestStruct { one: val.one + 1 } | ||
853 | } | ||
854 | "#, | ||
855 | ); | ||
856 | } | ||
793 | } | 857 | } |