aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_ide_api/src/goto_definition.rs
diff options
context:
space:
mode:
authorkjeremy <[email protected]>2019-03-01 23:26:49 +0000
committerJeremy Kolb <[email protected]>2019-03-04 13:27:08 +0000
commit49da9a3e814a42a2f4dea0cd79dbdae86bea5ce4 (patch)
tree27710b8c6c7f63e2ddb25d178988f4dd6cbc2540 /crates/ra_ide_api/src/goto_definition.rs
parentdc8bcc1e42b573a8c315dd42a43c0fc4d5bfa8f8 (diff)
Make goto definition/hover resolve constructors
Diffstat (limited to 'crates/ra_ide_api/src/goto_definition.rs')
-rw-r--r--crates/ra_ide_api/src/goto_definition.rs29
1 files changed, 25 insertions, 4 deletions
diff --git a/crates/ra_ide_api/src/goto_definition.rs b/crates/ra_ide_api/src/goto_definition.rs
index 9ec179593..e4febe8cc 100644
--- a/crates/ra_ide_api/src/goto_definition.rs
+++ b/crates/ra_ide_api/src/goto_definition.rs
@@ -47,9 +47,10 @@ pub(crate) fn reference_definition(
47 name_ref: &ast::NameRef, 47 name_ref: &ast::NameRef,
48) -> ReferenceResult { 48) -> ReferenceResult {
49 use self::ReferenceResult::*; 49 use self::ReferenceResult::*;
50 if let Some(function) = 50
51 hir::source_binder::function_from_child_node(db, file_id, name_ref.syntax()) 51 let function = hir::source_binder::function_from_child_node(db, file_id, name_ref.syntax());
52 { 52
53 if let Some(function) = function {
53 // Check if it is a method 54 // Check if it is a method
54 if let Some(method_call) = name_ref.syntax().parent().and_then(ast::MethodCallExpr::cast) { 55 if let Some(method_call) = name_ref.syntax().parent().and_then(ast::MethodCallExpr::cast) {
55 tested_by!(goto_definition_works_for_methods); 56 tested_by!(goto_definition_works_for_methods);
@@ -122,9 +123,29 @@ pub(crate) fn reference_definition(
122 Some(Resolution::SelfType(_impl_block)) => { 123 Some(Resolution::SelfType(_impl_block)) => {
123 // TODO: go to the implemented type 124 // TODO: go to the implemented type
124 } 125 }
125 None => {} 126 None => {
127 // If we failed to resolve then check associated items
128 if let Some(function) = function {
129 // Should we do this above and then grab path from the PathExpr?
130 if let Some(path_expr) =
131 name_ref.syntax().ancestors().find_map(ast::PathExpr::cast)
132 {
133 let infer_result = function.infer(db);
134 let syntax_mapping = function.body_syntax_mapping(db);
135 let expr = ast::Expr::cast(path_expr.syntax()).unwrap();
136
137 if let Some(func) = syntax_mapping
138 .node_expr(expr)
139 .and_then(|it| infer_result.assoc_fn_resolutions(it))
140 {
141 return Exact(NavigationTarget::from_function(db, func));
142 }
143 }
144 }
145 }
126 } 146 }
127 } 147 }
148
128 // If that fails try the index based approach. 149 // If that fails try the index based approach.
129 let navs = crate::symbol_index::index_resolve(db, name_ref) 150 let navs = crate::symbol_index::index_resolve(db, name_ref)
130 .into_iter() 151 .into_iter()