aboutsummaryrefslogtreecommitdiff
path: root/crates/ide_completion/src/completions/lifetime.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ide_completion/src/completions/lifetime.rs')
-rw-r--r--crates/ide_completion/src/completions/lifetime.rs181
1 files changed, 181 insertions, 0 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.
2use hir::ScopeDef;
3
4use crate::{completions::Completions, context::CompletionContext};
5
6/// Completes lifetimes.
7pub(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)]
33mod 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#"
55fn func<'lifetime>(foo: &'li$0) {}
56"#,
57 r#"
58fn func<'lifetime>(foo: &'lifetime) {}
59"#,
60 );
61 }
62
63 #[test]
64 fn complete_lifetime_in_ref() {
65 check(
66 r#"
67fn 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#"
80fn 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#"
92struct Foo;
93impl<'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#"
109struct Foo<'lt>;
110fn 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#"
123fn 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#"
136fn foo2<'lifetime, T>() where T: 'a$0 {}
137"#,
138 expect![[r#"
139 lt 'lifetime
140 lt 'static
141 "#]],
142 );
143 check(
144 r#"
145fn 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#"
158fn 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#"
168fn foo<'a$0>() {}
169"#,
170 expect![[r#""#]],
171 );
172 check(
173 r#"
174fn foo<'footime, 'lifetime: 'a$0>() {}
175"#,
176 expect![[r#"
177 lt 'footime
178 "#]],
179 );
180 }
181}