Use name resolution for goto definition

This commit is contained in:
Florian Diebold 2019-01-08 00:30:49 +01:00 committed by Florian Diebold
parent dc2a8d5acc
commit a6590ce231
7 changed files with 179 additions and 16 deletions

View file

@ -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(