From 54f7ed13f56bb130b000eb60eb676c979ca5e00d Mon Sep 17 00:00:00 2001 From: Tarek Date: Wed, 27 Nov 2024 14:56:56 +0200 Subject: [PATCH] fix: refactor `syntax_editor_add_generic_param` to handle adding new generic parameters Signed-off-by: Tarek --- .../src/handlers/introduce_named_generic.rs | 23 +++---- crates/syntax/src/ast/edit_in_place.rs | 65 +++++++++---------- 2 files changed, 42 insertions(+), 46 deletions(-) diff --git a/crates/ide-assists/src/handlers/introduce_named_generic.rs b/crates/ide-assists/src/handlers/introduce_named_generic.rs index c6945d6245..25628c1656 100644 --- a/crates/ide-assists/src/handlers/introduce_named_generic.rs +++ b/crates/ide-assists/src/handlers/introduce_named_generic.rs @@ -39,16 +39,17 @@ pub(crate) fn introduce_named_generic(acc: &mut Assists, ctx: &AssistContext<'_> target, |edit| { let mut editor = edit.make_editor(&parent_node); - let fn_generic_param_list = - fn_.syntax_editor_get_or_create_generic_param_list(&mut editor); - let existing_names = fn_generic_param_list - .generic_params() - .flat_map(|param| match param { - ast::GenericParam::TypeParam(t) => t.name().map(|name| name.to_string()), - p => Some(p.to_string()), - }) - .collect_vec(); + let existing_names = match fn_.generic_param_list() { + Some(generic_param_list) => generic_param_list + .generic_params() + .flat_map(|param| match param { + ast::GenericParam::TypeParam(t) => t.name().map(|name| name.to_string()), + p => Some(p.to_string()), + }) + .collect_vec(), + None => Vec::new(), + }; let type_param_name = suggest_name::NameGenerator::new_with_names( existing_names.iter().map(|s| s.as_str()), ) @@ -58,13 +59,13 @@ pub(crate) fn introduce_named_generic(acc: &mut Assists, ctx: &AssistContext<'_> let new_ty = make.ty(&type_param_name); editor.replace(impl_trait_type.syntax(), new_ty.syntax()); - fn_generic_param_list.syntax_editor_add_generic_param(&mut editor, type_param.into()); + fn_.syntax_editor_add_generic_param(&mut editor, type_param.into()); if let Some(cap) = ctx.config.snippet_cap { if let Some(generic_param) = fn_.generic_param_list().and_then(|it| it.generic_params().last()) { - edit.add_tabstop_before(cap, generic_param); + editor.add_annotation(generic_param.syntax(), edit.make_tabstop_before(cap)); } } diff --git a/crates/syntax/src/ast/edit_in_place.rs b/crates/syntax/src/ast/edit_in_place.rs index 9a5c122e27..360ee14fa2 100644 --- a/crates/syntax/src/ast/edit_in_place.rs +++ b/crates/syntax/src/ast/edit_in_place.rs @@ -56,13 +56,37 @@ impl GenericParamsOwnerEdit for ast::Fn { } impl ast::Fn { - pub fn syntax_editor_get_or_create_generic_param_list( + pub fn syntax_editor_add_generic_param( &self, editor: &mut SyntaxEditor, - ) -> ast::GenericParamList { + new_param: GenericParam, + ) { match self.generic_param_list() { - Some(it) => it, + Some(generic_param_list) => match generic_param_list.generic_params().last() { + Some(_last_param) => { + // There exists a generic param list and it's not empty + let mut params = generic_param_list + .generic_params() + .map(|param| param.clone()) + .collect::>(); + params.push(new_param.into()); + let new_param_list = make::generic_param_list(params); + editor.replace( + generic_param_list.syntax(), + new_param_list.syntax().clone_for_update(), + ); + } + None => { + // There exists a generic param list but it's empty + let position = crate::syntax_editor::Position::after( + generic_param_list.l_angle_token().unwrap(), + ); + + editor.insert(position, new_param.syntax()); + } + }, None => { + // There was no generic param list let position = if let Some(name) = self.name() { crate::syntax_editor::Position::after(name.syntax) } else if let Some(fn_token) = self.fn_token() { @@ -72,7 +96,9 @@ impl ast::Fn { } else { crate::syntax_editor::Position::last_child_of(self.syntax()) }; - syntax_editor_create_generic_param_list(editor, position) + + let new_param_list = make::generic_param_list(once(new_param.clone())); + editor.insert(position, new_param_list.syntax().clone_for_update()); } } } @@ -214,15 +240,6 @@ fn create_generic_param_list(position: Position) -> ast::GenericParamList { gpl } -fn syntax_editor_create_generic_param_list( - editor: &mut SyntaxEditor, - position: crate::syntax_editor::Position, -) -> ast::GenericParamList { - let gpl = make::generic_param_list(empty()).clone_for_update(); - editor.insert(position, gpl.syntax()); - gpl -} - pub trait AttrsOwnerEdit: ast::HasAttrs { fn remove_attrs_and_docs(&self) { remove_attrs_and_docs(self.syntax()); @@ -290,28 +307,6 @@ impl ast::GenericParamList { } } - pub fn syntax_editor_add_generic_param( - &self, - editor: &mut SyntaxEditor, - new_param: ast::GenericParam, - ) { - match self.generic_params().last() { - Some(_) => { - let mut params = - self.generic_params().map(|param| param.clone()).collect::>(); - params.push(new_param.into()); - let new_param_list = make::generic_param_list(params); - - editor.replace(self.syntax(), new_param_list.syntax()); - } - None => { - let position = crate::syntax_editor::Position::after(self.l_angle_token().unwrap()); - let new_param_list = make::generic_param_list(once(new_param.clone())); - editor.insert(position, new_param_list.syntax()); - } - } - } - /// Removes the existing generic param pub fn remove_generic_param(&self, generic_param: ast::GenericParam) { if let Some(previous) = generic_param.syntax().prev_sibling() {