Skip to content

Commit 9edac77

Browse files
authored
Merge pull request #19901 from BazookaMusic/master
Enable Assist edit for tuple<->named struct for the struct and visiblity keywords
2 parents 25808c1 + 34b31f1 commit 9edac77

File tree

2 files changed

+192
-12
lines changed

2 files changed

+192
-12
lines changed

crates/ide-assists/src/handlers/convert_named_struct_to_tuple_struct.rs

Lines changed: 96 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -56,26 +56,34 @@ pub(crate) fn convert_named_struct_to_tuple_struct(
5656
// XXX: We don't currently provide this assist for struct definitions inside macros, but if we
5757
// are to lift this limitation, don't forget to make `edit_struct_def()` consider macro files
5858
// too.
59-
let name = ctx.find_node_at_offset::<ast::Name>()?;
60-
let strukt = name.syntax().parent().and_then(<Either<ast::Struct, ast::Variant>>::cast)?;
61-
let field_list = strukt.as_ref().either(|s| s.field_list(), |v| v.field_list())?;
59+
let strukt_or_variant = ctx
60+
.find_node_at_offset::<ast::Struct>()
61+
.map(Either::Left)
62+
.or_else(|| ctx.find_node_at_offset::<ast::Variant>().map(Either::Right))?;
63+
let field_list = strukt_or_variant.as_ref().either(|s| s.field_list(), |v| v.field_list())?;
64+
65+
if ctx.offset() > field_list.syntax().text_range().start() {
66+
// Assist could be distracting after the braces
67+
return None;
68+
}
69+
6270
let record_fields = match field_list {
6371
ast::FieldList::RecordFieldList(it) => it,
6472
ast::FieldList::TupleFieldList(_) => return None,
6573
};
66-
let strukt_def = match &strukt {
74+
let strukt_def = match &strukt_or_variant {
6775
Either::Left(s) => Either::Left(ctx.sema.to_def(s)?),
6876
Either::Right(v) => Either::Right(ctx.sema.to_def(v)?),
6977
};
7078

7179
acc.add(
7280
AssistId::refactor_rewrite("convert_named_struct_to_tuple_struct"),
7381
"Convert to tuple struct",
74-
strukt.syntax().text_range(),
82+
strukt_or_variant.syntax().text_range(),
7583
|edit| {
7684
edit_field_references(ctx, edit, record_fields.fields());
7785
edit_struct_references(ctx, edit, strukt_def);
78-
edit_struct_def(ctx, edit, &strukt, record_fields);
86+
edit_struct_def(ctx, edit, &strukt_or_variant, record_fields);
7987
},
8088
)
8189
}
@@ -277,6 +285,88 @@ impl A {
277285
struct Inner;
278286
struct A(Inner);
279287
288+
impl A {
289+
fn new(inner: Inner) -> A {
290+
A(inner)
291+
}
292+
293+
fn new_with_default() -> A {
294+
A::new(Inner)
295+
}
296+
297+
fn into_inner(self) -> Inner {
298+
self.0
299+
}
300+
}"#,
301+
);
302+
}
303+
304+
#[test]
305+
fn convert_simple_struct_cursor_on_struct_keyword() {
306+
check_assist(
307+
convert_named_struct_to_tuple_struct,
308+
r#"
309+
struct Inner;
310+
struct$0 A { inner: Inner }
311+
312+
impl A {
313+
fn new(inner: Inner) -> A {
314+
A { inner }
315+
}
316+
317+
fn new_with_default() -> A {
318+
A::new(Inner)
319+
}
320+
321+
fn into_inner(self) -> Inner {
322+
self.inner
323+
}
324+
}"#,
325+
r#"
326+
struct Inner;
327+
struct A(Inner);
328+
329+
impl A {
330+
fn new(inner: Inner) -> A {
331+
A(inner)
332+
}
333+
334+
fn new_with_default() -> A {
335+
A::new(Inner)
336+
}
337+
338+
fn into_inner(self) -> Inner {
339+
self.0
340+
}
341+
}"#,
342+
);
343+
}
344+
345+
#[test]
346+
fn convert_simple_struct_cursor_on_visibility_keyword() {
347+
check_assist(
348+
convert_named_struct_to_tuple_struct,
349+
r#"
350+
struct Inner;
351+
pub$0 struct A { inner: Inner }
352+
353+
impl A {
354+
fn new(inner: Inner) -> A {
355+
A { inner }
356+
}
357+
358+
fn new_with_default() -> A {
359+
A::new(Inner)
360+
}
361+
362+
fn into_inner(self) -> Inner {
363+
self.inner
364+
}
365+
}"#,
366+
r#"
367+
struct Inner;
368+
pub struct A(Inner);
369+
280370
impl A {
281371
fn new(inner: Inner) -> A {
282372
A(inner)

crates/ide-assists/src/handlers/convert_tuple_struct_to_named_struct.rs

Lines changed: 96 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -51,18 +51,26 @@ pub(crate) fn convert_tuple_struct_to_named_struct(
5151
acc: &mut Assists,
5252
ctx: &AssistContext<'_>,
5353
) -> Option<()> {
54-
let name = ctx.find_node_at_offset::<ast::Name>()?;
55-
let strukt = name.syntax().parent().and_then(<Either<ast::Struct, ast::Variant>>::cast)?;
56-
let field_list = strukt.as_ref().either(|s| s.field_list(), |v| v.field_list())?;
54+
let strukt_or_variant = ctx
55+
.find_node_at_offset::<ast::Struct>()
56+
.map(Either::Left)
57+
.or_else(|| ctx.find_node_at_offset::<ast::Variant>().map(Either::Right))?;
58+
let field_list = strukt_or_variant.as_ref().either(|s| s.field_list(), |v| v.field_list())?;
59+
60+
if ctx.offset() > field_list.syntax().text_range().start() {
61+
// Assist could be distracting after the braces
62+
return None;
63+
}
64+
5765
let tuple_fields = match field_list {
5866
ast::FieldList::TupleFieldList(it) => it,
5967
ast::FieldList::RecordFieldList(_) => return None,
6068
};
61-
let strukt_def = match &strukt {
69+
let strukt_def = match &strukt_or_variant {
6270
Either::Left(s) => Either::Left(ctx.sema.to_def(s)?),
6371
Either::Right(v) => Either::Right(ctx.sema.to_def(v)?),
6472
};
65-
let target = strukt.as_ref().either(|s| s.syntax(), |v| v.syntax()).text_range();
73+
let target = strukt_or_variant.as_ref().either(|s| s.syntax(), |v| v.syntax()).text_range();
6674

6775
acc.add(
6876
AssistId::refactor_rewrite("convert_tuple_struct_to_named_struct"),
@@ -72,7 +80,7 @@ pub(crate) fn convert_tuple_struct_to_named_struct(
7280
let names = generate_names(tuple_fields.fields());
7381
edit_field_references(ctx, edit, tuple_fields.fields(), &names);
7482
edit_struct_references(ctx, edit, strukt_def, &names);
75-
edit_struct_def(ctx, edit, &strukt, tuple_fields, names);
83+
edit_struct_def(ctx, edit, &strukt_or_variant, tuple_fields, names);
7684
},
7785
)
7886
}
@@ -300,6 +308,88 @@ impl A {
300308
struct Inner;
301309
struct A { field1: Inner }
302310
311+
impl A {
312+
fn new(inner: Inner) -> A {
313+
A { field1: inner }
314+
}
315+
316+
fn new_with_default() -> A {
317+
A::new(Inner)
318+
}
319+
320+
fn into_inner(self) -> Inner {
321+
self.field1
322+
}
323+
}"#,
324+
);
325+
}
326+
327+
#[test]
328+
fn convert_simple_struct_cursor_on_struct_keyword() {
329+
check_assist(
330+
convert_tuple_struct_to_named_struct,
331+
r#"
332+
struct Inner;
333+
struct$0 A(Inner);
334+
335+
impl A {
336+
fn new(inner: Inner) -> A {
337+
A(inner)
338+
}
339+
340+
fn new_with_default() -> A {
341+
A::new(Inner)
342+
}
343+
344+
fn into_inner(self) -> Inner {
345+
self.0
346+
}
347+
}"#,
348+
r#"
349+
struct Inner;
350+
struct A { field1: Inner }
351+
352+
impl A {
353+
fn new(inner: Inner) -> A {
354+
A { field1: inner }
355+
}
356+
357+
fn new_with_default() -> A {
358+
A::new(Inner)
359+
}
360+
361+
fn into_inner(self) -> Inner {
362+
self.field1
363+
}
364+
}"#,
365+
);
366+
}
367+
368+
#[test]
369+
fn convert_simple_struct_cursor_on_visibility_keyword() {
370+
check_assist(
371+
convert_tuple_struct_to_named_struct,
372+
r#"
373+
struct Inner;
374+
pub$0 struct A(Inner);
375+
376+
impl A {
377+
fn new(inner: Inner) -> A {
378+
A(inner)
379+
}
380+
381+
fn new_with_default() -> A {
382+
A::new(Inner)
383+
}
384+
385+
fn into_inner(self) -> Inner {
386+
self.0
387+
}
388+
}"#,
389+
r#"
390+
struct Inner;
391+
pub struct A { field1: Inner }
392+
303393
impl A {
304394
fn new(inner: Inner) -> A {
305395
A { field1: inner }

0 commit comments

Comments
 (0)