diff options
author | bors[bot] <26634292+bors[bot]@users.noreply.github.com> | 2019-12-11 12:39:33 +0000 |
---|---|---|
committer | GitHub <[email protected]> | 2019-12-11 12:39:33 +0000 |
commit | 5202b0ecbaab2d44e886828f0e30dee67fad0c5c (patch) | |
tree | b5a6ae0efb25d4f9a4cb69e626d0600838ccd842 | |
parent | ee904594af174866cfa10474fd8fd3f23580b6af (diff) | |
parent | 20ccabc01de7306f44e0b2a460152f0c97f19d76 (diff) |
Merge #2523
2523: Fixed #2250 r=matklad a=gab-umich
Bugfix Debriefing:
1. Tuple in type annotation expands correctly;
2. Expansion will prefer the following delimiter when possible. This involves modification of previous test cases to match current behaviour.
3. New regression tests added to verify the consistency between tuple expansion in type annotation and tuple expansion in rvalue. Both should behave exactly the same.
Co-authored-by: Gabriel Luo <[email protected]>
-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 | } |