Skip to content

Commit 027a99f

Browse files
committed
Do no tear comments apart in extract_function assist
1 parent b96f1ad commit 027a99f

File tree

1 file changed

+50
-19
lines changed

1 file changed

+50
-19
lines changed

crates/ide_assists/src/handlers/extract_function.rs

Lines changed: 50 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ use ide_db::{
88
search::{FileReference, ReferenceAccess, SearchScope},
99
RootDatabase,
1010
};
11+
use itertools::Itertools;
1112
use rustc_hash::FxHasher;
1213
use stdx::format_to;
1314
use 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#"
32313237
fn 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#"
34363441
fn 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() {
38303834
fn $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

Comments
 (0)