@@ -57,14 +57,16 @@ impl Completions {
57
57
let kind = match resolution {
58
58
ScopeDef :: ModuleDef ( Module ( ..) ) => CompletionItemKind :: Module ,
59
59
ScopeDef :: ModuleDef ( Function ( func) ) => {
60
- return self . add_function_with_name ( ctx, Some ( local_name) , * func ) ;
60
+ return self . add_function ( ctx, * func , Some ( local_name) ) ;
61
61
}
62
62
ScopeDef :: ModuleDef ( Adt ( hir:: Adt :: Struct ( _) ) ) => CompletionItemKind :: Struct ,
63
63
// FIXME: add CompletionItemKind::Union
64
64
ScopeDef :: ModuleDef ( Adt ( hir:: Adt :: Union ( _) ) ) => CompletionItemKind :: Struct ,
65
65
ScopeDef :: ModuleDef ( Adt ( hir:: Adt :: Enum ( _) ) ) => CompletionItemKind :: Enum ,
66
66
67
- ScopeDef :: ModuleDef ( EnumVariant ( ..) ) => CompletionItemKind :: EnumVariant ,
67
+ ScopeDef :: ModuleDef ( EnumVariant ( var) ) => {
68
+ return self . add_enum_variant ( ctx, * var, Some ( local_name) ) ;
69
+ }
68
70
ScopeDef :: ModuleDef ( Const ( ..) ) => CompletionItemKind :: Const ,
69
71
ScopeDef :: ModuleDef ( Static ( ..) ) => CompletionItemKind :: Static ,
70
72
ScopeDef :: ModuleDef ( Trait ( ..) ) => CompletionItemKind :: Trait ,
@@ -125,10 +127,6 @@ impl Completions {
125
127
completion_item. kind ( kind) . set_documentation ( docs) . add_to ( self )
126
128
}
127
129
128
- pub ( crate ) fn add_function ( & mut self , ctx : & CompletionContext , func : hir:: Function ) {
129
- self . add_function_with_name ( ctx, None , func)
130
- }
131
-
132
130
fn guess_macro_braces ( & self , macro_name : & str , docs : & str ) -> & ' static str {
133
131
let mut votes = [ 0 , 0 , 0 ] ;
134
132
for ( idx, s) in docs. match_indices ( & macro_name) {
@@ -187,15 +185,15 @@ impl Completions {
187
185
self . add ( builder) ;
188
186
}
189
187
190
- fn add_function_with_name (
188
+ pub ( crate ) fn add_function (
191
189
& mut self ,
192
190
ctx : & CompletionContext ,
193
- name : Option < String > ,
194
191
func : hir:: Function ,
192
+ local_name : Option < String > ,
195
193
) {
196
194
let has_self_param = func. has_self_param ( ctx. db ) ;
197
195
198
- let name = name . unwrap_or_else ( || func. name ( ctx. db ) . to_string ( ) ) ;
196
+ let name = local_name . unwrap_or_else ( || func. name ( ctx. db ) . to_string ( ) ) ;
199
197
let ast_node = func. source ( ctx. db ) . value ;
200
198
let function_signature = FunctionSignature :: from ( & ast_node) ;
201
199
@@ -217,7 +215,7 @@ impl Completions {
217
215
. cloned ( )
218
216
. collect ( ) ;
219
217
220
- builder = builder. add_call_parens ( ctx, name, params) ;
218
+ builder = builder. add_call_parens ( ctx, name, Params :: Named ( params) ) ;
221
219
222
220
self . add ( builder)
223
221
}
@@ -254,14 +252,20 @@ impl Completions {
254
252
. add_to ( self ) ;
255
253
}
256
254
257
- pub ( crate ) fn add_enum_variant ( & mut self , ctx : & CompletionContext , variant : hir:: EnumVariant ) {
255
+ pub ( crate ) fn add_enum_variant (
256
+ & mut self ,
257
+ ctx : & CompletionContext ,
258
+ variant : hir:: EnumVariant ,
259
+ local_name : Option < String > ,
260
+ ) {
258
261
let is_deprecated = is_deprecated ( variant, ctx. db ) ;
259
- let name = variant. name ( ctx. db ) ;
262
+ let name = local_name . unwrap_or_else ( || variant. name ( ctx. db ) . to_string ( ) ) ;
260
263
let detail_types = variant
261
264
. fields ( ctx. db )
262
265
. into_iter ( )
263
266
. map ( |field| ( field. name ( ctx. db ) , field. signature_ty ( ctx. db ) ) ) ;
264
- let detail = match variant. kind ( ctx. db ) {
267
+ let variant_kind = variant. kind ( ctx. db ) ;
268
+ let detail = match variant_kind {
265
269
StructKind :: Tuple | StructKind :: Unit => detail_types
266
270
. map ( |( _, t) | t. display ( ctx. db ) . to_string ( ) )
267
271
. sep_by ( ", " )
@@ -273,22 +277,42 @@ impl Completions {
273
277
. surround_with ( "{ " , " }" )
274
278
. to_string ( ) ,
275
279
} ;
276
- CompletionItem :: new ( CompletionKind :: Reference , ctx. source_range ( ) , name. to_string ( ) )
277
- . kind ( CompletionItemKind :: EnumVariant )
278
- . set_documentation ( variant. docs ( ctx. db ) )
279
- . set_deprecated ( is_deprecated)
280
- . detail ( detail)
281
- . add_to ( self ) ;
280
+ let mut res =
281
+ CompletionItem :: new ( CompletionKind :: Reference , ctx. source_range ( ) , name. clone ( ) )
282
+ . kind ( CompletionItemKind :: EnumVariant )
283
+ . set_documentation ( variant. docs ( ctx. db ) )
284
+ . set_deprecated ( is_deprecated)
285
+ . detail ( detail) ;
286
+
287
+ if variant_kind == StructKind :: Tuple {
288
+ let params = Params :: Anonymous ( variant. fields ( ctx. db ) . len ( ) ) ;
289
+ res = res. add_call_parens ( ctx, name, params)
290
+ }
291
+
292
+ res. add_to ( self ) ;
293
+ }
294
+ }
295
+
296
+ enum Params {
297
+ Named ( Vec < String > ) ,
298
+ Anonymous ( usize ) ,
299
+ }
300
+
301
+ impl Params {
302
+ fn len ( & self ) -> usize {
303
+ match self {
304
+ Params :: Named ( xs) => xs. len ( ) ,
305
+ Params :: Anonymous ( len) => * len,
306
+ }
307
+ }
308
+
309
+ fn is_empty ( & self ) -> bool {
310
+ self . len ( ) == 0
282
311
}
283
312
}
284
313
285
314
impl Builder {
286
- fn add_call_parens (
287
- mut self ,
288
- ctx : & CompletionContext ,
289
- name : String ,
290
- params : Vec < String > ,
291
- ) -> Builder {
315
+ fn add_call_parens ( mut self , ctx : & CompletionContext , name : String , params : Params ) -> Builder {
292
316
if !ctx. config . add_call_parenthesis {
293
317
return self ;
294
318
}
@@ -302,15 +326,16 @@ impl Builder {
302
326
( format ! ( "{}()$0" , name) , format ! ( "{}()" , name) )
303
327
} else {
304
328
self = self . trigger_call_info ( ) ;
305
- let snippet = if ctx. config . add_call_argument_snippets {
306
- let function_params_snippet = params
307
- . iter ( )
308
- . enumerate ( )
309
- . map ( |( index, param_name) | format ! ( "${{{}:{}}}" , index + 1 , param_name) )
310
- . sep_by ( ", " ) ;
311
- format ! ( "{}({})$0" , name, function_params_snippet)
312
- } else {
313
- format ! ( "{}($0)" , name)
329
+ let snippet = match ( ctx. config . add_call_argument_snippets , params) {
330
+ ( true , Params :: Named ( params) ) => {
331
+ let function_params_snippet = params
332
+ . iter ( )
333
+ . enumerate ( )
334
+ . map ( |( index, param_name) | format ! ( "${{{}:{}}}" , index + 1 , param_name) )
335
+ . sep_by ( ", " ) ;
336
+ format ! ( "{}({})$0" , name, function_params_snippet)
337
+ }
338
+ _ => format ! ( "{}($0)" , name) ,
314
339
} ;
315
340
316
341
( snippet, format ! ( "{}(…)" , name) )
@@ -385,12 +410,14 @@ mod tests {
385
410
@r###"
386
411
[
387
412
CompletionItem {
388
- label: "Foo",
413
+ label: "Foo(…) ",
389
414
source_range: [115; 117),
390
415
delete: [115; 117),
391
- insert: "Foo",
416
+ insert: "Foo($0) ",
392
417
kind: EnumVariant,
418
+ lookup: "Foo",
393
419
detail: "(i32, i32)",
420
+ trigger_call_info: true,
394
421
},
395
422
]"###
396
423
) ;
@@ -564,6 +591,101 @@ mod tests {
564
591
) ;
565
592
}
566
593
594
+ #[ test]
595
+ fn inserts_parens_for_tuple_enums ( ) {
596
+ assert_debug_snapshot ! (
597
+ do_reference_completion(
598
+ r"
599
+ enum Option<T> { Some(T), None }
600
+ use Option::*;
601
+ fn main() -> Option<i32> {
602
+ Som<|>
603
+ }
604
+ "
605
+ ) ,
606
+ @r###"
607
+ [
608
+ CompletionItem {
609
+ label: "None",
610
+ source_range: [144; 147),
611
+ delete: [144; 147),
612
+ insert: "None",
613
+ kind: EnumVariant,
614
+ detail: "()",
615
+ },
616
+ CompletionItem {
617
+ label: "Option",
618
+ source_range: [144; 147),
619
+ delete: [144; 147),
620
+ insert: "Option",
621
+ kind: Enum,
622
+ },
623
+ CompletionItem {
624
+ label: "Some(…)",
625
+ source_range: [144; 147),
626
+ delete: [144; 147),
627
+ insert: "Some($0)",
628
+ kind: EnumVariant,
629
+ lookup: "Some",
630
+ detail: "(T)",
631
+ trigger_call_info: true,
632
+ },
633
+ CompletionItem {
634
+ label: "main()",
635
+ source_range: [144; 147),
636
+ delete: [144; 147),
637
+ insert: "main()$0",
638
+ kind: Function,
639
+ lookup: "main",
640
+ detail: "fn main() -> Option<i32>",
641
+ },
642
+ ]
643
+ "###
644
+ ) ;
645
+ assert_debug_snapshot ! (
646
+ do_reference_completion(
647
+ r"
648
+ enum Option<T> { Some(T), None }
649
+ use Option::*;
650
+ fn main(value: Option<i32>) {
651
+ match value {
652
+ Som<|>
653
+ }
654
+ }
655
+ "
656
+ ) ,
657
+ @r###"
658
+ [
659
+ CompletionItem {
660
+ label: "None",
661
+ source_range: [185; 188),
662
+ delete: [185; 188),
663
+ insert: "None",
664
+ kind: EnumVariant,
665
+ detail: "()",
666
+ },
667
+ CompletionItem {
668
+ label: "Option",
669
+ source_range: [185; 188),
670
+ delete: [185; 188),
671
+ insert: "Option",
672
+ kind: Enum,
673
+ },
674
+ CompletionItem {
675
+ label: "Some(…)",
676
+ source_range: [185; 188),
677
+ delete: [185; 188),
678
+ insert: "Some($0)",
679
+ kind: EnumVariant,
680
+ lookup: "Some",
681
+ detail: "(T)",
682
+ trigger_call_info: true,
683
+ },
684
+ ]
685
+ "###
686
+ ) ;
687
+ }
688
+
567
689
#[ test]
568
690
fn arg_snippets_for_method_call ( ) {
569
691
assert_debug_snapshot ! (
0 commit comments