diff options
author | Florian Diebold <[email protected]> | 2018-12-02 13:00:46 +0000 |
---|---|---|
committer | Florian Diebold <[email protected]> | 2018-12-02 13:00:46 +0000 |
commit | 270645683216c11a81b2b144576d9b18a0d947ad (patch) | |
tree | c281ac0d99d161de0e6fe056a481da1cbd6eadc7 /crates/ra_editor/src/code_actions.rs | |
parent | 477de790b0211196256a772befe4f577d1a8ba14 (diff) |
Improve 'introduce variable'
- make it possible to extract a prefix of an expression statement (e.g.
<|>foo.bar()<|>.baz())
- don't turn the last expression in a block into a let statement
Diffstat (limited to 'crates/ra_editor/src/code_actions.rs')
-rw-r--r-- | crates/ra_editor/src/code_actions.rs | 49 |
1 files changed, 43 insertions, 6 deletions
diff --git a/crates/ra_editor/src/code_actions.rs b/crates/ra_editor/src/code_actions.rs index 0139b19d3..bc0e120d3 100644 --- a/crates/ra_editor/src/code_actions.rs +++ b/crates/ra_editor/src/code_actions.rs | |||
@@ -113,7 +113,7 @@ pub fn introduce_variable<'a>( | |||
113 | let node = find_covering_node(file.syntax(), range); | 113 | let node = find_covering_node(file.syntax(), range); |
114 | let expr = node.ancestors().filter_map(ast::Expr::cast).next()?; | 114 | let expr = node.ancestors().filter_map(ast::Expr::cast).next()?; |
115 | 115 | ||
116 | let anchor_stmt = ahchor_stmt(expr)?; | 116 | let anchor_stmt = anchor_stmt(expr)?; |
117 | let indent = anchor_stmt.prev_sibling()?; | 117 | let indent = anchor_stmt.prev_sibling()?; |
118 | if indent.kind() != WHITESPACE { | 118 | if indent.kind() != WHITESPACE { |
119 | return None; | 119 | return None; |
@@ -124,7 +124,12 @@ pub fn introduce_variable<'a>( | |||
124 | 124 | ||
125 | buf.push_str("let var_name = "); | 125 | buf.push_str("let var_name = "); |
126 | expr.syntax().text().push_to(&mut buf); | 126 | expr.syntax().text().push_to(&mut buf); |
127 | if expr.syntax().range().start() == anchor_stmt.range().start() { | 127 | let is_full_stmt = if let Some(expr_stmt) = ast::ExprStmt::cast(anchor_stmt) { |
128 | Some(expr.syntax()) == expr_stmt.expr().map(|e| e.syntax()) | ||
129 | } else { | ||
130 | false | ||
131 | }; | ||
132 | if is_full_stmt { | ||
128 | edit.replace(expr.syntax().range(), buf); | 133 | edit.replace(expr.syntax().range(), buf); |
129 | } else { | 134 | } else { |
130 | buf.push_str(";"); | 135 | buf.push_str(";"); |
@@ -141,7 +146,7 @@ pub fn introduce_variable<'a>( | |||
141 | 146 | ||
142 | /// Statement or last in the block expression, which will follow | 147 | /// Statement or last in the block expression, which will follow |
143 | /// the freshly introduced var. | 148 | /// the freshly introduced var. |
144 | fn ahchor_stmt(expr: ast::Expr) -> Option<SyntaxNodeRef> { | 149 | fn anchor_stmt(expr: ast::Expr) -> Option<SyntaxNodeRef> { |
145 | expr.syntax().ancestors().find(|&node| { | 150 | expr.syntax().ancestors().find(|&node| { |
146 | if ast::Stmt::cast(node).is_some() { | 151 | if ast::Stmt::cast(node).is_some() { |
147 | return true; | 152 | return true; |
@@ -219,7 +224,7 @@ mod tests { | |||
219 | } | 224 | } |
220 | 225 | ||
221 | #[test] | 226 | #[test] |
222 | fn test_intrdoduce_var_simple() { | 227 | fn test_introduce_var_simple() { |
223 | check_action_range( | 228 | check_action_range( |
224 | " | 229 | " |
225 | fn foo() { | 230 | fn foo() { |
@@ -235,7 +240,7 @@ fn foo() { | |||
235 | } | 240 | } |
236 | 241 | ||
237 | #[test] | 242 | #[test] |
238 | fn test_intrdoduce_var_expr_stmt() { | 243 | fn test_introduce_var_expr_stmt() { |
239 | check_action_range( | 244 | check_action_range( |
240 | " | 245 | " |
241 | fn foo() { | 246 | fn foo() { |
@@ -250,7 +255,23 @@ fn foo() { | |||
250 | } | 255 | } |
251 | 256 | ||
252 | #[test] | 257 | #[test] |
253 | fn test_intrdoduce_var_last_expr() { | 258 | fn test_introduce_var_part_of_expr_stmt() { |
259 | check_action_range( | ||
260 | " | ||
261 | fn foo() { | ||
262 | <|>1<|> + 1; | ||
263 | }", | ||
264 | " | ||
265 | fn foo() { | ||
266 | let <|>var_name = 1; | ||
267 | var_name + 1; | ||
268 | }", | ||
269 | |file, range| introduce_variable(file, range).map(|f| f()), | ||
270 | ); | ||
271 | } | ||
272 | |||
273 | #[test] | ||
274 | fn test_introduce_var_last_expr() { | ||
254 | check_action_range( | 275 | check_action_range( |
255 | " | 276 | " |
256 | fn foo() { | 277 | fn foo() { |
@@ -265,4 +286,20 @@ fn foo() { | |||
265 | ); | 286 | ); |
266 | } | 287 | } |
267 | 288 | ||
289 | #[test] | ||
290 | fn test_introduce_var_last_full_expr() { | ||
291 | check_action_range( | ||
292 | " | ||
293 | fn foo() { | ||
294 | <|>bar(1 + 1)<|> | ||
295 | }", | ||
296 | " | ||
297 | fn foo() { | ||
298 | let <|>var_name = bar(1 + 1); | ||
299 | var_name | ||
300 | }", | ||
301 | |file, range| introduce_variable(file, range).map(|f| f()), | ||
302 | ); | ||
303 | } | ||
304 | |||
268 | } | 305 | } |