aboutsummaryrefslogtreecommitdiff
path: root/crates/ide_assists/src/handlers/extract_type_alias.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ide_assists/src/handlers/extract_type_alias.rs')
-rw-r--r--crates/ide_assists/src/handlers/extract_type_alias.rs68
1 files changed, 56 insertions, 12 deletions
diff --git a/crates/ide_assists/src/handlers/extract_type_alias.rs b/crates/ide_assists/src/handlers/extract_type_alias.rs
index 998e0de7b..eac8857c6 100644
--- a/crates/ide_assists/src/handlers/extract_type_alias.rs
+++ b/crates/ide_assists/src/handlers/extract_type_alias.rs
@@ -1,4 +1,7 @@
1use syntax::ast::{self, AstNode}; 1use syntax::{
2 ast::{self, edit::IndentLevel, AstNode},
3 match_ast,
4};
2 5
3use crate::{AssistContext, AssistId, AssistKind, Assists}; 6use crate::{AssistContext, AssistId, AssistKind, Assists};
4 7
@@ -25,12 +28,15 @@ pub(crate) fn extract_type_alias(acc: &mut Assists, ctx: &AssistContext) -> Opti
25 } 28 }
26 29
27 let node = ctx.find_node_at_range::<ast::Type>()?; 30 let node = ctx.find_node_at_range::<ast::Type>()?;
28 let insert = ctx 31 let item = ctx.find_node_at_offset::<ast::Item>()?;
29 .find_node_at_offset::<ast::Impl>() 32 let insert = match_ast! {
30 .map(|imp| imp.syntax().clone()) 33 match (item.syntax().parent()?) {
31 .or_else(|| ctx.find_node_at_offset::<ast::Item>().map(|item| item.syntax().clone()))? 34 ast::AssocItemList(it) => it.syntax().parent()?,
32 .text_range() 35 _ => item.syntax().clone(),
33 .start(); 36 }
37 };
38 let indent = IndentLevel::from_node(&insert);
39 let insert = insert.text_range().start();
34 let target = node.syntax().text_range(); 40 let target = node.syntax().text_range();
35 41
36 acc.add( 42 acc.add(
@@ -42,10 +48,14 @@ pub(crate) fn extract_type_alias(acc: &mut Assists, ctx: &AssistContext) -> Opti
42 builder.replace(target, "Type"); 48 builder.replace(target, "Type");
43 match ctx.config.snippet_cap { 49 match ctx.config.snippet_cap {
44 Some(cap) => { 50 Some(cap) => {
45 builder.insert_snippet(cap, insert, format!("type $0Type = {};\n\n", node)); 51 builder.insert_snippet(
52 cap,
53 insert,
54 format!("type $0Type = {};\n\n{}", node, indent),
55 );
46 } 56 }
47 None => { 57 None => {
48 builder.insert(insert, format!("type Type = {};\n\n", node)); 58 builder.insert(insert, format!("type Type = {};\n\n{}", node, indent));
49 } 59 }
50 } 60 }
51 }, 61 },
@@ -153,9 +163,9 @@ struct S {
153 } 163 }
154 164
155 #[test] 165 #[test]
156 fn extract_from_impl() { 166 fn extract_from_impl_or_trait() {
157 // When invoked in an impl, extracted type alias should be placed next to the impl, not 167 // When invoked in an impl/trait, extracted type alias should be placed next to the
158 // inside. 168 // impl/trait, not inside.
159 check_assist( 169 check_assist(
160 extract_type_alias, 170 extract_type_alias,
161 r#" 171 r#"
@@ -171,5 +181,39 @@ impl S {
171} 181}
172 "#, 182 "#,
173 ); 183 );
184 check_assist(
185 extract_type_alias,
186 r#"
187trait Tr {
188 fn f() -> $0(u8, u8)$0 {}
189}
190 "#,
191 r#"
192type $0Type = (u8, u8);
193
194trait Tr {
195 fn f() -> Type {}
196}
197 "#,
198 );
199 }
200
201 #[test]
202 fn indentation() {
203 check_assist(
204 extract_type_alias,
205 r#"
206mod m {
207 fn f() -> $0u8$0 {}
208}
209 "#,
210 r#"
211mod m {
212 type $0Type = u8;
213
214 fn f() -> Type {}
215}
216 "#,
217 );
174 } 218 }
175} 219}