@@ -4,20 +4,23 @@ use hir::ScopeDef;
44use test_utils:: tested_by;
55
66use crate :: completion:: { CompletionContext , Completions } ;
7+ use hir:: { Adt , ModuleDef } ;
78use ra_syntax:: AstNode ;
89
910pub ( super ) fn complete_unqualified_path ( acc : & mut Completions , ctx : & CompletionContext ) {
10- if !ctx. is_trivial_path {
11- return ;
12- }
13-
14- if ctx. is_pat_binding_or_const
11+ if ( !ctx. is_trivial_path && !ctx. is_pat_binding_or_const )
1512 || ctx. record_lit_syntax . is_some ( )
1613 || ctx. record_pat_syntax . is_some ( )
1714 {
1815 return ;
1916 }
2017
18+ complete_enum_variants ( acc, ctx) ;
19+
20+ if ctx. is_pat_binding_or_const {
21+ return ;
22+ }
23+
2124 ctx. scope ( ) . process_all_names ( & mut |name, res| {
2225 if ctx. use_item_syntax . is_some ( ) {
2326 if let ( ScopeDef :: Unknown , Some ( name_ref) ) = ( & res, & ctx. name_ref_syntax ) {
@@ -31,6 +34,24 @@ pub(super) fn complete_unqualified_path(acc: &mut Completions, ctx: &CompletionC
3134 } ) ;
3235}
3336
37+ fn complete_enum_variants ( acc : & mut Completions , ctx : & CompletionContext ) {
38+ if let Some ( ty) = ctx. expected_type_of ( & ctx. token . parent ( ) ) {
39+ if let Some ( Adt :: Enum ( enum_data) ) = ty. as_adt ( ) {
40+ let variants = enum_data. variants ( ctx. db ) ;
41+ let module = enum_data. module ( ctx. db ) ;
42+ for variant in variants {
43+ if let Some ( path) = module. find_use_path ( ctx. db , ModuleDef :: from ( variant) ) {
44+ // Variants with trivial paths are already added by the existing completion logic,
45+ // so we should avoid adding these twice
46+ if path. segments . len ( ) > 1 {
47+ acc. add_enum_variant ( ctx, variant, Some ( path. to_string ( ) ) ) ;
48+ }
49+ }
50+ }
51+ }
52+ }
53+ }
54+
3455#[ cfg( test) ]
3556mod tests {
3657 use insta:: assert_debug_snapshot;
@@ -82,7 +103,7 @@ mod tests {
82103 }
83104 "
84105 ) ,
85- @r### "[]"###
106+ @"[]"
86107 ) ;
87108 }
88109
@@ -1109,4 +1130,182 @@ mod tests {
11091130 "###
11101131 ) ;
11111132 }
1133+ #[ test]
1134+ fn completes_enum_variant_matcharm ( ) {
1135+ assert_debug_snapshot ! (
1136+ do_reference_completion(
1137+ r"
1138+ enum Foo {
1139+ Bar,
1140+ Baz,
1141+ Quux
1142+ }
1143+
1144+ fn main() {
1145+ let foo = Foo::Quux;
1146+
1147+ match foo {
1148+ Qu<|>
1149+ }
1150+ }
1151+ "
1152+ ) ,
1153+ @r###"
1154+ [
1155+ CompletionItem {
1156+ label: "Foo",
1157+ source_range: [248; 250),
1158+ delete: [248; 250),
1159+ insert: "Foo",
1160+ kind: Enum,
1161+ },
1162+ CompletionItem {
1163+ label: "Foo::Bar",
1164+ source_range: [248; 250),
1165+ delete: [248; 250),
1166+ insert: "Foo::Bar",
1167+ kind: EnumVariant,
1168+ detail: "()",
1169+ },
1170+ CompletionItem {
1171+ label: "Foo::Baz",
1172+ source_range: [248; 250),
1173+ delete: [248; 250),
1174+ insert: "Foo::Baz",
1175+ kind: EnumVariant,
1176+ detail: "()",
1177+ },
1178+ CompletionItem {
1179+ label: "Foo::Quux",
1180+ source_range: [248; 250),
1181+ delete: [248; 250),
1182+ insert: "Foo::Quux",
1183+ kind: EnumVariant,
1184+ detail: "()",
1185+ },
1186+ ]
1187+ "###
1188+ )
1189+ }
1190+
1191+ #[ test]
1192+ fn completes_enum_variant_iflet ( ) {
1193+ assert_debug_snapshot ! (
1194+ do_reference_completion(
1195+ r"
1196+ enum Foo {
1197+ Bar,
1198+ Baz,
1199+ Quux
1200+ }
1201+
1202+ fn main() {
1203+ let foo = Foo::Quux;
1204+
1205+ if let Qu<|> = foo {
1206+
1207+ }
1208+ }
1209+ "
1210+ ) ,
1211+ @r###"
1212+ [
1213+ CompletionItem {
1214+ label: "Foo",
1215+ source_range: [219; 221),
1216+ delete: [219; 221),
1217+ insert: "Foo",
1218+ kind: Enum,
1219+ },
1220+ CompletionItem {
1221+ label: "Foo::Bar",
1222+ source_range: [219; 221),
1223+ delete: [219; 221),
1224+ insert: "Foo::Bar",
1225+ kind: EnumVariant,
1226+ detail: "()",
1227+ },
1228+ CompletionItem {
1229+ label: "Foo::Baz",
1230+ source_range: [219; 221),
1231+ delete: [219; 221),
1232+ insert: "Foo::Baz",
1233+ kind: EnumVariant,
1234+ detail: "()",
1235+ },
1236+ CompletionItem {
1237+ label: "Foo::Quux",
1238+ source_range: [219; 221),
1239+ delete: [219; 221),
1240+ insert: "Foo::Quux",
1241+ kind: EnumVariant,
1242+ detail: "()",
1243+ },
1244+ ]
1245+ "###
1246+ )
1247+ }
1248+
1249+ #[ test]
1250+ fn completes_enum_variant_basic_expr ( ) {
1251+ assert_debug_snapshot ! (
1252+ do_reference_completion(
1253+ r"
1254+ enum Foo {
1255+ Bar,
1256+ Baz,
1257+ Quux
1258+ }
1259+
1260+ fn main() {
1261+ let foo: Foo = Q<|>
1262+ }
1263+ "
1264+ ) ,
1265+ @r###"
1266+ [
1267+ CompletionItem {
1268+ label: "Foo",
1269+ source_range: [185; 186),
1270+ delete: [185; 186),
1271+ insert: "Foo",
1272+ kind: Enum,
1273+ },
1274+ CompletionItem {
1275+ label: "Foo::Bar",
1276+ source_range: [185; 186),
1277+ delete: [185; 186),
1278+ insert: "Foo::Bar",
1279+ kind: EnumVariant,
1280+ detail: "()",
1281+ },
1282+ CompletionItem {
1283+ label: "Foo::Baz",
1284+ source_range: [185; 186),
1285+ delete: [185; 186),
1286+ insert: "Foo::Baz",
1287+ kind: EnumVariant,
1288+ detail: "()",
1289+ },
1290+ CompletionItem {
1291+ label: "Foo::Quux",
1292+ source_range: [185; 186),
1293+ delete: [185; 186),
1294+ insert: "Foo::Quux",
1295+ kind: EnumVariant,
1296+ detail: "()",
1297+ },
1298+ CompletionItem {
1299+ label: "main()",
1300+ source_range: [185; 186),
1301+ delete: [185; 186),
1302+ insert: "main()$0",
1303+ kind: Function,
1304+ lookup: "main",
1305+ detail: "fn main()",
1306+ },
1307+ ]
1308+ "###
1309+ )
1310+ }
11121311}
0 commit comments