]> git.lizzy.rs Git - rust.git/blob - crates/ide/src/goto_definition.rs
173509b08bd5c55ca79cf59c6dd1964eb27dab14
[rust.git] / crates / ide / src / goto_definition.rs
1 use either::Either;
2 use hir::Semantics;
3 use ide_db::{
4     base_db::FileId,
5     defs::{NameClass, NameRefClass},
6     symbol_index, RootDatabase,
7 };
8 use syntax::{ast, match_ast, AstNode, SyntaxKind::*, SyntaxToken, TokenAtOffset, T};
9
10 use crate::{
11     display::{ToNav, TryToNav},
12     FilePosition, NavigationTarget, RangeInfo,
13 };
14
15 // Feature: Go to Definition
16 //
17 // Navigates to the definition of an identifier.
18 //
19 // |===
20 // | Editor  | Shortcut
21 //
22 // | VS Code | kbd:[F12]
23 // |===
24 pub(crate) fn goto_definition(
25     db: &RootDatabase,
26     position: FilePosition,
27 ) -> Option<RangeInfo<Vec<NavigationTarget>>> {
28     let sema = Semantics::new(db);
29     let file = sema.parse(position.file_id).syntax().clone();
30     let original_token = pick_best(file.token_at_offset(position.offset))?;
31     let token = sema.descend_into_macros(original_token.clone());
32     let parent = token.parent();
33
34     let nav_targets = match_ast! {
35         match parent {
36             ast::NameRef(name_ref) => {
37                 reference_definition(&sema, Either::Right(&name_ref)).to_vec()
38             },
39             ast::Name(name) => {
40                 let def = NameClass::classify(&sema, &name)?.referenced_or_defined(sema.db);
41                 let nav = def.try_to_nav(sema.db)?;
42                 vec![nav]
43             },
44             ast::SelfParam(self_param) => {
45                 vec![self_to_nav_target(self_param, position.file_id)?]
46             },
47             ast::PathSegment(segment) => {
48                 segment.self_token()?;
49                 let path = segment.parent_path();
50                 if path.qualifier().is_some() && !ast::PathExpr::can_cast(path.syntax().parent()?.kind()) {
51                     return None;
52                 }
53                 let func = segment.syntax().ancestors().find_map(ast::Fn::cast)?;
54                 let self_param = func.param_list()?.self_param()?;
55                 vec![self_to_nav_target(self_param, position.file_id)?]
56             },
57             ast::Lifetime(lt) => if let Some(name_class) = NameClass::classify_lifetime(&sema, &lt) {
58                 let def = name_class.referenced_or_defined(sema.db);
59                 let nav = def.try_to_nav(sema.db)?;
60                 vec![nav]
61             } else {
62                 reference_definition(&sema, Either::Left(&lt)).to_vec()
63             },
64             _ => return None,
65         }
66     };
67
68     Some(RangeInfo::new(original_token.text_range(), nav_targets))
69 }
70
71 fn pick_best(tokens: TokenAtOffset<SyntaxToken>) -> Option<SyntaxToken> {
72     return tokens.max_by_key(priority);
73     fn priority(n: &SyntaxToken) -> usize {
74         match n.kind() {
75             IDENT | INT_NUMBER | LIFETIME_IDENT | T![self] => 2,
76             kind if kind.is_trivia() => 0,
77             _ => 1,
78         }
79     }
80 }
81
82 fn self_to_nav_target(self_param: ast::SelfParam, file_id: FileId) -> Option<NavigationTarget> {
83     let self_token = self_param.self_token()?;
84     Some(NavigationTarget {
85         file_id,
86         full_range: self_param.syntax().text_range(),
87         focus_range: Some(self_token.text_range()),
88         name: self_token.text().clone(),
89         kind: self_token.kind(),
90         container_name: None,
91         description: None,
92         docs: None,
93     })
94 }
95
96 #[derive(Debug)]
97 pub(crate) enum ReferenceResult {
98     Exact(NavigationTarget),
99     Approximate(Vec<NavigationTarget>),
100 }
101
102 impl ReferenceResult {
103     fn to_vec(self) -> Vec<NavigationTarget> {
104         match self {
105             ReferenceResult::Exact(target) => vec![target],
106             ReferenceResult::Approximate(vec) => vec,
107         }
108     }
109 }
110
111 pub(crate) fn reference_definition(
112     sema: &Semantics<RootDatabase>,
113     name_ref: Either<&ast::Lifetime, &ast::NameRef>,
114 ) -> ReferenceResult {
115     let name_kind = name_ref.either(
116         |lifetime| NameRefClass::classify_lifetime(sema, lifetime),
117         |name_ref| NameRefClass::classify(sema, name_ref),
118     );
119     if let Some(def) = name_kind {
120         let def = def.referenced(sema.db);
121         return match def.try_to_nav(sema.db) {
122             Some(nav) => ReferenceResult::Exact(nav),
123             None => ReferenceResult::Approximate(Vec::new()),
124         };
125     }
126
127     // Fallback index based approach:
128     let name = name_ref.either(ast::Lifetime::text, ast::NameRef::text);
129     let navs =
130         symbol_index::index_resolve(sema.db, name).into_iter().map(|s| s.to_nav(sema.db)).collect();
131     ReferenceResult::Approximate(navs)
132 }
133
134 #[cfg(test)]
135 mod tests {
136     use ide_db::base_db::FileRange;
137     use syntax::{TextRange, TextSize};
138
139     use crate::fixture;
140
141     fn check(ra_fixture: &str) {
142         let (analysis, position, mut annotations) = fixture::annotations(ra_fixture);
143         let (mut expected, data) = annotations.pop().unwrap();
144         match data.as_str() {
145             "" => (),
146             "file" => {
147                 expected.range =
148                     TextRange::up_to(TextSize::of(&*analysis.file_text(expected.file_id).unwrap()))
149             }
150             data => panic!("bad data: {}", data),
151         }
152
153         let mut navs =
154             analysis.goto_definition(position).unwrap().expect("no definition found").info;
155         if navs.len() == 0 {
156             panic!("unresolved reference")
157         }
158         assert_eq!(navs.len(), 1);
159
160         let nav = navs.pop().unwrap();
161         assert_eq!(expected, FileRange { file_id: nav.file_id, range: nav.focus_or_full_range() });
162     }
163
164     #[test]
165     fn goto_def_for_extern_crate() {
166         check(
167             r#"
168             //- /main.rs crate:main deps:std
169             extern crate std<|>;
170             //- /std/lib.rs crate:std
171             // empty
172             //^ file
173             "#,
174         )
175     }
176
177     #[test]
178     fn goto_def_for_renamed_extern_crate() {
179         check(
180             r#"
181             //- /main.rs crate:main deps:std
182             extern crate std as abc<|>;
183             //- /std/lib.rs crate:std
184             // empty
185             //^ file
186             "#,
187         )
188     }
189
190     #[test]
191     fn goto_def_in_items() {
192         check(
193             r#"
194 struct Foo;
195      //^^^
196 enum E { X(Foo<|>) }
197 "#,
198         );
199     }
200
201     #[test]
202     fn goto_def_at_start_of_item() {
203         check(
204             r#"
205 struct Foo;
206      //^^^
207 enum E { X(<|>Foo) }
208 "#,
209         );
210     }
211
212     #[test]
213     fn goto_definition_resolves_correct_name() {
214         check(
215             r#"
216 //- /lib.rs
217 use a::Foo;
218 mod a;
219 mod b;
220 enum E { X(Foo<|>) }
221
222 //- /a.rs
223 struct Foo;
224      //^^^
225 //- /b.rs
226 struct Foo;
227 "#,
228         );
229     }
230
231     #[test]
232     fn goto_def_for_module_declaration() {
233         check(
234             r#"
235 //- /lib.rs
236 mod <|>foo;
237
238 //- /foo.rs
239 // empty
240 //^ file
241 "#,
242         );
243
244         check(
245             r#"
246 //- /lib.rs
247 mod <|>foo;
248
249 //- /foo/mod.rs
250 // empty
251 //^ file
252 "#,
253         );
254     }
255
256     #[test]
257     fn goto_def_for_macros() {
258         check(
259             r#"
260 macro_rules! foo { () => { () } }
261            //^^^
262 fn bar() {
263     <|>foo!();
264 }
265 "#,
266         );
267     }
268
269     #[test]
270     fn goto_def_for_macros_from_other_crates() {
271         check(
272             r#"
273 //- /lib.rs
274 use foo::foo;
275 fn bar() {
276     <|>foo!();
277 }
278
279 //- /foo/lib.rs
280 #[macro_export]
281 macro_rules! foo { () => { () } }
282            //^^^
283 "#,
284         );
285     }
286
287     #[test]
288     fn goto_def_for_macros_in_use_tree() {
289         check(
290             r#"
291 //- /lib.rs
292 use foo::foo<|>;
293
294 //- /foo/lib.rs
295 #[macro_export]
296 macro_rules! foo { () => { () } }
297            //^^^
298 "#,
299         );
300     }
301
302     #[test]
303     fn goto_def_for_macro_defined_fn_with_arg() {
304         check(
305             r#"
306 //- /lib.rs
307 macro_rules! define_fn {
308     ($name:ident) => (fn $name() {})
309 }
310
311 define_fn!(foo);
312          //^^^
313
314 fn bar() {
315    <|>foo();
316 }
317 "#,
318         );
319     }
320
321     #[test]
322     fn goto_def_for_macro_defined_fn_no_arg() {
323         check(
324             r#"
325 //- /lib.rs
326 macro_rules! define_fn {
327     () => (fn foo() {})
328 }
329
330   define_fn!();
331 //^^^^^^^^^^^^^
332
333 fn bar() {
334    <|>foo();
335 }
336 "#,
337         );
338     }
339
340     #[test]
341     fn goto_definition_works_for_macro_inside_pattern() {
342         check(
343             r#"
344 //- /lib.rs
345 macro_rules! foo {() => {0}}
346            //^^^
347
348 fn bar() {
349     match (0,1) {
350         (<|>foo!(), _) => {}
351     }
352 }
353 "#,
354         );
355     }
356
357     #[test]
358     fn goto_definition_works_for_macro_inside_match_arm_lhs() {
359         check(
360             r#"
361 //- /lib.rs
362 macro_rules! foo {() => {0}}
363            //^^^
364 fn bar() {
365     match 0 {
366         <|>foo!() => {}
367     }
368 }
369 "#,
370         );
371     }
372
373     #[test]
374     fn goto_def_for_use_alias() {
375         check(
376             r#"
377 //- /lib.rs crate:main deps:foo
378 use foo as bar<|>;
379
380 //- /foo/lib.rs crate:foo
381 // empty
382 //^ file
383 "#,
384         );
385     }
386
387     #[test]
388     fn goto_def_for_use_alias_foo_macro() {
389         check(
390             r#"
391 //- /lib.rs crate:main deps:foo
392 use foo::foo as bar<|>;
393
394 //- /foo/lib.rs crate:foo
395 #[macro_export]
396 macro_rules! foo { () => { () } }
397            //^^^
398 "#,
399         );
400     }
401
402     #[test]
403     fn goto_def_for_methods() {
404         check(
405             r#"
406 struct Foo;
407 impl Foo {
408     fn frobnicate(&self) { }
409      //^^^^^^^^^^
410 }
411
412 fn bar(foo: &Foo) {
413     foo.frobnicate<|>();
414 }
415 "#,
416         );
417     }
418
419     #[test]
420     fn goto_def_for_fields() {
421         check(
422             r#"
423 struct Foo {
424     spam: u32,
425 } //^^^^
426
427 fn bar(foo: &Foo) {
428     foo.spam<|>;
429 }
430 "#,
431         );
432     }
433
434     #[test]
435     fn goto_def_for_record_fields() {
436         check(
437             r#"
438 //- /lib.rs
439 struct Foo {
440     spam: u32,
441 } //^^^^
442
443 fn bar() -> Foo {
444     Foo {
445         spam<|>: 0,
446     }
447 }
448 "#,
449         );
450     }
451
452     #[test]
453     fn goto_def_for_record_pat_fields() {
454         check(
455             r#"
456 //- /lib.rs
457 struct Foo {
458     spam: u32,
459 } //^^^^
460
461 fn bar(foo: Foo) -> Foo {
462     let Foo { spam<|>: _, } = foo
463 }
464 "#,
465         );
466     }
467
468     #[test]
469     fn goto_def_for_record_fields_macros() {
470         check(
471             r"
472 macro_rules! m { () => { 92 };}
473 struct Foo { spam: u32 }
474            //^^^^
475
476 fn bar() -> Foo {
477     Foo { spam<|>: m!() }
478 }
479 ",
480         );
481     }
482
483     #[test]
484     fn goto_for_tuple_fields() {
485         check(
486             r#"
487 struct Foo(u32);
488          //^^^
489
490 fn bar() {
491     let foo = Foo(0);
492     foo.<|>0;
493 }
494 "#,
495         );
496     }
497
498     #[test]
499     fn goto_def_for_ufcs_inherent_methods() {
500         check(
501             r#"
502 struct Foo;
503 impl Foo {
504     fn frobnicate() { }
505 }    //^^^^^^^^^^
506
507 fn bar(foo: &Foo) {
508     Foo::frobnicate<|>();
509 }
510 "#,
511         );
512     }
513
514     #[test]
515     fn goto_def_for_ufcs_trait_methods_through_traits() {
516         check(
517             r#"
518 trait Foo {
519     fn frobnicate();
520 }    //^^^^^^^^^^
521
522 fn bar() {
523     Foo::frobnicate<|>();
524 }
525 "#,
526         );
527     }
528
529     #[test]
530     fn goto_def_for_ufcs_trait_methods_through_self() {
531         check(
532             r#"
533 struct Foo;
534 trait Trait {
535     fn frobnicate();
536 }    //^^^^^^^^^^
537 impl Trait for Foo {}
538
539 fn bar() {
540     Foo::frobnicate<|>();
541 }
542 "#,
543         );
544     }
545
546     #[test]
547     fn goto_definition_on_self() {
548         check(
549             r#"
550 struct Foo;
551 impl Foo {
552    //^^^
553     pub fn new() -> Self {
554         Self<|> {}
555     }
556 }
557 "#,
558         );
559         check(
560             r#"
561 struct Foo;
562 impl Foo {
563    //^^^
564     pub fn new() -> Self<|> {
565         Self {}
566     }
567 }
568 "#,
569         );
570
571         check(
572             r#"
573 enum Foo { A }
574 impl Foo {
575    //^^^
576     pub fn new() -> Self<|> {
577         Foo::A
578     }
579 }
580 "#,
581         );
582
583         check(
584             r#"
585 enum Foo { A }
586 impl Foo {
587    //^^^
588     pub fn thing(a: &Self<|>) {
589     }
590 }
591 "#,
592         );
593     }
594
595     #[test]
596     fn goto_definition_on_self_in_trait_impl() {
597         check(
598             r#"
599 struct Foo;
600 trait Make {
601     fn new() -> Self;
602 }
603 impl Make for Foo {
604             //^^^
605     fn new() -> Self {
606         Self<|> {}
607     }
608 }
609 "#,
610         );
611
612         check(
613             r#"
614 struct Foo;
615 trait Make {
616     fn new() -> Self;
617 }
618 impl Make for Foo {
619             //^^^
620     fn new() -> Self<|> {
621         Self {}
622     }
623 }
624 "#,
625         );
626     }
627
628     #[test]
629     fn goto_def_when_used_on_definition_name_itself() {
630         check(
631             r#"
632 struct Foo<|> { value: u32 }
633      //^^^
634             "#,
635         );
636
637         check(
638             r#"
639 struct Foo {
640     field<|>: string,
641 } //^^^^^
642 "#,
643         );
644
645         check(
646             r#"
647 fn foo_test<|>() { }
648  //^^^^^^^^
649 "#,
650         );
651
652         check(
653             r#"
654 enum Foo<|> { Variant }
655    //^^^
656 "#,
657         );
658
659         check(
660             r#"
661 enum Foo {
662     Variant1,
663     Variant2<|>,
664   //^^^^^^^^
665     Variant3,
666 }
667 "#,
668         );
669
670         check(
671             r#"
672 static INNER<|>: &str = "";
673      //^^^^^
674 "#,
675         );
676
677         check(
678             r#"
679 const INNER<|>: &str = "";
680     //^^^^^
681 "#,
682         );
683
684         check(
685             r#"
686 type Thing<|> = Option<()>;
687    //^^^^^
688 "#,
689         );
690
691         check(
692             r#"
693 trait Foo<|> { }
694     //^^^
695 "#,
696         );
697
698         check(
699             r#"
700 mod bar<|> { }
701   //^^^
702 "#,
703         );
704     }
705
706     #[test]
707     fn goto_from_macro() {
708         check(
709             r#"
710 macro_rules! id {
711     ($($tt:tt)*) => { $($tt)* }
712 }
713 fn foo() {}
714  //^^^
715 id! {
716     fn bar() {
717         fo<|>o();
718     }
719 }
720 mod confuse_index { fn foo(); }
721 "#,
722         );
723     }
724
725     #[test]
726     fn goto_through_format() {
727         check(
728             r#"
729 #[macro_export]
730 macro_rules! format {
731     ($($arg:tt)*) => ($crate::fmt::format($crate::__export::format_args!($($arg)*)))
732 }
733 #[rustc_builtin_macro]
734 #[macro_export]
735 macro_rules! format_args {
736     ($fmt:expr) => ({ /* compiler built-in */ });
737     ($fmt:expr, $($args:tt)*) => ({ /* compiler built-in */ })
738 }
739 pub mod __export {
740     pub use crate::format_args;
741     fn foo() {} // for index confusion
742 }
743 fn foo() -> i8 {}
744  //^^^
745 fn test() {
746     format!("{}", fo<|>o())
747 }
748 "#,
749         );
750     }
751
752     #[test]
753     fn goto_for_type_param() {
754         check(
755             r#"
756 struct Foo<T: Clone> { t: <|>T }
757          //^
758 "#,
759         );
760     }
761
762     #[test]
763     fn goto_within_macro() {
764         check(
765             r#"
766 macro_rules! id {
767     ($($tt:tt)*) => ($($tt)*)
768 }
769
770 fn foo() {
771     let x = 1;
772       //^
773     id!({
774         let y = <|>x;
775         let z = y;
776     });
777 }
778 "#,
779         );
780
781         check(
782             r#"
783 macro_rules! id {
784     ($($tt:tt)*) => ($($tt)*)
785 }
786
787 fn foo() {
788     let x = 1;
789     id!({
790         let y = x;
791           //^
792         let z = <|>y;
793     });
794 }
795 "#,
796         );
797     }
798
799     #[test]
800     fn goto_def_in_local_fn() {
801         check(
802             r#"
803 fn main() {
804     fn foo() {
805         let x = 92;
806           //^
807         <|>x;
808     }
809 }
810 "#,
811         );
812     }
813
814     #[test]
815     fn goto_def_in_local_macro() {
816         check(
817             r#"
818 fn bar() {
819     macro_rules! foo { () => { () } }
820                //^^^
821     <|>foo!();
822 }
823 "#,
824         );
825     }
826
827     #[test]
828     fn goto_def_for_field_init_shorthand() {
829         check(
830             r#"
831 struct Foo { x: i32 }
832 fn main() {
833     let x = 92;
834       //^
835     Foo { x<|> };
836 }
837 "#,
838         )
839     }
840
841     #[test]
842     fn goto_def_for_enum_variant_field() {
843         check(
844             r#"
845 enum Foo {
846     Bar { x: i32 }
847 }       //^
848 fn baz(foo: Foo) {
849     match foo {
850         Foo::Bar { x<|> } => x
851     };
852 }
853 "#,
854         );
855     }
856
857     #[test]
858     fn goto_def_for_enum_variant_self_pattern_const() {
859         check(
860             r#"
861 enum Foo { Bar }
862          //^^^
863 impl Foo {
864     fn baz(self) {
865         match self { Self::Bar<|> => {} }
866     }
867 }
868 "#,
869         );
870     }
871
872     #[test]
873     fn goto_def_for_enum_variant_self_pattern_record() {
874         check(
875             r#"
876 enum Foo { Bar { val: i32 } }
877          //^^^
878 impl Foo {
879     fn baz(self) -> i32 {
880         match self { Self::Bar<|> { val } => {} }
881     }
882 }
883 "#,
884         );
885     }
886
887     #[test]
888     fn goto_def_for_enum_variant_self_expr_const() {
889         check(
890             r#"
891 enum Foo { Bar }
892          //^^^
893 impl Foo {
894     fn baz(self) { Self::Bar<|>; }
895 }
896 "#,
897         );
898     }
899
900     #[test]
901     fn goto_def_for_enum_variant_self_expr_record() {
902         check(
903             r#"
904 enum Foo { Bar { val: i32 } }
905          //^^^
906 impl Foo {
907     fn baz(self) { Self::Bar<|> {val: 4}; }
908 }
909 "#,
910         );
911     }
912
913     #[test]
914     fn goto_def_for_type_alias_generic_parameter() {
915         check(
916             r#"
917 type Alias<T> = T<|>;
918          //^
919 "#,
920         )
921     }
922
923     #[test]
924     fn goto_def_for_macro_container() {
925         check(
926             r#"
927 //- /lib.rs
928 foo::module<|>::mac!();
929
930 //- /foo/lib.rs
931 pub mod module {
932       //^^^^^^
933     #[macro_export]
934     macro_rules! _mac { () => { () } }
935     pub use crate::_mac as mac;
936 }
937 "#,
938         );
939     }
940
941     #[test]
942     fn goto_def_for_assoc_ty_in_path() {
943         check(
944             r#"
945 trait Iterator {
946     type Item;
947        //^^^^
948 }
949
950 fn f() -> impl Iterator<Item<|> = u8> {}
951 "#,
952         );
953     }
954
955     #[test]
956     fn goto_def_for_assoc_ty_in_path_multiple() {
957         check(
958             r#"
959 trait Iterator {
960     type A;
961        //^
962     type B;
963 }
964
965 fn f() -> impl Iterator<A<|> = u8, B = ()> {}
966 "#,
967         );
968         check(
969             r#"
970 trait Iterator {
971     type A;
972     type B;
973        //^
974 }
975
976 fn f() -> impl Iterator<A = u8, B<|> = ()> {}
977 "#,
978         );
979     }
980
981     #[test]
982     fn goto_def_for_assoc_ty_ufcs() {
983         check(
984             r#"
985 trait Iterator {
986     type Item;
987        //^^^^
988 }
989
990 fn g() -> <() as Iterator<Item<|> = ()>>::Item {}
991 "#,
992         );
993     }
994
995     #[test]
996     fn goto_def_for_assoc_ty_ufcs_multiple() {
997         check(
998             r#"
999 trait Iterator {
1000     type A;
1001        //^
1002     type B;
1003 }
1004
1005 fn g() -> <() as Iterator<A<|> = (), B = u8>>::B {}
1006 "#,
1007         );
1008         check(
1009             r#"
1010 trait Iterator {
1011     type A;
1012     type B;
1013        //^
1014 }
1015
1016 fn g() -> <() as Iterator<A = (), B<|> = u8>>::A {}
1017 "#,
1018         );
1019     }
1020
1021     #[test]
1022     fn goto_self_param_ty_specified() {
1023         check(
1024             r#"
1025 struct Foo {}
1026
1027 impl Foo {
1028     fn bar(self: &Foo) {
1029          //^^^^
1030         let foo = sel<|>f;
1031     }
1032 }"#,
1033         )
1034     }
1035
1036     #[test]
1037     fn goto_self_param_on_decl() {
1038         check(
1039             r#"
1040 struct Foo {}
1041
1042 impl Foo {
1043     fn bar(&self<|>) {
1044           //^^^^
1045     }
1046 }"#,
1047         )
1048     }
1049
1050     #[test]
1051     fn goto_lifetime_param_on_decl() {
1052         check(
1053             r#"
1054 fn foo<'foobar<|>>(_: &'foobar ()) {
1055      //^^^^^^^
1056 }"#,
1057         )
1058     }
1059
1060     #[test]
1061     fn goto_lifetime_param_decl() {
1062         check(
1063             r#"
1064 fn foo<'foobar>(_: &'foobar<|> ()) {
1065      //^^^^^^^
1066 }"#,
1067         )
1068     }
1069
1070     #[test]
1071     fn goto_lifetime_param_decl_nested() {
1072         check(
1073             r#"
1074 fn foo<'foobar>(_: &'foobar ()) {
1075     fn foo<'foobar>(_: &'foobar<|> ()) {}
1076          //^^^^^^^
1077 }"#,
1078         )
1079     }
1080 }