aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--crates/ra_editor/src/code_actions.rs49
-rw-r--r--crates/ra_editor/src/edit.rs2
2 files changed, 44 insertions, 7 deletions
diff --git a/crates/ra_editor/src/code_actions.rs b/crates/ra_editor/src/code_actions.rs
index 37e963bbd..6979251d1 100644
--- a/crates/ra_editor/src/code_actions.rs
+++ b/crates/ra_editor/src/code_actions.rs
@@ -122,7 +122,7 @@ pub fn introduce_variable<'a>(
122 let node = find_covering_node(file.syntax(), range); 122 let node = find_covering_node(file.syntax(), range);
123 let expr = node.ancestors().filter_map(ast::Expr::cast).next()?; 123 let expr = node.ancestors().filter_map(ast::Expr::cast).next()?;
124 124
125 let anchor_stmt = ahchor_stmt(expr)?; 125 let anchor_stmt = anchor_stmt(expr)?;
126 let indent = anchor_stmt.prev_sibling()?; 126 let indent = anchor_stmt.prev_sibling()?;
127 if indent.kind() != WHITESPACE { 127 if indent.kind() != WHITESPACE {
128 return None; 128 return None;
@@ -133,7 +133,12 @@ pub fn introduce_variable<'a>(
133 133
134 buf.push_str("let var_name = "); 134 buf.push_str("let var_name = ");
135 expr.syntax().text().push_to(&mut buf); 135 expr.syntax().text().push_to(&mut buf);
136 if expr.syntax().range().start() == anchor_stmt.range().start() { 136 let is_full_stmt = if let Some(expr_stmt) = ast::ExprStmt::cast(anchor_stmt) {
137 Some(expr.syntax()) == expr_stmt.expr().map(|e| e.syntax())
138 } else {
139 false
140 };
141 if is_full_stmt {
137 edit.replace(expr.syntax().range(), buf); 142 edit.replace(expr.syntax().range(), buf);
138 } else { 143 } else {
139 buf.push_str(";"); 144 buf.push_str(";");
@@ -150,7 +155,7 @@ pub fn introduce_variable<'a>(
150 155
151 /// Statement or last in the block expression, which will follow 156 /// Statement or last in the block expression, which will follow
152 /// the freshly introduced var. 157 /// the freshly introduced var.
153 fn ahchor_stmt(expr: ast::Expr) -> Option<SyntaxNodeRef> { 158 fn anchor_stmt(expr: ast::Expr) -> Option<SyntaxNodeRef> {
154 expr.syntax().ancestors().find(|&node| { 159 expr.syntax().ancestors().find(|&node| {
155 if ast::Stmt::cast(node).is_some() { 160 if ast::Stmt::cast(node).is_some() {
156 return true; 161 return true;
@@ -250,7 +255,7 @@ struct Foo { a: i32, }
250 } 255 }
251 256
252 #[test] 257 #[test]
253 fn test_intrdoduce_var_simple() { 258 fn test_introduce_var_simple() {
254 check_action_range( 259 check_action_range(
255 " 260 "
256fn foo() { 261fn foo() {
@@ -266,7 +271,7 @@ fn foo() {
266 } 271 }
267 272
268 #[test] 273 #[test]
269 fn test_intrdoduce_var_expr_stmt() { 274 fn test_introduce_var_expr_stmt() {
270 check_action_range( 275 check_action_range(
271 " 276 "
272fn foo() { 277fn foo() {
@@ -281,7 +286,23 @@ fn foo() {
281 } 286 }
282 287
283 #[test] 288 #[test]
284 fn test_intrdoduce_var_last_expr() { 289 fn test_introduce_var_part_of_expr_stmt() {
290 check_action_range(
291 "
292fn foo() {
293 <|>1<|> + 1;
294}",
295 "
296fn foo() {
297 let <|>var_name = 1;
298 var_name + 1;
299}",
300 |file, range| introduce_variable(file, range).map(|f| f()),
301 );
302 }
303
304 #[test]
305 fn test_introduce_var_last_expr() {
285 check_action_range( 306 check_action_range(
286 " 307 "
287fn foo() { 308fn foo() {
@@ -296,4 +317,20 @@ fn foo() {
296 ); 317 );
297 } 318 }
298 319
320 #[test]
321 fn test_introduce_var_last_full_expr() {
322 check_action_range(
323 "
324fn foo() {
325 <|>bar(1 + 1)<|>
326}",
327 "
328fn foo() {
329 let <|>var_name = bar(1 + 1);
330 var_name
331}",
332 |file, range| introduce_variable(file, range).map(|f| f()),
333 );
334 }
335
299} 336}
diff --git a/crates/ra_editor/src/edit.rs b/crates/ra_editor/src/edit.rs
index c3149ec54..372b8d14c 100644
--- a/crates/ra_editor/src/edit.rs
+++ b/crates/ra_editor/src/edit.rs
@@ -26,7 +26,7 @@ impl EditBuilder {
26 } 26 }
27 pub fn finish(self) -> Edit { 27 pub fn finish(self) -> Edit {
28 let mut atoms = self.atoms; 28 let mut atoms = self.atoms;
29 atoms.sort_by_key(|a| a.delete.start()); 29 atoms.sort_by_key(|a| (a.delete.start(), a.delete.end()));
30 for (a1, a2) in atoms.iter().zip(atoms.iter().skip(1)) { 30 for (a1, a2) in atoms.iter().zip(atoms.iter().skip(1)) {
31 assert!(a1.delete.end() <= a2.delete.start()) 31 assert!(a1.delete.end() <= a2.delete.start())
32 } 32 }