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 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 "
225fn foo() { 230fn 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 "
241fn foo() { 246fn 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 "
261fn foo() {
262 <|>1<|> + 1;
263}",
264 "
265fn 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 "
256fn foo() { 277fn 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 "
293fn foo() {
294 <|>bar(1 + 1)<|>
295}",
296 "
297fn 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}
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 }