aboutsummaryrefslogtreecommitdiff
path: root/crates/completion/src/completions
diff options
context:
space:
mode:
authorLukas Wirth <[email protected]>2020-12-20 17:19:23 +0000
committerLukas Wirth <[email protected]>2020-12-20 17:19:23 +0000
commitb184bfad7a2dc6a9bf6654a7eec6c68a27c49f70 (patch)
treea9d35d8053e13d22561156c760e0996323040169 /crates/completion/src/completions
parentf3125555a8de6fad4529408436800a6b1243a442 (diff)
Add completions for patterns
Diffstat (limited to 'crates/completion/src/completions')
-rw-r--r--crates/completion/src/completions/pattern.rs154
1 files changed, 139 insertions, 15 deletions
diff --git a/crates/completion/src/completions/pattern.rs b/crates/completion/src/completions/pattern.rs
index 4d56731ec..496f0b040 100644
--- a/crates/completion/src/completions/pattern.rs
+++ b/crates/completion/src/completions/pattern.rs
@@ -1,10 +1,12 @@
1//! Completes constats and paths in patterns. 1//! Completes constats and paths in patterns.
2 2
3use hir::StructKind;
4
3use crate::{CompletionContext, Completions}; 5use crate::{CompletionContext, Completions};
4 6
5/// Completes constats and paths in patterns. 7/// Completes constants and paths in patterns.
6pub(crate) fn complete_pattern(acc: &mut Completions, ctx: &CompletionContext) { 8pub(crate) fn complete_pattern(acc: &mut Completions, ctx: &CompletionContext) {
7 if !(ctx.is_pat_binding_or_const || ctx.is_irrefutable_let_pat_binding) { 9 if !(ctx.is_pat_binding_or_const || ctx.is_irrefutable_pat_binding) {
8 return; 10 return;
9 } 11 }
10 if ctx.record_pat_syntax.is_some() { 12 if ctx.record_pat_syntax.is_some() {
@@ -15,20 +17,25 @@ pub(crate) fn complete_pattern(acc: &mut Completions, ctx: &CompletionContext) {
15 // suggest variants + auto-imports 17 // suggest variants + auto-imports
16 ctx.scope.process_all_names(&mut |name, res| { 18 ctx.scope.process_all_names(&mut |name, res| {
17 let add_resolution = match &res { 19 let add_resolution = match &res {
18 hir::ScopeDef::ModuleDef(def) => { 20 hir::ScopeDef::ModuleDef(def) => match def {
19 if ctx.is_irrefutable_let_pat_binding { 21 hir::ModuleDef::Adt(hir::Adt::Struct(strukt)) => {
20 matches!(def, hir::ModuleDef::Adt(hir::Adt::Struct(_))) 22 acc.add_struct_pat(ctx, strukt.clone(), Some(name.clone()));
21 } else { 23 true
22 matches!( 24 }
23 def, 25 hir::ModuleDef::Variant(variant)
24 hir::ModuleDef::Adt(hir::Adt::Enum(..)) 26 if !ctx.is_irrefutable_pat_binding
25 | hir::ModuleDef::Adt(hir::Adt::Struct(..)) 27 // render_resolution already does some pattern completion tricks for tuple variants
26 | hir::ModuleDef::Variant(..) 28 && variant.kind(ctx.db) == StructKind::Record =>
27 | hir::ModuleDef::Const(..) 29 {
28 | hir::ModuleDef::Module(..) 30 acc.add_variant_pat(ctx, variant.clone(), Some(name.clone()));
29 ) 31 true
30 } 32 }
31 } 33 hir::ModuleDef::Adt(hir::Adt::Enum(..))
34 | hir::ModuleDef::Variant(..)
35 | hir::ModuleDef::Const(..)
36 | hir::ModuleDef::Module(..) => !ctx.is_irrefutable_pat_binding,
37 _ => false,
38 },
32 hir::ScopeDef::MacroDef(_) => true, 39 hir::ScopeDef::MacroDef(_) => true,
33 _ => false, 40 _ => false,
34 }; 41 };
@@ -49,6 +56,11 @@ mod tests {
49 expect.assert_eq(&actual) 56 expect.assert_eq(&actual)
50 } 57 }
51 58
59 fn check_snippet(ra_fixture: &str, expect: Expect) {
60 let actual = completion_list(ra_fixture, CompletionKind::Snippet);
61 expect.assert_eq(&actual)
62 }
63
52 #[test] 64 #[test]
53 fn completes_enum_variants_and_modules() { 65 fn completes_enum_variants_and_modules() {
54 check( 66 check(
@@ -114,4 +126,116 @@ fn foo() {
114 "#]], 126 "#]],
115 ); 127 );
116 } 128 }
129
130 #[test]
131 fn completes_in_param() {
132 check(
133 r#"
134enum E { X }
135
136static FOO: E = E::X;
137struct Bar { f: u32 }
138
139fn foo(<|>) {
140}
141"#,
142 expect![[r#"
143 st Bar
144 "#]],
145 );
146 }
147
148 #[test]
149 fn completes_pat_in_let() {
150 check_snippet(
151 r#"
152struct Bar { f: u32 }
153
154fn foo() {
155 let <|>
156}
157"#,
158 expect![[r#"
159 bn Bar Bar { f }$0
160 "#]],
161 );
162 }
163
164 #[test]
165 fn completes_param_pattern() {
166 check_snippet(
167 r#"
168struct Foo { bar: String, baz: String }
169struct Bar(String, String);
170struct Baz;
171fn outer(<|>) {}
172"#,
173 expect![[r#"
174 bn Foo Foo { bar, baz }: Foo$0
175 bn Bar Bar($1, $2): Bar$0
176 "#]],
177 )
178 }
179
180 #[test]
181 fn completes_let_pattern() {
182 check_snippet(
183 r#"
184struct Foo { bar: String, baz: String }
185struct Bar(String, String);
186struct Baz;
187fn outer() {
188 let <|>
189}
190"#,
191 expect![[r#"
192 bn Foo Foo { bar, baz }$0
193 bn Bar Bar($1, $2)$0
194 "#]],
195 )
196 }
197
198 #[test]
199 fn completes_refutable_pattern() {
200 check_snippet(
201 r#"
202struct Foo { bar: i32, baz: i32 }
203struct Bar(String, String);
204struct Baz;
205fn outer() {
206 match () {
207 <|>
208 }
209}
210"#,
211 expect![[r#"
212 bn Foo Foo { bar, baz }$0
213 bn Bar Bar($1, $2)$0
214 "#]],
215 )
216 }
217
218 #[test]
219 fn omits_private_fields_pat() {
220 check_snippet(
221 r#"
222mod foo {
223 pub struct Foo { pub bar: i32, baz: i32 }
224 pub struct Bar(pub String, String);
225 pub struct Invisible(String, String);
226}
227use foo::*;
228
229fn outer() {
230 match () {
231 <|>
232 }
233}
234"#,
235 expect![[r#"
236 bn Foo Foo { bar, .. }$0
237 bn Bar Bar($1, ..)$0
238 "#]],
239 )
240 }
117} 241}