aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--crates/assists/src/handlers/extract_function.rs116
1 files changed, 116 insertions, 0 deletions
diff --git a/crates/assists/src/handlers/extract_function.rs b/crates/assists/src/handlers/extract_function.rs
index a4b23d756..8a4073886 100644
--- a/crates/assists/src/handlers/extract_function.rs
+++ b/crates/assists/src/handlers/extract_function.rs
@@ -150,6 +150,10 @@ pub(crate) fn extract_function(acc: &mut Assists, ctx: &AssistContext) -> Option
150 return true; 150 return true;
151 } 151 }
152 152
153 if is_mut_method_call(ctx, path.as_ref()).unwrap_or(false) {
154 return true;
155 }
156
153 false 157 false
154 }); 158 });
155 159
@@ -429,6 +433,17 @@ fn is_mut_ref_expr(path: Option<&ast::Expr>) -> Option<bool> {
429 Some(ref_expr.mut_token().is_some()) 433 Some(ref_expr.mut_token().is_some())
430} 434}
431 435
436fn is_mut_method_call(ctx: &AssistContext, path: Option<&ast::Expr>) -> Option<bool> {
437 let path = path?;
438 let method_call = path.syntax().parent().and_then(ast::MethodCallExpr::cast)?;
439
440 let func = ctx.sema.resolve_method_call(&method_call)?;
441 let self_param = func.self_param(ctx.db())?;
442 let access = self_param.access(ctx.db());
443
444 Some(matches!(access, hir::Access::Exclusive))
445}
446
432fn fix_param_usages(ctx: &AssistContext, params: &[Param], syntax: &SyntaxNode) -> SyntaxNode { 447fn fix_param_usages(ctx: &AssistContext, params: &[Param], syntax: &SyntaxNode) -> SyntaxNode {
433 let mut rewriter = SyntaxRewriter::default(); 448 let mut rewriter = SyntaxRewriter::default();
434 for param in params { 449 for param in params {
@@ -1510,4 +1525,105 @@ fn $0fun_name(mut n: i32) {
1510}", 1525}",
1511 ); 1526 );
1512 } 1527 }
1528
1529 #[test]
1530 fn mut_method_call() {
1531 check_assist(
1532 extract_function,
1533 r"
1534trait I {
1535 fn inc(&mut self);
1536}
1537impl I for i32 {
1538 fn inc(&mut self) { *self += 1 }
1539}
1540fn foo() {
1541 let mut n = 1;
1542 $0n.inc();$0
1543}",
1544 r"
1545trait I {
1546 fn inc(&mut self);
1547}
1548impl I for i32 {
1549 fn inc(&mut self) { *self += 1 }
1550}
1551fn foo() {
1552 let mut n = 1;
1553 fun_name(n);
1554}
1555
1556fn $0fun_name(mut n: i32) {
1557 n.inc();
1558}",
1559 );
1560 }
1561
1562 #[test]
1563 fn shared_method_call() {
1564 check_assist(
1565 extract_function,
1566 r"
1567trait I {
1568 fn succ(&self);
1569}
1570impl I for i32 {
1571 fn succ(&self) { *self + 1 }
1572}
1573fn foo() {
1574 let mut n = 1;
1575 $0n.succ();$0
1576}",
1577 r"
1578trait I {
1579 fn succ(&self);
1580}
1581impl I for i32 {
1582 fn succ(&self) { *self + 1 }
1583}
1584fn foo() {
1585 let mut n = 1;
1586 fun_name(n);
1587}
1588
1589fn $0fun_name(n: i32) {
1590 n.succ();
1591}",
1592 );
1593 }
1594
1595 #[test]
1596 fn mut_method_call_with_other_receiver() {
1597 check_assist(
1598 extract_function,
1599 r"
1600trait I {
1601 fn inc(&mut self, n: i32);
1602}
1603impl I for i32 {
1604 fn inc(&mut self, n: i32) { *self += n }
1605}
1606fn foo() {
1607 let mut n = 1;
1608 $0let mut m = 2;
1609 m.inc(n);$0
1610}",
1611 r"
1612trait I {
1613 fn inc(&mut self, n: i32);
1614}
1615impl I for i32 {
1616 fn inc(&mut self, n: i32) { *self += n }
1617}
1618fn foo() {
1619 let mut n = 1;
1620 fun_name(n);
1621}
1622
1623fn $0fun_name(n: i32) {
1624 let mut m = 2;
1625 m.inc(n);
1626}",
1627 );
1628 }
1513} 1629}