diff options
Diffstat (limited to 'crates/ide_assists/src/handlers/extract_function.rs')
-rw-r--r-- | crates/ide_assists/src/handlers/extract_function.rs | 64 |
1 files changed, 62 insertions, 2 deletions
diff --git a/crates/ide_assists/src/handlers/extract_function.rs b/crates/ide_assists/src/handlers/extract_function.rs index 059414274..78a57fbdc 100644 --- a/crates/ide_assists/src/handlers/extract_function.rs +++ b/crates/ide_assists/src/handlers/extract_function.rs | |||
@@ -599,7 +599,12 @@ fn extraction_target(node: &SyntaxNode, selection_range: TextRange) -> Option<Fu | |||
599 | // we have selected a few statements in a block | 599 | // we have selected a few statements in a block |
600 | // so covering_element returns the whole block | 600 | // so covering_element returns the whole block |
601 | if node.kind() == BLOCK_EXPR { | 601 | if node.kind() == BLOCK_EXPR { |
602 | let body = FunctionBody::from_range(node.clone(), selection_range); | 602 | // Extract the full statements. |
603 | let statements_range = node | ||
604 | .children() | ||
605 | .filter(|c| selection_range.intersect(c.text_range()).is_some()) | ||
606 | .fold(selection_range, |acc, c| acc.cover(c.text_range())); | ||
607 | let body = FunctionBody::from_range(node.clone(), statements_range); | ||
603 | if body.is_some() { | 608 | if body.is_some() { |
604 | return body; | 609 | return body; |
605 | } | 610 | } |
@@ -610,7 +615,8 @@ fn extraction_target(node: &SyntaxNode, selection_range: TextRange) -> Option<Fu | |||
610 | // so we try to expand covering_element to parent and repeat the previous | 615 | // so we try to expand covering_element to parent and repeat the previous |
611 | if let Some(parent) = node.parent() { | 616 | if let Some(parent) = node.parent() { |
612 | if parent.kind() == BLOCK_EXPR { | 617 | if parent.kind() == BLOCK_EXPR { |
613 | let body = FunctionBody::from_range(parent, selection_range); | 618 | // Extract the full statement. |
619 | let body = FunctionBody::from_range(parent, node.text_range()); | ||
614 | if body.is_some() { | 620 | if body.is_some() { |
615 | return body; | 621 | return body; |
616 | } | 622 | } |
@@ -1785,6 +1791,60 @@ fn $0fun_name() -> i32 { | |||
1785 | } | 1791 | } |
1786 | 1792 | ||
1787 | #[test] | 1793 | #[test] |
1794 | fn extract_partial_block_single_line() { | ||
1795 | check_assist( | ||
1796 | extract_function, | ||
1797 | r#" | ||
1798 | fn foo() { | ||
1799 | let n = 1; | ||
1800 | let mut v = $0n * n;$0 | ||
1801 | v += 1; | ||
1802 | }"#, | ||
1803 | r#" | ||
1804 | fn foo() { | ||
1805 | let n = 1; | ||
1806 | let mut v = fun_name(n); | ||
1807 | v += 1; | ||
1808 | } | ||
1809 | |||
1810 | fn $0fun_name(n: i32) -> i32 { | ||
1811 | let mut v = n * n; | ||
1812 | v | ||
1813 | }"#, | ||
1814 | ); | ||
1815 | } | ||
1816 | |||
1817 | #[test] | ||
1818 | fn extract_partial_block() { | ||
1819 | check_assist( | ||
1820 | extract_function, | ||
1821 | r#" | ||
1822 | fn foo() { | ||
1823 | let m = 2; | ||
1824 | let n = 1; | ||
1825 | let mut v = m $0* n; | ||
1826 | let mut w = 3;$0 | ||
1827 | v += 1; | ||
1828 | w += 1; | ||
1829 | }"#, | ||
1830 | r#" | ||
1831 | fn foo() { | ||
1832 | let m = 2; | ||
1833 | let n = 1; | ||
1834 | let (mut v, mut w) = fun_name(m, n); | ||
1835 | v += 1; | ||
1836 | w += 1; | ||
1837 | } | ||
1838 | |||
1839 | fn $0fun_name(m: i32, n: i32) -> (i32, i32) { | ||
1840 | let mut v = m * n; | ||
1841 | let mut w = 3; | ||
1842 | (v, w) | ||
1843 | }"#, | ||
1844 | ); | ||
1845 | } | ||
1846 | |||
1847 | #[test] | ||
1788 | fn argument_form_expr() { | 1848 | fn argument_form_expr() { |
1789 | check_assist( | 1849 | check_assist( |
1790 | extract_function, | 1850 | extract_function, |