diff options
Diffstat (limited to 'crates/ide_assists/src')
-rw-r--r-- | crates/ide_assists/src/handlers/extract_type_alias.rs | 68 |
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..4bccf5984 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 @@ | |||
1 | use syntax::ast::{self, AstNode}; | 1 | use syntax::{ |
2 | ast::{self, edit::IndentLevel, AstNode}, | ||
3 | match_ast, | ||
4 | }; | ||
2 | 5 | ||
3 | use crate::{AssistContext, AssistId, AssistKind, Assists}; | 6 | use 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()?.clone(), |
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#" | ||
187 | trait Tr { | ||
188 | fn f() -> $0(u8, u8)$0 {} | ||
189 | } | ||
190 | "#, | ||
191 | r#" | ||
192 | type $0Type = (u8, u8); | ||
193 | |||
194 | trait Tr { | ||
195 | fn f() -> Type {} | ||
196 | } | ||
197 | "#, | ||
198 | ); | ||
199 | } | ||
200 | |||
201 | #[test] | ||
202 | fn indentation() { | ||
203 | check_assist( | ||
204 | extract_type_alias, | ||
205 | r#" | ||
206 | mod m { | ||
207 | fn f() -> $0u8$0 {} | ||
208 | } | ||
209 | "#, | ||
210 | r#" | ||
211 | mod m { | ||
212 | type $0Type = u8; | ||
213 | |||
214 | fn f() -> Type {} | ||
215 | } | ||
216 | "#, | ||
217 | ); | ||
174 | } | 218 | } |
175 | } | 219 | } |