1
1
use std:: ops:: Range ;
2
2
3
- use hir:: { Function , HasCrate , Module , ModuleDef } ;
3
+ use hir:: { HasCrate , Module , ModuleDef } ;
4
4
use ide_db:: {
5
5
FxHashSet , RootDatabase ,
6
6
assists:: AssistId ,
@@ -16,8 +16,7 @@ use syntax::{
16
16
AstNode , Edition , SyntaxElement , SyntaxKind , SyntaxNode , T ,
17
17
algo:: find_node_at_range,
18
18
ast:: {
19
- self , HasArgList , HasAttrs , HasGenericParams , HasName , HasVisibility , MethodCallExpr ,
20
- RecordExprField ,
19
+ self , HasArgList , HasAttrs , HasGenericParams , HasName , HasVisibility ,
21
20
edit:: { AstNodeEdit , IndentLevel } ,
22
21
make,
23
22
} ,
@@ -45,19 +44,19 @@ pub(crate) fn extract_struct_from_function_signature(
45
44
ctx : & AssistContext < ' _ > ,
46
45
) -> Option < ( ) > {
47
46
let find_node_at_offset = ctx. find_node_at_offset :: < ast:: Fn > ( ) ?;
48
- let fn_ast = find_node_at_offset;
49
- let param_list = fn_ast . param_list ( ) ?;
47
+ let func = find_node_at_offset;
48
+ let param_list = func . param_list ( ) ?;
50
49
let used_param_list = param_list
51
50
. params ( )
52
51
// filter to only parameters in selection
53
52
. filter ( |p| p. syntax ( ) . text_range ( ) . intersect ( ctx. selection_trimmed ( ) ) . is_some ( ) )
54
53
. collect_vec ( ) ;
55
54
let target =
56
55
used_param_list. iter ( ) . map ( |p| p. syntax ( ) . text_range ( ) ) . reduce ( |t, t2| t. cover ( t2) ) ?;
57
- let fn_name = fn_ast . name ( ) ?;
56
+ let fn_name = func . name ( ) ?;
58
57
let name = make:: name ( & format ! ( "{}Struct" , stdx:: to_camel_case( fn_name. text_non_mutable( ) ) ) ) ;
59
58
60
- let fn_hir = ctx. sema . to_def ( & fn_ast ) ?;
59
+ let fn_hir = ctx. sema . to_def ( & func ) ?;
61
60
if existing_definition ( ctx. db ( ) , & name, & fn_hir) {
62
61
cov_mark:: hit!( test_extract_function_signature_not_applicable_if_struct_exists) ;
63
62
return None ;
@@ -76,17 +75,17 @@ pub(crate) fn extract_struct_from_function_signature(
76
75
// TODO: (future)special handling for destrutered types (or maybe just don't support code action on
77
76
// destructed types yet
78
77
79
- let field_list = extract_field_list ( & fn_ast , & used_param_list) ?;
78
+ let field_list = extract_field_list ( & func , & used_param_list) ?;
80
79
81
- let start_index = used_param_list. first ( ) ?. syntax ( ) . index ( ) ;
82
- let end_index = used_param_list. last ( ) ?. syntax ( ) . index ( ) ;
83
- let used_params_range = start_index..end_index + 1 ;
80
+ let start_idx = used_param_list. first ( ) ?. syntax ( ) . index ( ) ;
81
+ let end_idx = used_param_list. last ( ) ?. syntax ( ) . index ( ) ;
82
+ let used_params_range = start_idx..end_idx + 1 ;
84
83
acc. add (
85
84
AssistId :: refactor_rewrite ( "extract_struct_from_function_signature" ) ,
86
85
"Extract struct from signature of a function" ,
87
86
target,
88
87
|builder| {
89
- let new_lifetime_count = field_list. fields ( ) . filter_map ( |f|f. ty ( ) ) . map ( |t|new_life_time_count ( & t) ) . sum ( ) ;
88
+ let n_new_lifetimes = field_list. fields ( ) . filter_map ( |f|f. ty ( ) ) . map ( |t|new_life_time_count ( & t) ) . sum ( ) ;
90
89
let edition = fn_hir. krate ( ctx. db ( ) ) . edition ( ctx. db ( ) ) ;
91
90
let enum_module_def = ModuleDef :: from ( fn_hir) ;
92
91
@@ -121,12 +120,12 @@ pub(crate) fn extract_struct_from_function_signature(
121
120
122
121
tracing:: info!( "extract_struct_from_function_signature: starting edit" ) ;
123
122
builder. edit_file ( ctx. vfs_file_id ( ) ) ;
124
- let fn_ast_mut = builder. make_mut ( fn_ast . clone ( ) ) ;
123
+ let func_mut = builder. make_mut ( func . clone ( ) ) ;
125
124
builder. make_mut ( param_list. clone ( ) ) ;
126
125
let used_param_list = used_param_list. into_iter ( ) . map ( |p| builder. make_mut ( p) ) . collect_vec ( ) ;
127
126
tracing:: info!( "extract_struct_from_function_signature: editing main file" ) ;
128
127
// this has to be after the edit_file (order matters)
129
- // fn_ast and param_list must be "mut" for the effect to work on used_param_list
128
+ // func and param_list must be "mut" for the effect to work on used_param_list
130
129
if let Some ( references) = def_file_references {
131
130
let processed = process_references (
132
131
ctx,
@@ -144,7 +143,7 @@ pub(crate) fn extract_struct_from_function_signature(
144
143
}
145
144
146
145
147
- let generic_params = fn_ast
146
+ let generic_params = func
148
147
. generic_param_list ( )
149
148
. and_then ( |known_generics| extract_generic_params ( & known_generics, & field_list) ) ;
150
149
tracing:: info!( "extract_struct_from_function_signature: collecting generics" ) ;
@@ -157,7 +156,7 @@ pub(crate) fn extract_struct_from_function_signature(
157
156
// So I do the resolving while its still param list
158
157
// and then apply it into record list after
159
158
let field_list = if let Some ( ( target_scope, source_scope) ) =
160
- ctx. sema . scope ( fn_ast . syntax ( ) ) . zip ( ctx. sema . scope ( param_list. syntax ( ) ) )
159
+ ctx. sema . scope ( func . syntax ( ) ) . zip ( ctx. sema . scope ( param_list. syntax ( ) ) )
161
160
{
162
161
let field_list = field_list. reset_indent ( ) ;
163
162
let field_list =
@@ -174,11 +173,11 @@ pub(crate) fn extract_struct_from_function_signature(
174
173
} ;
175
174
field_list. fields ( ) . filter_map ( |f|f. ty ( ) ) . try_for_each ( |t|generate_new_lifetimes ( & t, & mut generics) ) ;
176
175
tracing:: info!( "extract_struct_from_function_signature: collecting fields" ) ;
177
- let def = create_struct_def ( name. clone ( ) , & fn_ast_mut , & used_param_list, & field_list, generics) ;
176
+ let def = create_struct_def ( name. clone ( ) , & func_mut , & used_param_list, & field_list, generics) ;
178
177
tracing:: info!( "extract_struct_from_function_signature: creating struct" ) ;
179
178
180
179
// if in impl block then put struct before the impl block
181
- let ( indent, syntax) = param_list. self_param ( ) . and_then ( |_|ctx. find_node_at_range :: < ast:: Impl > ( ) ) . map ( |impl_ |builder. make_mut ( impl_ ) ) . map ( |impl_ |( impl_ . indent_level ( ) , impl_ . syntax ( ) . clone ( ) ) ) . unwrap_or ( ( fn_ast . indent_level ( ) , fn_ast_mut . syntax ( ) . clone ( ) ) ) ;
180
+ let ( indent, syntax) = param_list. self_param ( ) . and_then ( |_|ctx. find_node_at_range :: < ast:: Impl > ( ) ) . map ( |imp |builder. make_mut ( imp ) ) . map ( |imp |( imp . indent_level ( ) , imp . syntax ( ) . clone ( ) ) ) . unwrap_or ( ( func . indent_level ( ) , func_mut . syntax ( ) . clone ( ) ) ) ;
182
181
let def = def. indent ( indent) ;
183
182
184
183
@@ -190,22 +189,22 @@ pub(crate) fn extract_struct_from_function_signature(
190
189
] ,
191
190
) ;
192
191
tracing:: info!( "extract_struct_from_function_signature: inserting struct {def}" ) ;
193
- update_function ( name, generic_params. map ( |g| g. clone_for_update ( ) ) , & used_param_list, new_lifetime_count ) . unwrap ( ) ;
192
+ update_function ( name, generic_params. map ( |g| g. clone_for_update ( ) ) , & used_param_list, n_new_lifetimes ) . unwrap ( ) ;
194
193
tracing:: info!( "extract_struct_from_function_signature: updating function signature and parameter uses" ) ;
195
194
} ,
196
195
)
197
196
}
198
197
199
198
fn extract_field_list (
200
- fn_ast : & ast:: Fn ,
199
+ func : & ast:: Fn ,
201
200
used_param_list : & [ ast:: Param ] ,
202
201
) -> Option < ast:: RecordFieldList > {
203
202
let field_list = make:: record_field_list (
204
203
used_param_list
205
204
. iter ( )
206
205
. map ( |param| {
207
206
Some ( make:: record_field (
208
- fn_ast . visibility ( ) ,
207
+ func . visibility ( ) ,
209
208
// only works if its an ident pattern
210
209
param. pat ( ) . and_then ( pat_to_name) ?,
211
210
param. ty ( ) . filter ( |ty| !contains_impl_trait ( ty) ) ?,
@@ -220,14 +219,14 @@ fn update_function(
220
219
name : ast:: Name ,
221
220
generics : Option < ast:: GenericParamList > ,
222
221
used_param_list : & [ ast:: Param ] ,
223
- new_lifetime_count : usize ,
222
+ n_new_lifetimes : usize ,
224
223
) -> Option < ( ) > {
225
224
let generic_args = generics
226
225
. filter ( |generics| generics. generic_params ( ) . count ( ) > 0 )
227
- . or ( ( new_lifetime_count > 0 ) . then_some ( make:: generic_param_list ( std:: iter:: empty ( ) ) ) )
226
+ . or ( ( n_new_lifetimes > 0 ) . then_some ( make:: generic_param_list ( std:: iter:: empty ( ) ) ) )
228
227
. map ( |generics| {
229
228
let args = generics. to_generic_args ( ) . clone_for_update ( ) ;
230
- ( 0 ..new_lifetime_count ) . for_each ( |_| {
229
+ ( 0 ..n_new_lifetimes ) . for_each ( |_| {
231
230
args. add_generic_arg (
232
231
make:: lifetime_arg ( make:: lifetime ( "'_" ) ) . clone_for_update ( ) . into ( ) ,
233
232
)
@@ -258,9 +257,9 @@ fn update_function(
258
257
259
258
// it is fine to unwrap() to because there is at least one parameter (if there is no parameters
260
259
// the code action will not show)
261
- let start_index = used_param_list. first ( ) . unwrap ( ) . syntax ( ) . index ( ) ;
262
- let end_index = used_param_list. last ( ) . unwrap ( ) . syntax ( ) . index ( ) ;
263
- let used_params_range = start_index..end_index + 1 ;
260
+ let start_idx = used_param_list. first ( ) . unwrap ( ) . syntax ( ) . index ( ) ;
261
+ let end_idx = used_param_list. last ( ) . unwrap ( ) . syntax ( ) . index ( ) ;
262
+ let used_params_range = start_idx..end_idx + 1 ;
264
263
let new = vec ! [ param. syntax( ) . syntax_element( ) ] ;
265
264
used_param_list. first ( ) . unwrap ( ) . syntax ( ) . parent ( ) ?. splice_children ( used_params_range, new) ;
266
265
// no need update uses of parameters in function, because we destructure the struct
@@ -274,12 +273,12 @@ fn pat_to_name(pat: ast::Pat) -> Option<ast::Name> {
274
273
}
275
274
fn create_struct_def (
276
275
name : ast:: Name ,
277
- fn_ast : & ast:: Fn ,
276
+ func : & ast:: Fn ,
278
277
param_ast : & [ ast:: Param ] ,
279
278
field_list : & ast:: RecordFieldList ,
280
279
generics : Option < ast:: GenericParamList > ,
281
280
) -> ast:: Struct {
282
- let fn_vis = fn_ast . visibility ( ) ;
281
+ let fn_vis = func . visibility ( ) ;
283
282
284
283
let insert_vis = |node : & ' _ SyntaxNode , vis : & ' _ SyntaxNode | {
285
284
let vis = vis. clone_for_update ( ) ;
@@ -449,7 +448,11 @@ fn tag_generics_in_function_signature(
449
448
450
449
tagged_one
451
450
}
452
- fn existing_definition ( db : & RootDatabase , variant_name : & ast:: Name , variant : & Function ) -> bool {
451
+ fn existing_definition (
452
+ db : & RootDatabase ,
453
+ variant_name : & ast:: Name ,
454
+ variant : & hir:: Function ,
455
+ ) -> bool {
453
456
variant
454
457
. module ( db)
455
458
. scope ( db, None )
@@ -519,7 +522,7 @@ fn reference_to_node(
519
522
// return None;
520
523
// }
521
524
522
- let module = sema. scope ( & node. syntax ( ) ) ?. module ( ) ;
525
+ let module = sema. scope ( node. syntax ( ) ) ?. module ( ) ;
523
526
524
527
Some ( ( node. clone ( ) , node. syntax ( ) . clone ( ) , module) )
525
528
}
@@ -551,7 +554,7 @@ fn apply_references(
551
554
// the zip implicitly makes that it will only take the amount of parameters required
552
555
. zip ( field_list. fields ( ) )
553
556
. map ( |e| {
554
- e. 1 . name ( ) . map ( |name| -> RecordExprField {
557
+ e. 1 . name ( ) . map ( |name| -> ast :: RecordExprField {
555
558
make:: record_expr_field ( make:: name_ref ( name. text_non_mutable ( ) ) , Some ( e. 0 ) )
556
559
} )
557
560
} )
@@ -591,7 +594,7 @@ impl AstNode for CallExpr {
591
594
{
592
595
ast:: CallExpr :: cast ( syntax. clone ( ) )
593
596
. map ( CallExpr :: Normal )
594
- . or ( MethodCallExpr :: cast ( syntax) . map ( CallExpr :: Method ) )
597
+ . or ( ast :: MethodCallExpr :: cast ( syntax) . map ( CallExpr :: Method ) )
595
598
}
596
599
597
600
fn syntax ( & self ) -> & SyntaxNode {
0 commit comments