diff options
author | Steffen Lyngbaek <[email protected]> | 2020-03-07 01:35:39 +0000 |
---|---|---|
committer | Steffen Lyngbaek <[email protected]> | 2020-03-07 01:35:39 +0000 |
commit | 15ed114a4935684ded93c717f6a3240888b58985 (patch) | |
tree | 8a08d5e48e4b4bcba9b09248ddfa2392a143de59 /crates/ra_ide/src/completion | |
parent | 48bb1c51721b7736b6d6f2e5cb82126c91934433 (diff) |
Next steps in assoc item completion #3183
Allow trait autocompletions for unimplemented associated fn's, types,
and consts without using explicit keywords before hand (fn, type,
const).
The sequel to #3108.
Diffstat (limited to 'crates/ra_ide/src/completion')
-rw-r--r-- | crates/ra_ide/src/completion/complete_trait_impl.rs | 105 |
1 files changed, 99 insertions, 6 deletions
diff --git a/crates/ra_ide/src/completion/complete_trait_impl.rs b/crates/ra_ide/src/completion/complete_trait_impl.rs index 18a1d2995..8cb0c72bb 100644 --- a/crates/ra_ide/src/completion/complete_trait_impl.rs +++ b/crates/ra_ide/src/completion/complete_trait_impl.rs | |||
@@ -47,22 +47,39 @@ use crate::{ | |||
47 | }; | 47 | }; |
48 | 48 | ||
49 | pub(crate) fn complete_trait_impl(acc: &mut Completions, ctx: &CompletionContext) { | 49 | pub(crate) fn complete_trait_impl(acc: &mut Completions, ctx: &CompletionContext) { |
50 | let trigger = ctx.token.ancestors().find(|p| match p.kind() { | 50 | let mut tokens = ctx.token.ancestors(); |
51 | let trigger = tokens.find(|p| match p.kind() { | ||
51 | SyntaxKind::FN_DEF | 52 | SyntaxKind::FN_DEF |
52 | | SyntaxKind::TYPE_ALIAS_DEF | 53 | | SyntaxKind::TYPE_ALIAS_DEF |
53 | | SyntaxKind::CONST_DEF | 54 | | SyntaxKind::CONST_DEF |
55 | | SyntaxKind::NAME_REF | ||
54 | | SyntaxKind::BLOCK_EXPR => true, | 56 | | SyntaxKind::BLOCK_EXPR => true, |
55 | _ => false, | 57 | _ => false, |
56 | }); | 58 | }); |
57 | 59 | ||
58 | let impl_def = trigger | 60 | let impl_def = tokens |
59 | .as_ref() | 61 | .find(|p| match p.kind() { |
60 | .and_then(|node| node.parent()) | 62 | SyntaxKind::IMPL_DEF => true, |
61 | .and_then(|node| node.parent()) | 63 | _ => false, |
62 | .and_then(ast::ImplDef::cast); | 64 | }) |
65 | .and_then(|n| ast::ImplDef::cast(n)); | ||
63 | 66 | ||
64 | if let (Some(trigger), Some(impl_def)) = (trigger, impl_def) { | 67 | if let (Some(trigger), Some(impl_def)) = (trigger, impl_def) { |
65 | match trigger.kind() { | 68 | match trigger.kind() { |
69 | SyntaxKind::NAME_REF => { | ||
70 | get_missing_impl_items(&ctx.sema, &impl_def).iter().for_each(|item| match item { | ||
71 | hir::AssocItem::Function(fn_item) => { | ||
72 | add_function_impl(&trigger, acc, ctx, &fn_item) | ||
73 | } | ||
74 | hir::AssocItem::TypeAlias(type_item) => { | ||
75 | add_type_alias_impl(&trigger, acc, ctx, &type_item) | ||
76 | } | ||
77 | hir::AssocItem::Const(const_item) => { | ||
78 | add_const_impl(&trigger, acc, ctx, &const_item) | ||
79 | } | ||
80 | }) | ||
81 | } | ||
82 | |||
66 | SyntaxKind::FN_DEF => { | 83 | SyntaxKind::FN_DEF => { |
67 | for missing_fn in get_missing_impl_items(&ctx.sema, &impl_def).iter().filter_map( | 84 | for missing_fn in get_missing_impl_items(&ctx.sema, &impl_def).iter().filter_map( |
68 | |item| match item { | 85 | |item| match item { |
@@ -210,6 +227,82 @@ mod tests { | |||
210 | } | 227 | } |
211 | 228 | ||
212 | #[test] | 229 | #[test] |
230 | fn name_ref_function_type_const() { | ||
231 | let completions = complete( | ||
232 | r" | ||
233 | trait Test { | ||
234 | type TestType; | ||
235 | const TEST_CONST: u16; | ||
236 | fn test(); | ||
237 | } | ||
238 | |||
239 | struct T1; | ||
240 | |||
241 | impl Test for T1 { | ||
242 | t<|> | ||
243 | } | ||
244 | ", | ||
245 | ); | ||
246 | assert_debug_snapshot!(completions, @r###" | ||
247 | [ | ||
248 | CompletionItem { | ||
249 | label: "const TEST_CONST: u16 = ", | ||
250 | source_range: [209; 210), | ||
251 | delete: [209; 210), | ||
252 | insert: "const TEST_CONST: u16 = ", | ||
253 | kind: Const, | ||
254 | lookup: "TEST_CONST", | ||
255 | }, | ||
256 | CompletionItem { | ||
257 | label: "fn test()", | ||
258 | source_range: [209; 210), | ||
259 | delete: [209; 210), | ||
260 | insert: "fn test() {}", | ||
261 | kind: Function, | ||
262 | lookup: "test", | ||
263 | }, | ||
264 | CompletionItem { | ||
265 | label: "type TestType = ", | ||
266 | source_range: [209; 210), | ||
267 | delete: [209; 210), | ||
268 | insert: "type TestType = ", | ||
269 | kind: TypeAlias, | ||
270 | lookup: "TestType", | ||
271 | }, | ||
272 | ] | ||
273 | "###); | ||
274 | } | ||
275 | |||
276 | #[test] | ||
277 | fn name_ref_single_function() { | ||
278 | let completions = complete( | ||
279 | r" | ||
280 | trait Test { | ||
281 | fn test(); | ||
282 | } | ||
283 | |||
284 | struct T1; | ||
285 | |||
286 | impl Test for T1 { | ||
287 | t<|> | ||
288 | } | ||
289 | ", | ||
290 | ); | ||
291 | assert_debug_snapshot!(completions, @r###" | ||
292 | [ | ||
293 | CompletionItem { | ||
294 | label: "fn test()", | ||
295 | source_range: [139; 140), | ||
296 | delete: [139; 140), | ||
297 | insert: "fn test() {}", | ||
298 | kind: Function, | ||
299 | lookup: "test", | ||
300 | }, | ||
301 | ] | ||
302 | "###); | ||
303 | } | ||
304 | |||
305 | #[test] | ||
213 | fn single_function() { | 306 | fn single_function() { |
214 | let completions = complete( | 307 | let completions = complete( |
215 | r" | 308 | r" |