diff options
Diffstat (limited to 'crates/ra_ide_api/src/goto_definition.rs')
-rw-r--r-- | crates/ra_ide_api/src/goto_definition.rs | 40 |
1 files changed, 12 insertions, 28 deletions
diff --git a/crates/ra_ide_api/src/goto_definition.rs b/crates/ra_ide_api/src/goto_definition.rs index 69f2d2bf6..413720960 100644 --- a/crates/ra_ide_api/src/goto_definition.rs +++ b/crates/ra_ide_api/src/goto_definition.rs | |||
@@ -50,18 +50,13 @@ pub(crate) fn reference_definition( | |||
50 | hir::source_binder::function_from_child_node(db, file_id, name_ref.syntax()) | 50 | hir::source_binder::function_from_child_node(db, file_id, name_ref.syntax()) |
51 | { | 51 | { |
52 | // Check if it is a method | 52 | // Check if it is a method |
53 | if let Some(method_call) = name_ref | 53 | if let Some(method_call) = name_ref.syntax().parent().and_then(ast::MethodCallExpr::cast) { |
54 | .syntax() | ||
55 | .parent() | ||
56 | .and_then(ast::MethodCallExpr::cast) | ||
57 | { | ||
58 | tested_by!(goto_definition_works_for_methods); | 54 | tested_by!(goto_definition_works_for_methods); |
59 | let infer_result = function.infer(db); | 55 | let infer_result = function.infer(db); |
60 | let syntax_mapping = function.body_syntax_mapping(db); | 56 | let syntax_mapping = function.body_syntax_mapping(db); |
61 | let expr = ast::Expr::cast(method_call.syntax()).unwrap(); | 57 | let expr = ast::Expr::cast(method_call.syntax()).unwrap(); |
62 | if let Some(func) = syntax_mapping | 58 | if let Some(func) = |
63 | .node_expr(expr) | 59 | syntax_mapping.node_expr(expr).and_then(|it| infer_result.method_resolution(it)) |
64 | .and_then(|it| infer_result.method_resolution(it)) | ||
65 | { | 60 | { |
66 | return Exact(NavigationTarget::from_function(db, func)); | 61 | return Exact(NavigationTarget::from_function(db, func)); |
67 | }; | 62 | }; |
@@ -72,9 +67,8 @@ pub(crate) fn reference_definition( | |||
72 | let infer_result = function.infer(db); | 67 | let infer_result = function.infer(db); |
73 | let syntax_mapping = function.body_syntax_mapping(db); | 68 | let syntax_mapping = function.body_syntax_mapping(db); |
74 | let expr = ast::Expr::cast(field_expr.syntax()).unwrap(); | 69 | let expr = ast::Expr::cast(field_expr.syntax()).unwrap(); |
75 | if let Some(field) = syntax_mapping | 70 | if let Some(field) = |
76 | .node_expr(expr) | 71 | syntax_mapping.node_expr(expr).and_then(|it| infer_result.field_resolution(it)) |
77 | .and_then(|it| infer_result.field_resolution(it)) | ||
78 | { | 72 | { |
79 | return Exact(NavigationTarget::from_field(db, field)); | 73 | return Exact(NavigationTarget::from_field(db, field)); |
80 | }; | 74 | }; |
@@ -82,29 +76,19 @@ pub(crate) fn reference_definition( | |||
82 | } | 76 | } |
83 | // Try name resolution | 77 | // Try name resolution |
84 | let resolver = hir::source_binder::resolver_for_node(db, file_id, name_ref.syntax()); | 78 | let resolver = hir::source_binder::resolver_for_node(db, file_id, name_ref.syntax()); |
85 | if let Some(path) = name_ref | 79 | if let Some(path) = |
86 | .syntax() | 80 | name_ref.syntax().ancestors().find_map(ast::Path::cast).and_then(hir::Path::from_ast) |
87 | .ancestors() | ||
88 | .find_map(ast::Path::cast) | ||
89 | .and_then(hir::Path::from_ast) | ||
90 | { | 81 | { |
91 | let resolved = resolver.resolve_path(db, &path); | 82 | let resolved = resolver.resolve_path(db, &path); |
92 | match resolved | 83 | match resolved.clone().take_types().or_else(|| resolved.take_values()) { |
93 | .clone() | ||
94 | .take_types() | ||
95 | .or_else(|| resolved.take_values()) | ||
96 | { | ||
97 | Some(Resolution::Def(def)) => return Exact(NavigationTarget::from_def(db, def)), | 84 | Some(Resolution::Def(def)) => return Exact(NavigationTarget::from_def(db, def)), |
98 | Some(Resolution::LocalBinding(pat)) => { | 85 | Some(Resolution::LocalBinding(pat)) => { |
99 | let body = resolver.body().expect("no body for local binding"); | 86 | let body = resolver.body().expect("no body for local binding"); |
100 | let syntax_mapping = body.syntax_mapping(db); | 87 | let syntax_mapping = body.syntax_mapping(db); |
101 | let ptr = syntax_mapping | 88 | let ptr = |
102 | .pat_syntax(pat) | 89 | syntax_mapping.pat_syntax(pat).expect("pattern not found in syntax mapping"); |
103 | .expect("pattern not found in syntax mapping"); | 90 | let name = |
104 | let name = path | 91 | path.as_ident().cloned().expect("local binding from a multi-segment path"); |
105 | .as_ident() | ||
106 | .cloned() | ||
107 | .expect("local binding from a multi-segment path"); | ||
108 | let nav = NavigationTarget::from_scope_entry(file_id, name, ptr); | 92 | let nav = NavigationTarget::from_scope_entry(file_id, name, ptr); |
109 | return Exact(nav); | 93 | return Exact(nav); |
110 | } | 94 | } |