aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_ide_api/src/completion/complete_record_literal.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_ide_api/src/completion/complete_record_literal.rs')
-rw-r--r--crates/ra_ide_api/src/completion/complete_record_literal.rs132
1 files changed, 132 insertions, 0 deletions
diff --git a/crates/ra_ide_api/src/completion/complete_record_literal.rs b/crates/ra_ide_api/src/completion/complete_record_literal.rs
new file mode 100644
index 000000000..6b929a8ac
--- /dev/null
+++ b/crates/ra_ide_api/src/completion/complete_record_literal.rs
@@ -0,0 +1,132 @@
1use hir::Substs;
2
3use crate::completion::{CompletionContext, Completions};
4
5/// Complete fields in fields literals.
6pub(super) fn complete_record_literal(acc: &mut Completions, ctx: &CompletionContext) {
7 let (ty, variant) = match ctx.record_lit_syntax.as_ref().and_then(|it| {
8 Some((
9 ctx.analyzer.type_of(ctx.db, &it.clone().into())?,
10 ctx.analyzer.resolve_record_literal(it)?,
11 ))
12 }) {
13 Some(it) => it,
14 _ => return,
15 };
16 let substs = &ty.substs().unwrap_or_else(Substs::empty);
17
18 for field in variant.fields(ctx.db) {
19 acc.add_field(ctx, field, substs);
20 }
21}
22
23#[cfg(test)]
24mod tests {
25 use crate::completion::{do_completion, CompletionItem, CompletionKind};
26 use insta::assert_debug_snapshot_matches;
27
28 fn complete(code: &str) -> Vec<CompletionItem> {
29 do_completion(code, CompletionKind::Reference)
30 }
31
32 #[test]
33 fn test_record_literal_field() {
34 let completions = complete(
35 r"
36 struct A { the_field: u32 }
37 fn foo() {
38 A { the<|> }
39 }
40 ",
41 );
42 assert_debug_snapshot_matches!(completions, @r###"
43 ⋮[
44 ⋮ CompletionItem {
45 ⋮ label: "the_field",
46 ⋮ source_range: [83; 86),
47 ⋮ delete: [83; 86),
48 ⋮ insert: "the_field",
49 ⋮ kind: Field,
50 ⋮ detail: "u32",
51 ⋮ },
52 ⋮]
53 "###);
54 }
55
56 #[test]
57 fn test_record_literal_enum_variant() {
58 let completions = complete(
59 r"
60 enum E {
61 A { a: u32 }
62 }
63 fn foo() {
64 let _ = E::A { <|> }
65 }
66 ",
67 );
68 assert_debug_snapshot_matches!(completions, @r###"
69 ⋮[
70 ⋮ CompletionItem {
71 ⋮ label: "a",
72 ⋮ source_range: [119; 119),
73 ⋮ delete: [119; 119),
74 ⋮ insert: "a",
75 ⋮ kind: Field,
76 ⋮ detail: "u32",
77 ⋮ },
78 ⋮]
79 "###);
80 }
81
82 #[test]
83 fn test_record_literal_two_structs() {
84 let completions = complete(
85 r"
86 struct A { a: u32 }
87 struct B { b: u32 }
88
89 fn foo() {
90 let _: A = B { <|> }
91 }
92 ",
93 );
94 assert_debug_snapshot_matches!(completions, @r###"
95 ⋮[
96 ⋮ CompletionItem {
97 ⋮ label: "b",
98 ⋮ source_range: [119; 119),
99 ⋮ delete: [119; 119),
100 ⋮ insert: "b",
101 ⋮ kind: Field,
102 ⋮ detail: "u32",
103 ⋮ },
104 ⋮]
105 "###);
106 }
107
108 #[test]
109 fn test_record_literal_generic_struct() {
110 let completions = complete(
111 r"
112 struct A<T> { a: T }
113
114 fn foo() {
115 let _: A<u32> = A { <|> }
116 }
117 ",
118 );
119 assert_debug_snapshot_matches!(completions, @r###"
120 ⋮[
121 ⋮ CompletionItem {
122 ⋮ label: "a",
123 ⋮ source_range: [93; 93),
124 ⋮ delete: [93; 93),
125 ⋮ insert: "a",
126 ⋮ kind: Field,
127 ⋮ detail: "u32",
128 ⋮ },
129 ⋮]
130 "###);
131 }
132}