1
- use std:: collections:: { HashMap , HashSet } ;
1
+ use std:: {
2
+ collections:: { HashMap , HashSet } ,
3
+ iter,
4
+ } ;
2
5
3
6
use hir:: { HasSource , ModuleSource } ;
4
7
use ide_db:: {
@@ -207,31 +210,25 @@ pub(crate) fn extract_module(acc: &mut Assists, ctx: &AssistContext) -> Option<(
207
210
#[ derive( Debug ) ]
208
211
struct Module {
209
212
text_range : TextRange ,
210
- name : String ,
211
- body_items : Vec < ast:: Item > , // All items except use items
212
- use_items : Vec < ast:: Item > , // Use items are kept separately as they help when the selection is inside an impl block, we can directly take these items and keep them outside generated impl block inside generated module
213
+ name : & ' static str ,
214
+ /// All items except use items.
215
+ body_items : Vec < ast:: Item > ,
216
+ /// Use items are kept separately as they help when the selection is inside an impl block,
217
+ /// we can directly take these items and keep them outside generated impl block inside
218
+ /// generated module.
219
+ use_items : Vec < ast:: Item > ,
213
220
}
214
221
215
222
fn extract_target ( node : & SyntaxNode , selection_range : TextRange ) -> Option < Module > {
216
- let mut use_items = vec ! [ ] ;
217
-
218
- let mut body_items: Vec < ast:: Item > = node
223
+ let selected_nodes = node
219
224
. children ( )
220
- . filter ( |child| selection_range. contains_range ( child. text_range ( ) ) )
221
- . filter_map ( |child| match ast:: Item :: cast ( child) {
222
- Some ( it @ ast:: Item :: Use ( _) ) => {
223
- use_items. push ( it) ;
224
- None
225
- }
226
- item => item,
227
- } )
228
- . collect ( ) ;
229
-
230
- if let Some ( node_item) = ast:: Item :: cast ( node. clone ( ) ) {
231
- body_items. push ( node_item) ;
232
- }
225
+ . filter ( |node| selection_range. contains_range ( node. text_range ( ) ) )
226
+ . chain ( iter:: once ( node. clone ( ) ) ) ;
227
+ let ( use_items, body_items) = selected_nodes
228
+ . filter_map ( ast:: Item :: cast)
229
+ . partition ( |item| matches ! ( item, ast:: Item :: Use ( ..) ) ) ;
233
230
234
- Some ( Module { text_range : selection_range, name : "modname" . to_string ( ) , body_items, use_items } )
231
+ Some ( Module { text_range : selection_range, name : "modname" , body_items, use_items } )
235
232
}
236
233
237
234
impl Module {
@@ -245,7 +242,7 @@ impl Module {
245
242
//Here impl is not included as each item inside impl will be tied to the parent of
246
243
//implementing block(a struct, enum, etc), if the parent is in selected module, it will
247
244
//get updated by ADT section given below or if it is not, then we dont need to do any operation
248
- self . body_items . iter ( ) . cloned ( ) . for_each ( |item| {
245
+ for item in & self . body_items {
249
246
match_ast ! {
250
247
match ( item. syntax( ) ) {
251
248
ast:: Adt ( it) => {
@@ -314,7 +311,7 @@ impl Module {
314
311
_ => ( ) ,
315
312
}
316
313
}
317
- } ) ;
314
+ }
318
315
319
316
( refs, adt_fields)
320
317
}
@@ -323,36 +320,17 @@ impl Module {
323
320
& self ,
324
321
ctx : & AssistContext ,
325
322
node_def : Definition ,
326
- refs : & mut HashMap < FileId , Vec < ( TextRange , String ) > > ,
323
+ refs_in_files : & mut HashMap < FileId , Vec < ( TextRange , String ) > > ,
327
324
) {
328
325
for ( file_id, references) in node_def. usages ( & ctx. sema ) . all ( ) {
329
- if let Some ( file_refs) = refs. get_mut ( & file_id) {
330
- let mut usages = self . expand_ref_to_usages ( references, ctx, file_id) ;
331
- file_refs. append ( & mut usages) ;
332
- } else {
333
- refs. insert ( file_id, self . expand_ref_to_usages ( references, ctx, file_id) ) ;
334
- }
326
+ let source_file = ctx. sema . parse ( file_id) ;
327
+ let usages_in_file = references
328
+ . into_iter ( )
329
+ . filter_map ( |usage| self . get_usage_to_be_processed ( & source_file, usage) ) ;
330
+ refs_in_files. entry ( file_id) . or_default ( ) . extend ( usages_in_file) ;
335
331
}
336
332
}
337
333
338
- fn expand_ref_to_usages (
339
- & self ,
340
- refs : Vec < FileReference > ,
341
- ctx : & AssistContext ,
342
- file_id : FileId ,
343
- ) -> Vec < ( TextRange , String ) > {
344
- let source_file = ctx. sema . parse ( file_id) ;
345
-
346
- let mut usages_to_be_processed_for_file = Vec :: new ( ) ;
347
- for usage in refs {
348
- if let Some ( x) = self . get_usage_to_be_processed ( & source_file, usage) {
349
- usages_to_be_processed_for_file. push ( x) ;
350
- }
351
- }
352
-
353
- usages_to_be_processed_for_file
354
- }
355
-
356
334
fn get_usage_to_be_processed (
357
335
& self ,
358
336
source_file : & SourceFile ,
@@ -380,36 +358,30 @@ impl Module {
380
358
let ( mut replacements, record_field_parents, impls) =
381
359
get_replacements_for_visibilty_change ( & mut self . body_items , false ) ;
382
360
383
- let mut impl_items = Vec :: new ( ) ;
384
- for impl_ in impls {
385
- let mut this_impl_items = Vec :: new ( ) ;
386
- for node in impl_. syntax ( ) . descendants ( ) {
387
- if let Some ( item) = ast:: Item :: cast ( node) {
388
- this_impl_items. push ( item) ;
389
- }
390
- }
391
-
392
- impl_items. append ( & mut this_impl_items) ;
393
- }
361
+ let mut impl_items: Vec < ast:: Item > = impls
362
+ . into_iter ( )
363
+ . flat_map ( |impl_| impl_. syntax ( ) . descendants ( ) )
364
+ . filter_map ( ast:: Item :: cast)
365
+ . collect ( ) ;
394
366
395
367
let ( mut impl_item_replacements, _, _) =
396
368
get_replacements_for_visibilty_change ( & mut impl_items, true ) ;
397
369
398
370
replacements. append ( & mut impl_item_replacements) ;
399
371
400
- record_field_parents . into_iter ( ) . for_each ( |x| {
401
- x . 1 . descendants ( ) . filter_map ( ast:: RecordField :: cast) . for_each ( |desc| {
372
+ for ( _ , field_owner ) in record_field_parents {
373
+ for desc in field_owner . descendants ( ) . filter_map ( ast:: RecordField :: cast) {
402
374
let is_record_field_present =
403
375
record_fields. clone ( ) . into_iter ( ) . any ( |x| x. to_string ( ) == desc. to_string ( ) ) ;
404
376
if is_record_field_present {
405
377
replacements. push ( ( desc. visibility ( ) , desc. syntax ( ) . clone ( ) ) ) ;
406
378
}
407
- } ) ;
408
- } ) ;
379
+ }
380
+ }
409
381
410
- replacements . into_iter ( ) . for_each ( | ( vis, syntax) | {
382
+ for ( vis, syntax) in replacements {
411
383
add_change_vis ( vis, syntax. first_child_or_token ( ) ) ;
412
- } ) ;
384
+ }
413
385
}
414
386
415
387
fn resolve_imports (
@@ -420,8 +392,8 @@ impl Module {
420
392
let mut import_paths_to_be_removed: Vec < TextRange > = vec ! [ ] ;
421
393
let mut node_set: HashSet < String > = HashSet :: new ( ) ;
422
394
423
- self . body_items . clone ( ) . into_iter ( ) . for_each ( |item| {
424
- item. syntax ( ) . descendants ( ) . for_each ( |x| {
395
+ for item in self . body_items . clone ( ) {
396
+ for x in item. syntax ( ) . descendants ( ) {
425
397
if let Some ( name) = ast:: Name :: cast ( x. clone ( ) ) {
426
398
if let Some ( name_classify) = NameClass :: classify ( & ctx. sema , & name) {
427
399
//Necessary to avoid two same names going through
@@ -473,8 +445,8 @@ impl Module {
473
445
}
474
446
}
475
447
}
476
- } ) ;
477
- } ) ;
448
+ }
449
+ }
478
450
479
451
import_paths_to_be_removed
480
452
}
@@ -495,8 +467,8 @@ impl Module {
495
467
496
468
let mut exists_inside_sel = false ;
497
469
let mut exists_outside_sel = false ;
498
- usage_res . clone ( ) . into_iter ( ) . for_each ( |x| {
499
- let mut non_use_nodes_itr = ( & x . 1 ) . iter ( ) . filter_map ( |x| {
470
+ for ( _ , refs ) in usage_res . iter ( ) {
471
+ let mut non_use_nodes_itr = refs . iter ( ) . filter_map ( |x| {
500
472
if find_node_at_range :: < ast:: Use > ( file. syntax ( ) , x. range ) . is_none ( ) {
501
473
let path_opt = find_node_at_range :: < ast:: Path > ( file. syntax ( ) , x. range ) ;
502
474
return path_opt;
@@ -514,7 +486,7 @@ impl Module {
514
486
if non_use_nodes_itr. any ( |x| selection_range. contains_range ( x. syntax ( ) . text_range ( ) ) ) {
515
487
exists_inside_sel = true ;
516
488
}
517
- } ) ;
489
+ }
518
490
519
491
let source_exists_outside_sel_in_same_mod = does_source_exists_outside_sel_in_same_mod (
520
492
def,
@@ -524,18 +496,14 @@ impl Module {
524
496
curr_file_id,
525
497
) ;
526
498
527
- let use_stmt_opt: Option < ast:: Use > = usage_res. into_iter ( ) . find_map ( |x| {
528
- let file_id = x. 0 ;
529
- let mut use_opt: Option < ast:: Use > = None ;
499
+ let use_stmt_opt: Option < ast:: Use > = usage_res. into_iter ( ) . find_map ( |( file_id, refs) | {
530
500
if file_id == curr_file_id {
531
- ( & x. 1 ) . iter ( ) . for_each ( |x| {
532
- let node_opt: Option < ast:: Use > = find_node_at_range ( file. syntax ( ) , x. range ) ;
533
- if let Some ( node) = node_opt {
534
- use_opt = Some ( node) ;
535
- }
536
- } ) ;
501
+ refs. into_iter ( )
502
+ . rev ( )
503
+ . find_map ( |fref| find_node_at_range ( file. syntax ( ) , fref. range ) )
504
+ } else {
505
+ None
537
506
}
538
- use_opt
539
507
} ) ;
540
508
541
509
let mut use_tree_str_opt: Option < Vec < ast:: Path > > = None ;
@@ -811,7 +779,7 @@ fn get_replacements_for_visibilty_change(
811
779
let mut record_field_parents = Vec :: new ( ) ;
812
780
let mut impls = Vec :: new ( ) ;
813
781
814
- items . into_iter ( ) . for_each ( | item| {
782
+ for item in items {
815
783
if !is_clone_for_updated {
816
784
* item = item. clone_for_update ( ) ;
817
785
}
@@ -838,7 +806,7 @@ fn get_replacements_for_visibilty_change(
838
806
}
839
807
_ => ( ) ,
840
808
}
841
- } ) ;
809
+ }
842
810
843
811
( replacements, record_field_parents, impls)
844
812
}
0 commit comments