diff options
Diffstat (limited to 'crates/ra_ide/src/completion/complete_unqualified_path.rs')
-rw-r--r-- | crates/ra_ide/src/completion/complete_unqualified_path.rs | 229 |
1 files changed, 214 insertions, 15 deletions
diff --git a/crates/ra_ide/src/completion/complete_unqualified_path.rs b/crates/ra_ide/src/completion/complete_unqualified_path.rs index ad5fdcc4e..638f86eda 100644 --- a/crates/ra_ide/src/completion/complete_unqualified_path.rs +++ b/crates/ra_ide/src/completion/complete_unqualified_path.rs | |||
@@ -4,20 +4,23 @@ use hir::ScopeDef; | |||
4 | use test_utils::tested_by; | 4 | use test_utils::tested_by; |
5 | 5 | ||
6 | use crate::completion::{CompletionContext, Completions}; | 6 | use crate::completion::{CompletionContext, Completions}; |
7 | use hir::{Adt, ModuleDef}; | ||
7 | use ra_syntax::AstNode; | 8 | use ra_syntax::AstNode; |
8 | 9 | ||
9 | pub(super) fn complete_unqualified_path(acc: &mut Completions, ctx: &CompletionContext) { | 10 | pub(super) fn complete_unqualified_path(acc: &mut Completions, ctx: &CompletionContext) { |
10 | if !ctx.is_trivial_path { | 11 | if (!ctx.is_trivial_path && !ctx.is_pat_binding_or_const) |
11 | return; | ||
12 | } | ||
13 | |||
14 | if ctx.is_pat_binding_or_const | ||
15 | || ctx.record_lit_syntax.is_some() | 12 | || ctx.record_lit_syntax.is_some() |
16 | || ctx.record_pat_syntax.is_some() | 13 | || ctx.record_pat_syntax.is_some() |
17 | { | 14 | { |
18 | return; | 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 | ctx.scope().process_all_names(&mut |name, res| { | 24 | ctx.scope().process_all_names(&mut |name, res| { |
22 | if ctx.use_item_syntax.is_some() { | 25 | if ctx.use_item_syntax.is_some() { |
23 | if let (ScopeDef::Unknown, Some(name_ref)) = (&res, &ctx.name_ref_syntax) { | 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 | #[cfg(test)] | 55 | #[cfg(test)] |
35 | mod tests { | 56 | mod tests { |
36 | use insta::assert_debug_snapshot; | 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 | ||
@@ -712,7 +733,7 @@ mod tests { | |||
712 | @r###" | 733 | @r###" |
713 | [ | 734 | [ |
714 | CompletionItem { | 735 | CompletionItem { |
715 | label: "bar!", | 736 | label: "bar!(…)", |
716 | source_range: [252; 252), | 737 | source_range: [252; 252), |
717 | delete: [252; 252), | 738 | delete: [252; 252), |
718 | insert: "bar!($0)", | 739 | insert: "bar!($0)", |
@@ -720,7 +741,7 @@ mod tests { | |||
720 | detail: "macro_rules! bar", | 741 | detail: "macro_rules! bar", |
721 | }, | 742 | }, |
722 | CompletionItem { | 743 | CompletionItem { |
723 | label: "baz!", | 744 | label: "baz!(…)", |
724 | source_range: [252; 252), | 745 | source_range: [252; 252), |
725 | delete: [252; 252), | 746 | delete: [252; 252), |
726 | insert: "baz!($0)", | 747 | insert: "baz!($0)", |
@@ -728,7 +749,7 @@ mod tests { | |||
728 | detail: "#[macro_export]\nmacro_rules! baz", | 749 | detail: "#[macro_export]\nmacro_rules! baz", |
729 | }, | 750 | }, |
730 | CompletionItem { | 751 | CompletionItem { |
731 | label: "foo!", | 752 | label: "foo!(…)", |
732 | source_range: [252; 252), | 753 | source_range: [252; 252), |
733 | delete: [252; 252), | 754 | delete: [252; 252), |
734 | insert: "foo!($0)", | 755 | insert: "foo!($0)", |
@@ -781,7 +802,7 @@ mod tests { | |||
781 | @r###" | 802 | @r###" |
782 | [ | 803 | [ |
783 | CompletionItem { | 804 | CompletionItem { |
784 | label: "foo!", | 805 | label: "foo!(…)", |
785 | source_range: [49; 49), | 806 | source_range: [49; 49), |
786 | delete: [49; 49), | 807 | delete: [49; 49), |
787 | insert: "foo!($0)", | 808 | insert: "foo!($0)", |
@@ -820,7 +841,7 @@ mod tests { | |||
820 | @r###" | 841 | @r###" |
821 | [ | 842 | [ |
822 | CompletionItem { | 843 | CompletionItem { |
823 | label: "foo!", | 844 | label: "foo!(…)", |
824 | source_range: [57; 57), | 845 | source_range: [57; 57), |
825 | delete: [57; 57), | 846 | delete: [57; 57), |
826 | insert: "foo!($0)", | 847 | insert: "foo!($0)", |
@@ -859,7 +880,7 @@ mod tests { | |||
859 | @r###" | 880 | @r###" |
860 | [ | 881 | [ |
861 | CompletionItem { | 882 | CompletionItem { |
862 | label: "foo!", | 883 | label: "foo!(…)", |
863 | source_range: [50; 50), | 884 | source_range: [50; 50), |
864 | delete: [50; 50), | 885 | delete: [50; 50), |
865 | insert: "foo!($0)", | 886 | insert: "foo!($0)", |
@@ -932,7 +953,7 @@ mod tests { | |||
932 | @r###" | 953 | @r###" |
933 | [ | 954 | [ |
934 | CompletionItem { | 955 | CompletionItem { |
935 | label: "m!", | 956 | label: "m!(…)", |
936 | source_range: [145; 145), | 957 | source_range: [145; 145), |
937 | delete: [145; 145), | 958 | delete: [145; 145), |
938 | insert: "m!($0)", | 959 | insert: "m!($0)", |
@@ -985,7 +1006,7 @@ mod tests { | |||
985 | @r###" | 1006 | @r###" |
986 | [ | 1007 | [ |
987 | CompletionItem { | 1008 | CompletionItem { |
988 | label: "m!", | 1009 | label: "m!(…)", |
989 | source_range: [145; 146), | 1010 | source_range: [145; 146), |
990 | delete: [145; 146), | 1011 | delete: [145; 146), |
991 | insert: "m!($0)", | 1012 | insert: "m!($0)", |
@@ -1038,7 +1059,7 @@ mod tests { | |||
1038 | @r###" | 1059 | @r###" |
1039 | [ | 1060 | [ |
1040 | CompletionItem { | 1061 | CompletionItem { |
1041 | label: "m!", | 1062 | label: "m!(…)", |
1042 | source_range: [145; 146), | 1063 | source_range: [145; 146), |
1043 | delete: [145; 146), | 1064 | delete: [145; 146), |
1044 | insert: "m!($0)", | 1065 | insert: "m!($0)", |
@@ -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 | } |