From 70ef2f23c239d66b29281c12c87b52dc4ffc2095 Mon Sep 17 00:00:00 2001 From: Tarek Date: Tue, 3 Dec 2024 23:47:52 +0200 Subject: [PATCH] fix: refactor `syntax_editor_add_generic_param` Signed-off-by: Tarek --- .../src/handlers/introduce_named_generic.rs | 9 ++-- crates/syntax/src/ast/edit_in_place.rs | 51 ++++++++++++++----- 2 files changed, 41 insertions(+), 19 deletions(-) diff --git a/crates/ide-assists/src/handlers/introduce_named_generic.rs b/crates/ide-assists/src/handlers/introduce_named_generic.rs index 25628c1656..4b4433419a 100644 --- a/crates/ide-assists/src/handlers/introduce_named_generic.rs +++ b/crates/ide-assists/src/handlers/introduce_named_generic.rs @@ -59,14 +59,11 @@ 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_.syntax_editor_add_generic_param(&mut editor, type_param.into()); + let generic_param = syntax::ast::GenericParam::from(type_param); + fn_.syntax_editor_add_generic_param(&mut editor, generic_param.clone()); if let Some(cap) = ctx.config.snippet_cap { - if let Some(generic_param) = - fn_.generic_param_list().and_then(|it| it.generic_params().last()) - { - editor.add_annotation(generic_param.syntax(), edit.make_tabstop_before(cap)); - } + editor.add_annotation(generic_param.syntax(), edit.make_tabstop_before(cap)); } editor.add_mappings(make.finish_with_mappings()); diff --git a/crates/syntax/src/ast/edit_in_place.rs b/crates/syntax/src/ast/edit_in_place.rs index 360ee14fa2..22afb8297b 100644 --- a/crates/syntax/src/ast/edit_in_place.rs +++ b/crates/syntax/src/ast/edit_in_place.rs @@ -56,6 +56,7 @@ impl GenericParamsOwnerEdit for ast::Fn { } impl ast::Fn { + /// Adds a new generic param to the function using `SyntaxEditor` pub fn syntax_editor_add_generic_param( &self, editor: &mut SyntaxEditor, @@ -65,23 +66,44 @@ impl ast::Fn { 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(), + let position = generic_param_list.r_angle_token().map_or_else( + || crate::syntax_editor::Position::last_child_of(self.syntax()), + crate::syntax_editor::Position::before, ); + + if let Some(last_param) = generic_param_list.generic_params().last() { + if last_param + .syntax() + .next_sibling_or_token() + .map_or(false, |it| it.kind() == SyntaxKind::COMMA) + { + editor.insert( + crate::syntax_editor::Position::after(last_param.syntax()), + new_param.syntax().clone(), + ); + editor.insert( + crate::syntax_editor::Position::after(last_param.syntax()), + make::token(SyntaxKind::WHITESPACE), + ); + editor.insert( + crate::syntax_editor::Position::after(last_param.syntax()), + make::token(SyntaxKind::COMMA), + ); + } else { + let elements = vec![ + make::token(SyntaxKind::COMMA).into(), + make::token(SyntaxKind::WHITESPACE).into(), + new_param.syntax().clone().into(), + ]; + editor.insert_all(position, elements); + } + }; } 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()); } }, @@ -96,9 +118,12 @@ impl ast::Fn { } else { crate::syntax_editor::Position::last_child_of(self.syntax()) }; - - let new_param_list = make::generic_param_list(once(new_param.clone())); - editor.insert(position, new_param_list.syntax().clone_for_update()); + let elements = vec![ + make::token(SyntaxKind::L_ANGLE).into(), + new_param.syntax().clone().into(), + make::token(T![>]).into(), + ]; + editor.insert_all(position, elements); } } }