Add fix for incorrect case diagnostic

This commit is contained in:
Igor Aleksanov 2020-10-03 17:34:52 +03:00
parent 17f1026c46
commit e24e22f288
8 changed files with 112 additions and 30 deletions

View file

@ -96,6 +96,9 @@ pub(crate) fn diagnostics(
.on::<hir::diagnostics::NoSuchField, _>(|d| {
res.borrow_mut().push(diagnostic_with_fix(d, &sema));
})
.on::<hir::diagnostics::IncorrectCase, _>(|d| {
res.borrow_mut().push(warning_with_fix(d, &sema));
})
// Only collect experimental diagnostics when they're enabled.
.filter(|diag| !(diag.is_experimental() && config.disable_experimental))
.filter(|diag| !config.disabled.contains(diag.code().as_str()));
@ -130,6 +133,16 @@ fn diagnostic_with_fix<D: DiagnosticWithFix>(d: &D, sema: &Semantics<RootDatabas
}
}
fn warning_with_fix<D: DiagnosticWithFix>(d: &D, sema: &Semantics<RootDatabase>) -> Diagnostic {
Diagnostic {
// name: Some(d.name().into()),
range: sema.diagnostics_display_range(d).range,
message: d.message(),
severity: Severity::WeakWarning,
fix: d.fix(&sema),
}
}
fn check_unnecessary_braces_in_use_statement(
acc: &mut Vec<Diagnostic>,
file_id: FileId,
@ -253,6 +266,37 @@ mod tests {
);
}
/// Similar to `check_fix`, but applies all the available fixes.
fn check_fixes(ra_fixture_before: &str, ra_fixture_after: &str) {
let after = trim_indent(ra_fixture_after);
let (analysis, file_position) = fixture::position(ra_fixture_before);
let diagnostic = analysis
.diagnostics(&DiagnosticsConfig::default(), file_position.file_id)
.unwrap()
.pop()
.unwrap();
let fix = diagnostic.fix.unwrap();
let target_file_contents = analysis.file_text(file_position.file_id).unwrap();
let actual = {
let mut actual = target_file_contents.to_string();
// Go from the last one to the first one, so that ranges won't be affected by previous edits.
for edit in fix.source_change.source_file_edits.iter().rev() {
edit.edit.apply(&mut actual);
}
actual
};
assert_eq_text!(&after, &actual);
assert!(
fix.fix_trigger_range.start() <= file_position.offset
&& fix.fix_trigger_range.end() >= file_position.offset,
"diagnostic fix range {:?} does not touch cursor position {:?}",
fix.fix_trigger_range,
file_position.offset
);
}
/// Checks that a diagnostic applies to the file containing the `<|>` cursor marker
/// which has a fix that can apply to other files.
fn check_apply_diagnostic_fix_in_other_file(ra_fixture_before: &str, ra_fixture_after: &str) {
@ -790,4 +834,24 @@ struct Foo {
let diagnostics = analysis.diagnostics(&DiagnosticsConfig::default(), file_id).unwrap();
assert!(!diagnostics.is_empty());
}
#[test]
fn test_rename_incorrect_case() {
check_fixes(
r#"
pub struct test_struct<|> { one: i32 }
pub fn some_fn(val: test_struct) -> test_struct {
test_struct { one: val.one + 1 }
}
"#,
r#"
pub struct TestStruct { one: i32 }
pub fn some_fn(val: TestStruct) -> TestStruct {
TestStruct { one: val.one + 1 }
}
"#,
);
}
}