diff options
Diffstat (limited to 'crates/assists/src/handlers/extract_function.rs')
-rw-r--r-- | crates/assists/src/handlers/extract_function.rs | 116 |
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 | ||
436 | fn 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 | |||
432 | fn fix_param_usages(ctx: &AssistContext, params: &[Param], syntax: &SyntaxNode) -> SyntaxNode { | 447 | fn 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" | ||
1534 | trait I { | ||
1535 | fn inc(&mut self); | ||
1536 | } | ||
1537 | impl I for i32 { | ||
1538 | fn inc(&mut self) { *self += 1 } | ||
1539 | } | ||
1540 | fn foo() { | ||
1541 | let mut n = 1; | ||
1542 | $0n.inc();$0 | ||
1543 | }", | ||
1544 | r" | ||
1545 | trait I { | ||
1546 | fn inc(&mut self); | ||
1547 | } | ||
1548 | impl I for i32 { | ||
1549 | fn inc(&mut self) { *self += 1 } | ||
1550 | } | ||
1551 | fn foo() { | ||
1552 | let mut n = 1; | ||
1553 | fun_name(n); | ||
1554 | } | ||
1555 | |||
1556 | fn $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" | ||
1567 | trait I { | ||
1568 | fn succ(&self); | ||
1569 | } | ||
1570 | impl I for i32 { | ||
1571 | fn succ(&self) { *self + 1 } | ||
1572 | } | ||
1573 | fn foo() { | ||
1574 | let mut n = 1; | ||
1575 | $0n.succ();$0 | ||
1576 | }", | ||
1577 | r" | ||
1578 | trait I { | ||
1579 | fn succ(&self); | ||
1580 | } | ||
1581 | impl I for i32 { | ||
1582 | fn succ(&self) { *self + 1 } | ||
1583 | } | ||
1584 | fn foo() { | ||
1585 | let mut n = 1; | ||
1586 | fun_name(n); | ||
1587 | } | ||
1588 | |||
1589 | fn $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" | ||
1600 | trait I { | ||
1601 | fn inc(&mut self, n: i32); | ||
1602 | } | ||
1603 | impl I for i32 { | ||
1604 | fn inc(&mut self, n: i32) { *self += n } | ||
1605 | } | ||
1606 | fn foo() { | ||
1607 | let mut n = 1; | ||
1608 | $0let mut m = 2; | ||
1609 | m.inc(n);$0 | ||
1610 | }", | ||
1611 | r" | ||
1612 | trait I { | ||
1613 | fn inc(&mut self, n: i32); | ||
1614 | } | ||
1615 | impl I for i32 { | ||
1616 | fn inc(&mut self, n: i32) { *self += n } | ||
1617 | } | ||
1618 | fn foo() { | ||
1619 | let mut n = 1; | ||
1620 | fun_name(n); | ||
1621 | } | ||
1622 | |||
1623 | fn $0fun_name(n: i32) { | ||
1624 | let mut m = 2; | ||
1625 | m.inc(n); | ||
1626 | }", | ||
1627 | ); | ||
1628 | } | ||
1513 | } | 1629 | } |