diff options
Diffstat (limited to 'crates/ra_assists')
-rw-r--r-- | crates/ra_assists/src/handlers/change_lifetime_anon_to_named.rs | 43 |
1 files changed, 36 insertions, 7 deletions
diff --git a/crates/ra_assists/src/handlers/change_lifetime_anon_to_named.rs b/crates/ra_assists/src/handlers/change_lifetime_anon_to_named.rs index 63f0a7dab..8d8f7833f 100644 --- a/crates/ra_assists/src/handlers/change_lifetime_anon_to_named.rs +++ b/crates/ra_assists/src/handlers/change_lifetime_anon_to_named.rs | |||
@@ -1,5 +1,6 @@ | |||
1 | use crate::{AssistContext, AssistId, Assists}; | 1 | use crate::{AssistContext, AssistId, Assists}; |
2 | use ra_syntax::{ast, ast::{TypeParamsOwner}, AstNode, SyntaxKind}; | 2 | use ra_syntax::{ast, ast::TypeParamsOwner, AstNode, SyntaxKind}; |
3 | use std::collections::HashSet; | ||
3 | 4 | ||
4 | /// Assist: change_lifetime_anon_to_named | 5 | /// Assist: change_lifetime_anon_to_named |
5 | /// | 6 | /// |
@@ -24,7 +25,7 @@ use ra_syntax::{ast, ast::{TypeParamsOwner}, AstNode, SyntaxKind}; | |||
24 | /// } | 25 | /// } |
25 | /// } | 26 | /// } |
26 | /// ``` | 27 | /// ``` |
27 | // TODO : How can we handle renaming any one of multiple anonymous lifetimes? | 28 | // FIXME: How can we handle renaming any one of multiple anonymous lifetimes? |
28 | pub(crate) fn change_lifetime_anon_to_named(acc: &mut Assists, ctx: &AssistContext) -> Option<()> { | 29 | pub(crate) fn change_lifetime_anon_to_named(acc: &mut Assists, ctx: &AssistContext) -> Option<()> { |
29 | let lifetime_token = ctx.find_token_at_offset(SyntaxKind::LIFETIME)?; | 30 | let lifetime_token = ctx.find_token_at_offset(SyntaxKind::LIFETIME)?; |
30 | let lifetime_arg = ast::LifetimeArg::cast(lifetime_token.parent())?; | 31 | let lifetime_arg = ast::LifetimeArg::cast(lifetime_token.parent())?; |
@@ -43,6 +44,22 @@ pub(crate) fn change_lifetime_anon_to_named(acc: &mut Assists, ctx: &AssistConte | |||
43 | if impl_kw.kind() != SyntaxKind::IMPL_KW { | 44 | if impl_kw.kind() != SyntaxKind::IMPL_KW { |
44 | return None; | 45 | return None; |
45 | } | 46 | } |
47 | let new_lifetime_param = match impl_def.type_param_list() { | ||
48 | Some(type_params) => { | ||
49 | let used_lifetime_params: HashSet<_> = type_params | ||
50 | .lifetime_params() | ||
51 | .map(|p| { | ||
52 | let mut param_name = p.syntax().text().to_string(); | ||
53 | param_name.remove(0); | ||
54 | param_name | ||
55 | }) | ||
56 | .collect(); | ||
57 | "abcdefghijklmnopqrstuvwxyz" | ||
58 | .chars() | ||
59 | .find(|c| !used_lifetime_params.contains(&c.to_string()))? | ||
60 | } | ||
61 | None => 'a', | ||
62 | }; | ||
46 | acc.add( | 63 | acc.add( |
47 | AssistId("change_lifetime_anon_to_named"), | 64 | AssistId("change_lifetime_anon_to_named"), |
48 | "Give anonymous lifetime a name", | 65 | "Give anonymous lifetime a name", |
@@ -52,17 +69,20 @@ pub(crate) fn change_lifetime_anon_to_named(acc: &mut Assists, ctx: &AssistConte | |||
52 | Some(type_params) => { | 69 | Some(type_params) => { |
53 | builder.insert( | 70 | builder.insert( |
54 | (u32::from(type_params.syntax().text_range().end()) - 1).into(), | 71 | (u32::from(type_params.syntax().text_range().end()) - 1).into(), |
55 | ", 'a", | 72 | format!(", '{}", new_lifetime_param), |
56 | ); | 73 | ); |
57 | }, | 74 | } |
58 | None => { | 75 | None => { |
59 | builder.insert( | 76 | builder.insert( |
60 | impl_kw.text_range().end(), | 77 | impl_kw.text_range().end(), |
61 | "<'a>", | 78 | format!("<'{}>", new_lifetime_param), |
62 | ); | 79 | ); |
63 | }, | 80 | } |
64 | } | 81 | } |
65 | builder.replace(lifetime_arg.syntax().text_range(), "'a"); | 82 | builder.replace( |
83 | lifetime_arg.syntax().text_range(), | ||
84 | format!("'{}", new_lifetime_param), | ||
85 | ); | ||
66 | }, | 86 | }, |
67 | ) | 87 | ) |
68 | } | 88 | } |
@@ -120,4 +140,13 @@ mod tests { | |||
120 | r#"impl<T, 'a> Cursor<T, 'a>"#, | 140 | r#"impl<T, 'a> Cursor<T, 'a>"#, |
121 | ); | 141 | ); |
122 | } | 142 | } |
143 | |||
144 | #[test] | ||
145 | fn test_with_existing_lifetime_name_conflict() { | ||
146 | check_assist( | ||
147 | change_lifetime_anon_to_named, | ||
148 | r#"impl<'a, 'b> Cursor<'a, 'b, '_<|>>"#, | ||
149 | r#"impl<'a, 'b, 'c> Cursor<'a, 'b, 'c>"#, | ||
150 | ); | ||
151 | } | ||
123 | } | 152 | } |