mirror of
https://github.com/rust-lang/rust-analyzer
synced 2024-12-26 13:03:31 +00:00
parent
90332ca219
commit
2ab79c6f4d
3 changed files with 149 additions and 0 deletions
123
crates/ra_assists/src/handlers/change_lifetime_anon_to_named.rs
Normal file
123
crates/ra_assists/src/handlers/change_lifetime_anon_to_named.rs
Normal file
|
@ -0,0 +1,123 @@
|
|||
use crate::{AssistContext, AssistId, Assists};
|
||||
use ra_syntax::{ast, ast::{TypeParamsOwner}, AstNode, SyntaxKind};
|
||||
|
||||
/// Assist: change_lifetime_anon_to_named
|
||||
///
|
||||
/// Change an anonymous lifetime to a named lifetime.
|
||||
///
|
||||
/// ```
|
||||
/// impl Cursor<'_<|>> {
|
||||
/// fn node(self) -> &SyntaxNode {
|
||||
/// match self {
|
||||
/// Cursor::Replace(node) | Cursor::Before(node) => node,
|
||||
/// }
|
||||
/// }
|
||||
/// }
|
||||
/// ```
|
||||
/// ->
|
||||
/// ```
|
||||
/// impl<'a> Cursor<'a> {
|
||||
/// fn node(self) -> &SyntaxNode {
|
||||
/// match self {
|
||||
/// Cursor::Replace(node) | Cursor::Before(node) => node,
|
||||
/// }
|
||||
/// }
|
||||
/// }
|
||||
/// ```
|
||||
// TODO : How can we handle renaming any one of multiple anonymous lifetimes?
|
||||
pub(crate) fn change_lifetime_anon_to_named(acc: &mut Assists, ctx: &AssistContext) -> Option<()> {
|
||||
let lifetime_token = ctx.find_token_at_offset(SyntaxKind::LIFETIME)?;
|
||||
let lifetime_arg = ast::LifetimeArg::cast(lifetime_token.parent())?;
|
||||
if lifetime_arg.syntax().text() != "'_" {
|
||||
return None;
|
||||
}
|
||||
let next_token = lifetime_token.next_token()?;
|
||||
if next_token.kind() != SyntaxKind::R_ANGLE {
|
||||
// only allow naming the last anonymous lifetime
|
||||
return None;
|
||||
}
|
||||
match lifetime_arg.syntax().ancestors().find_map(ast::ImplDef::cast) {
|
||||
Some(impl_def) => {
|
||||
// get the `impl` keyword so we know where to add the lifetime argument
|
||||
let impl_kw = impl_def.syntax().first_child_or_token()?.into_token()?;
|
||||
if impl_kw.kind() != SyntaxKind::IMPL_KW {
|
||||
return None;
|
||||
}
|
||||
acc.add(
|
||||
AssistId("change_lifetime_anon_to_named"),
|
||||
"Give anonymous lifetime a name",
|
||||
lifetime_arg.syntax().text_range(),
|
||||
|builder| {
|
||||
match impl_def.type_param_list() {
|
||||
Some(type_params) => {
|
||||
builder.insert(
|
||||
(u32::from(type_params.syntax().text_range().end()) - 1).into(),
|
||||
", 'a",
|
||||
);
|
||||
},
|
||||
None => {
|
||||
builder.insert(
|
||||
impl_kw.text_range().end(),
|
||||
"<'a>",
|
||||
);
|
||||
},
|
||||
}
|
||||
builder.replace(lifetime_arg.syntax().text_range(), "'a");
|
||||
},
|
||||
)
|
||||
}
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::tests::{check_assist, check_assist_not_applicable};
|
||||
|
||||
#[test]
|
||||
fn test_example_case() {
|
||||
check_assist(
|
||||
change_lifetime_anon_to_named,
|
||||
r#"impl Cursor<'_<|>> {
|
||||
fn node(self) -> &SyntaxNode {
|
||||
match self {
|
||||
Cursor::Replace(node) | Cursor::Before(node) => node,
|
||||
}
|
||||
}
|
||||
}"#,
|
||||
r#"impl<'a> Cursor<'a> {
|
||||
fn node(self) -> &SyntaxNode {
|
||||
match self {
|
||||
Cursor::Replace(node) | Cursor::Before(node) => node,
|
||||
}
|
||||
}
|
||||
}"#,
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_example_case_simplified() {
|
||||
check_assist(
|
||||
change_lifetime_anon_to_named,
|
||||
r#"impl Cursor<'_<|>> {"#,
|
||||
r#"impl<'a> Cursor<'a> {"#,
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_not_applicable() {
|
||||
check_assist_not_applicable(change_lifetime_anon_to_named, r#"impl Cursor<'_><|> {"#);
|
||||
check_assist_not_applicable(change_lifetime_anon_to_named, r#"impl Cursor<|><'_> {"#);
|
||||
check_assist_not_applicable(change_lifetime_anon_to_named, r#"impl Cursor<'a<|>> {"#);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_with_type_parameter() {
|
||||
check_assist(
|
||||
change_lifetime_anon_to_named,
|
||||
r#"impl<T> Cursor<T, '_<|>>"#,
|
||||
r#"impl<T, 'a> Cursor<T, 'a>"#,
|
||||
);
|
||||
}
|
||||
}
|
|
@ -112,6 +112,7 @@ mod handlers {
|
|||
mod add_turbo_fish;
|
||||
mod apply_demorgan;
|
||||
mod auto_import;
|
||||
mod change_lifetime_anon_to_named;
|
||||
mod change_return_type_to_result;
|
||||
mod change_visibility;
|
||||
mod early_return;
|
||||
|
@ -151,6 +152,7 @@ mod handlers {
|
|||
add_turbo_fish::add_turbo_fish,
|
||||
apply_demorgan::apply_demorgan,
|
||||
auto_import::auto_import,
|
||||
change_lifetime_anon_to_named::change_lifetime_anon_to_named,
|
||||
change_return_type_to_result::change_return_type_to_result,
|
||||
change_visibility::change_visibility,
|
||||
early_return::convert_to_guarded_return,
|
||||
|
|
|
@ -259,6 +259,30 @@ fn main() {
|
|||
}
|
||||
```
|
||||
|
||||
## `change_lifetime_anon_to_named`
|
||||
|
||||
Change an anonymous lifetime to a named lifetime.
|
||||
|
||||
```rust
|
||||
// BEFORE
|
||||
impl Cursor<'_<|>> {
|
||||
fn node(self) -> &SyntaxNode {
|
||||
match self {
|
||||
Cursor::Replace(node) | Cursor::Before(node) => node,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// AFTER
|
||||
impl<'a> Cursor<'a> {
|
||||
fn node(self) -> &SyntaxNode {
|
||||
match self {
|
||||
Cursor::Replace(node) | Cursor::Before(node) => node,
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## `change_return_type_to_result`
|
||||
|
||||
Change the function's return type to Result.
|
||||
|
|
Loading…
Reference in a new issue