34
34
use hir:: { self , Docs , HasSource } ;
35
35
use ra_assists:: utils:: get_missing_impl_items;
36
36
use ra_syntax:: {
37
- ast:: { self , edit} ,
37
+ ast:: { self , edit, ImplDef } ,
38
38
AstNode , SyntaxKind , SyntaxNode , TextRange ,
39
39
} ;
40
40
use ra_text_edit:: TextEdit ;
@@ -47,22 +47,22 @@ use crate::{
47
47
} ;
48
48
49
49
pub ( crate ) fn complete_trait_impl ( acc : & mut Completions , ctx : & CompletionContext ) {
50
- let trigger = ctx. token . ancestors ( ) . find ( |p| match p. kind ( ) {
51
- SyntaxKind :: FN_DEF
52
- | SyntaxKind :: TYPE_ALIAS_DEF
53
- | SyntaxKind :: CONST_DEF
54
- | SyntaxKind :: BLOCK_EXPR => true ,
55
- _ => false ,
56
- } ) ;
57
-
58
- let impl_def = trigger
59
- . as_ref ( )
60
- . and_then ( |node| node. parent ( ) )
61
- . and_then ( |node| node. parent ( ) )
62
- . and_then ( ast:: ImplDef :: cast) ;
63
-
64
- if let ( Some ( trigger) , Some ( impl_def) ) = ( trigger, impl_def) {
50
+ if let Some ( ( trigger, impl_def) ) = completion_match ( ctx) {
65
51
match trigger. kind ( ) {
52
+ SyntaxKind :: NAME_REF => {
53
+ get_missing_impl_items ( & ctx. sema , & impl_def) . iter ( ) . for_each ( |item| match item {
54
+ hir:: AssocItem :: Function ( fn_item) => {
55
+ add_function_impl ( & trigger, acc, ctx, & fn_item)
56
+ }
57
+ hir:: AssocItem :: TypeAlias ( type_item) => {
58
+ add_type_alias_impl ( & trigger, acc, ctx, & type_item)
59
+ }
60
+ hir:: AssocItem :: Const ( const_item) => {
61
+ add_const_impl ( & trigger, acc, ctx, & const_item)
62
+ }
63
+ } )
64
+ }
65
+
66
66
SyntaxKind :: FN_DEF => {
67
67
for missing_fn in get_missing_impl_items ( & ctx. sema , & impl_def) . iter ( ) . filter_map (
68
68
|item| match item {
@@ -101,6 +101,21 @@ pub(crate) fn complete_trait_impl(acc: &mut Completions, ctx: &CompletionContext
101
101
}
102
102
}
103
103
104
+ fn completion_match ( ctx : & CompletionContext ) -> Option < ( SyntaxNode , ImplDef ) > {
105
+ let ( trigger, impl_def_offset) = ctx. token . ancestors ( ) . find_map ( |p| match p. kind ( ) {
106
+ SyntaxKind :: FN_DEF
107
+ | SyntaxKind :: TYPE_ALIAS_DEF
108
+ | SyntaxKind :: CONST_DEF
109
+ | SyntaxKind :: BLOCK_EXPR => Some ( ( p, 2 ) ) ,
110
+ SyntaxKind :: NAME_REF => Some ( ( p, 5 ) ) ,
111
+ _ => None ,
112
+ } ) ?;
113
+ let impl_def = ( 0 ..impl_def_offset - 1 )
114
+ . try_fold ( trigger. parent ( ) ?, |t, _| t. parent ( ) )
115
+ . and_then ( ast:: ImplDef :: cast) ?;
116
+ Some ( ( trigger, impl_def) )
117
+ }
118
+
104
119
fn add_function_impl (
105
120
fn_def_node : & SyntaxNode ,
106
121
acc : & mut Completions ,
@@ -209,6 +224,103 @@ mod tests {
209
224
do_completion ( code, CompletionKind :: Magic )
210
225
}
211
226
227
+ #[ test]
228
+ fn name_ref_function_type_const ( ) {
229
+ let completions = complete (
230
+ r"
231
+ trait Test {
232
+ type TestType;
233
+ const TEST_CONST: u16;
234
+ fn test();
235
+ }
236
+
237
+ struct T1;
238
+
239
+ impl Test for T1 {
240
+ t<|>
241
+ }
242
+ " ,
243
+ ) ;
244
+ assert_debug_snapshot ! ( completions, @r###"
245
+ [
246
+ CompletionItem {
247
+ label: "const TEST_CONST: u16 = ",
248
+ source_range: [209; 210),
249
+ delete: [209; 210),
250
+ insert: "const TEST_CONST: u16 = ",
251
+ kind: Const,
252
+ lookup: "TEST_CONST",
253
+ },
254
+ CompletionItem {
255
+ label: "fn test()",
256
+ source_range: [209; 210),
257
+ delete: [209; 210),
258
+ insert: "fn test() {}",
259
+ kind: Function,
260
+ lookup: "test",
261
+ },
262
+ CompletionItem {
263
+ label: "type TestType = ",
264
+ source_range: [209; 210),
265
+ delete: [209; 210),
266
+ insert: "type TestType = ",
267
+ kind: TypeAlias,
268
+ lookup: "TestType",
269
+ },
270
+ ]
271
+ "### ) ;
272
+ }
273
+
274
+ #[ test]
275
+ fn no_nested_fn_completions ( ) {
276
+ let completions = complete (
277
+ r"
278
+ trait Test {
279
+ fn test();
280
+ fn test2();
281
+ }
282
+
283
+ struct T1;
284
+
285
+ impl Test for T1 {
286
+ fn test() {
287
+ t<|>
288
+ }
289
+ }
290
+ " ,
291
+ ) ;
292
+ assert_debug_snapshot ! ( completions, @r###"[]"### ) ;
293
+ }
294
+
295
+ #[ test]
296
+ fn name_ref_single_function ( ) {
297
+ let completions = complete (
298
+ r"
299
+ trait Test {
300
+ fn test();
301
+ }
302
+
303
+ struct T1;
304
+
305
+ impl Test for T1 {
306
+ t<|>
307
+ }
308
+ " ,
309
+ ) ;
310
+ assert_debug_snapshot ! ( completions, @r###"
311
+ [
312
+ CompletionItem {
313
+ label: "fn test()",
314
+ source_range: [139; 140),
315
+ delete: [139; 140),
316
+ insert: "fn test() {}",
317
+ kind: Function,
318
+ lookup: "test",
319
+ },
320
+ ]
321
+ "### ) ;
322
+ }
323
+
212
324
#[ test]
213
325
fn single_function ( ) {
214
326
let completions = complete (
0 commit comments