aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbors[bot] <26634292+bors[bot]@users.noreply.github.com>2019-12-11 12:39:33 +0000
committerGitHub <[email protected]>2019-12-11 12:39:33 +0000
commit5202b0ecbaab2d44e886828f0e30dee67fad0c5c (patch)
treeb5a6ae0efb25d4f9a4cb69e626d0600838ccd842
parentee904594af174866cfa10474fd8fd3f23580b6af (diff)
parent20ccabc01de7306f44e0b2a460152f0c97f19d76 (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.rs78
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#"
468fn 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#"
494fn 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}