Skip to content

Commit 65e31a1

Browse files
bors[bot]sasurau4
andauthored
Merge #6875
6875: Add find usages for enum constructors r=matklad a=sasurau4 Fix #2549 for enum Co-authored-by: Daiki Ihara <[email protected]>
2 parents 67e299f + 36a9daa commit 65e31a1

File tree

2 files changed

+130
-0
lines changed

2 files changed

+130
-0
lines changed

crates/ide/src/references.rs

Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,9 @@ pub(crate) fn find_all_refs(
9797
get_struct_def_name_for_struct_literal_search(&sema, &syntax, position)
9898
{
9999
(Some(name), ReferenceKind::StructLiteral)
100+
} else if let Some(name) = get_enum_def_name_for_struct_literal_search(&sema, &syntax, position)
101+
{
102+
(Some(name), ReferenceKind::EnumLiteral)
100103
} else {
101104
(
102105
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(
198201
None
199202
}
200203

204+
fn get_enum_def_name_for_struct_literal_search(
205+
sema: &Semantics<RootDatabase>,
206+
syntax: &SyntaxNode,
207+
position: FilePosition,
208+
) -> Option<ast::Name> {
209+
if let TokenAtOffset::Between(ref left, ref right) = syntax.token_at_offset(position.offset) {
210+
if right.kind() != SyntaxKind::L_CURLY && right.kind() != SyntaxKind::L_PAREN {
211+
return None;
212+
}
213+
if let Some(name) =
214+
sema.find_node_at_offset_with_descend::<ast::Name>(&syntax, left.text_range().start())
215+
{
216+
return name.syntax().ancestors().find_map(ast::Enum::cast).and_then(|l| l.name());
217+
}
218+
if sema
219+
.find_node_at_offset_with_descend::<ast::GenericParamList>(
220+
&syntax,
221+
left.text_range().start(),
222+
)
223+
.is_some()
224+
{
225+
return left.ancestors().find_map(ast::Enum::cast).and_then(|l| l.name());
226+
}
227+
}
228+
None
229+
}
230+
201231
fn try_find_self_references(
202232
syntax: &SyntaxNode,
203233
position: FilePosition,
@@ -356,6 +386,91 @@ fn main() {
356386
);
357387
}
358388

389+
#[test]
390+
fn test_enum_after_space() {
391+
check(
392+
r#"
393+
enum Foo <|>{
394+
A,
395+
B,
396+
}
397+
fn main() {
398+
let f: Foo;
399+
f = Foo::A;
400+
}
401+
"#,
402+
expect![[r#"
403+
Foo ENUM FileId(0) 0..26 5..8 Other
404+
405+
FileId(0) 63..66 EnumLiteral
406+
"#]],
407+
);
408+
}
409+
410+
#[test]
411+
fn test_enum_before_space() {
412+
check(
413+
r#"
414+
enum Foo<|> {
415+
A,
416+
B,
417+
}
418+
fn main() {
419+
let f: Foo;
420+
f = Foo::A;
421+
}
422+
"#,
423+
expect![[r#"
424+
Foo ENUM FileId(0) 0..26 5..8 Other
425+
426+
FileId(0) 50..53 Other
427+
FileId(0) 63..66 EnumLiteral
428+
"#]],
429+
);
430+
}
431+
432+
#[test]
433+
fn test_enum_with_generic_type() {
434+
check(
435+
r#"
436+
enum Foo<T> <|>{
437+
A(T),
438+
B,
439+
}
440+
fn main() {
441+
let f: Foo<i8>;
442+
f = Foo::A(1);
443+
}
444+
"#,
445+
expect![[r#"
446+
Foo ENUM FileId(0) 0..32 5..8 Other
447+
448+
FileId(0) 73..76 EnumLiteral
449+
"#]],
450+
);
451+
}
452+
453+
#[test]
454+
fn test_enum_for_tuple() {
455+
check(
456+
r#"
457+
enum Foo<|>{
458+
A(i8),
459+
B(i8),
460+
}
461+
fn main() {
462+
let f: Foo;
463+
f = Foo::A(1);
464+
}
465+
"#,
466+
expect![[r#"
467+
Foo ENUM FileId(0) 0..33 5..8 Other
468+
469+
FileId(0) 70..73 EnumLiteral
470+
"#]],
471+
);
472+
}
473+
359474
#[test]
360475
fn test_find_all_refs_for_local() {
361476
check(

crates/ide_db/src/search.rs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ pub enum ReferenceKind {
3232
StructLiteral,
3333
RecordFieldExprOrPat,
3434
SelfKw,
35+
EnumLiteral,
3536
Other,
3637
}
3738

@@ -284,6 +285,8 @@ impl<'a> FindUsages<'a> {
284285
ReferenceKind::RecordFieldExprOrPat
285286
} else if is_record_lit_name_ref(&name_ref) || is_call_expr_name_ref(&name_ref) {
286287
ReferenceKind::StructLiteral
288+
} else if is_enum_lit_name_ref(&name_ref) {
289+
ReferenceKind::EnumLiteral
287290
} else {
288291
ReferenceKind::Other
289292
};
@@ -402,3 +405,15 @@ fn is_record_field_expr_or_pat(name_ref: &ast::NameRef) -> bool {
402405
false
403406
}
404407
}
408+
409+
fn is_enum_lit_name_ref(name_ref: &ast::NameRef) -> bool {
410+
name_ref
411+
.syntax()
412+
.ancestors()
413+
.find_map(ast::PathExpr::cast)
414+
.and_then(|p| p.path())
415+
.and_then(|p| p.qualifier())
416+
.and_then(|p| p.segment())
417+
.map(|p| p.name_ref().as_ref() == Some(name_ref))
418+
.unwrap_or(false)
419+
}

0 commit comments

Comments
 (0)