aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_ide
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_ide')
-rw-r--r--crates/ra_ide/src/goto_definition.rs124
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}