diff options
author | Gabriel Luo <[email protected]> | 2019-12-11 03:18:05 +0000 |
---|---|---|
committer | Gabriel Luo <[email protected]> | 2019-12-11 03:18:05 +0000 |
commit | 20ccabc01de7306f44e0b2a460152f0c97f19d76 (patch) | |
tree | b5a6ae0efb25d4f9a4cb69e626d0600838ccd842 | |
parent | ee904594af174866cfa10474fd8fd3f23580b6af (diff) |
Fixed #2250
Tuple in type annotation expands correctly;
Expansion will prefer the following delimiter when possible.
New regression tests added to verify the consistency between tuple expansion in type annotation and tuple expansion in rvalue.
-rw-r--r-- | crates/ra_ide/src/extend_selection.rs | 78 |
1 files changed, 66 insertions, 12 deletions
diff --git a/crates/ra_ide/src/extend_selection.rs b/crates/ra_ide/src/extend_selection.rs index 4b7bfc0b1..c096ca6ae 100644 --- a/crates/ra_ide/src/extend_selection.rs +++ b/crates/ra_ide/src/extend_selection.rs | |||
@@ -34,6 +34,7 @@ fn try_extend_selection(root: &SyntaxNode, range: TextRange) -> Option<TextRange | |||
34 | ARG_LIST, | 34 | ARG_LIST, |
35 | ARRAY_EXPR, | 35 | ARRAY_EXPR, |
36 | TUPLE_EXPR, | 36 | TUPLE_EXPR, |
37 | TUPLE_TYPE, | ||
37 | WHERE_CLAUSE, | 38 | WHERE_CLAUSE, |
38 | ]; | 39 | ]; |
39 | 40 | ||
@@ -174,12 +175,7 @@ fn extend_list_item(node: &SyntaxNode) -> Option<TextRange> { | |||
174 | TYPE_BOUND => T![+], | 175 | TYPE_BOUND => T![+], |
175 | _ => T![,], | 176 | _ => T![,], |
176 | }; | 177 | }; |
177 | if let Some(delimiter_node) = nearby_delimiter(delimiter, node, Direction::Prev) { | 178 | |
178 | return Some(TextRange::from_to( | ||
179 | delimiter_node.text_range().start(), | ||
180 | node.text_range().end(), | ||
181 | )); | ||
182 | } | ||
183 | if let Some(delimiter_node) = nearby_delimiter(delimiter, node, Direction::Next) { | 179 | if let Some(delimiter_node) = nearby_delimiter(delimiter, node, Direction::Next) { |
184 | // Include any following whitespace when delimiter is after list item. | 180 | // Include any following whitespace when delimiter is after list item. |
185 | let final_node = delimiter_node | 181 | let final_node = delimiter_node |
@@ -190,6 +186,12 @@ fn extend_list_item(node: &SyntaxNode) -> Option<TextRange> { | |||
190 | 186 | ||
191 | return Some(TextRange::from_to(node.text_range().start(), final_node.text_range().end())); | 187 | return Some(TextRange::from_to(node.text_range().start(), final_node.text_range().end())); |
192 | } | 188 | } |
189 | if let Some(delimiter_node) = nearby_delimiter(delimiter, node, Direction::Prev) { | ||
190 | return Some(TextRange::from_to( | ||
191 | delimiter_node.text_range().start(), | ||
192 | node.text_range().end(), | ||
193 | )); | ||
194 | } | ||
193 | 195 | ||
194 | None | 196 | None |
195 | } | 197 | } |
@@ -250,14 +252,14 @@ mod tests { | |||
250 | fn test_extend_selection_list() { | 252 | fn test_extend_selection_list() { |
251 | do_check(r#"fn foo(<|>x: i32) {}"#, &["x", "x: i32"]); | 253 | do_check(r#"fn foo(<|>x: i32) {}"#, &["x", "x: i32"]); |
252 | do_check(r#"fn foo(<|>x: i32, y: i32) {}"#, &["x", "x: i32", "x: i32, "]); | 254 | do_check(r#"fn foo(<|>x: i32, y: i32) {}"#, &["x", "x: i32", "x: i32, "]); |
253 | do_check(r#"fn foo(<|>x: i32,y: i32) {}"#, &["x", "x: i32", "x: i32,"]); | 255 | do_check(r#"fn foo(<|>x: i32,y: i32) {}"#, &["x", "x: i32", "x: i32,", "(x: i32,y: i32)"]); |
254 | do_check(r#"fn foo(x: i32, <|>y: i32) {}"#, &["y", "y: i32", ", y: i32"]); | 256 | do_check(r#"fn foo(x: i32, <|>y: i32) {}"#, &["y", "y: i32", ", y: i32"]); |
255 | do_check(r#"fn foo(x: i32, <|>y: i32, ) {}"#, &["y", "y: i32", ", y: i32"]); | 257 | do_check(r#"fn foo(x: i32, <|>y: i32, ) {}"#, &["y", "y: i32", "y: i32, "]); |
256 | do_check(r#"fn foo(x: i32,<|>y: i32) {}"#, &["y", "y: i32", ",y: i32"]); | 258 | do_check(r#"fn foo(x: i32,<|>y: i32) {}"#, &["y", "y: i32", ",y: i32"]); |
257 | 259 | ||
258 | do_check(r#"const FOO: [usize; 2] = [ 22<|> , 33];"#, &["22", "22 , "]); | 260 | do_check(r#"const FOO: [usize; 2] = [ 22<|> , 33];"#, &["22", "22 , "]); |
259 | do_check(r#"const FOO: [usize; 2] = [ 22 , 33<|>];"#, &["33", ", 33"]); | 261 | do_check(r#"const FOO: [usize; 2] = [ 22 , 33<|>];"#, &["33", ", 33"]); |
260 | do_check(r#"const FOO: [usize; 2] = [ 22 , 33<|> ,];"#, &["33", ", 33"]); | 262 | do_check(r#"const FOO: [usize; 2] = [ 22 , 33<|> ,];"#, &["33", "33 ,", "[ 22 , 33 ,]"]); |
261 | 263 | ||
262 | do_check(r#"fn main() { (1, 2<|>) }"#, &["2", ", 2", "(1, 2)"]); | 264 | do_check(r#"fn main() { (1, 2<|>) }"#, &["2", ", 2", "(1, 2)"]); |
263 | 265 | ||
@@ -276,7 +278,7 @@ const FOO: [usize; 2] = [ | |||
276 | 22 | 278 | 22 |
277 | , 33<|>, | 279 | , 33<|>, |
278 | ]"#, | 280 | ]"#, |
279 | &["33", ", 33"], | 281 | &["33", "33,"], |
280 | ); | 282 | ); |
281 | } | 283 | } |
282 | 284 | ||
@@ -424,7 +426,7 @@ fn foo<R>() | |||
424 | do_check(r#"fn foo<T>() where T: <|>Copy +Display"#, &["Copy", "Copy +"]); | 426 | do_check(r#"fn foo<T>() where T: <|>Copy +Display"#, &["Copy", "Copy +"]); |
425 | do_check(r#"fn foo<T>() where T: <|>Copy+Display"#, &["Copy", "Copy+"]); | 427 | do_check(r#"fn foo<T>() where T: <|>Copy+Display"#, &["Copy", "Copy+"]); |
426 | do_check(r#"fn foo<T>() where T: Copy + <|>Display"#, &["Display", "+ Display"]); | 428 | do_check(r#"fn foo<T>() where T: Copy + <|>Display"#, &["Display", "+ Display"]); |
427 | do_check(r#"fn foo<T>() where T: Copy + <|>Display + Sync"#, &["Display", "+ Display"]); | 429 | do_check(r#"fn foo<T>() where T: Copy + <|>Display + Sync"#, &["Display", "Display + "]); |
428 | do_check(r#"fn foo<T>() where T: Copy +<|>Display"#, &["Display", "+Display"]); | 430 | do_check(r#"fn foo<T>() where T: Copy +<|>Display"#, &["Display", "+Display"]); |
429 | } | 431 | } |
430 | 432 | ||
@@ -435,7 +437,7 @@ fn foo<R>() | |||
435 | do_check(r#"fn foo<T: <|>Copy +Display>() {}"#, &["Copy", "Copy +"]); | 437 | do_check(r#"fn foo<T: <|>Copy +Display>() {}"#, &["Copy", "Copy +"]); |
436 | do_check(r#"fn foo<T: <|>Copy+Display>() {}"#, &["Copy", "Copy+"]); | 438 | do_check(r#"fn foo<T: <|>Copy+Display>() {}"#, &["Copy", "Copy+"]); |
437 | do_check(r#"fn foo<T: Copy + <|>Display>() {}"#, &["Display", "+ Display"]); | 439 | do_check(r#"fn foo<T: Copy + <|>Display>() {}"#, &["Display", "+ Display"]); |
438 | do_check(r#"fn foo<T: Copy + <|>Display + Sync>() {}"#, &["Display", "+ Display"]); | 440 | do_check(r#"fn foo<T: Copy + <|>Display + Sync>() {}"#, &["Display", "Display + "]); |
439 | do_check(r#"fn foo<T: Copy +<|>Display>() {}"#, &["Display", "+Display"]); | 441 | do_check(r#"fn foo<T: Copy +<|>Display>() {}"#, &["Display", "+Display"]); |
440 | do_check( | 442 | do_check( |
441 | r#"fn foo<T: Copy<|> + Display, U: Copy>() {}"#, | 443 | r#"fn foo<T: Copy<|> + Display, U: Copy>() {}"#, |
@@ -449,4 +451,56 @@ fn foo<R>() | |||
449 | ], | 451 | ], |
450 | ); | 452 | ); |
451 | } | 453 | } |
454 | |||
455 | #[test] | ||
456 | fn test_extend_selection_on_tuple_in_type() { | ||
457 | do_check( | ||
458 | r#"fn main() { let _: (krate, <|>_crate_def_map, module_id) = (); }"#, | ||
459 | &["_crate_def_map", "_crate_def_map, ", "(krate, _crate_def_map, module_id)"], | ||
460 | ); | ||
461 | // white space variations | ||
462 | do_check( | ||
463 | r#"fn main() { let _: (krate,<|>_crate_def_map,module_id) = (); }"#, | ||
464 | &["_crate_def_map", "_crate_def_map,", "(krate,_crate_def_map,module_id)"], | ||
465 | ); | ||
466 | do_check( | ||
467 | r#" | ||
468 | fn main() { let _: ( | ||
469 | krate, | ||
470 | _crate<|>_def_map, | ||
471 | module_id | ||
472 | ) = (); }"#, | ||
473 | &[ | ||
474 | "_crate_def_map", | ||
475 | "_crate_def_map,", | ||
476 | "(\n krate,\n _crate_def_map,\n module_id\n)", | ||
477 | ], | ||
478 | ); | ||
479 | } | ||
480 | |||
481 | #[test] | ||
482 | fn test_extend_selection_on_tuple_in_rvalue() { | ||
483 | do_check( | ||
484 | r#"fn main() { let var = (krate, _crate_def_map<|>, module_id); }"#, | ||
485 | &["_crate_def_map", "_crate_def_map, ", "(krate, _crate_def_map, module_id)"], | ||
486 | ); | ||
487 | // white space variations | ||
488 | do_check( | ||
489 | r#"fn main() { let var = (krate,_crate<|>_def_map,module_id); }"#, | ||
490 | &["_crate_def_map", "_crate_def_map,", "(krate,_crate_def_map,module_id)"], | ||
491 | ); | ||
492 | do_check( | ||
493 | r#" | ||
494 | fn main() { let var = ( | ||
495 | krate, | ||
496 | _crate_def_map<|>, | ||
497 | module_id | ||
498 | ); }"#, | ||
499 | &[ | ||
500 | "_crate_def_map", | ||
501 | "_crate_def_map,", | ||
502 | "(\n krate,\n _crate_def_map,\n module_id\n)", | ||
503 | ], | ||
504 | ); | ||
505 | } | ||
452 | } | 506 | } |