mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-30 02:33:55 +00:00
Fix goto def not working when cursor was over the name of a def
We now allow goto_definition to return the named NavigationTarget if the cursor is on the name of a definition.
This commit is contained in:
parent
3d8a0982a1
commit
2a3abe2ce3
@ -1,7 +1,8 @@
|
||||
use ra_db::{FileId, SourceDatabase};
|
||||
use ra_syntax::{
|
||||
AstNode, ast,
|
||||
algo::find_node_at_offset,
|
||||
AstNode, ast::{self, NameOwner},
|
||||
algo::{find_node_at_offset, visit::{visitor, Visitor}},
|
||||
SyntaxNode,
|
||||
};
|
||||
use test_utils::tested_by;
|
||||
use hir::Resolution;
|
||||
@ -114,7 +115,9 @@ fn name_definition(
|
||||
file_id: FileId,
|
||||
name: &ast::Name,
|
||||
) -> Option<Vec<NavigationTarget>> {
|
||||
if let Some(module) = name.syntax().parent().and_then(ast::Module::cast) {
|
||||
let parent = name.syntax().parent()?;
|
||||
|
||||
if let Some(module) = ast::Module::cast(&parent) {
|
||||
if module.has_semi() {
|
||||
if let Some(child_module) =
|
||||
hir::source_binder::module_from_declaration(db, file_id, module)
|
||||
@ -124,9 +127,33 @@ fn name_definition(
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(nav) = named_target(file_id, &parent) {
|
||||
return Some(vec![nav]);
|
||||
}
|
||||
|
||||
None
|
||||
}
|
||||
|
||||
fn named_target(file_id: FileId, node: &SyntaxNode) -> Option<NavigationTarget> {
|
||||
fn to_nav_target<N: NameOwner>(node: &N, file_id: FileId) -> Option<NavigationTarget> {
|
||||
Some(NavigationTarget::from_named(file_id, node))
|
||||
}
|
||||
|
||||
visitor()
|
||||
.visit(|n: &ast::StructDef| to_nav_target(n, file_id))
|
||||
.visit(|n: &ast::EnumDef| to_nav_target(n, file_id))
|
||||
.visit(|n: &ast::EnumVariant| to_nav_target(n, file_id))
|
||||
.visit(|n: &ast::FnDef| to_nav_target(n, file_id))
|
||||
.visit(|n: &ast::TypeDef| to_nav_target(n, file_id))
|
||||
.visit(|n: &ast::ConstDef| to_nav_target(n, file_id))
|
||||
.visit(|n: &ast::StaticDef| to_nav_target(n, file_id))
|
||||
.visit(|n: &ast::TraitDef| to_nav_target(n, file_id))
|
||||
.visit(|n: &ast::NamedFieldDef| to_nav_target(n, file_id))
|
||||
.visit(|n: &ast::Module| to_nav_target(n, file_id))
|
||||
.accept(node)?
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use test_utils::covers;
|
||||
@ -231,4 +258,98 @@ mod tests {
|
||||
"spam NAMED_FIELD_DEF FileId(1) [17; 26) [17; 21)",
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn goto_definition_works_when_used_on_definition_name_itself() {
|
||||
check_goto(
|
||||
"
|
||||
//- /lib.rs
|
||||
struct Foo<|> { value: u32 }
|
||||
",
|
||||
"Foo STRUCT_DEF FileId(1) [0; 25) [7; 10)",
|
||||
);
|
||||
|
||||
check_goto(
|
||||
r#"
|
||||
//- /lib.rs
|
||||
struct Foo {
|
||||
field<|>: string,
|
||||
}
|
||||
"#,
|
||||
"field NAMED_FIELD_DEF FileId(1) [17; 30) [17; 22)",
|
||||
);
|
||||
|
||||
check_goto(
|
||||
"
|
||||
//- /lib.rs
|
||||
fn foo_test<|>() {
|
||||
}
|
||||
",
|
||||
"foo_test FN_DEF FileId(1) [0; 17) [3; 11)",
|
||||
);
|
||||
|
||||
check_goto(
|
||||
"
|
||||
//- /lib.rs
|
||||
enum Foo<|> {
|
||||
Variant,
|
||||
}
|
||||
",
|
||||
"Foo ENUM_DEF FileId(1) [0; 25) [5; 8)",
|
||||
);
|
||||
|
||||
check_goto(
|
||||
"
|
||||
//- /lib.rs
|
||||
enum Foo {
|
||||
Variant1,
|
||||
Variant2<|>,
|
||||
Variant3,
|
||||
}
|
||||
",
|
||||
"Variant2 ENUM_VARIANT FileId(1) [29; 37) [29; 37)",
|
||||
);
|
||||
|
||||
check_goto(
|
||||
r#"
|
||||
//- /lib.rs
|
||||
static inner<|>: &str = "";
|
||||
"#,
|
||||
"inner STATIC_DEF FileId(1) [0; 24) [7; 12)",
|
||||
);
|
||||
|
||||
check_goto(
|
||||
r#"
|
||||
//- /lib.rs
|
||||
const inner<|>: &str = "";
|
||||
"#,
|
||||
"inner CONST_DEF FileId(1) [0; 23) [6; 11)",
|
||||
);
|
||||
|
||||
check_goto(
|
||||
r#"
|
||||
//- /lib.rs
|
||||
type Thing<|> = Option<()>;
|
||||
"#,
|
||||
"Thing TYPE_DEF FileId(1) [0; 24) [5; 10)",
|
||||
);
|
||||
|
||||
check_goto(
|
||||
r#"
|
||||
//- /lib.rs
|
||||
trait Foo<|> {
|
||||
}
|
||||
"#,
|
||||
"Foo TRAIT_DEF FileId(1) [0; 13) [6; 9)",
|
||||
);
|
||||
|
||||
check_goto(
|
||||
r#"
|
||||
//- /lib.rs
|
||||
mod bar<|> {
|
||||
}
|
||||
"#,
|
||||
"bar MODULE FileId(1) [0; 11) [4; 7)",
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -198,7 +198,8 @@ impl NavigationTarget {
|
||||
buf
|
||||
}
|
||||
|
||||
fn from_named(file_id: FileId, node: &impl ast::NameOwner) -> NavigationTarget {
|
||||
/// Allows `NavigationTarget` to be created from a `NameOwner`
|
||||
pub(crate) fn from_named(file_id: FileId, node: &impl ast::NameOwner) -> NavigationTarget {
|
||||
let name = node.name().map(|it| it.text().clone()).unwrap_or_default();
|
||||
let focus_range = node.name().map(|it| it.syntax().range());
|
||||
NavigationTarget::from_syntax(file_id, name, focus_range, node.syntax())
|
||||
|
Loading…
Reference in New Issue
Block a user