@@ -8,6 +8,7 @@ use ide_db::{
8
8
search:: { FileReference , ReferenceAccess , SearchScope } ,
9
9
RootDatabase ,
10
10
} ;
11
+ use itertools:: Itertools ;
11
12
use rustc_hash:: FxHasher ;
12
13
use stdx:: format_to;
13
14
use syntax:: {
@@ -389,8 +390,23 @@ impl FunctionBody {
389
390
}
390
391
}
391
392
392
- fn from_range ( parent : ast:: BlockExpr , text_range : TextRange ) -> FunctionBody {
393
- Self :: Span { parent, text_range }
393
+ fn from_range ( parent : ast:: BlockExpr , selected : TextRange ) -> FunctionBody {
394
+ let mut text_range = parent
395
+ . statements ( )
396
+ . map ( |stmt| stmt. syntax ( ) . text_range ( ) )
397
+ . filter ( |& stmt| selected. intersect ( stmt) . filter ( |it| !it. is_empty ( ) ) . is_some ( ) )
398
+ . fold1 ( |acc, stmt| acc. cover ( stmt) ) ;
399
+ if let Some ( tail_range) = parent
400
+ . tail_expr ( )
401
+ . map ( |it| it. syntax ( ) . text_range ( ) )
402
+ . filter ( |& it| selected. intersect ( it) . is_some ( ) )
403
+ {
404
+ text_range = Some ( match text_range {
405
+ Some ( text_range) => text_range. cover ( tail_range) ,
406
+ None => tail_range,
407
+ } ) ;
408
+ }
409
+ Self :: Span { parent, text_range : text_range. unwrap_or ( selected) }
394
410
}
395
411
396
412
fn indent_level ( & self ) -> IndentLevel {
@@ -546,17 +562,7 @@ fn extraction_target(node: &SyntaxNode, selection_range: TextRange) -> Option<Fu
546
562
// Covering element returned the parent block of one or multiple statements that have been selected
547
563
if let ast:: Expr :: BlockExpr ( block) = expr {
548
564
// Extract the full statements.
549
- let mut statements_range = block
550
- . statements ( )
551
- . filter ( |stmt| selection_range. intersect ( stmt. syntax ( ) . text_range ( ) ) . is_some ( ) )
552
- . fold ( selection_range, |acc, stmt| acc. cover ( stmt. syntax ( ) . text_range ( ) ) ) ;
553
- if let Some ( e) = block
554
- . tail_expr ( )
555
- . filter ( |it| selection_range. intersect ( it. syntax ( ) . text_range ( ) ) . is_some ( ) )
556
- {
557
- statements_range = statements_range. cover ( e. syntax ( ) . text_range ( ) ) ;
558
- }
559
- return Some ( FunctionBody :: from_range ( block, statements_range) ) ;
565
+ return Some ( FunctionBody :: from_range ( block, selection_range) ) ;
560
566
}
561
567
562
568
node. ancestors ( ) . find_map ( ast:: Expr :: cast) . and_then ( FunctionBody :: from_expr)
@@ -586,7 +592,6 @@ fn analyze_body(
586
592
| NameRefClass :: FieldShorthand { local_ref, field_ref : _ } ,
587
593
) = NameRefClass :: classify ( sema, & name_ref)
588
594
{
589
- res. insert ( local_ref) ;
590
595
if local_ref. is_self ( sema. db ) {
591
596
match local_ref. source ( sema. db ) . value {
592
597
Either :: Right ( it) => {
@@ -599,6 +604,8 @@ fn analyze_body(
599
604
stdx:: never!( "Local::is_self returned true, but source is IdentPat" ) ;
600
605
}
601
606
}
607
+ } else {
608
+ res. insert ( local_ref) ;
602
609
}
603
610
}
604
611
}
@@ -615,7 +622,6 @@ fn extracted_function_params(
615
622
locals : impl Iterator < Item = Local > ,
616
623
) -> Vec < Param > {
617
624
locals
618
- . filter ( |local| !local. is_self ( ctx. db ( ) ) )
619
625
. map ( |local| ( local, local. source ( ctx. db ( ) ) ) )
620
626
. filter ( |( _, src) | is_defined_outside_of_body ( ctx, body, src) )
621
627
. filter_map ( |( local, src) | {
@@ -3230,8 +3236,7 @@ fn $0fun_name(n: i32) -> bool {
3230
3236
r#"
3231
3237
fn foo() {
3232
3238
loop {
3233
- let n = 1;
3234
- $0
3239
+ let n = 1;$0
3235
3240
let k = 1;
3236
3241
loop {
3237
3242
return;
@@ -3435,8 +3440,7 @@ fn $0fun_name() -> Option<i32> {
3435
3440
r#"
3436
3441
fn foo() -> i64 {
3437
3442
loop {
3438
- let n = 1;
3439
- $0
3443
+ let n = 1;$0
3440
3444
let k = 1;
3441
3445
if k == 42 {
3442
3446
break 3;
@@ -3830,6 +3834,33 @@ fn main() {
3830
3834
fn $0fun_name() -> i32 {
3831
3835
100
3832
3836
}
3837
+ "# ,
3838
+ ) ;
3839
+ }
3840
+
3841
+ #[ test]
3842
+ fn extract_does_not_tear_comments_apart ( ) {
3843
+ check_assist (
3844
+ extract_function,
3845
+ r#"
3846
+ fn foo() {
3847
+ /*$0*/
3848
+ foo();
3849
+ foo();
3850
+ /*$0*/
3851
+ }
3852
+ "# ,
3853
+ r#"
3854
+ fn foo() {
3855
+ /**/
3856
+ fun_name();
3857
+ /**/
3858
+ }
3859
+
3860
+ fn $0fun_name() {
3861
+ foo();
3862
+ foo();
3863
+ }
3833
3864
"# ,
3834
3865
) ;
3835
3866
}
0 commit comments