@@ -2,9 +2,10 @@ use ide_db::{defs::Definition, search::Reference};
22use syntax:: {
33 algo:: find_node_at_range,
44 ast:: { self , ArgListOwner } ,
5- AstNode , SyntaxNode , TextRange , T ,
5+ AstNode , SyntaxKind , SyntaxNode , TextRange , T ,
66} ;
77use test_utils:: mark;
8+ use SyntaxKind :: WHITESPACE ;
89
910use crate :: {
1011 assist_context:: AssistBuilder , utils:: next_prev, AssistContext , AssistId , AssistKind , Assists ,
@@ -56,7 +57,7 @@ pub(crate) fn remove_unused_param(acc: &mut Assists, ctx: &AssistContext) -> Opt
5657 "Remove unused parameter" ,
5758 param. syntax ( ) . text_range ( ) ,
5859 |builder| {
59- builder. delete ( range_with_coma ( param. syntax ( ) ) ) ;
60+ builder. delete ( range_to_remove ( param. syntax ( ) ) ) ;
6061 for usage in fn_def. usages ( & ctx. sema ) . all ( ) {
6162 process_usage ( ctx, builder, usage, param_position) ;
6263 }
@@ -80,19 +81,34 @@ fn process_usage(
8081 let arg = call_expr. arg_list ( ) ?. args ( ) . nth ( arg_to_remove) ?;
8182
8283 builder. edit_file ( usage. file_range . file_id ) ;
83- builder. delete ( range_with_coma ( arg. syntax ( ) ) ) ;
84+ builder. delete ( range_to_remove ( arg. syntax ( ) ) ) ;
8485
8586 Some ( ( ) )
8687}
8788
88- fn range_with_coma ( node : & SyntaxNode ) -> TextRange {
89- let up_to = next_prev ( ) . find_map ( |dir| {
89+ fn range_to_remove ( node : & SyntaxNode ) -> TextRange {
90+ let up_to_comma = next_prev ( ) . find_map ( |dir| {
9091 node. siblings_with_tokens ( dir)
9192 . filter_map ( |it| it. into_token ( ) )
9293 . find ( |it| it. kind ( ) == T ! [ , ] )
94+ . map ( |it| ( dir, it) )
9395 } ) ;
94- let up_to = up_to. map_or ( node. text_range ( ) , |it| it. text_range ( ) ) ;
95- node. text_range ( ) . cover ( up_to)
96+ if let Some ( ( dir, token) ) = up_to_comma {
97+ if node. next_sibling ( ) . is_some ( ) {
98+ let up_to_space = token
99+ . siblings_with_tokens ( dir)
100+ . skip ( 1 )
101+ . take_while ( |it| it. kind ( ) == WHITESPACE )
102+ . last ( )
103+ . and_then ( |it| it. into_token ( ) ) ;
104+ return node
105+ . text_range ( )
106+ . cover ( up_to_space. map_or ( token. text_range ( ) , |it| it. text_range ( ) ) ) ;
107+ }
108+ node. text_range ( ) . cover ( token. text_range ( ) )
109+ } else {
110+ node. text_range ( )
111+ }
96112}
97113
98114#[ cfg( test) ]
@@ -118,6 +134,57 @@ fn b() { foo(9, ) }
118134 ) ;
119135 }
120136
137+ #[ test]
138+ fn remove_unused_first_param ( ) {
139+ check_assist (
140+ remove_unused_param,
141+ r#"
142+ fn foo(<|>x: i32, y: i32) { y; }
143+ fn a() { foo(1, 2) }
144+ fn b() { foo(1, 2,) }
145+ "# ,
146+ r#"
147+ fn foo(y: i32) { y; }
148+ fn a() { foo(2) }
149+ fn b() { foo(2,) }
150+ "# ,
151+ ) ;
152+ }
153+
154+ #[ test]
155+ fn remove_unused_single_param ( ) {
156+ check_assist (
157+ remove_unused_param,
158+ r#"
159+ fn foo(<|>x: i32) { 0; }
160+ fn a() { foo(1) }
161+ fn b() { foo(1, ) }
162+ "# ,
163+ r#"
164+ fn foo() { 0; }
165+ fn a() { foo() }
166+ fn b() { foo( ) }
167+ "# ,
168+ ) ;
169+ }
170+
171+ #[ test]
172+ fn remove_unused_surrounded_by_parms ( ) {
173+ check_assist (
174+ remove_unused_param,
175+ r#"
176+ fn foo(x: i32, <|>y: i32, z: i32) { x; }
177+ fn a() { foo(1, 2, 3) }
178+ fn b() { foo(1, 2, 3,) }
179+ "# ,
180+ r#"
181+ fn foo(x: i32, z: i32) { x; }
182+ fn a() { foo(1, 3) }
183+ fn b() { foo(1, 3,) }
184+ "# ,
185+ ) ;
186+ }
187+
121188 #[ test]
122189 fn remove_unused_qualified_call ( ) {
123190 check_assist (
0 commit comments