mirror of
https://github.com/rust-lang/rust-analyzer
synced 2024-11-10 15:14:32 +00:00
Add find usages for enum constructors
This commit is contained in:
parent
8cba423109
commit
36a9daac70
2 changed files with 130 additions and 0 deletions
|
@ -97,6 +97,9 @@ pub(crate) fn find_all_refs(
|
|||
get_struct_def_name_for_struct_literal_search(&sema, &syntax, position)
|
||||
{
|
||||
(Some(name), ReferenceKind::StructLiteral)
|
||||
} else if let Some(name) = get_enum_def_name_for_struct_literal_search(&sema, &syntax, position)
|
||||
{
|
||||
(Some(name), ReferenceKind::EnumLiteral)
|
||||
} else {
|
||||
(
|
||||
sema.find_node_at_offset_with_descend::<ast::Name>(&syntax, position.offset),
|
||||
|
@ -198,6 +201,33 @@ fn get_struct_def_name_for_struct_literal_search(
|
|||
None
|
||||
}
|
||||
|
||||
fn get_enum_def_name_for_struct_literal_search(
|
||||
sema: &Semantics<RootDatabase>,
|
||||
syntax: &SyntaxNode,
|
||||
position: FilePosition,
|
||||
) -> Option<ast::Name> {
|
||||
if let TokenAtOffset::Between(ref left, ref right) = syntax.token_at_offset(position.offset) {
|
||||
if right.kind() != SyntaxKind::L_CURLY && right.kind() != SyntaxKind::L_PAREN {
|
||||
return None;
|
||||
}
|
||||
if let Some(name) =
|
||||
sema.find_node_at_offset_with_descend::<ast::Name>(&syntax, left.text_range().start())
|
||||
{
|
||||
return name.syntax().ancestors().find_map(ast::Enum::cast).and_then(|l| l.name());
|
||||
}
|
||||
if sema
|
||||
.find_node_at_offset_with_descend::<ast::GenericParamList>(
|
||||
&syntax,
|
||||
left.text_range().start(),
|
||||
)
|
||||
.is_some()
|
||||
{
|
||||
return left.ancestors().find_map(ast::Enum::cast).and_then(|l| l.name());
|
||||
}
|
||||
}
|
||||
None
|
||||
}
|
||||
|
||||
fn try_find_self_references(
|
||||
syntax: &SyntaxNode,
|
||||
position: FilePosition,
|
||||
|
@ -356,6 +386,91 @@ fn main() {
|
|||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_enum_after_space() {
|
||||
check(
|
||||
r#"
|
||||
enum Foo <|>{
|
||||
A,
|
||||
B,
|
||||
}
|
||||
fn main() {
|
||||
let f: Foo;
|
||||
f = Foo::A;
|
||||
}
|
||||
"#,
|
||||
expect![[r#"
|
||||
Foo ENUM FileId(0) 0..26 5..8 Other
|
||||
|
||||
FileId(0) 63..66 EnumLiteral
|
||||
"#]],
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_enum_before_space() {
|
||||
check(
|
||||
r#"
|
||||
enum Foo<|> {
|
||||
A,
|
||||
B,
|
||||
}
|
||||
fn main() {
|
||||
let f: Foo;
|
||||
f = Foo::A;
|
||||
}
|
||||
"#,
|
||||
expect![[r#"
|
||||
Foo ENUM FileId(0) 0..26 5..8 Other
|
||||
|
||||
FileId(0) 50..53 Other
|
||||
FileId(0) 63..66 EnumLiteral
|
||||
"#]],
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_enum_with_generic_type() {
|
||||
check(
|
||||
r#"
|
||||
enum Foo<T> <|>{
|
||||
A(T),
|
||||
B,
|
||||
}
|
||||
fn main() {
|
||||
let f: Foo<i8>;
|
||||
f = Foo::A(1);
|
||||
}
|
||||
"#,
|
||||
expect![[r#"
|
||||
Foo ENUM FileId(0) 0..32 5..8 Other
|
||||
|
||||
FileId(0) 73..76 EnumLiteral
|
||||
"#]],
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_enum_for_tuple() {
|
||||
check(
|
||||
r#"
|
||||
enum Foo<|>{
|
||||
A(i8),
|
||||
B(i8),
|
||||
}
|
||||
fn main() {
|
||||
let f: Foo;
|
||||
f = Foo::A(1);
|
||||
}
|
||||
"#,
|
||||
expect![[r#"
|
||||
Foo ENUM FileId(0) 0..33 5..8 Other
|
||||
|
||||
FileId(0) 70..73 EnumLiteral
|
||||
"#]],
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_find_all_refs_for_local() {
|
||||
check(
|
||||
|
|
|
@ -32,6 +32,7 @@ pub enum ReferenceKind {
|
|||
StructLiteral,
|
||||
RecordFieldExprOrPat,
|
||||
SelfKw,
|
||||
EnumLiteral,
|
||||
Other,
|
||||
}
|
||||
|
||||
|
@ -284,6 +285,8 @@ impl<'a> FindUsages<'a> {
|
|||
ReferenceKind::RecordFieldExprOrPat
|
||||
} else if is_record_lit_name_ref(&name_ref) || is_call_expr_name_ref(&name_ref) {
|
||||
ReferenceKind::StructLiteral
|
||||
} else if is_enum_lit_name_ref(&name_ref) {
|
||||
ReferenceKind::EnumLiteral
|
||||
} else {
|
||||
ReferenceKind::Other
|
||||
};
|
||||
|
@ -402,3 +405,15 @@ fn is_record_field_expr_or_pat(name_ref: &ast::NameRef) -> bool {
|
|||
false
|
||||
}
|
||||
}
|
||||
|
||||
fn is_enum_lit_name_ref(name_ref: &ast::NameRef) -> bool {
|
||||
name_ref
|
||||
.syntax()
|
||||
.ancestors()
|
||||
.find_map(ast::PathExpr::cast)
|
||||
.and_then(|p| p.path())
|
||||
.and_then(|p| p.qualifier())
|
||||
.and_then(|p| p.segment())
|
||||
.map(|p| p.name_ref().as_ref() == Some(name_ref))
|
||||
.unwrap_or(false)
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue