@@ -8,6 +8,7 @@ use ide_db::{
88 search:: { FileReference , ReferenceAccess , SearchScope } ,
99 RootDatabase ,
1010} ;
11+ use itertools:: Itertools ;
1112use rustc_hash:: FxHasher ;
1213use stdx:: format_to;
1314use syntax:: {
@@ -389,8 +390,23 @@ impl FunctionBody {
389390 }
390391 }
391392
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) }
394410 }
395411
396412 fn indent_level ( & self ) -> IndentLevel {
@@ -546,17 +562,7 @@ fn extraction_target(node: &SyntaxNode, selection_range: TextRange) -> Option<Fu
546562 // Covering element returned the parent block of one or multiple statements that have been selected
547563 if let ast:: Expr :: BlockExpr ( block) = expr {
548564 // 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) ) ;
560566 }
561567
562568 node. ancestors ( ) . find_map ( ast:: Expr :: cast) . and_then ( FunctionBody :: from_expr)
@@ -586,7 +592,6 @@ fn analyze_body(
586592 | NameRefClass :: FieldShorthand { local_ref, field_ref : _ } ,
587593 ) = NameRefClass :: classify ( sema, & name_ref)
588594 {
589- res. insert ( local_ref) ;
590595 if local_ref. is_self ( sema. db ) {
591596 match local_ref. source ( sema. db ) . value {
592597 Either :: Right ( it) => {
@@ -599,6 +604,8 @@ fn analyze_body(
599604 stdx:: never!( "Local::is_self returned true, but source is IdentPat" ) ;
600605 }
601606 }
607+ } else {
608+ res. insert ( local_ref) ;
602609 }
603610 }
604611 }
@@ -615,7 +622,6 @@ fn extracted_function_params(
615622 locals : impl Iterator < Item = Local > ,
616623) -> Vec < Param > {
617624 locals
618- . filter ( |local| !local. is_self ( ctx. db ( ) ) )
619625 . map ( |local| ( local, local. source ( ctx. db ( ) ) ) )
620626 . filter ( |( _, src) | is_defined_outside_of_body ( ctx, body, src) )
621627 . filter_map ( |( local, src) | {
@@ -3230,8 +3236,7 @@ fn $0fun_name(n: i32) -> bool {
32303236 r#"
32313237fn foo() {
32323238 loop {
3233- let n = 1;
3234- $0
3239+ let n = 1;$0
32353240 let k = 1;
32363241 loop {
32373242 return;
@@ -3435,8 +3440,7 @@ fn $0fun_name() -> Option<i32> {
34353440 r#"
34363441fn foo() -> i64 {
34373442 loop {
3438- let n = 1;
3439- $0
3443+ let n = 1;$0
34403444 let k = 1;
34413445 if k == 42 {
34423446 break 3;
@@ -3830,6 +3834,33 @@ fn main() {
38303834fn $0fun_name() -> i32 {
38313835 100
38323836}
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+ }
38333864"# ,
38343865 ) ;
38353866 }
0 commit comments