diff options
author | bors[bot] <bors[bot]@users.noreply.github.com> | 2019-01-05 17:03:55 +0000 |
---|---|---|
committer | bors[bot] <bors[bot]@users.noreply.github.com> | 2019-01-05 17:03:55 +0000 |
commit | cc53e9e7d17871c03fa9d88c709873e20690ca84 (patch) | |
tree | 9021f6b236ce24d19a7a419c9f8c9c08c9ff08f4 /crates | |
parent | 2a19d699eb594c4929215a24df333f87fd41881a (diff) | |
parent | ee461a211195b093269ead477f01fcf63f20cf34 (diff) |
Merge #437
437: refactor goto defenition r=matklad a=matklad
Co-authored-by: Aleksey Kladov <[email protected]>
Diffstat (limited to 'crates')
-rw-r--r-- | crates/ra_analysis/src/goto_defenition.rs | 177 | ||||
-rw-r--r-- | crates/ra_analysis/src/hover.rs | 17 | ||||
-rw-r--r-- | crates/ra_analysis/src/imp.rs | 64 | ||||
-rw-r--r-- | crates/ra_analysis/src/lib.rs | 28 | ||||
-rw-r--r-- | crates/ra_analysis/tests/test/main.rs | 59 | ||||
-rw-r--r-- | crates/ra_lsp_server/src/main_loop/handlers.rs | 5 |
6 files changed, 138 insertions, 212 deletions
diff --git a/crates/ra_analysis/src/goto_defenition.rs b/crates/ra_analysis/src/goto_defenition.rs index 607a25115..e37421f8d 100644 --- a/crates/ra_analysis/src/goto_defenition.rs +++ b/crates/ra_analysis/src/goto_defenition.rs | |||
@@ -1,73 +1,138 @@ | |||
1 | use ra_db::FileId; | 1 | use ra_db::{FileId, Cancelable, SyntaxDatabase}; |
2 | use ra_syntax::ast; | 2 | use ra_syntax::{TextRange, AstNode, ast, SyntaxKind::{NAME, MODULE}}; |
3 | 3 | ||
4 | use crate::db::RootDatabase; | 4 | use ra_editor::find_node_at_offset; |
5 | 5 | ||
6 | pub fn goto_defenition(db: &RootDatabase, position: FilePosition, | 6 | use crate::{FilePosition, NavigationTarget, db::RootDatabase}; |
7 | |||
8 | pub(crate) fn goto_defenition( | ||
9 | db: &RootDatabase, | ||
10 | position: FilePosition, | ||
7 | ) -> Cancelable<Option<Vec<NavigationTarget>>> { | 11 | ) -> Cancelable<Option<Vec<NavigationTarget>>> { |
8 | let file = db.source_file(position.file_id); | 12 | let file = db.source_file(position.file_id); |
9 | let syntax = file.syntax(); | 13 | let syntax = file.syntax(); |
10 | if let Some(name_ref) = find_node_at_offset::<ast::NameRef>(syntax, position.offset) { | 14 | if let Some(name_ref) = find_node_at_offset::<ast::NameRef>(syntax, position.offset) { |
11 | return Ok(Some(reference_defenition(db, position.file_id, name_ref))); | 15 | return Ok(Some(reference_defenition(db, position.file_id, name_ref)?)); |
12 | } | 16 | } |
13 | if let Some(name) = find_node_at_offset::<ast::Name>(syntax, position.offset) { | 17 | if let Some(name) = find_node_at_offset::<ast::Name>(syntax, position.offset) { |
14 | return Ok(Some(name_defenition(db, position.file_idname))); | 18 | return name_defenition(db, position.file_id, name); |
15 | } | 19 | } |
16 | Ok(None) | 20 | Ok(None) |
17 | } | 21 | } |
18 | 22 | ||
19 | fn reference_defenition(db: &RootDatabase, file_id: FileId, name_ref: ast::NameRef) -> Cancelable<Vec<Nav>> { | 23 | pub(crate) fn reference_defenition( |
20 | if let Some(name_ref) = find_node_at_offset::<ast::NameRef>(syntax, position.offset) { | 24 | db: &RootDatabase, |
21 | let mut rr = ReferenceResolution::new(name_ref.syntax().range()); | 25 | file_id: FileId, |
22 | if let Some(fn_descr) = | 26 | name_ref: ast::NameRef, |
23 | source_binder::function_from_child_node(self, position.file_id, name_ref.syntax())? | 27 | ) -> Cancelable<Vec<NavigationTarget>> { |
24 | { | 28 | if let Some(fn_descr) = |
25 | let scope = fn_descr.scopes(self); | 29 | hir::source_binder::function_from_child_node(db, file_id, name_ref.syntax())? |
26 | // First try to resolve the symbol locally | 30 | { |
27 | if let Some(entry) = scope.resolve_local_name(name_ref) { | 31 | let scope = fn_descr.scopes(db); |
28 | rr.resolves_to.push(NavigationTarget { | 32 | // First try to resolve the symbol locally |
29 | file_id: position.file_id, | 33 | if let Some(entry) = scope.resolve_local_name(name_ref) { |
30 | name: entry.name().to_string().into(), | 34 | let nav = NavigationTarget { |
31 | range: entry.ptr().range(), | 35 | file_id, |
32 | kind: NAME, | 36 | name: entry.name().to_string().into(), |
33 | ptr: None, | 37 | range: entry.ptr().range(), |
34 | }); | 38 | kind: NAME, |
35 | return Ok(Some(rr)); | 39 | ptr: None, |
36 | }; | 40 | }; |
37 | } | 41 | return Ok(vec![nav]); |
38 | // If that fails try the index based approach. | 42 | }; |
39 | rr.resolves_to.extend( | ||
40 | self.index_resolve(name_ref)? | ||
41 | .into_iter() | ||
42 | .map(NavigationTarget::from_symbol), | ||
43 | ); | ||
44 | return Ok(Some(rr)); | ||
45 | } | 43 | } |
46 | if let Some(name) = find_node_at_offset::<ast::Name>(syntax, position.offset) { | 44 | // If that fails try the index based approach. |
47 | let mut rr = ReferenceResolution::new(name.syntax().range()); | 45 | let navs = db |
48 | if let Some(module) = name.syntax().parent().and_then(ast::Module::cast) { | 46 | .index_resolve(name_ref)? |
49 | if module.has_semi() { | 47 | .into_iter() |
50 | if let Some(child_module) = | 48 | .map(NavigationTarget::from_symbol) |
51 | source_binder::module_from_declaration(self, position.file_id, module)? | 49 | .collect(); |
52 | { | 50 | Ok(navs) |
53 | let file_id = child_module.file_id(); | 51 | } |
54 | let name = match child_module.name() { | 52 | |
55 | Some(name) => name.to_string().into(), | 53 | fn name_defenition( |
56 | None => "".into(), | 54 | db: &RootDatabase, |
57 | }; | 55 | file_id: FileId, |
58 | let symbol = NavigationTarget { | 56 | name: ast::Name, |
59 | file_id, | 57 | ) -> Cancelable<Option<Vec<NavigationTarget>>> { |
60 | name, | 58 | if let Some(module) = name.syntax().parent().and_then(ast::Module::cast) { |
61 | range: TextRange::offset_len(0.into(), 0.into()), | 59 | if module.has_semi() { |
62 | kind: MODULE, | 60 | if let Some(child_module) = |
63 | ptr: None, | 61 | hir::source_binder::module_from_declaration(db, file_id, module)? |
64 | }; | 62 | { |
65 | rr.resolves_to.push(symbol); | 63 | let file_id = child_module.file_id(); |
66 | return Ok(Some(rr)); | 64 | let name = match child_module.name() { |
67 | } | 65 | Some(name) => name.to_string().into(), |
68 | } | 66 | None => "".into(), |
67 | }; | ||
68 | let nav = NavigationTarget { | ||
69 | file_id, | ||
70 | name, | ||
71 | range: TextRange::offset_len(0.into(), 0.into()), | ||
72 | kind: MODULE, | ||
73 | ptr: None, | ||
74 | }; | ||
75 | return Ok(Some(vec![nav])); | ||
69 | } | 76 | } |
70 | } | 77 | } |
71 | Ok(None) | 78 | } |
79 | Ok(None) | ||
80 | } | ||
81 | |||
82 | #[cfg(test)] | ||
83 | mod tests { | ||
84 | use test_utils::assert_eq_dbg; | ||
85 | use crate::mock_analysis::analysis_and_position; | ||
72 | 86 | ||
87 | #[test] | ||
88 | fn goto_defenition_works_in_items() { | ||
89 | let (analysis, pos) = analysis_and_position( | ||
90 | " | ||
91 | //- /lib.rs | ||
92 | struct Foo; | ||
93 | enum E { X(Foo<|>) } | ||
94 | ", | ||
95 | ); | ||
96 | |||
97 | let symbols = analysis.goto_defenition(pos).unwrap().unwrap(); | ||
98 | assert_eq_dbg( | ||
99 | r#"[NavigationTarget { file_id: FileId(1), name: "Foo", | ||
100 | kind: STRUCT_DEF, range: [0; 11), | ||
101 | ptr: Some(LocalSyntaxPtr { range: [0; 11), kind: STRUCT_DEF }) }]"#, | ||
102 | &symbols, | ||
103 | ); | ||
104 | } | ||
105 | |||
106 | #[test] | ||
107 | fn goto_defenition_works_for_module_declaration() { | ||
108 | let (analysis, pos) = analysis_and_position( | ||
109 | " | ||
110 | //- /lib.rs | ||
111 | mod <|>foo; | ||
112 | //- /foo.rs | ||
113 | // empty | ||
114 | ", | ||
115 | ); | ||
116 | |||
117 | let symbols = analysis.goto_defenition(pos).unwrap().unwrap(); | ||
118 | assert_eq_dbg( | ||
119 | r#"[NavigationTarget { file_id: FileId(2), name: "foo", kind: MODULE, range: [0; 0), ptr: None }]"#, | ||
120 | &symbols, | ||
121 | ); | ||
122 | |||
123 | let (analysis, pos) = analysis_and_position( | ||
124 | " | ||
125 | //- /lib.rs | ||
126 | mod <|>foo; | ||
127 | //- /foo/mod.rs | ||
128 | // empty | ||
129 | ", | ||
130 | ); | ||
131 | |||
132 | let symbols = analysis.goto_defenition(pos).unwrap().unwrap(); | ||
133 | assert_eq_dbg( | ||
134 | r#"[NavigationTarget { file_id: FileId(2), name: "foo", kind: MODULE, range: [0; 0), ptr: None }]"#, | ||
135 | &symbols, | ||
136 | ); | ||
137 | } | ||
73 | } | 138 | } |
diff --git a/crates/ra_analysis/src/hover.rs b/crates/ra_analysis/src/hover.rs index 766fa0547..758de376e 100644 --- a/crates/ra_analysis/src/hover.rs +++ b/crates/ra_analysis/src/hover.rs | |||
@@ -1,4 +1,5 @@ | |||
1 | use ra_db::{Cancelable, SyntaxDatabase}; | 1 | use ra_db::{Cancelable, SyntaxDatabase}; |
2 | use ra_editor::find_node_at_offset; | ||
2 | use ra_syntax::{ | 3 | use ra_syntax::{ |
3 | AstNode, SyntaxNode, | 4 | AstNode, SyntaxNode, |
4 | ast::{self, NameOwner}, | 5 | ast::{self, NameOwner}, |
@@ -11,18 +12,18 @@ pub(crate) fn hover( | |||
11 | db: &RootDatabase, | 12 | db: &RootDatabase, |
12 | position: FilePosition, | 13 | position: FilePosition, |
13 | ) -> Cancelable<Option<RangeInfo<String>>> { | 14 | ) -> Cancelable<Option<RangeInfo<String>>> { |
15 | let file = db.source_file(position.file_id); | ||
14 | let mut res = Vec::new(); | 16 | let mut res = Vec::new(); |
15 | let range = if let Some(rr) = db.approximately_resolve_symbol(position)? { | 17 | let range = if let Some(name_ref) = |
16 | for nav in rr.resolves_to { | 18 | find_node_at_offset::<ast::NameRef>(file.syntax(), position.offset) |
19 | { | ||
20 | let navs = crate::goto_defenition::reference_defenition(db, position.file_id, name_ref)?; | ||
21 | for nav in navs { | ||
17 | res.extend(doc_text_for(db, nav)?) | 22 | res.extend(doc_text_for(db, nav)?) |
18 | } | 23 | } |
19 | rr.reference_range | 24 | name_ref.syntax().range() |
20 | } else { | 25 | } else { |
21 | let file = db.source_file(position.file_id); | 26 | let expr: ast::Expr = ctry!(find_node_at_offset(file.syntax(), position.offset)); |
22 | let expr: ast::Expr = ctry!(ra_editor::find_node_at_offset( | ||
23 | file.syntax(), | ||
24 | position.offset | ||
25 | )); | ||
26 | let frange = FileRange { | 27 | let frange = FileRange { |
27 | file_id: position.file_id, | 28 | file_id: position.file_id, |
28 | range: expr.syntax().range(), | 29 | range: expr.syntax().range(), |
diff --git a/crates/ra_analysis/src/imp.rs b/crates/ra_analysis/src/imp.rs index e2871451c..6ab3c5476 100644 --- a/crates/ra_analysis/src/imp.rs +++ b/crates/ra_analysis/src/imp.rs | |||
@@ -18,7 +18,7 @@ use crate::{ | |||
18 | AnalysisChange, | 18 | AnalysisChange, |
19 | Cancelable, NavigationTarget, | 19 | Cancelable, NavigationTarget, |
20 | CrateId, db, Diagnostic, FileId, FilePosition, FileRange, FileSystemEdit, | 20 | CrateId, db, Diagnostic, FileId, FilePosition, FileRange, FileSystemEdit, |
21 | Query, ReferenceResolution, RootChange, SourceChange, SourceFileEdit, | 21 | Query, RootChange, SourceChange, SourceFileEdit, |
22 | symbol_index::{LibrarySymbolsQuery, FileSymbol}, | 22 | symbol_index::{LibrarySymbolsQuery, FileSymbol}, |
23 | }; | 23 | }; |
24 | 24 | ||
@@ -139,66 +139,6 @@ impl db::RootDatabase { | |||
139 | pub(crate) fn crate_root(&self, crate_id: CrateId) -> FileId { | 139 | pub(crate) fn crate_root(&self, crate_id: CrateId) -> FileId { |
140 | self.crate_graph().crate_root(crate_id) | 140 | self.crate_graph().crate_root(crate_id) |
141 | } | 141 | } |
142 | pub(crate) fn approximately_resolve_symbol( | ||
143 | &self, | ||
144 | position: FilePosition, | ||
145 | ) -> Cancelable<Option<ReferenceResolution>> { | ||
146 | let file = self.source_file(position.file_id); | ||
147 | let syntax = file.syntax(); | ||
148 | if let Some(name_ref) = find_node_at_offset::<ast::NameRef>(syntax, position.offset) { | ||
149 | let mut rr = ReferenceResolution::new(name_ref.syntax().range()); | ||
150 | if let Some(fn_descr) = | ||
151 | source_binder::function_from_child_node(self, position.file_id, name_ref.syntax())? | ||
152 | { | ||
153 | let scope = fn_descr.scopes(self); | ||
154 | // First try to resolve the symbol locally | ||
155 | if let Some(entry) = scope.resolve_local_name(name_ref) { | ||
156 | rr.resolves_to.push(NavigationTarget { | ||
157 | file_id: position.file_id, | ||
158 | name: entry.name().to_string().into(), | ||
159 | range: entry.ptr().range(), | ||
160 | kind: NAME, | ||
161 | ptr: None, | ||
162 | }); | ||
163 | return Ok(Some(rr)); | ||
164 | }; | ||
165 | } | ||
166 | // If that fails try the index based approach. | ||
167 | rr.resolves_to.extend( | ||
168 | self.index_resolve(name_ref)? | ||
169 | .into_iter() | ||
170 | .map(NavigationTarget::from_symbol), | ||
171 | ); | ||
172 | return Ok(Some(rr)); | ||
173 | } | ||
174 | if let Some(name) = find_node_at_offset::<ast::Name>(syntax, position.offset) { | ||
175 | let mut rr = ReferenceResolution::new(name.syntax().range()); | ||
176 | if let Some(module) = name.syntax().parent().and_then(ast::Module::cast) { | ||
177 | if module.has_semi() { | ||
178 | if let Some(child_module) = | ||
179 | source_binder::module_from_declaration(self, position.file_id, module)? | ||
180 | { | ||
181 | let file_id = child_module.file_id(); | ||
182 | let name = match child_module.name() { | ||
183 | Some(name) => name.to_string().into(), | ||
184 | None => "".into(), | ||
185 | }; | ||
186 | let symbol = NavigationTarget { | ||
187 | file_id, | ||
188 | name, | ||
189 | range: TextRange::offset_len(0.into(), 0.into()), | ||
190 | kind: MODULE, | ||
191 | ptr: None, | ||
192 | }; | ||
193 | rr.resolves_to.push(symbol); | ||
194 | return Ok(Some(rr)); | ||
195 | } | ||
196 | } | ||
197 | } | ||
198 | } | ||
199 | Ok(None) | ||
200 | } | ||
201 | |||
202 | pub(crate) fn find_all_refs( | 142 | pub(crate) fn find_all_refs( |
203 | &self, | 143 | &self, |
204 | position: FilePosition, | 144 | position: FilePosition, |
@@ -416,7 +356,7 @@ impl db::RootDatabase { | |||
416 | .collect::<Vec<_>>(); | 356 | .collect::<Vec<_>>(); |
417 | Ok(res) | 357 | Ok(res) |
418 | } | 358 | } |
419 | fn index_resolve(&self, name_ref: ast::NameRef) -> Cancelable<Vec<FileSymbol>> { | 359 | pub(crate) fn index_resolve(&self, name_ref: ast::NameRef) -> Cancelable<Vec<FileSymbol>> { |
420 | let name = name_ref.text(); | 360 | let name = name_ref.text(); |
421 | let mut query = Query::new(name.to_string()); | 361 | let mut query = Query::new(name.to_string()); |
422 | query.exact(); | 362 | query.exact(); |
diff --git a/crates/ra_analysis/src/lib.rs b/crates/ra_analysis/src/lib.rs index b068119d2..4d895b004 100644 --- a/crates/ra_analysis/src/lib.rs +++ b/crates/ra_analysis/src/lib.rs | |||
@@ -15,6 +15,7 @@ macro_rules! ctry { | |||
15 | mod db; | 15 | mod db; |
16 | mod imp; | 16 | mod imp; |
17 | mod completion; | 17 | mod completion; |
18 | mod goto_defenition; | ||
18 | mod symbol_index; | 19 | mod symbol_index; |
19 | pub mod mock_analysis; | 20 | pub mod mock_analysis; |
20 | mod runnables; | 21 | mod runnables; |
@@ -273,26 +274,6 @@ impl<T> RangeInfo<T> { | |||
273 | } | 274 | } |
274 | } | 275 | } |
275 | 276 | ||
276 | /// Result of "goto def" query. | ||
277 | #[derive(Debug)] | ||
278 | pub struct ReferenceResolution { | ||
279 | /// The range of the reference itself. Client does not know what constitutes | ||
280 | /// a reference, it handles us only the offset. It's helpful to tell the | ||
281 | /// client where the reference was. | ||
282 | pub reference_range: TextRange, | ||
283 | /// What this reference resolves to. | ||
284 | pub resolves_to: Vec<NavigationTarget>, | ||
285 | } | ||
286 | |||
287 | impl ReferenceResolution { | ||
288 | fn new(reference_range: TextRange) -> ReferenceResolution { | ||
289 | ReferenceResolution { | ||
290 | reference_range, | ||
291 | resolves_to: Vec::new(), | ||
292 | } | ||
293 | } | ||
294 | } | ||
295 | |||
296 | /// `AnalysisHost` stores the current state of the world. | 277 | /// `AnalysisHost` stores the current state of the world. |
297 | #[derive(Debug, Default)] | 278 | #[derive(Debug, Default)] |
298 | pub struct AnalysisHost { | 279 | pub struct AnalysisHost { |
@@ -392,12 +373,11 @@ impl Analysis { | |||
392 | .collect(); | 373 | .collect(); |
393 | Ok(res) | 374 | Ok(res) |
394 | } | 375 | } |
395 | /// Resolves reference to definition, but does not gurantee correctness. | 376 | pub fn goto_defenition( |
396 | pub fn approximately_resolve_symbol( | ||
397 | &self, | 377 | &self, |
398 | position: FilePosition, | 378 | position: FilePosition, |
399 | ) -> Cancelable<Option<ReferenceResolution>> { | 379 | ) -> Cancelable<Option<Vec<NavigationTarget>>> { |
400 | self.db.approximately_resolve_symbol(position) | 380 | goto_defenition::goto_defenition(&*self.db, position) |
401 | } | 381 | } |
402 | /// Finds all usages of the reference at point. | 382 | /// Finds all usages of the reference at point. |
403 | pub fn find_all_refs(&self, position: FilePosition) -> Cancelable<Vec<(FileId, TextRange)>> { | 383 | pub fn find_all_refs(&self, position: FilePosition) -> Cancelable<Vec<(FileId, TextRange)>> { |
diff --git a/crates/ra_analysis/tests/test/main.rs b/crates/ra_analysis/tests/test/main.rs index beeae1e19..e15035304 100644 --- a/crates/ra_analysis/tests/test/main.rs +++ b/crates/ra_analysis/tests/test/main.rs | |||
@@ -15,65 +15,6 @@ fn get_signature(text: &str) -> (FnSignatureInfo, Option<usize>) { | |||
15 | } | 15 | } |
16 | 16 | ||
17 | #[test] | 17 | #[test] |
18 | fn approximate_resolve_works_in_items() { | ||
19 | let (analysis, pos) = analysis_and_position( | ||
20 | " | ||
21 | //- /lib.rs | ||
22 | struct Foo; | ||
23 | enum E { X(Foo<|>) } | ||
24 | ", | ||
25 | ); | ||
26 | |||
27 | let symbols = analysis.approximately_resolve_symbol(pos).unwrap().unwrap(); | ||
28 | assert_eq_dbg( | ||
29 | r#"ReferenceResolution { | ||
30 | reference_range: [23; 26), | ||
31 | resolves_to: [NavigationTarget { file_id: FileId(1), name: "Foo", kind: STRUCT_DEF, range: [0; 11), ptr: Some(LocalSyntaxPtr { range: [0; 11), kind: STRUCT_DEF }) }] | ||
32 | }"#, | ||
33 | &symbols, | ||
34 | ); | ||
35 | } | ||
36 | |||
37 | #[test] | ||
38 | fn test_resolve_module() { | ||
39 | let (analysis, pos) = analysis_and_position( | ||
40 | " | ||
41 | //- /lib.rs | ||
42 | mod <|>foo; | ||
43 | //- /foo.rs | ||
44 | // empty | ||
45 | ", | ||
46 | ); | ||
47 | |||
48 | let symbols = analysis.approximately_resolve_symbol(pos).unwrap().unwrap(); | ||
49 | assert_eq_dbg( | ||
50 | r#"ReferenceResolution { | ||
51 | reference_range: [4; 7), | ||
52 | resolves_to: [NavigationTarget { file_id: FileId(2), name: "foo", kind: MODULE, range: [0; 0), ptr: None }] | ||
53 | }"#, | ||
54 | &symbols, | ||
55 | ); | ||
56 | |||
57 | let (analysis, pos) = analysis_and_position( | ||
58 | " | ||
59 | //- /lib.rs | ||
60 | mod <|>foo; | ||
61 | //- /foo/mod.rs | ||
62 | // empty | ||
63 | ", | ||
64 | ); | ||
65 | |||
66 | let symbols = analysis.approximately_resolve_symbol(pos).unwrap().unwrap(); | ||
67 | assert_eq_dbg( | ||
68 | r#"ReferenceResolution { | ||
69 | reference_range: [4; 7), | ||
70 | resolves_to: [NavigationTarget { file_id: FileId(2), name: "foo", kind: MODULE, range: [0; 0), ptr: None }] | ||
71 | }"#, | ||
72 | &symbols, | ||
73 | ); | ||
74 | } | ||
75 | |||
76 | #[test] | ||
77 | fn test_unresolved_module_diagnostic() { | 18 | fn test_unresolved_module_diagnostic() { |
78 | let (analysis, file_id) = single_file("mod foo;"); | 19 | let (analysis, file_id) = single_file("mod foo;"); |
79 | let diagnostics = analysis.diagnostics(file_id).unwrap(); | 20 | let diagnostics = analysis.diagnostics(file_id).unwrap(); |
diff --git a/crates/ra_lsp_server/src/main_loop/handlers.rs b/crates/ra_lsp_server/src/main_loop/handlers.rs index ffca3f51c..1baed73ad 100644 --- a/crates/ra_lsp_server/src/main_loop/handlers.rs +++ b/crates/ra_lsp_server/src/main_loop/handlers.rs | |||
@@ -207,12 +207,11 @@ pub fn handle_goto_definition( | |||
207 | params: req::TextDocumentPositionParams, | 207 | params: req::TextDocumentPositionParams, |
208 | ) -> Result<Option<req::GotoDefinitionResponse>> { | 208 | ) -> Result<Option<req::GotoDefinitionResponse>> { |
209 | let position = params.try_conv_with(&world)?; | 209 | let position = params.try_conv_with(&world)?; |
210 | let rr = match world.analysis().approximately_resolve_symbol(position)? { | 210 | let navs = match world.analysis().goto_defenition(position)? { |
211 | None => return Ok(None), | 211 | None => return Ok(None), |
212 | Some(it) => it, | 212 | Some(it) => it, |
213 | }; | 213 | }; |
214 | let res = rr | 214 | let res = navs |
215 | .resolves_to | ||
216 | .into_iter() | 215 | .into_iter() |
217 | .map(|nav| nav.try_conv_with(&world)) | 216 | .map(|nav| nav.try_conv_with(&world)) |
218 | .collect::<Result<Vec<_>>>()?; | 217 | .collect::<Result<Vec<_>>>()?; |