aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_ide_api/src/completion/complete_struct_literal.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_ide_api/src/completion/complete_struct_literal.rs')
-rw-r--r--crates/ra_ide_api/src/completion/complete_struct_literal.rs103
1 files changed, 88 insertions, 15 deletions
diff --git a/crates/ra_ide_api/src/completion/complete_struct_literal.rs b/crates/ra_ide_api/src/completion/complete_struct_literal.rs
index 35fb21113..b6216f857 100644
--- a/crates/ra_ide_api/src/completion/complete_struct_literal.rs
+++ b/crates/ra_ide_api/src/completion/complete_struct_literal.rs
@@ -1,28 +1,24 @@
1use hir::AdtDef; 1use hir::{Substs, Ty};
2 2
3use crate::completion::{CompletionContext, Completions}; 3use crate::completion::{CompletionContext, Completions};
4 4
5/// Complete fields in fields literals. 5/// Complete fields in fields literals.
6pub(super) fn complete_struct_literal(acc: &mut Completions, ctx: &CompletionContext) { 6pub(super) fn complete_struct_literal(acc: &mut Completions, ctx: &CompletionContext) {
7 let ty = match ctx.struct_lit_syntax.and_then(|it| ctx.analyzer.type_of(ctx.db, it.into())) { 7 let (ty, variant) = match ctx.struct_lit_syntax.and_then(|it| {
8 Some((ctx.analyzer.type_of(ctx.db, it.into())?, ctx.analyzer.resolve_variant(it)?))
9 }) {
8 Some(it) => it, 10 Some(it) => it,
9 None => return,
10 };
11 let (adt, substs) = match ty.as_adt() {
12 Some(res) => res,
13 _ => return, 11 _ => return,
14 }; 12 };
15 match adt {
16 AdtDef::Struct(s) => {
17 for field in s.fields(ctx.db) {
18 acc.add_field(ctx, field, substs);
19 }
20 }
21 13
22 // FIXME unions 14 let ty_substs = match ty {
23 AdtDef::Union(_) => (), 15 Ty::Apply(it) => it.parameters,
24 AdtDef::Enum(_) => (), 16 _ => Substs::empty(),
25 }; 17 };
18
19 for field in variant.fields(ctx.db) {
20 acc.add_field(ctx, field, &ty_substs);
21 }
26} 22}
27 23
28#[cfg(test)] 24#[cfg(test)]
@@ -57,4 +53,81 @@ mod tests {
57 ⋮] 53 ⋮]
58 "###); 54 "###);
59 } 55 }
56
57 #[test]
58 fn test_struct_literal_enum_variant() {
59 let completions = complete(
60 r"
61 enum E {
62 A { a: u32 }
63 }
64 fn foo() {
65 let _ = E::A { <|> }
66 }
67 ",
68 );
69 assert_debug_snapshot_matches!(completions, @r###"
70 ⋮[
71 ⋮ CompletionItem {
72 ⋮ label: "a",
73 ⋮ source_range: [119; 119),
74 ⋮ delete: [119; 119),
75 ⋮ insert: "a",
76 ⋮ kind: Field,
77 ⋮ detail: "u32",
78 ⋮ },
79 ⋮]
80 "###);
81 }
82
83 #[test]
84 fn test_struct_literal_two_structs() {
85 let completions = complete(
86 r"
87 struct A { a: u32 }
88 struct B { b: u32 }
89
90 fn foo() {
91 let _: A = B { <|> }
92 }
93 ",
94 );
95 assert_debug_snapshot_matches!(completions, @r###"
96 ⋮[
97 ⋮ CompletionItem {
98 ⋮ label: "b",
99 ⋮ source_range: [119; 119),
100 ⋮ delete: [119; 119),
101 ⋮ insert: "b",
102 ⋮ kind: Field,
103 ⋮ detail: "u32",
104 ⋮ },
105 ⋮]
106 "###);
107 }
108
109 #[test]
110 fn test_struct_literal_generic_struct() {
111 let completions = complete(
112 r"
113 struct A<T> { a: T }
114
115 fn foo() {
116 let _: A<u32> = A { <|> }
117 }
118 ",
119 );
120 assert_debug_snapshot_matches!(completions, @r###"
121 ⋮[
122 ⋮ CompletionItem {
123 ⋮ label: "a",
124 ⋮ source_range: [93; 93),
125 ⋮ delete: [93; 93),
126 ⋮ insert: "a",
127 ⋮ kind: Field,
128 ⋮ detail: "u32",
129 ⋮ },
130 ⋮]
131 "###);
132 }
60} 133}