diff options
Diffstat (limited to 'crates/ra_ide')
-rw-r--r-- | crates/ra_ide/src/goto_definition.rs | 124 |
1 files changed, 74 insertions, 50 deletions
diff --git a/crates/ra_ide/src/goto_definition.rs b/crates/ra_ide/src/goto_definition.rs index 3b4d89e3e..48757f170 100644 --- a/crates/ra_ide/src/goto_definition.rs +++ b/crates/ra_ide/src/goto_definition.rs | |||
@@ -225,30 +225,35 @@ mod tests { | |||
225 | 225 | ||
226 | use crate::mock_analysis::analysis_and_position; | 226 | use crate::mock_analysis::analysis_and_position; |
227 | 227 | ||
228 | fn check_goto(fixture: &str, expected: &str) { | 228 | fn check_goto(fixture: &str, expected: &str, expected_range: &str) { |
229 | let (analysis, pos) = analysis_and_position(fixture); | 229 | let (analysis, pos) = analysis_and_position(fixture); |
230 | 230 | ||
231 | let mut navs = analysis.goto_definition(pos).unwrap().unwrap().info; | 231 | let mut navs = analysis.goto_definition(pos).unwrap().unwrap().info; |
232 | assert_eq!(navs.len(), 1); | 232 | assert_eq!(navs.len(), 1); |
233 | let nav = navs.pop().unwrap(); | ||
234 | nav.assert_match(expected); | ||
235 | } | ||
236 | |||
237 | fn check_goto_with_range_content(fixture: &str, expected: &str, expected_range: &str) { | ||
238 | let (analysis, pos) = analysis_and_position(fixture); | ||
239 | 233 | ||
240 | let mut navs = analysis.goto_definition(pos).unwrap().unwrap().info; | ||
241 | assert_eq!(navs.len(), 1); | ||
242 | let nav = navs.pop().unwrap(); | 234 | let nav = navs.pop().unwrap(); |
243 | let file_text = analysis.file_text(pos.file_id).unwrap(); | 235 | let file_text = analysis.file_text(nav.file_id()).unwrap(); |
244 | 236 | ||
245 | let actual_full_range = &file_text[nav.full_range()]; | 237 | let mut actual = file_text[nav.full_range()].to_string(); |
246 | let actual_range = &file_text[nav.range()]; | 238 | if let Some(focus) = nav.focus_range() { |
239 | actual += "|"; | ||
240 | actual += &file_text[focus]; | ||
241 | } | ||
242 | |||
243 | if !expected_range.contains("...") { | ||
244 | test_utils::assert_eq_text!(&actual, expected_range); | ||
245 | } else { | ||
246 | let mut parts = expected_range.split("..."); | ||
247 | let prefix = parts.next().unwrap(); | ||
248 | let suffix = parts.next().unwrap(); | ||
249 | assert!( | ||
250 | actual.starts_with(prefix) && actual.ends_with(suffix), | ||
251 | "\nExpected: {}\n Actual: {}\n", | ||
252 | expected_range, | ||
253 | actual | ||
254 | ); | ||
255 | } | ||
247 | 256 | ||
248 | test_utils::assert_eq_text!( | ||
249 | &format!("{}|{}", actual_full_range, actual_range), | ||
250 | expected_range | ||
251 | ); | ||
252 | nav.assert_match(expected); | 257 | nav.assert_match(expected); |
253 | } | 258 | } |
254 | 259 | ||
@@ -261,6 +266,7 @@ mod tests { | |||
261 | enum E { X(Foo<|>) } | 266 | enum E { X(Foo<|>) } |
262 | ", | 267 | ", |
263 | "Foo STRUCT_DEF FileId(1) [0; 11) [7; 10)", | 268 | "Foo STRUCT_DEF FileId(1) [0; 11) [7; 10)", |
269 | "struct Foo;|Foo", | ||
264 | ); | 270 | ); |
265 | } | 271 | } |
266 | 272 | ||
@@ -273,6 +279,7 @@ mod tests { | |||
273 | enum E { X(<|>Foo) } | 279 | enum E { X(<|>Foo) } |
274 | ", | 280 | ", |
275 | "Foo STRUCT_DEF FileId(1) [0; 11) [7; 10)", | 281 | "Foo STRUCT_DEF FileId(1) [0; 11) [7; 10)", |
282 | "struct Foo;|Foo", | ||
276 | ); | 283 | ); |
277 | } | 284 | } |
278 | 285 | ||
@@ -293,6 +300,7 @@ mod tests { | |||
293 | struct Foo; | 300 | struct Foo; |
294 | ", | 301 | ", |
295 | "Foo STRUCT_DEF FileId(2) [0; 11) [7; 10)", | 302 | "Foo STRUCT_DEF FileId(2) [0; 11) [7; 10)", |
303 | "struct Foo;|Foo", | ||
296 | ); | 304 | ); |
297 | } | 305 | } |
298 | 306 | ||
@@ -307,6 +315,7 @@ mod tests { | |||
307 | // empty | 315 | // empty |
308 | ", | 316 | ", |
309 | "foo SOURCE_FILE FileId(2) [0; 10)", | 317 | "foo SOURCE_FILE FileId(2) [0; 10)", |
318 | "// empty\n\n", | ||
310 | ); | 319 | ); |
311 | 320 | ||
312 | check_goto( | 321 | check_goto( |
@@ -318,6 +327,7 @@ mod tests { | |||
318 | // empty | 327 | // empty |
319 | ", | 328 | ", |
320 | "foo SOURCE_FILE FileId(2) [0; 10)", | 329 | "foo SOURCE_FILE FileId(2) [0; 10)", |
330 | "// empty\n\n", | ||
321 | ); | 331 | ); |
322 | } | 332 | } |
323 | 333 | ||
@@ -327,17 +337,14 @@ mod tests { | |||
327 | check_goto( | 337 | check_goto( |
328 | " | 338 | " |
329 | //- /lib.rs | 339 | //- /lib.rs |
330 | macro_rules! foo { | 340 | macro_rules! foo { () => { () } } |
331 | () => { | ||
332 | {} | ||
333 | }; | ||
334 | } | ||
335 | 341 | ||
336 | fn bar() { | 342 | fn bar() { |
337 | <|>foo!(); | 343 | <|>foo!(); |
338 | } | 344 | } |
339 | ", | 345 | ", |
340 | "foo MACRO_CALL FileId(1) [0; 50) [13; 16)", | 346 | "foo MACRO_CALL FileId(1) [0; 33) [13; 16)", |
347 | "macro_rules! foo { () => { () } }|foo", | ||
341 | ); | 348 | ); |
342 | } | 349 | } |
343 | 350 | ||
@@ -354,13 +361,10 @@ mod tests { | |||
354 | 361 | ||
355 | //- /foo/lib.rs | 362 | //- /foo/lib.rs |
356 | #[macro_export] | 363 | #[macro_export] |
357 | macro_rules! foo { | 364 | macro_rules! foo { () => { () } } |
358 | () => { | ||
359 | {} | ||
360 | }; | ||
361 | } | ||
362 | ", | 365 | ", |
363 | "foo MACRO_CALL FileId(2) [0; 66) [29; 32)", | 366 | "foo MACRO_CALL FileId(2) [0; 49) [29; 32)", |
367 | "#[macro_export]\nmacro_rules! foo { () => { () } }|foo", | ||
364 | ); | 368 | ); |
365 | } | 369 | } |
366 | 370 | ||
@@ -373,19 +377,16 @@ mod tests { | |||
373 | 377 | ||
374 | //- /foo/lib.rs | 378 | //- /foo/lib.rs |
375 | #[macro_export] | 379 | #[macro_export] |
376 | macro_rules! foo { | 380 | macro_rules! foo { () => { () } } |
377 | () => { | ||
378 | {} | ||
379 | }; | ||
380 | } | ||
381 | ", | 381 | ", |
382 | "foo MACRO_CALL FileId(2) [0; 66) [29; 32)", | 382 | "foo MACRO_CALL FileId(2) [0; 49) [29; 32)", |
383 | "#[macro_export]\nmacro_rules! foo { () => { () } }|foo", | ||
383 | ); | 384 | ); |
384 | } | 385 | } |
385 | 386 | ||
386 | #[test] | 387 | #[test] |
387 | fn goto_definition_works_for_macro_defined_fn_with_arg() { | 388 | fn goto_definition_works_for_macro_defined_fn_with_arg() { |
388 | check_goto_with_range_content( | 389 | check_goto( |
389 | " | 390 | " |
390 | //- /lib.rs | 391 | //- /lib.rs |
391 | macro_rules! define_fn { | 392 | macro_rules! define_fn { |
@@ -405,7 +406,7 @@ mod tests { | |||
405 | 406 | ||
406 | #[test] | 407 | #[test] |
407 | fn goto_definition_works_for_macro_defined_fn_no_arg() { | 408 | fn goto_definition_works_for_macro_defined_fn_no_arg() { |
408 | check_goto_with_range_content( | 409 | check_goto( |
409 | " | 410 | " |
410 | //- /lib.rs | 411 | //- /lib.rs |
411 | macro_rules! define_fn { | 412 | macro_rules! define_fn { |
@@ -431,14 +432,15 @@ mod tests { | |||
431 | //- /lib.rs | 432 | //- /lib.rs |
432 | struct Foo; | 433 | struct Foo; |
433 | impl Foo { | 434 | impl Foo { |
434 | fn frobnicate(&self) { } | 435 | fn frobnicate(&self) { } |
435 | } | 436 | } |
436 | 437 | ||
437 | fn bar(foo: &Foo) { | 438 | fn bar(foo: &Foo) { |
438 | foo.frobnicate<|>(); | 439 | foo.frobnicate<|>(); |
439 | } | 440 | } |
440 | ", | 441 | ", |
441 | "frobnicate FN_DEF FileId(1) [27; 52) [30; 40)", | 442 | "frobnicate FN_DEF FileId(1) [27; 51) [30; 40)", |
443 | "fn frobnicate(&self) { }|frobnicate", | ||
442 | ); | 444 | ); |
443 | } | 445 | } |
444 | 446 | ||
@@ -457,6 +459,7 @@ mod tests { | |||
457 | } | 459 | } |
458 | ", | 460 | ", |
459 | "spam RECORD_FIELD_DEF FileId(1) [17; 26) [17; 21)", | 461 | "spam RECORD_FIELD_DEF FileId(1) [17; 26) [17; 21)", |
462 | "spam: u32|spam", | ||
460 | ); | 463 | ); |
461 | } | 464 | } |
462 | 465 | ||
@@ -477,6 +480,7 @@ mod tests { | |||
477 | } | 480 | } |
478 | ", | 481 | ", |
479 | "spam RECORD_FIELD_DEF FileId(1) [17; 26) [17; 21)", | 482 | "spam RECORD_FIELD_DEF FileId(1) [17; 26) [17; 21)", |
483 | "spam: u32|spam", | ||
480 | ); | 484 | ); |
481 | } | 485 | } |
482 | 486 | ||
@@ -493,6 +497,7 @@ mod tests { | |||
493 | } | 497 | } |
494 | ", | 498 | ", |
495 | "TUPLE_FIELD_DEF FileId(1) [11; 14)", | 499 | "TUPLE_FIELD_DEF FileId(1) [11; 14)", |
500 | "u32", | ||
496 | ); | 501 | ); |
497 | } | 502 | } |
498 | 503 | ||
@@ -503,14 +508,15 @@ mod tests { | |||
503 | //- /lib.rs | 508 | //- /lib.rs |
504 | struct Foo; | 509 | struct Foo; |
505 | impl Foo { | 510 | impl Foo { |
506 | fn frobnicate() { } | 511 | fn frobnicate() { } |
507 | } | 512 | } |
508 | 513 | ||
509 | fn bar(foo: &Foo) { | 514 | fn bar(foo: &Foo) { |
510 | Foo::frobnicate<|>(); | 515 | Foo::frobnicate<|>(); |
511 | } | 516 | } |
512 | ", | 517 | ", |
513 | "frobnicate FN_DEF FileId(1) [27; 47) [30; 40)", | 518 | "frobnicate FN_DEF FileId(1) [27; 46) [30; 40)", |
519 | "fn frobnicate() { }|frobnicate", | ||
514 | ); | 520 | ); |
515 | } | 521 | } |
516 | 522 | ||
@@ -528,6 +534,7 @@ mod tests { | |||
528 | } | 534 | } |
529 | ", | 535 | ", |
530 | "frobnicate FN_DEF FileId(1) [16; 32) [19; 29)", | 536 | "frobnicate FN_DEF FileId(1) [16; 32) [19; 29)", |
537 | "fn frobnicate();|frobnicate", | ||
531 | ); | 538 | ); |
532 | } | 539 | } |
533 | 540 | ||
@@ -547,6 +554,7 @@ mod tests { | |||
547 | } | 554 | } |
548 | ", | 555 | ", |
549 | "frobnicate FN_DEF FileId(1) [30; 46) [33; 43)", | 556 | "frobnicate FN_DEF FileId(1) [30; 46) [33; 43)", |
557 | "fn frobnicate();|frobnicate", | ||
550 | ); | 558 | ); |
551 | } | 559 | } |
552 | 560 | ||
@@ -563,6 +571,7 @@ mod tests { | |||
563 | } | 571 | } |
564 | ", | 572 | ", |
565 | "impl IMPL_BLOCK FileId(1) [12; 73)", | 573 | "impl IMPL_BLOCK FileId(1) [12; 73)", |
574 | "impl Foo {...}", | ||
566 | ); | 575 | ); |
567 | 576 | ||
568 | check_goto( | 577 | check_goto( |
@@ -576,6 +585,7 @@ mod tests { | |||
576 | } | 585 | } |
577 | ", | 586 | ", |
578 | "impl IMPL_BLOCK FileId(1) [12; 73)", | 587 | "impl IMPL_BLOCK FileId(1) [12; 73)", |
588 | "impl Foo {...}", | ||
579 | ); | 589 | ); |
580 | 590 | ||
581 | check_goto( | 591 | check_goto( |
@@ -589,6 +599,7 @@ mod tests { | |||
589 | } | 599 | } |
590 | ", | 600 | ", |
591 | "impl IMPL_BLOCK FileId(1) [15; 75)", | 601 | "impl IMPL_BLOCK FileId(1) [15; 75)", |
602 | "impl Foo {...}", | ||
592 | ); | 603 | ); |
593 | 604 | ||
594 | check_goto( | 605 | check_goto( |
@@ -601,6 +612,7 @@ mod tests { | |||
601 | } | 612 | } |
602 | ", | 613 | ", |
603 | "impl IMPL_BLOCK FileId(1) [15; 62)", | 614 | "impl IMPL_BLOCK FileId(1) [15; 62)", |
615 | "impl Foo {...}", | ||
604 | ); | 616 | ); |
605 | } | 617 | } |
606 | 618 | ||
@@ -620,6 +632,7 @@ mod tests { | |||
620 | } | 632 | } |
621 | ", | 633 | ", |
622 | "impl IMPL_BLOCK FileId(1) [49; 115)", | 634 | "impl IMPL_BLOCK FileId(1) [49; 115)", |
635 | "impl Make for Foo {...}", | ||
623 | ); | 636 | ); |
624 | 637 | ||
625 | check_goto( | 638 | check_goto( |
@@ -636,6 +649,7 @@ mod tests { | |||
636 | } | 649 | } |
637 | ", | 650 | ", |
638 | "impl IMPL_BLOCK FileId(1) [49; 115)", | 651 | "impl IMPL_BLOCK FileId(1) [49; 115)", |
652 | "impl Make for Foo {...}", | ||
639 | ); | 653 | ); |
640 | } | 654 | } |
641 | 655 | ||
@@ -647,6 +661,7 @@ mod tests { | |||
647 | struct Foo<|> { value: u32 } | 661 | struct Foo<|> { value: u32 } |
648 | ", | 662 | ", |
649 | "Foo STRUCT_DEF FileId(1) [0; 25) [7; 10)", | 663 | "Foo STRUCT_DEF FileId(1) [0; 25) [7; 10)", |
664 | "struct Foo { value: u32 }|Foo", | ||
650 | ); | 665 | ); |
651 | 666 | ||
652 | check_goto( | 667 | check_goto( |
@@ -657,15 +672,16 @@ mod tests { | |||
657 | } | 672 | } |
658 | "#, | 673 | "#, |
659 | "field RECORD_FIELD_DEF FileId(1) [17; 30) [17; 22)", | 674 | "field RECORD_FIELD_DEF FileId(1) [17; 30) [17; 22)", |
675 | "field: string|field", | ||
660 | ); | 676 | ); |
661 | 677 | ||
662 | check_goto( | 678 | check_goto( |
663 | " | 679 | " |
664 | //- /lib.rs | 680 | //- /lib.rs |
665 | fn foo_test<|>() { | 681 | fn foo_test<|>() { } |
666 | } | ||
667 | ", | 682 | ", |
668 | "foo_test FN_DEF FileId(1) [0; 17) [3; 11)", | 683 | "foo_test FN_DEF FileId(1) [0; 17) [3; 11)", |
684 | "fn foo_test() { }|foo_test", | ||
669 | ); | 685 | ); |
670 | 686 | ||
671 | check_goto( | 687 | check_goto( |
@@ -676,6 +692,7 @@ mod tests { | |||
676 | } | 692 | } |
677 | ", | 693 | ", |
678 | "Foo ENUM_DEF FileId(1) [0; 25) [5; 8)", | 694 | "Foo ENUM_DEF FileId(1) [0; 25) [5; 8)", |
695 | "enum Foo {...}|Foo", | ||
679 | ); | 696 | ); |
680 | 697 | ||
681 | check_goto( | 698 | check_goto( |
@@ -688,22 +705,25 @@ mod tests { | |||
688 | } | 705 | } |
689 | ", | 706 | ", |
690 | "Variant2 ENUM_VARIANT FileId(1) [29; 37) [29; 37)", | 707 | "Variant2 ENUM_VARIANT FileId(1) [29; 37) [29; 37)", |
708 | "Variant2|Variant2", | ||
691 | ); | 709 | ); |
692 | 710 | ||
693 | check_goto( | 711 | check_goto( |
694 | r#" | 712 | r#" |
695 | //- /lib.rs | 713 | //- /lib.rs |
696 | static inner<|>: &str = ""; | 714 | static INNER<|>: &str = ""; |
697 | "#, | 715 | "#, |
698 | "inner STATIC_DEF FileId(1) [0; 24) [7; 12)", | 716 | "INNER STATIC_DEF FileId(1) [0; 24) [7; 12)", |
717 | "static INNER: &str = \"\";|INNER", | ||
699 | ); | 718 | ); |
700 | 719 | ||
701 | check_goto( | 720 | check_goto( |
702 | r#" | 721 | r#" |
703 | //- /lib.rs | 722 | //- /lib.rs |
704 | const inner<|>: &str = ""; | 723 | const INNER<|>: &str = ""; |
705 | "#, | 724 | "#, |
706 | "inner CONST_DEF FileId(1) [0; 23) [6; 11)", | 725 | "INNER CONST_DEF FileId(1) [0; 23) [6; 11)", |
726 | "const INNER: &str = \"\";|INNER", | ||
707 | ); | 727 | ); |
708 | 728 | ||
709 | check_goto( | 729 | check_goto( |
@@ -712,24 +732,25 @@ mod tests { | |||
712 | type Thing<|> = Option<()>; | 732 | type Thing<|> = Option<()>; |
713 | "#, | 733 | "#, |
714 | "Thing TYPE_ALIAS_DEF FileId(1) [0; 24) [5; 10)", | 734 | "Thing TYPE_ALIAS_DEF FileId(1) [0; 24) [5; 10)", |
735 | "type Thing = Option<()>;|Thing", | ||
715 | ); | 736 | ); |
716 | 737 | ||
717 | check_goto( | 738 | check_goto( |
718 | r#" | 739 | r#" |
719 | //- /lib.rs | 740 | //- /lib.rs |
720 | trait Foo<|> { | 741 | trait Foo<|> { } |
721 | } | ||
722 | "#, | 742 | "#, |
723 | "Foo TRAIT_DEF FileId(1) [0; 13) [6; 9)", | 743 | "Foo TRAIT_DEF FileId(1) [0; 13) [6; 9)", |
744 | "trait Foo { }|Foo", | ||
724 | ); | 745 | ); |
725 | 746 | ||
726 | check_goto( | 747 | check_goto( |
727 | r#" | 748 | r#" |
728 | //- /lib.rs | 749 | //- /lib.rs |
729 | mod bar<|> { | 750 | mod bar<|> { } |
730 | } | ||
731 | "#, | 751 | "#, |
732 | "bar MODULE FileId(1) [0; 11) [4; 7)", | 752 | "bar MODULE FileId(1) [0; 11) [4; 7)", |
753 | "mod bar { }|bar", | ||
733 | ); | 754 | ); |
734 | } | 755 | } |
735 | 756 | ||
@@ -750,6 +771,7 @@ mod tests { | |||
750 | mod confuse_index { fn foo(); } | 771 | mod confuse_index { fn foo(); } |
751 | ", | 772 | ", |
752 | "foo FN_DEF FileId(1) [52; 63) [55; 58)", | 773 | "foo FN_DEF FileId(1) [52; 63) [55; 58)", |
774 | "fn foo() {}|foo", | ||
753 | ); | 775 | ); |
754 | } | 776 | } |
755 | 777 | ||
@@ -778,6 +800,7 @@ mod tests { | |||
778 | } | 800 | } |
779 | ", | 801 | ", |
780 | "foo FN_DEF FileId(1) [398; 415) [401; 404)", | 802 | "foo FN_DEF FileId(1) [398; 415) [401; 404)", |
803 | "fn foo() -> i8 {}|foo", | ||
781 | ); | 804 | ); |
782 | } | 805 | } |
783 | 806 | ||
@@ -791,6 +814,7 @@ mod tests { | |||
791 | } | 814 | } |
792 | ", | 815 | ", |
793 | "T TYPE_PARAM FileId(1) [11; 12)", | 816 | "T TYPE_PARAM FileId(1) [11; 12)", |
817 | "T", | ||
794 | ); | 818 | ); |
795 | } | 819 | } |
796 | } | 820 | } |