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