diff options
Diffstat (limited to 'crates/ide_completion/src/completions')
-rw-r--r-- | crates/ide_completion/src/completions/lifetime.rs | 181 | ||||
-rw-r--r-- | crates/ide_completion/src/completions/pattern.rs | 2 |
2 files changed, 182 insertions, 1 deletions
diff --git a/crates/ide_completion/src/completions/lifetime.rs b/crates/ide_completion/src/completions/lifetime.rs new file mode 100644 index 000000000..74eb23360 --- /dev/null +++ b/crates/ide_completion/src/completions/lifetime.rs | |||
@@ -0,0 +1,181 @@ | |||
1 | //! Completes lifetimes. | ||
2 | use hir::ScopeDef; | ||
3 | |||
4 | use crate::{completions::Completions, context::CompletionContext}; | ||
5 | |||
6 | /// Completes lifetimes. | ||
7 | pub(crate) fn complete_lifetime(acc: &mut Completions, ctx: &CompletionContext) { | ||
8 | if !ctx.lifetime_allowed { | ||
9 | return; | ||
10 | } | ||
11 | let param_lifetime = match ( | ||
12 | &ctx.lifetime_syntax, | ||
13 | ctx.lifetime_param_syntax.as_ref().and_then(|lp| lp.lifetime()), | ||
14 | ) { | ||
15 | (Some(lt), Some(lp)) if lp == lt.clone() => return, | ||
16 | (Some(_), Some(lp)) => Some(lp.to_string()), | ||
17 | _ => None, | ||
18 | }; | ||
19 | |||
20 | ctx.scope.process_all_names(&mut |name, res| { | ||
21 | if let ScopeDef::GenericParam(hir::GenericParam::LifetimeParam(_)) = res { | ||
22 | if param_lifetime != Some(name.to_string()) { | ||
23 | acc.add_resolution(ctx, name.to_string(), &res); | ||
24 | } | ||
25 | } | ||
26 | }); | ||
27 | if param_lifetime.is_none() { | ||
28 | acc.add_static_lifetime(ctx); | ||
29 | } | ||
30 | } | ||
31 | |||
32 | #[cfg(test)] | ||
33 | mod tests { | ||
34 | use expect_test::{expect, Expect}; | ||
35 | |||
36 | use crate::{ | ||
37 | test_utils::{check_edit, completion_list_with_config, TEST_CONFIG}, | ||
38 | CompletionConfig, CompletionKind, | ||
39 | }; | ||
40 | |||
41 | fn check(ra_fixture: &str, expect: Expect) { | ||
42 | check_with_config(TEST_CONFIG, ra_fixture, expect); | ||
43 | } | ||
44 | |||
45 | fn check_with_config(config: CompletionConfig, ra_fixture: &str, expect: Expect) { | ||
46 | let actual = completion_list_with_config(config, ra_fixture, CompletionKind::Reference); | ||
47 | expect.assert_eq(&actual) | ||
48 | } | ||
49 | |||
50 | #[test] | ||
51 | fn check_lifetime_edit() { | ||
52 | check_edit( | ||
53 | "'lifetime", | ||
54 | r#" | ||
55 | fn func<'lifetime>(foo: &'li$0) {} | ||
56 | "#, | ||
57 | r#" | ||
58 | fn func<'lifetime>(foo: &'lifetime) {} | ||
59 | "#, | ||
60 | ); | ||
61 | } | ||
62 | |||
63 | #[test] | ||
64 | fn complete_lifetime_in_ref() { | ||
65 | check( | ||
66 | r#" | ||
67 | fn foo<'lifetime>(foo: &'a$0 usize) {} | ||
68 | "#, | ||
69 | expect![[r#" | ||
70 | lt 'lifetime | ||
71 | lt 'static | ||
72 | "#]], | ||
73 | ); | ||
74 | } | ||
75 | |||
76 | #[test] | ||
77 | fn complete_lifetime_in_ref_missing_ty() { | ||
78 | check( | ||
79 | r#" | ||
80 | fn foo<'lifetime>(foo: &'a$0) {} | ||
81 | "#, | ||
82 | expect![[r#" | ||
83 | lt 'lifetime | ||
84 | lt 'static | ||
85 | "#]], | ||
86 | ); | ||
87 | } | ||
88 | #[test] | ||
89 | fn complete_lifetime_in_self_ref() { | ||
90 | check( | ||
91 | r#" | ||
92 | struct Foo; | ||
93 | impl<'impl> Foo { | ||
94 | fn foo<'func>(&'a$0 self) {} | ||
95 | } | ||
96 | "#, | ||
97 | expect![[r#" | ||
98 | lt 'func | ||
99 | lt 'impl | ||
100 | lt 'static | ||
101 | "#]], | ||
102 | ); | ||
103 | } | ||
104 | |||
105 | #[test] | ||
106 | fn complete_lifetime_in_arg_list() { | ||
107 | check( | ||
108 | r#" | ||
109 | struct Foo<'lt>; | ||
110 | fn foo<'lifetime>(_: Foo<'a$0>) {} | ||
111 | "#, | ||
112 | expect![[r#" | ||
113 | lt 'lifetime | ||
114 | lt 'static | ||
115 | "#]], | ||
116 | ); | ||
117 | } | ||
118 | |||
119 | #[test] | ||
120 | fn complete_lifetime_in_where_pred() { | ||
121 | check( | ||
122 | r#" | ||
123 | fn foo2<'lifetime, T>() where 'a$0 {} | ||
124 | "#, | ||
125 | expect![[r#" | ||
126 | lt 'lifetime | ||
127 | lt 'static | ||
128 | "#]], | ||
129 | ); | ||
130 | } | ||
131 | |||
132 | #[test] | ||
133 | fn complete_lifetime_in_ty_bound() { | ||
134 | check( | ||
135 | r#" | ||
136 | fn foo2<'lifetime, T>() where T: 'a$0 {} | ||
137 | "#, | ||
138 | expect![[r#" | ||
139 | lt 'lifetime | ||
140 | lt 'static | ||
141 | "#]], | ||
142 | ); | ||
143 | check( | ||
144 | r#" | ||
145 | fn foo2<'lifetime, T>() where T: Trait<'a$0> {} | ||
146 | "#, | ||
147 | expect![[r#" | ||
148 | lt 'lifetime | ||
149 | lt 'static | ||
150 | "#]], | ||
151 | ); | ||
152 | } | ||
153 | |||
154 | #[test] | ||
155 | fn dont_complete_lifetime_in_assoc_ty_bound() { | ||
156 | check( | ||
157 | r#" | ||
158 | fn foo2<'lifetime, T>() where T: Trait<Item = 'a$0> {} | ||
159 | "#, | ||
160 | expect![[r#""#]], | ||
161 | ); | ||
162 | } | ||
163 | |||
164 | #[test] | ||
165 | fn complete_lifetime_in_param_list() { | ||
166 | check( | ||
167 | r#" | ||
168 | fn foo<'a$0>() {} | ||
169 | "#, | ||
170 | expect![[r#""#]], | ||
171 | ); | ||
172 | check( | ||
173 | r#" | ||
174 | fn foo<'footime, 'lifetime: 'a$0>() {} | ||
175 | "#, | ||
176 | expect![[r#" | ||
177 | lt 'footime | ||
178 | "#]], | ||
179 | ); | ||
180 | } | ||
181 | } | ||
diff --git a/crates/ide_completion/src/completions/pattern.rs b/crates/ide_completion/src/completions/pattern.rs index 476eecff0..b06498e6d 100644 --- a/crates/ide_completion/src/completions/pattern.rs +++ b/crates/ide_completion/src/completions/pattern.rs | |||
@@ -1,4 +1,4 @@ | |||
1 | //! Completes constats and paths in patterns. | 1 | //! Completes constants and paths in patterns. |
2 | 2 | ||
3 | use crate::{CompletionContext, Completions}; | 3 | use crate::{CompletionContext, Completions}; |
4 | 4 | ||