From 7259cc82f362bd1cd00f47ff3ffc71be769162b6 Mon Sep 17 00:00:00 2001 From: Aleksei Sidorov Date: Thu, 3 Sep 2020 14:46:28 +0300 Subject: Resolve most of corner cases --- .../handlers/replace_impl_trait_with_generic.rs | 110 +++++++++++++++++++-- 1 file changed, 102 insertions(+), 8 deletions(-) (limited to 'crates/assists') diff --git a/crates/assists/src/handlers/replace_impl_trait_with_generic.rs b/crates/assists/src/handlers/replace_impl_trait_with_generic.rs index 8af2d16dd..5b0d5d971 100644 --- a/crates/assists/src/handlers/replace_impl_trait_with_generic.rs +++ b/crates/assists/src/handlers/replace_impl_trait_with_generic.rs @@ -13,9 +13,6 @@ pub(crate) fn replace_impl_trait_with_generic( let type_param = type_impl_trait.syntax().parent().and_then(ast::Param::cast)?; let type_fn = type_param.syntax().ancestors().nth(2).and_then(ast::Fn::cast)?; - let generic_param_list = - type_fn.generic_param_list().unwrap_or_else(|| make::generic_param_list(None)); - let impl_trait_ty = type_impl_trait .syntax() .descendants() @@ -31,11 +28,16 @@ pub(crate) fn replace_impl_trait_with_generic( target, |edit| { let generic_letter = impl_trait_ty[..1].to_string(); - edit.replace_ast::(type_impl_trait.into(), make::ty(&generic_letter)); - let new_params = generic_param_list - .append_param(make::generic_param(generic_letter, Some(impl_trait_ty))); - let new_type_fn = type_fn.replace_descendant(generic_param_list, new_params); + let generic_param_list = type_fn + .generic_param_list() + .unwrap_or_else(|| make::generic_param_list(None)) + .append_param(make::generic_param(generic_letter.clone(), Some(impl_trait_ty))); + + let new_type_fn = type_fn + .replace_descendant::(type_impl_trait.into(), make::ty(&generic_letter)) + .with_generic_params(generic_param_list); + edit.replace_ast(type_fn.clone(), new_type_fn); }, ) @@ -48,7 +50,7 @@ mod tests { use crate::tests::check_assist; #[test] - fn replace_with_generic_params() { + fn replace_impl_trait_with_generic_params() { check_assist( replace_impl_trait_with_generic, r#" @@ -59,4 +61,96 @@ mod tests { "#, ); } + + #[test] + fn replace_impl_trait_without_generic_params() { + check_assist( + replace_impl_trait_with_generic, + r#" + fn foo(bar: <|>impl Bar) {} + "#, + r#" + fn foo(bar: B) {} + "#, + ); + } + + #[test] + fn replace_two_impl_trait_with_generic_params() { + check_assist( + replace_impl_trait_with_generic, + r#" + fn foo(foo: impl Foo, bar: <|>impl Bar) {} + "#, + r#" + fn foo(foo: impl Foo, bar: B) {} + "#, + ); + } + + #[test] + fn replace_impl_trait_with_empty_generic_params() { + check_assist( + replace_impl_trait_with_generic, + r#" + fn foo<>(bar: <|>impl Bar) {} + "#, + r#" + fn foo(bar: B) {} + "#, + ); + } + + #[test] + fn replace_impl_trait_with_empty_multiline_generic_params() { + // FIXME: It would be more correct to place the generic parameter + // on the next line after the left angle. + check_assist( + replace_impl_trait_with_generic, + r#" + fn foo< + >(bar: <|>impl Bar) {} + "#, + r#" + fn foo(bar: B) {} + "#, + ); + } + + #[test] + #[ignore = "This case is very rare but there is no simple solutions to fix it."] + fn replace_impl_trait_with_exist_generic_letter() { + check_assist( + replace_impl_trait_with_generic, + r#" + fn foo(bar: <|>impl Bar) {} + "#, + r#" + fn foo(bar: C) {} + "#, + ); + } + + #[test] + fn replace_impl_trait_with_multiline_generic_params() { + check_assist( + replace_impl_trait_with_generic, + r#" + fn foo< + G: Foo, + F, + H, + >(bar: <|>impl Bar) {} + "#, + r#" + fn foo< + G: Foo, + F, + H, + B: Bar, + >(bar: B) {} + "#, + ); + } } -- cgit v1.2.3