From a6590ce2318676210b6b5a197b76b5861a3407c9 Mon Sep 17 00:00:00 2001 From: Florian Diebold Date: Tue, 8 Jan 2019 00:30:49 +0100 Subject: Use name resolution for goto definition --- crates/ra_ide_api/src/goto_definition.rs | 43 ++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) (limited to 'crates/ra_ide_api/src/goto_definition.rs') diff --git a/crates/ra_ide_api/src/goto_definition.rs b/crates/ra_ide_api/src/goto_definition.rs index 0d524b6f1..eaddd5083 100644 --- a/crates/ra_ide_api/src/goto_definition.rs +++ b/crates/ra_ide_api/src/goto_definition.rs @@ -42,6 +42,24 @@ pub(crate) fn reference_definition( return Ok(vec![nav]); }; } + // Then try module name resolution + if let Some(module) = + hir::source_binder::module_from_child_node(db, file_id, name_ref.syntax())? + { + if let Some(path) = name_ref + .syntax() + .ancestors() + .find_map(ast::Path::cast) + .and_then(hir::Path::from_ast) + { + let resolved = module.resolve_path(db, &path)?; + if let Some(def_id) = resolved.take_types().or(resolved.take_values()) { + if let Some(target) = NavigationTarget::from_def(db, def_id.resolve(db)?)? { + return Ok(vec![target]); + } + } + } + } // If that fails try the index based approach. let navs = db .index_resolve(name_ref)? @@ -104,6 +122,31 @@ mod tests { ); } + #[test] + fn goto_definition_resolves_correct_name() { + let (analysis, pos) = analysis_and_position( + " + //- /lib.rs + use a::Foo; + mod a; + mod b; + enum E { X(Foo<|>) } + //- /a.rs + struct Foo; + //- /b.rs + struct Foo; + ", + ); + + let symbols = analysis.goto_definition(pos).unwrap().unwrap(); + assert_eq_dbg( + r#"[NavigationTarget { file_id: FileId(2), name: "Foo", + kind: STRUCT_DEF, range: [0; 11), + ptr: Some(LocalSyntaxPtr { range: [0; 11), kind: STRUCT_DEF }) }]"#, + &symbols, + ); + } + #[test] fn goto_definition_works_for_module_declaration() { let (analysis, pos) = analysis_and_position( -- cgit v1.2.3