rust/crates/ide/src/diagnostics/fixes/change_case.rs

156 lines
3.5 KiB
Rust
Raw Normal View History

use hir::{db::AstDatabase, diagnostics::IncorrectCase, InFile, Semantics};
use ide_assists::{Assist, AssistResolveStrategy};
use ide_db::{base_db::FilePosition, RootDatabase};
use syntax::AstNode;
use crate::{
2021-05-18 08:11:07 +09:00
diagnostics::{unresolved_fix, DiagnosticWithFixes},
references::rename::rename_with_semantics,
};
2021-05-18 08:11:07 +09:00
impl DiagnosticWithFixes for IncorrectCase {
fn fixes(
&self,
sema: &Semantics<RootDatabase>,
resolve: &AssistResolveStrategy,
2021-05-18 08:11:07 +09:00
) -> Option<Vec<Assist>> {
let root = sema.db.parse_or_expand(self.file)?;
let name_node = self.ident.to_node(&root);
let name_node = InFile::new(self.file, name_node.syntax());
let frange = name_node.original_file_range(sema.db);
let file_position = FilePosition { file_id: frange.file_id, offset: frange.range.start() };
let label = format!("Rename to {}", self.suggested_text);
let mut res = unresolved_fix("change_case", &label, frange.range);
if resolve.should_resolve(&res.id) {
let source_change = rename_with_semantics(sema, file_position, &self.suggested_text);
res.source_change = Some(source_change.ok().unwrap_or_default());
}
2021-05-18 08:11:07 +09:00
Some(vec![res])
}
}
#[cfg(test)]
mod change_case {
use crate::{
2021-06-13 19:27:14 +03:00
diagnostics::tests::{check_diagnostics, check_fix},
fixture, AssistResolveStrategy, DiagnosticsConfig,
};
#[test]
fn test_rename_incorrect_case() {
check_fix(
r#"
pub struct test_struct$0 { 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 }
}
"#,
);
check_fix(
r#"
pub fn some_fn(NonSnakeCase$0: u8) -> u8 {
NonSnakeCase
}
"#,
r#"
pub fn some_fn(non_snake_case: u8) -> u8 {
non_snake_case
}
"#,
);
check_fix(
r#"
pub fn SomeFn$0(val: u8) -> u8 {
if val != 0 { SomeFn(val - 1) } else { val }
}
"#,
r#"
pub fn some_fn(val: u8) -> u8 {
if val != 0 { some_fn(val - 1) } else { val }
}
"#,
);
check_fix(
r#"
fn some_fn() {
let whatAWeird_Formatting$0 = 10;
another_func(whatAWeird_Formatting);
}
"#,
r#"
fn some_fn() {
let what_a_weird_formatting = 10;
another_func(what_a_weird_formatting);
}
"#,
);
}
#[test]
fn test_uppercase_const_no_diagnostics() {
2021-06-13 19:27:14 +03:00
check_diagnostics(
r#"
fn foo() {
const ANOTHER_ITEM$0: &str = "some_item";
}
"#,
);
}
#[test]
fn test_rename_incorrect_case_struct_method() {
check_fix(
r#"
pub struct TestStruct;
impl TestStruct {
pub fn SomeFn$0() -> TestStruct {
TestStruct
}
}
"#,
r#"
pub struct TestStruct;
impl TestStruct {
pub fn some_fn() -> TestStruct {
TestStruct
}
}
"#,
);
}
#[test]
fn test_single_incorrect_case_diagnostic_in_function_name_issue_6970() {
let input = r#"fn FOO$0() {}"#;
let expected = r#"fn foo() {}"#;
let (analysis, file_position) = fixture::position(input);
let diagnostics = analysis
.diagnostics(
&DiagnosticsConfig::default(),
AssistResolveStrategy::All,
file_position.file_id,
)
.unwrap();
assert_eq!(diagnostics.len(), 1);
check_fix(input, expected);
}
}