aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_ide/src/completion/complete_unqualified_path.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_ide/src/completion/complete_unqualified_path.rs')
-rw-r--r--crates/ra_ide/src/completion/complete_unqualified_path.rs229
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;
4use test_utils::tested_by; 4use test_utils::tested_by;
5 5
6use crate::completion::{CompletionContext, Completions}; 6use crate::completion::{CompletionContext, Completions};
7use hir::{Adt, ModuleDef};
7use ra_syntax::AstNode; 8use ra_syntax::AstNode;
8 9
9pub(super) fn complete_unqualified_path(acc: &mut Completions, ctx: &CompletionContext) { 10pub(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
37fn 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)]
35mod tests { 56mod 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}