@@ -2,9 +2,10 @@ use ide_db::{defs::Definition, search::Reference};
2
2
use syntax:: {
3
3
algo:: find_node_at_range,
4
4
ast:: { self , ArgListOwner } ,
5
- AstNode , SyntaxNode , TextRange , T ,
5
+ AstNode , SyntaxKind , SyntaxNode , TextRange , T ,
6
6
} ;
7
7
use test_utils:: mark;
8
+ use SyntaxKind :: WHITESPACE ;
8
9
9
10
use crate :: {
10
11
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
56
57
"Remove unused parameter" ,
57
58
param. syntax ( ) . text_range ( ) ,
58
59
|builder| {
59
- builder. delete ( range_with_coma ( param. syntax ( ) ) ) ;
60
+ builder. delete ( range_to_remove ( param. syntax ( ) ) ) ;
60
61
for usage in fn_def. usages ( & ctx. sema ) . all ( ) {
61
62
process_usage ( ctx, builder, usage, param_position) ;
62
63
}
@@ -80,19 +81,34 @@ fn process_usage(
80
81
let arg = call_expr. arg_list ( ) ?. args ( ) . nth ( arg_to_remove) ?;
81
82
82
83
builder. edit_file ( usage. file_range . file_id ) ;
83
- builder. delete ( range_with_coma ( arg. syntax ( ) ) ) ;
84
+ builder. delete ( range_to_remove ( arg. syntax ( ) ) ) ;
84
85
85
86
Some ( ( ) )
86
87
}
87
88
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| {
90
91
node. siblings_with_tokens ( dir)
91
92
. filter_map ( |it| it. into_token ( ) )
92
93
. find ( |it| it. kind ( ) == T ! [ , ] )
94
+ . map ( |it| ( dir, it) )
93
95
} ) ;
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
+ }
96
112
}
97
113
98
114
#[ cfg( test) ]
@@ -118,6 +134,57 @@ fn b() { foo(9, ) }
118
134
) ;
119
135
}
120
136
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
+
121
188
#[ test]
122
189
fn remove_unused_qualified_call ( ) {
123
190
check_assist (
0 commit comments