aboutsummaryrefslogtreecommitdiff
path: root/crates
diff options
context:
space:
mode:
authorbors[bot] <26634292+bors[bot]@users.noreply.github.com>2020-11-29 14:35:38 +0000
committerGitHub <[email protected]>2020-11-29 14:35:38 +0000
commit05f75d601f10b32a39b4f03a49f9bde268f0bfc0 (patch)
tree7a9676bfe0e5bef8a9c2c78a80e60896b097a6b1 /crates
parentc8a2ff6ecc8e45c7e1420e01d52c8b7a315140e6 (diff)
parent37438c3335cedc6d89e47cc123a5c23dabaef2a2 (diff)
Merge #6666
6666: Support 'go to definition' for self r=jonas-schievink a=Veykril Also reverts #6660, instead of showing the type it now works like it does for names by returning the declaration we are already on. This for example enables VSCode to show all references(#6665) when executing `go to definition` on the declaration. Co-authored-by: Lukas Wirth <[email protected]>
Diffstat (limited to 'crates')
-rw-r--r--crates/ide/src/goto_definition.rs56
1 files changed, 39 insertions, 17 deletions
diff --git a/crates/ide/src/goto_definition.rs b/crates/ide/src/goto_definition.rs
index d41dd3d92..b9810457f 100644
--- a/crates/ide/src/goto_definition.rs
+++ b/crates/ide/src/goto_definition.rs
@@ -1,5 +1,6 @@
1use hir::Semantics; 1use hir::Semantics;
2use ide_db::{ 2use ide_db::{
3 base_db::FileId,
3 defs::{NameClass, NameRefClass}, 4 defs::{NameClass, NameRefClass},
4 symbol_index, RootDatabase, 5 symbol_index, RootDatabase,
5}; 6};
@@ -40,10 +41,17 @@ pub(crate) fn goto_definition(
40 vec![nav] 41 vec![nav]
41 }, 42 },
42 ast::SelfParam(self_param) => { 43 ast::SelfParam(self_param) => {
43 let ty = sema.type_of_self(&self_param)?; 44 vec![self_to_nav_target(self_param, position.file_id)?]
44 let adt_def = ty.autoderef(db).filter_map(|ty| ty.as_adt()).last()?; 45 },
45 let nav = adt_def.to_nav(db); 46 ast::PathSegment(segment) => {
46 vec![nav] 47 segment.self_token()?;
48 let path = segment.parent_path();
49 if path.qualifier().is_some() && !ast::PathExpr::can_cast(path.syntax().parent()?.kind()) {
50 return None;
51 }
52 let func = segment.syntax().ancestors().find_map(ast::Fn::cast)?;
53 let self_param = func.param_list()?.self_param()?;
54 vec![self_to_nav_target(self_param, position.file_id)?]
47 }, 55 },
48 _ => return None, 56 _ => return None,
49 } 57 }
@@ -63,6 +71,20 @@ fn pick_best(tokens: TokenAtOffset<SyntaxToken>) -> Option<SyntaxToken> {
63 } 71 }
64} 72}
65 73
74fn self_to_nav_target(self_param: ast::SelfParam, file_id: FileId) -> Option<NavigationTarget> {
75 let self_token = self_param.self_token()?;
76 Some(NavigationTarget {
77 file_id,
78 full_range: self_param.syntax().text_range(),
79 focus_range: Some(self_token.text_range()),
80 name: self_token.text().clone(),
81 kind: self_token.kind(),
82 container_name: None,
83 description: None,
84 docs: None,
85 })
86}
87
66#[derive(Debug)] 88#[derive(Debug)]
67pub(crate) enum ReferenceResult { 89pub(crate) enum ReferenceResult {
68 Exact(NavigationTarget), 90 Exact(NavigationTarget),
@@ -987,31 +1009,31 @@ fn g() -> <() as Iterator<A = (), B<|> = u8>>::A {}
987 } 1009 }
988 1010
989 #[test] 1011 #[test]
990 fn todo_def_type_for_self() { 1012 fn goto_self_param_ty_specified() {
991 check( 1013 check(
992 r#" 1014 r#"
993struct Foo {} 1015struct Foo {}
994 //^^^
995 1016
996impl Foo { 1017impl Foo {
997 fn bar(&self<|>) {} 1018 fn bar(self: &Foo) {
998} 1019 //^^^^
999"#, 1020 let foo = sel<|>f;
1000 ); 1021 }
1022}"#,
1023 )
1001 } 1024 }
1002 1025
1003 #[test] 1026 #[test]
1004 fn todo_def_type_for_arbitrary_self() { 1027 fn goto_self_param_on_decl() {
1005 check( 1028 check(
1006 r#" 1029 r#"
1007struct Arc<T>(T);
1008 //^^^
1009struct Foo {} 1030struct Foo {}
1010 1031
1011impl Foo { 1032impl Foo {
1012 fn bar(self<|>: Arc<Self>) {} 1033 fn bar(&self<|>) {
1013} 1034 //^^^^
1014"#, 1035 }
1015 ); 1036}"#,
1037 )
1016 } 1038 }
1017} 1039}