aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLukas Wirth <[email protected]>2020-11-28 21:50:59 +0000
committerLukas Wirth <[email protected]>2020-11-29 11:28:47 +0000
commit37438c3335cedc6d89e47cc123a5c23dabaef2a2 (patch)
tree2655046584291d7da76899c14a14533d7ebcf081
parenta6f26ded0037a3efb5625ac3482a2f4ec9eb01a3 (diff)
Support 'go to definition' for self
-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}