mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-09-30 22:01:37 +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)
|
get_struct_def_name_for_struct_literal_search(&sema, &syntax, position)
|
||||||
{
|
{
|
||||||
(Some(name), ReferenceKind::StructLiteral)
|
(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 {
|
} else {
|
||||||
(
|
(
|
||||||
sema.find_node_at_offset_with_descend::<ast::Name>(&syntax, position.offset),
|
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
|
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(
|
fn try_find_self_references(
|
||||||
syntax: &SyntaxNode,
|
syntax: &SyntaxNode,
|
||||||
position: FilePosition,
|
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]
|
#[test]
|
||||||
fn test_find_all_refs_for_local() {
|
fn test_find_all_refs_for_local() {
|
||||||
check(
|
check(
|
||||||
|
|
|
@ -32,6 +32,7 @@ pub enum ReferenceKind {
|
||||||
StructLiteral,
|
StructLiteral,
|
||||||
RecordFieldExprOrPat,
|
RecordFieldExprOrPat,
|
||||||
SelfKw,
|
SelfKw,
|
||||||
|
EnumLiteral,
|
||||||
Other,
|
Other,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -284,6 +285,8 @@ impl<'a> FindUsages<'a> {
|
||||||
ReferenceKind::RecordFieldExprOrPat
|
ReferenceKind::RecordFieldExprOrPat
|
||||||
} else if is_record_lit_name_ref(&name_ref) || is_call_expr_name_ref(&name_ref) {
|
} else if is_record_lit_name_ref(&name_ref) || is_call_expr_name_ref(&name_ref) {
|
||||||
ReferenceKind::StructLiteral
|
ReferenceKind::StructLiteral
|
||||||
|
} else if is_enum_lit_name_ref(&name_ref) {
|
||||||
|
ReferenceKind::EnumLiteral
|
||||||
} else {
|
} else {
|
||||||
ReferenceKind::Other
|
ReferenceKind::Other
|
||||||
};
|
};
|
||||||
|
@ -402,3 +405,15 @@ fn is_record_field_expr_or_pat(name_ref: &ast::NameRef) -> bool {
|
||||||
false
|
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…
Add table
Add a link
Reference in a new issue