aboutsummaryrefslogtreecommitdiff
path: root/crates/ide_assists/src/handlers
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ide_assists/src/handlers')
-rw-r--r--crates/ide_assists/src/handlers/auto_import.rs26
-rw-r--r--crates/ide_assists/src/handlers/extract_struct_from_enum_variant.rs135
-rw-r--r--crates/ide_assists/src/handlers/move_module_to_file.rs38
-rw-r--r--crates/ide_assists/src/handlers/replace_unwrap_with_match.rs2
4 files changed, 186 insertions, 15 deletions
diff --git a/crates/ide_assists/src/handlers/auto_import.rs b/crates/ide_assists/src/handlers/auto_import.rs
index a454a2af3..506cc292c 100644
--- a/crates/ide_assists/src/handlers/auto_import.rs
+++ b/crates/ide_assists/src/handlers/auto_import.rs
@@ -969,4 +969,30 @@ mod bar {
969"#, 969"#,
970 ); 970 );
971 } 971 }
972
973 #[test]
974 fn uses_abs_path_with_extern_crate_clash() {
975 check_assist(
976 auto_import,
977 r#"
978//- /main.rs crate:main deps:foo
979mod foo {}
980
981const _: () = {
982 Foo$0
983};
984//- /foo.rs crate:foo
985pub struct Foo
986"#,
987 r#"
988use ::foo::Foo;
989
990mod foo {}
991
992const _: () = {
993 Foo
994};
995"#,
996 );
997 }
972} 998}
diff --git a/crates/ide_assists/src/handlers/extract_struct_from_enum_variant.rs b/crates/ide_assists/src/handlers/extract_struct_from_enum_variant.rs
index 66f274fa7..8e2178391 100644
--- a/crates/ide_assists/src/handlers/extract_struct_from_enum_variant.rs
+++ b/crates/ide_assists/src/handlers/extract_struct_from_enum_variant.rs
@@ -151,20 +151,37 @@ fn create_struct_def(
151 field_list: &Either<ast::RecordFieldList, ast::TupleFieldList>, 151 field_list: &Either<ast::RecordFieldList, ast::TupleFieldList>,
152 visibility: Option<ast::Visibility>, 152 visibility: Option<ast::Visibility>,
153) -> ast::Struct { 153) -> ast::Struct {
154 let pub_vis = Some(make::visibility_pub()); 154 let pub_vis = make::visibility_pub();
155
156 let insert_pub = |node: &'_ SyntaxNode| {
157 let pub_vis = pub_vis.clone_for_update();
158 ted::insert(ted::Position::before(node), pub_vis.syntax());
159 };
160
161 // for fields without any existing visibility, use pub visibility
155 let field_list = match field_list { 162 let field_list = match field_list {
156 Either::Left(field_list) => { 163 Either::Left(field_list) => {
157 make::record_field_list(field_list.fields().flat_map(|field| { 164 let field_list = field_list.clone_for_update();
158 Some(make::record_field(pub_vis.clone(), field.name()?, field.ty()?)) 165
159 })) 166 field_list
160 .into() 167 .fields()
168 .filter(|field| field.visibility().is_none())
169 .filter_map(|field| field.name())
170 .for_each(|it| insert_pub(it.syntax()));
171
172 field_list.into()
161 } 173 }
162 Either::Right(field_list) => make::tuple_field_list( 174 Either::Right(field_list) => {
175 let field_list = field_list.clone_for_update();
176
163 field_list 177 field_list
164 .fields() 178 .fields()
165 .flat_map(|field| Some(make::tuple_field(pub_vis.clone(), field.ty()?))), 179 .filter(|field| field.visibility().is_none())
166 ) 180 .filter_map(|field| field.ty())
167 .into(), 181 .for_each(|it| insert_pub(it.syntax()));
182
183 field_list.into()
184 }
168 }; 185 };
169 186
170 make::struct_(visibility, variant_name, None, field_list).clone_for_update() 187 make::struct_(visibility, variant_name, None, field_list).clone_for_update()
@@ -295,6 +312,106 @@ enum A { One(One) }"#,
295 } 312 }
296 313
297 #[test] 314 #[test]
315 fn test_extract_struct_keep_comments_and_attrs_one_field_named() {
316 check_assist(
317 extract_struct_from_enum_variant,
318 r#"
319enum A {
320 $0One {
321 // leading comment
322 /// doc comment
323 #[an_attr]
324 foo: u32
325 // trailing comment
326 }
327}"#,
328 r#"
329struct One{
330 // leading comment
331 /// doc comment
332 #[an_attr]
333 pub foo: u32
334 // trailing comment
335 }
336
337enum A {
338 One(One)
339}"#,
340 );
341 }
342
343 #[test]
344 fn test_extract_struct_keep_comments_and_attrs_several_fields_named() {
345 check_assist(
346 extract_struct_from_enum_variant,
347 r#"
348enum A {
349 $0One {
350 // comment
351 /// doc
352 #[attr]
353 foo: u32,
354 // comment
355 #[attr]
356 /// doc
357 bar: u32
358 }
359}"#,
360 r#"
361struct One{
362 // comment
363 /// doc
364 #[attr]
365 pub foo: u32,
366 // comment
367 #[attr]
368 /// doc
369 pub bar: u32
370 }
371
372enum A {
373 One(One)
374}"#,
375 );
376 }
377
378 #[test]
379 fn test_extract_struct_keep_comments_and_attrs_several_fields_tuple() {
380 check_assist(
381 extract_struct_from_enum_variant,
382 "enum A { $0One(/* comment */ #[attr] u32, /* another */ u32 /* tail */) }",
383 r#"
384struct One(/* comment */ #[attr] pub u32, /* another */ pub u32 /* tail */);
385
386enum A { One(One) }"#,
387 );
388 }
389
390 #[test]
391 fn test_extract_struct_keep_existing_visibility_named() {
392 check_assist(
393 extract_struct_from_enum_variant,
394 "enum A { $0One{ pub a: u32, pub(crate) b: u32, pub(super) c: u32, d: u32 } }",
395 r#"
396struct One{ pub a: u32, pub(crate) b: u32, pub(super) c: u32, pub d: u32 }
397
398enum A { One(One) }"#,
399 );
400 }
401
402 #[test]
403 fn test_extract_struct_keep_existing_visibility_tuple() {
404 check_assist(
405 extract_struct_from_enum_variant,
406 "enum A { $0One(pub u32, pub(crate) u32, pub(super) u32, u32) }",
407 r#"
408struct One(pub u32, pub(crate) u32, pub(super) u32, pub u32);
409
410enum A { One(One) }"#,
411 );
412 }
413
414 #[test]
298 fn test_extract_enum_variant_name_value_namespace() { 415 fn test_extract_enum_variant_name_value_namespace() {
299 check_assist( 416 check_assist(
300 extract_struct_from_enum_variant, 417 extract_struct_from_enum_variant,
diff --git a/crates/ide_assists/src/handlers/move_module_to_file.rs b/crates/ide_assists/src/handlers/move_module_to_file.rs
index 6e685b4b2..93f702c55 100644
--- a/crates/ide_assists/src/handlers/move_module_to_file.rs
+++ b/crates/ide_assists/src/handlers/move_module_to_file.rs
@@ -1,4 +1,4 @@
1use ast::{edit::IndentLevel, VisibilityOwner}; 1use ast::edit::IndentLevel;
2use ide_db::base_db::AnchoredPathBuf; 2use ide_db::base_db::AnchoredPathBuf;
3use stdx::format_to; 3use stdx::format_to;
4use syntax::{ 4use syntax::{
@@ -60,12 +60,18 @@ pub(crate) fn move_module_to_file(acc: &mut Assists, ctx: &AssistContext) -> Opt
60 }; 60 };
61 61
62 let mut buf = String::new(); 62 let mut buf = String::new();
63 if let Some(v) = module_ast.visibility() {
64 format_to!(buf, "{} ", v);
65 }
66 format_to!(buf, "mod {};", module_name); 63 format_to!(buf, "mod {};", module_name);
67 64
68 builder.replace(module_ast.syntax().text_range(), buf); 65 let replacement_start = if let Some(mod_token) = module_ast.mod_token() {
66 mod_token.text_range().start()
67 } else {
68 module_ast.syntax().text_range().start()
69 };
70
71 builder.replace(
72 TextRange::new(replacement_start, module_ast.syntax().text_range().end()),
73 buf,
74 );
69 75
70 let dst = AnchoredPathBuf { anchor: ctx.frange.file_id, path }; 76 let dst = AnchoredPathBuf { anchor: ctx.frange.file_id, path };
71 builder.create_file(dst, contents); 77 builder.create_file(dst, contents);
@@ -184,4 +190,26 @@ pub(crate) mod tests;
184 cov_mark::check!(available_before_curly); 190 cov_mark::check!(available_before_curly);
185 check_assist_not_applicable(move_module_to_file, r#"mod m { $0 }"#); 191 check_assist_not_applicable(move_module_to_file, r#"mod m { $0 }"#);
186 } 192 }
193
194 #[test]
195 fn keep_outer_comments_and_attributes() {
196 check_assist(
197 move_module_to_file,
198 r#"
199/// doc comment
200#[attribute]
201mod $0tests {
202 #[test] fn t() {}
203}
204"#,
205 r#"
206//- /main.rs
207/// doc comment
208#[attribute]
209mod tests;
210//- /tests.rs
211#[test] fn t() {}
212"#,
213 );
214 }
187} 215}
diff --git a/crates/ide_assists/src/handlers/replace_unwrap_with_match.rs b/crates/ide_assists/src/handlers/replace_unwrap_with_match.rs
index 0fec961b4..a3bfa221c 100644
--- a/crates/ide_assists/src/handlers/replace_unwrap_with_match.rs
+++ b/crates/ide_assists/src/handlers/replace_unwrap_with_match.rs
@@ -17,7 +17,7 @@ use ide_db::ty_filter::TryEnum;
17 17
18// Assist: replace_unwrap_with_match 18// Assist: replace_unwrap_with_match
19// 19//
20// Replaces `unwrap` a `match` expression. Works for Result and Option. 20// Replaces `unwrap` with a `match` expression. Works for Result and Option.
21// 21//
22// ``` 22// ```
23// enum Result<T, E> { Ok(T), Err(E) } 23// enum Result<T, E> { Ok(T), Err(E) }