@@ -4,20 +4,23 @@ use hir::ScopeDef;
4
4
use test_utils:: tested_by;
5
5
6
6
use crate :: completion:: { CompletionContext , Completions } ;
7
+ use hir:: { Adt , ModuleDef } ;
7
8
use ra_syntax:: AstNode ;
8
9
9
10
pub ( 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 )
15
12
|| ctx. record_lit_syntax . is_some ( )
16
13
|| ctx. record_pat_syntax . is_some ( )
17
14
{
18
15
return ;
19
16
}
20
17
18
+ complete_enum_variants ( acc, ctx) ;
19
+
20
+ if ctx. is_pat_binding_or_const {
21
+ return ;
22
+ }
23
+
21
24
ctx. scope ( ) . process_all_names ( & mut |name, res| {
22
25
if ctx. use_item_syntax . is_some ( ) {
23
26
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
31
34
} ) ;
32
35
}
33
36
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
+
34
55
#[ cfg( test) ]
35
56
mod tests {
36
57
use insta:: assert_debug_snapshot;
@@ -82,7 +103,7 @@ mod tests {
82
103
}
83
104
"
84
105
) ,
85
- @r### "[]"###
106
+ @"[]"
86
107
) ;
87
108
}
88
109
@@ -1109,4 +1130,182 @@ mod tests {
1109
1130
"###
1110
1131
) ;
1111
1132
}
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
+ }
1112
1311
}
0 commit comments