]> git.lizzy.rs Git - rust.git/blobdiff - crates/assists/src/handlers/introduce_named_lifetime.rs
Wrap remaining self/super/crate in Name{Ref}
[rust.git] / crates / assists / src / handlers / introduce_named_lifetime.rs
index 4cc8dae65026fbb7b9c67c1ad4aa88771446e6f3..02782eb6deddcf34e644cbf4746cd88c0a62dc15 100644 (file)
@@ -1,7 +1,7 @@
 use rustc_hash::FxHashSet;
 use syntax::{
     ast::{self, GenericParamsOwner, NameOwner},
-    AstNode, SyntaxKind, TextRange, TextSize,
+    AstNode, TextRange, TextSize,
 };
 
 use crate::{assist_context::AssistBuilder, AssistContext, AssistId, AssistKind, Assists};
@@ -14,7 +14,7 @@
 // Change an anonymous lifetime to a named lifetime.
 //
 // ```
-// impl Cursor<'_<|>> {
+// impl Cursor<'_$0> {
 //     fn node(self) -> &SyntaxNode {
 //         match self {
 //             Cursor::Replace(node) | Cursor::Before(node) => node,
 // }
 // ```
 // FIXME: How can we handle renaming any one of multiple anonymous lifetimes?
-// FIXME: should also add support for the case fun(f: &Foo) -> &<|>Foo
+// FIXME: should also add support for the case fun(f: &Foo) -> &$0Foo
 pub(crate) fn introduce_named_lifetime(acc: &mut Assists, ctx: &AssistContext) -> Option<()> {
-    let lifetime_token = ctx
-        .find_token_syntax_at_offset(SyntaxKind::LIFETIME)
-        .filter(|lifetime| lifetime.text() == "'_")?;
-    if let Some(fn_def) = lifetime_token.ancestors().find_map(ast::Fn::cast) {
-        generate_fn_def_assist(acc, &fn_def, lifetime_token.text_range())
-    } else if let Some(impl_def) = lifetime_token.ancestors().find_map(ast::Impl::cast) {
-        generate_impl_def_assist(acc, &impl_def, lifetime_token.text_range())
+    let lifetime =
+        ctx.find_node_at_offset::<ast::Lifetime>().filter(|lifetime| lifetime.text() == "'_")?;
+    if let Some(fn_def) = lifetime.syntax().ancestors().find_map(ast::Fn::cast) {
+        generate_fn_def_assist(acc, &fn_def, lifetime.lifetime_ident_token()?.text_range())
+    } else if let Some(impl_def) = lifetime.syntax().ancestors().find_map(ast::Impl::cast) {
+        generate_impl_def_assist(acc, &impl_def, lifetime.lifetime_ident_token()?.text_range())
     } else {
         None
     }
@@ -58,19 +57,17 @@ fn generate_fn_def_assist(
     let end_of_fn_ident = fn_def.name()?.ident_token()?.text_range().end();
     let self_param =
         // use the self if it's a reference and has no explicit lifetime
-        param_list.self_param().filter(|p| p.lifetime_token().is_none() && p.amp_token().is_some());
+        param_list.self_param().filter(|p| p.lifetime().is_none() && p.amp_token().is_some());
     // compute the location which implicitly has the same lifetime as the anonymous lifetime
     let loc_needing_lifetime = if let Some(self_param) = self_param {
         // if we have a self reference, use that
-        Some(self_param.self_token()?.text_range().start())
+        Some(self_param.name()?.syntax().text_range().start())
     } else {
         // otherwise, if there's a single reference parameter without a named liftime, use that
         let fn_params_without_lifetime: Vec<_> = param_list
             .params()
             .filter_map(|param| match param.ty() {
-                Some(ast::Type::RefType(ascribed_type))
-                    if ascribed_type.lifetime_token() == None =>
-                {
+                Some(ast::Type::RefType(ascribed_type)) if ascribed_type.lifetime().is_none() => {
                     Some(ascribed_type.amp_token()?.text_range().end())
                 }
                 _ => None,
@@ -153,7 +150,7 @@ mod tests {
     fn test_example_case() {
         check_assist(
             introduce_named_lifetime,
-            r#"impl Cursor<'_<|>> {
+            r#"impl Cursor<'_$0> {
                 fn node(self) -> &SyntaxNode {
                     match self {
                         Cursor::Replace(node) | Cursor::Before(node) => node,
@@ -174,7 +171,7 @@ fn node(self) -> &SyntaxNode {
     fn test_example_case_simplified() {
         check_assist(
             introduce_named_lifetime,
-            r#"impl Cursor<'_<|>> {"#,
+            r#"impl Cursor<'_$0> {"#,
             r#"impl<'a> Cursor<'a> {"#,
         );
     }
@@ -183,7 +180,7 @@ fn test_example_case_simplified() {
     fn test_example_case_cursor_after_tick() {
         check_assist(
             introduce_named_lifetime,
-            r#"impl Cursor<'<|>_> {"#,
+            r#"impl Cursor<'$0_> {"#,
             r#"impl<'a> Cursor<'a> {"#,
         );
     }
@@ -192,7 +189,7 @@ fn test_example_case_cursor_after_tick() {
     fn test_impl_with_other_type_param() {
         check_assist(
             introduce_named_lifetime,
-            "impl<I> fmt::Display for SepByBuilder<'_<|>, I>
+            "impl<I> fmt::Display for SepByBuilder<'_$0, I>
         where
             I: Iterator,
             I::Item: fmt::Display,
@@ -209,28 +206,28 @@ fn test_impl_with_other_type_param() {
     fn test_example_case_cursor_before_tick() {
         check_assist(
             introduce_named_lifetime,
-            r#"impl Cursor<<|>'_> {"#,
+            r#"impl Cursor<$0'_> {"#,
             r#"impl<'a> Cursor<'a> {"#,
         );
     }
 
     #[test]
     fn test_not_applicable_cursor_position() {
-        check_assist_not_applicable(introduce_named_lifetime, r#"impl Cursor<'_><|> {"#);
-        check_assist_not_applicable(introduce_named_lifetime, r#"impl Cursor<|><'_> {"#);
+        check_assist_not_applicable(introduce_named_lifetime, r#"impl Cursor<'_>$0 {"#);
+        check_assist_not_applicable(introduce_named_lifetime, r#"impl Cursor$0<'_> {"#);
     }
 
     #[test]
     fn test_not_applicable_lifetime_already_name() {
-        check_assist_not_applicable(introduce_named_lifetime, r#"impl Cursor<'a<|>> {"#);
-        check_assist_not_applicable(introduce_named_lifetime, r#"fn my_fun<'a>() -> X<'a<|>>"#);
+        check_assist_not_applicable(introduce_named_lifetime, r#"impl Cursor<'a$0> {"#);
+        check_assist_not_applicable(introduce_named_lifetime, r#"fn my_fun<'a>() -> X<'a$0>"#);
     }
 
     #[test]
     fn test_with_type_parameter() {
         check_assist(
             introduce_named_lifetime,
-            r#"impl<T> Cursor<T, '_<|>>"#,
+            r#"impl<T> Cursor<T, '_$0>"#,
             r#"impl<T, 'a> Cursor<T, 'a>"#,
         );
     }
@@ -239,7 +236,7 @@ fn test_with_type_parameter() {
     fn test_with_existing_lifetime_name_conflict() {
         check_assist(
             introduce_named_lifetime,
-            r#"impl<'a, 'b> Cursor<'a, 'b, '_<|>>"#,
+            r#"impl<'a, 'b> Cursor<'a, 'b, '_$0>"#,
             r#"impl<'a, 'b, 'c> Cursor<'a, 'b, 'c>"#,
         );
     }
@@ -248,7 +245,7 @@ fn test_with_existing_lifetime_name_conflict() {
     fn test_function_return_value_anon_lifetime_param() {
         check_assist(
             introduce_named_lifetime,
-            r#"fn my_fun() -> X<'_<|>>"#,
+            r#"fn my_fun() -> X<'_$0>"#,
             r#"fn my_fun<'a>() -> X<'a>"#,
         );
     }
@@ -257,7 +254,7 @@ fn test_function_return_value_anon_lifetime_param() {
     fn test_function_return_value_anon_reference_lifetime() {
         check_assist(
             introduce_named_lifetime,
-            r#"fn my_fun() -> &'_<|> X"#,
+            r#"fn my_fun() -> &'_$0 X"#,
             r#"fn my_fun<'a>() -> &'a X"#,
         );
     }
@@ -266,7 +263,7 @@ fn test_function_return_value_anon_reference_lifetime() {
     fn test_function_param_anon_lifetime() {
         check_assist(
             introduce_named_lifetime,
-            r#"fn my_fun(x: X<'_<|>>)"#,
+            r#"fn my_fun(x: X<'_$0>)"#,
             r#"fn my_fun<'a>(x: X<'a>)"#,
         );
     }
@@ -275,7 +272,7 @@ fn test_function_param_anon_lifetime() {
     fn test_function_add_lifetime_to_params() {
         check_assist(
             introduce_named_lifetime,
-            r#"fn my_fun(f: &Foo) -> X<'_<|>>"#,
+            r#"fn my_fun(f: &Foo) -> X<'_$0>"#,
             r#"fn my_fun<'a>(f: &'a Foo) -> X<'a>"#,
         );
     }
@@ -284,7 +281,7 @@ fn test_function_add_lifetime_to_params() {
     fn test_function_add_lifetime_to_params_in_presence_of_other_lifetime() {
         check_assist(
             introduce_named_lifetime,
-            r#"fn my_fun<'other>(f: &Foo, b: &'other Bar) -> X<'_<|>>"#,
+            r#"fn my_fun<'other>(f: &Foo, b: &'other Bar) -> X<'_$0>"#,
             r#"fn my_fun<'other, 'a>(f: &'a Foo, b: &'other Bar) -> X<'a>"#,
         );
     }
@@ -294,7 +291,7 @@ fn test_function_not_applicable_without_self_and_multiple_unnamed_param_lifetime
         // this is not permitted under lifetime elision rules
         check_assist_not_applicable(
             introduce_named_lifetime,
-            r#"fn my_fun(f: &Foo, b: &Bar) -> X<'_<|>>"#,
+            r#"fn my_fun(f: &Foo, b: &Bar) -> X<'_$0>"#,
         );
     }
 
@@ -302,7 +299,7 @@ fn test_function_not_applicable_without_self_and_multiple_unnamed_param_lifetime
     fn test_function_add_lifetime_to_self_ref_param() {
         check_assist(
             introduce_named_lifetime,
-            r#"fn my_fun<'other>(&self, f: &Foo, b: &'other Bar) -> X<'_<|>>"#,
+            r#"fn my_fun<'other>(&self, f: &Foo, b: &'other Bar) -> X<'_$0>"#,
             r#"fn my_fun<'other, 'a>(&'a self, f: &Foo, b: &'other Bar) -> X<'a>"#,
         );
     }
@@ -311,7 +308,7 @@ fn test_function_add_lifetime_to_self_ref_param() {
     fn test_function_add_lifetime_to_param_with_non_ref_self() {
         check_assist(
             introduce_named_lifetime,
-            r#"fn my_fun<'other>(self, f: &Foo, b: &'other Bar) -> X<'_<|>>"#,
+            r#"fn my_fun<'other>(self, f: &Foo, b: &'other Bar) -> X<'_$0>"#,
             r#"fn my_fun<'other, 'a>(self, f: &'a Foo, b: &'other Bar) -> X<'a>"#,
         );
     }