aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--crates/ide/src/references.rs115
-rw-r--r--crates/ide_db/src/search.rs15
2 files changed, 130 insertions, 0 deletions
diff --git a/crates/ide/src/references.rs b/crates/ide/src/references.rs
index 7395b81bd..66f0f7950 100644
--- a/crates/ide/src/references.rs
+++ b/crates/ide/src/references.rs
@@ -97,6 +97,9 @@ pub(crate) fn find_all_refs(
97 get_struct_def_name_for_struct_literal_search(&sema, &syntax, position) 97 get_struct_def_name_for_struct_literal_search(&sema, &syntax, position)
98 { 98 {
99 (Some(name), ReferenceKind::StructLiteral) 99 (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)
100 } else { 103 } else {
101 ( 104 (
102 sema.find_node_at_offset_with_descend::<ast::Name>(&syntax, position.offset), 105 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(
198 None 201 None
199} 202}
200 203
204fn 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
201fn try_find_self_references( 231fn try_find_self_references(
202 syntax: &SyntaxNode, 232 syntax: &SyntaxNode,
203 position: FilePosition, 233 position: FilePosition,
@@ -357,6 +387,91 @@ fn main() {
357 } 387 }
358 388
359 #[test] 389 #[test]
390 fn test_enum_after_space() {
391 check(
392 r#"
393enum Foo <|>{
394 A,
395 B,
396}
397fn 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#"
414enum Foo<|> {
415 A,
416 B,
417}
418fn 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#"
436enum Foo<T> <|>{
437 A(T),
438 B,
439}
440fn 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#"
457enum Foo<|>{
458 A(i8),
459 B(i8),
460}
461fn 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
474 #[test]
360 fn test_find_all_refs_for_local() { 475 fn test_find_all_refs_for_local() {
361 check( 476 check(
362 r#" 477 r#"
diff --git a/crates/ide_db/src/search.rs b/crates/ide_db/src/search.rs
index 607185ca9..3936c7390 100644
--- a/crates/ide_db/src/search.rs
+++ b/crates/ide_db/src/search.rs
@@ -32,6 +32,7 @@ pub enum ReferenceKind {
32 StructLiteral, 32 StructLiteral,
33 RecordFieldExprOrPat, 33 RecordFieldExprOrPat,
34 SelfKw, 34 SelfKw,
35 EnumLiteral,
35 Other, 36 Other,
36} 37}
37 38
@@ -284,6 +285,8 @@ impl<'a> FindUsages<'a> {
284 ReferenceKind::RecordFieldExprOrPat 285 ReferenceKind::RecordFieldExprOrPat
285 } else if is_record_lit_name_ref(&name_ref) || is_call_expr_name_ref(&name_ref) { 286 } else if is_record_lit_name_ref(&name_ref) || is_call_expr_name_ref(&name_ref) {
286 ReferenceKind::StructLiteral 287 ReferenceKind::StructLiteral
288 } else if is_enum_lit_name_ref(&name_ref) {
289 ReferenceKind::EnumLiteral
287 } else { 290 } else {
288 ReferenceKind::Other 291 ReferenceKind::Other
289 }; 292 };
@@ -402,3 +405,15 @@ fn is_record_field_expr_or_pat(name_ref: &ast::NameRef) -> bool {
402 false 405 false
403 } 406 }
404} 407}
408
409fn 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}