mirror of
https://github.com/rust-lang/rust-analyzer
synced 2024-12-27 05:23:24 +00:00
Auto merge of #17571 - winstxnhdw:bool-to-enum-no-dupe, r=Veykril
feat: do not add new enum if it already exists ## Summary This PR introduces a check for the existence of another enum within the current scope, and if it exist, we skip `add_enum_def`. ## Why? Currently, when using the `bool_to_enum` assist more than once, it is possible to add multiple enum definitions. For example, the following snippet, ```rs #[derive(PartialEq, Eq)] enum Bool { True, False, } fn main() { let a = Bool::True; let b = true; println!("Hello, world!"); } ``` will be transformed into, ```rs #[derive(PartialEq, Eq)] enum Bool { True, False, } #[derive(PartialEq, Eq)] enum Bool { True, False, } fn main() { let a = Bool::True; let b = Bool::True; println!("Hello, world!"); } ``` This can be annoying for users to clean up.
This commit is contained in:
commit
5577e4e3b1
1 changed files with 44 additions and 3 deletions
|
@ -96,7 +96,7 @@ struct BoolNodeData {
|
|||
|
||||
/// Attempts to find an appropriate node to apply the action to.
|
||||
fn find_bool_node(ctx: &AssistContext<'_>) -> Option<BoolNodeData> {
|
||||
let name: ast::Name = ctx.find_node_at_offset()?;
|
||||
let name = ctx.find_node_at_offset::<ast::Name>()?;
|
||||
|
||||
if let Some(ident_pat) = name.syntax().parent().and_then(ast::IdentPat::cast) {
|
||||
let def = ctx.sema.to_def(&ident_pat)?;
|
||||
|
@ -461,7 +461,20 @@ fn add_enum_def(
|
|||
usages: &UsageSearchResult,
|
||||
target_node: SyntaxNode,
|
||||
target_module: &hir::Module,
|
||||
) {
|
||||
) -> Option<()> {
|
||||
let insert_before = node_to_insert_before(target_node);
|
||||
|
||||
if ctx
|
||||
.sema
|
||||
.scope(&insert_before)?
|
||||
.module()
|
||||
.scope(ctx.db(), Some(*target_module))
|
||||
.iter()
|
||||
.any(|(name, _)| name.as_str() == Some("Bool"))
|
||||
{
|
||||
return None;
|
||||
}
|
||||
|
||||
let make_enum_pub = usages
|
||||
.iter()
|
||||
.flat_map(|(_, refs)| refs)
|
||||
|
@ -472,7 +485,6 @@ fn add_enum_def(
|
|||
.any(|module| module.nearest_non_block_module(ctx.db()) != *target_module);
|
||||
let enum_def = make_bool_enum(make_enum_pub);
|
||||
|
||||
let insert_before = node_to_insert_before(target_node);
|
||||
let indent = IndentLevel::from_node(&insert_before);
|
||||
enum_def.reindent_to(indent);
|
||||
|
||||
|
@ -480,6 +492,8 @@ fn add_enum_def(
|
|||
insert_before.text_range().start(),
|
||||
format!("{}\n\n{indent}", enum_def.syntax().text()),
|
||||
);
|
||||
|
||||
Some(())
|
||||
}
|
||||
|
||||
/// Finds where to put the new enum definition.
|
||||
|
@ -553,6 +567,33 @@ fn function(foo: Bool, bar: bool) {
|
|||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn no_duplicate_enums() {
|
||||
check_assist(
|
||||
bool_to_enum,
|
||||
r#"
|
||||
#[derive(PartialEq, Eq)]
|
||||
enum Bool { True, False }
|
||||
|
||||
fn function(foo: bool, $0bar: bool) {
|
||||
if bar {
|
||||
println!("bar");
|
||||
}
|
||||
}
|
||||
"#,
|
||||
r#"
|
||||
#[derive(PartialEq, Eq)]
|
||||
enum Bool { True, False }
|
||||
|
||||
fn function(foo: bool, bar: Bool) {
|
||||
if bar == Bool::True {
|
||||
println!("bar");
|
||||
}
|
||||
}
|
||||
"#,
|
||||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn parameter_with_last_param_usage() {
|
||||
check_assist(
|
||||
|
|
Loading…
Reference in a new issue