Skip to content

Commit d571ca8

Browse files
bors[bot]feniljain
andauthored
Merge #9593
9593: fix: Adding remove_unused_param for method and fixing same for assoc func r=matklad a=feniljain Solves #9571 Co-authored-by: vi_mi <[email protected]>
2 parents bf8a55a + 0898d3b commit d571ca8

File tree

1 file changed

+50
-18
lines changed

1 file changed

+50
-18
lines changed

crates/ide_assists/src/handlers/remove_unused_param.rs

Lines changed: 50 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,8 @@ pub(crate) fn remove_unused_param(acc: &mut Assists, ctx: &AssistContext) -> Opt
3737
_ => return None,
3838
};
3939
let func = param.syntax().ancestors().find_map(ast::Fn::cast)?;
40+
let is_self_present =
41+
param.syntax().parent()?.children().find_map(ast::SelfParam::cast).is_some();
4042

4143
// check if fn is in impl Trait for ..
4244
if func
@@ -50,7 +52,16 @@ pub(crate) fn remove_unused_param(acc: &mut Assists, ctx: &AssistContext) -> Opt
5052
return None;
5153
}
5254

53-
let param_position = func.param_list()?.params().position(|it| it == param)?;
55+
let mut param_position = func.param_list()?.params().position(|it| it == param)?;
56+
// param_list() does not take self param into consideration, hence this additional check is
57+
// added. There are two cases to handle in this scenario, where functions are
58+
// associative(functions not associative and not containting contain self, are not allowed), in
59+
// this case param position is rightly set. If a method call is present which has self param,
60+
// that needs to be handled and is added below in process_usage function to reduce this increment and
61+
// not consider self param.
62+
if is_self_present {
63+
param_position += 1;
64+
}
5465
let fn_def = {
5566
let func = ctx.sema.to_def(&func)?;
5667
Definition::ModuleDef(func.into())
@@ -71,7 +82,7 @@ pub(crate) fn remove_unused_param(acc: &mut Assists, ctx: &AssistContext) -> Opt
7182
|builder| {
7283
builder.delete(range_to_remove(param.syntax()));
7384
for (file_id, references) in fn_def.usages(&ctx.sema).all() {
74-
process_usages(ctx, builder, file_id, references, param_position);
85+
process_usages(ctx, builder, file_id, references, param_position, is_self_present);
7586
}
7687
},
7788
)
@@ -83,11 +94,13 @@ fn process_usages(
8394
file_id: FileId,
8495
references: Vec<FileReference>,
8596
arg_to_remove: usize,
97+
is_self_present: bool,
8698
) {
8799
let source_file = ctx.sema.parse(file_id);
88100
builder.edit_file(file_id);
89101
for usage in references {
90-
if let Some(text_range) = process_usage(&source_file, usage, arg_to_remove) {
102+
if let Some(text_range) = process_usage(&source_file, usage, arg_to_remove, is_self_present)
103+
{
91104
builder.delete(text_range);
92105
}
93106
}
@@ -96,15 +109,37 @@ fn process_usages(
96109
fn process_usage(
97110
source_file: &SourceFile,
98111
FileReference { range, .. }: FileReference,
99-
arg_to_remove: usize,
112+
mut arg_to_remove: usize,
113+
is_self_present: bool,
100114
) -> Option<TextRange> {
101-
let call_expr: ast::CallExpr = find_node_at_range(source_file.syntax(), range)?;
102-
let call_expr_range = call_expr.expr()?.syntax().text_range();
103-
if !call_expr_range.contains_range(range) {
104-
return None;
115+
let call_expr_opt: Option<ast::CallExpr> = find_node_at_range(source_file.syntax(), range);
116+
if let Some(call_expr) = call_expr_opt {
117+
let call_expr_range = call_expr.expr()?.syntax().text_range();
118+
if !call_expr_range.contains_range(range) {
119+
return None;
120+
}
121+
122+
let arg = call_expr.arg_list()?.args().nth(arg_to_remove)?;
123+
return Some(range_to_remove(arg.syntax()));
105124
}
106-
let arg = call_expr.arg_list()?.args().nth(arg_to_remove)?;
107-
Some(range_to_remove(arg.syntax()))
125+
126+
let method_call_expr_opt: Option<ast::MethodCallExpr> =
127+
find_node_at_range(source_file.syntax(), range);
128+
if let Some(method_call_expr) = method_call_expr_opt {
129+
let method_call_expr_range = method_call_expr.name_ref()?.syntax().text_range();
130+
if !method_call_expr_range.contains_range(range) {
131+
return None;
132+
}
133+
134+
if is_self_present {
135+
arg_to_remove -= 1;
136+
}
137+
138+
let arg = method_call_expr.arg_list()?.args().nth(arg_to_remove)?;
139+
return Some(range_to_remove(arg.syntax()));
140+
}
141+
142+
return None;
108143
}
109144

110145
fn range_to_remove(node: &SyntaxNode) -> TextRange {
@@ -315,10 +350,7 @@ fn bar() {
315350
}
316351

317352
#[test]
318-
fn remove_method_param() {
319-
// FIXME: This is completely wrong:
320-
// * method call expressions are not handled
321-
// * assoc function syntax removes the wrong argument.
353+
fn test_remove_method_param() {
322354
check_assist(
323355
remove_unused_param,
324356
r#"
@@ -327,18 +359,18 @@ impl S { fn f(&self, $0_unused: i32) {} }
327359
fn main() {
328360
S.f(92);
329361
S.f();
330-
S.f(92, 92);
362+
S.f(93, 92);
331363
S::f(&S, 92);
332364
}
333365
"#,
334366
r#"
335367
struct S;
336368
impl S { fn f(&self) {} }
337369
fn main() {
338-
S.f(92);
339370
S.f();
340-
S.f(92, 92);
341-
S::f(92);
371+
S.f();
372+
S.f(92);
373+
S::f(&S);
342374
}
343375
"#,
344376
)

0 commit comments

Comments
 (0)