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,29 +47,7 @@ use crate::{
47
47
} ;
48
48
49
49
pub ( crate ) fn complete_trait_impl ( acc : & mut Completions , ctx : & CompletionContext ) {
50
- let mut tokens = ctx. token . ancestors ( ) ;
51
- let completion_match = tokens
52
- . find ( |p| match p. kind ( ) {
53
- SyntaxKind :: FN_DEF
54
- | SyntaxKind :: TYPE_ALIAS_DEF
55
- | SyntaxKind :: CONST_DEF
56
- | SyntaxKind :: NAME_REF
57
- | SyntaxKind :: BLOCK_EXPR => true ,
58
- _ => false ,
59
- } )
60
- . and_then ( |trigger| {
61
- for p in tokens {
62
- match p. kind ( ) {
63
- // No nested completions
64
- SyntaxKind :: FN_DEF | SyntaxKind :: BLOCK => return None ,
65
- SyntaxKind :: IMPL_DEF => return ast:: ImplDef :: cast ( p) . map ( |p| ( trigger, p) ) ,
66
- _ => { }
67
- }
68
- }
69
- None
70
- } ) ;
71
-
72
- if let Some ( ( trigger, impl_def) ) = completion_match {
50
+ if let Some ( ( trigger, impl_def) ) = completion_match ( ctx) {
73
51
match trigger. kind ( ) {
74
52
SyntaxKind :: NAME_REF => {
75
53
get_missing_impl_items ( & ctx. sema , & impl_def) . iter ( ) . for_each ( |item| match item {
@@ -123,6 +101,36 @@ pub(crate) fn complete_trait_impl(acc: &mut Completions, ctx: &CompletionContext
123
101
}
124
102
}
125
103
104
+ fn completion_match ( ctx : & CompletionContext ) -> Option < ( SyntaxNode , ImplDef ) > {
105
+ let ( trigger_idx, trigger) =
106
+ ctx. token . ancestors ( ) . enumerate ( ) . find ( |( _idx, p) | match p. kind ( ) {
107
+ SyntaxKind :: FN_DEF
108
+ | SyntaxKind :: TYPE_ALIAS_DEF
109
+ | SyntaxKind :: CONST_DEF
110
+ | SyntaxKind :: NAME_REF
111
+ | SyntaxKind :: BLOCK_EXPR => true ,
112
+ _ => false ,
113
+ } ) ?;
114
+ let ( impl_def_idx, impl_def) =
115
+ ctx. token . ancestors ( ) . enumerate ( ) . skip ( trigger_idx + 1 ) . find_map ( |( idx, p) | {
116
+ match p. kind ( ) {
117
+ SyntaxKind :: IMPL_DEF => ast:: ImplDef :: cast ( p) . map ( |p| ( idx, p) ) ,
118
+ _ => None ,
119
+ }
120
+ } ) ?;
121
+ let _is_nested = ctx
122
+ . token
123
+ . ancestors ( )
124
+ . skip ( trigger_idx + 1 )
125
+ . take ( impl_def_idx - trigger_idx - 1 )
126
+ . find_map ( |p| match p. kind ( ) {
127
+ SyntaxKind :: FN_DEF | SyntaxKind :: BLOCK => Some ( ( ) ) ,
128
+ _ => None ,
129
+ } )
130
+ . xor ( Some ( ( ) ) ) ?;
131
+ Some ( ( trigger, impl_def) )
132
+ }
133
+
126
134
fn add_function_impl (
127
135
fn_def_node : & SyntaxNode ,
128
136
acc : & mut Completions ,
@@ -278,6 +286,27 @@ mod tests {
278
286
"### ) ;
279
287
}
280
288
289
+ #[ test]
290
+ fn no_nested_fn_completions ( ) {
291
+ let completions = complete (
292
+ r"
293
+ trait Test {
294
+ fn test();
295
+ fn test2();
296
+ }
297
+
298
+ struct T1;
299
+
300
+ impl Test for T1 {
301
+ fn test() {
302
+ t<|>
303
+ }
304
+ }
305
+ " ,
306
+ ) ;
307
+ assert_debug_snapshot ! ( completions, @r###"[]"### ) ;
308
+ }
309
+
281
310
#[ test]
282
311
fn name_ref_single_function ( ) {
283
312
let completions = complete (
0 commit comments