Skip to content

Commit 40c7666

Browse files
committed
feat: extract_struct_from_function_signature
the signature of the function now uses the struct with all the generic args while uses don't specifiy any generics
1 parent 63b8d61 commit 40c7666

File tree

1 file changed

+20
-15
lines changed

1 file changed

+20
-15
lines changed

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

Lines changed: 20 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,8 @@ use itertools::Itertools;
1515
use syntax::{
1616
AstNode, Edition, SyntaxElement, SyntaxKind, SyntaxNode, T,
1717
ast::{
18-
self, CallExpr, HasArgList, HasAttrs, HasGenericParams, HasName, HasVisibility,
19-
RecordExprField,
18+
self, CallExpr, HasArgList, HasAttrs, HasGenericArgs, HasGenericParams, HasName,
19+
HasVisibility, RecordExprField,
2020
edit::{AstNodeEdit, IndentLevel},
2121
make,
2222
},
@@ -66,6 +66,7 @@ pub(crate) fn extract_struct_from_function_signature(
6666
// TODO: special handling for destrutered types (or maybe just don't support code action on
6767
// destructed types yet
6868

69+
// TODO: don't allow if there is impl traits
6970
let field_list = make::record_field_list(
7071
used_param_list
7172
.iter()
@@ -118,12 +119,11 @@ pub(crate) fn extract_struct_from_function_signature(
118119
processed.into_iter().for_each(|(path, node, import)| {
119120
apply_references(ctx.config.insert_use, path, node, import, edition, used_params_range.clone(), &field_list,
120121
name.clone(),
121-
new_lifetime_count
122+
// new_lifetime_count
122123
);
123124
});
124125
}
125126

126-
// TODO: update calls to the function
127127
tracing::info!("extract_struct_from_function_signature: starting edit");
128128
builder.edit_file(ctx.vfs_file_id());
129129
let fn_ast_mut = builder.make_mut(fn_ast.clone());
@@ -144,7 +144,7 @@ pub(crate) fn extract_struct_from_function_signature(
144144
processed.into_iter().for_each(|(path, node, import)| {
145145
apply_references(ctx.config.insert_use, path, node, import, edition, used_params_range.clone(), &field_list,
146146
name.clone(),
147-
new_lifetime_count
147+
// new_lifetime_count
148148
);
149149
});
150150
}
@@ -207,9 +207,10 @@ fn update_function(
207207
used_param_list: &[ast::Param],
208208
new_lifetime_count: usize,
209209
) -> Option<()> {
210-
// TODO: add new generics if needed
211-
let generic_args =
212-
generics.filter(|generics| generics.generic_params().count() > 0).map(|generics| {
210+
let generic_args = generics
211+
.filter(|generics| generics.generic_params().count() > 0)
212+
.or((new_lifetime_count > 0).then_some(make::generic_param_list(std::iter::empty())))
213+
.map(|generics| {
213214
let args = generics.to_generic_args().clone_for_update();
214215
(0..new_lifetime_count).for_each(|_| {
215216
args.add_generic_arg(
@@ -490,14 +491,14 @@ fn reference_to_node(
490491
sema: &hir::Semantics<'_, RootDatabase>,
491492
reference: FileReference,
492493
) -> Option<(ast::PathSegment, SyntaxNode, hir::Module)> {
493-
// filter out the reference in macro
494+
// filter out the reference in macro (seems to be probalamtic with lifetimes/generics arguments)
494495
let segment =
495496
reference.name.as_name_ref()?.syntax().parent().and_then(ast::PathSegment::cast)?;
496497

497-
let segment_range = segment.syntax().text_range();
498-
if segment_range != reference.range {
499-
return None;
500-
}
498+
// let segment_range = segment.syntax().text_range();
499+
// if segment_range != reference.range {
500+
// return None;
501+
// }
501502

502503
let parent = segment.parent_path().syntax().parent()?;
503504
let expr_or_pat = match_ast! {
@@ -523,7 +524,7 @@ fn apply_references(
523524
used_params_range: Range<usize>,
524525
field_list: &ast::RecordFieldList,
525526
name: ast::Name,
526-
new_lifetime_count: usize,
527+
// new_lifetime_count: usize,
527528
) -> Option<()> {
528529
if let Some((scope, path)) = import {
529530
insert_use(&scope, mod_path_to_ast(&path, edition), &insert_use_cfg);
@@ -540,6 +541,10 @@ fn apply_references(
540541
// });
541542
// }
542543

544+
// current idea: the lifetimes can be inferred from the call
545+
if let Some(generics) = segment.generic_arg_list() {
546+
ted::remove(generics.syntax());
547+
}
543548
ted::replace(segment.name_ref()?.syntax(), name.clone_for_update().syntax());
544549
// deep clone to prevent cycle
545550
let path = make::path_from_segments(std::iter::once(segment.clone_subtree()), false);
@@ -735,7 +740,7 @@ fn foo($0bar: &'_ i32$0, baz: i32) {}
735740
r#"
736741
struct FooStruct<'a>{ bar: &'a i32 }
737742
738-
fn foo(FooStruct { bar, .. }: FooStruct, baz: i32) {}
743+
fn foo(FooStruct { bar, .. }: FooStruct<'_>, baz: i32) {}
739744
"#,
740745
);
741746
}

0 commit comments

Comments
 (0)