@@ -4,20 +4,19 @@ use hir::{db::HirDatabase, AsAssocItem, HirDisplay};
44use ide_db:: { SnippetCap , SymbolKind } ;
55use itertools:: Itertools ;
66use stdx:: { format_to, to_lower_snake_case} ;
7- use syntax:: SmolStr ;
7+ use syntax:: { AstNode , SmolStr } ;
88
99use crate :: {
10- context:: {
11- CompletionContext , DotAccess , DotAccessKind , PathCompletionCtx , PathKind , Qualified ,
12- } ,
10+ context:: { CompletionContext , DotAccess , DotAccessKind , PathCompletionCtx , PathKind } ,
1311 item:: { Builder , CompletionItem , CompletionItemKind , CompletionRelevance } ,
1412 render:: { compute_exact_name_match, compute_ref_match, compute_type_match, RenderContext } ,
1513 CallableSnippets ,
1614} ;
1715
18- enum FuncKind {
19- Function ,
20- Method ( Option < hir:: Name > ) ,
16+ #[ derive( Debug ) ]
17+ enum FuncKind < ' ctx > {
18+ Function ( & ' ctx PathCompletionCtx ) ,
19+ Method ( & ' ctx DotAccess , Option < hir:: Name > ) ,
2120}
2221
2322pub ( crate ) fn render_fn (
@@ -27,29 +26,7 @@ pub(crate) fn render_fn(
2726 func : hir:: Function ,
2827) -> Builder {
2928 let _p = profile:: span ( "render_fn" ) ;
30- let func_kind = FuncKind :: Function ;
31- let params = match ctx. completion . config . snippet_cap {
32- Some ( _) => {
33- if !matches ! (
34- path_ctx,
35- PathCompletionCtx { kind: PathKind :: Expr { .. } , has_call_parens: true , .. }
36- | PathCompletionCtx { kind: PathKind :: Use | PathKind :: Type { .. } , .. }
37- ) {
38- params ( ctx. completion , func, & func_kind, false )
39- } else {
40- None
41- }
42- }
43- _ => None ,
44- } ;
45- render (
46- ctx,
47- local_name,
48- func,
49- func_kind,
50- params,
51- matches ! ( path_ctx. qualified, Qualified :: With { .. } ) ,
52- )
29+ render ( ctx, local_name, func, FuncKind :: Function ( path_ctx) )
5330}
5431
5532pub ( crate ) fn render_method (
@@ -60,32 +37,21 @@ pub(crate) fn render_method(
6037 func : hir:: Function ,
6138) -> Builder {
6239 let _p = profile:: span ( "render_method" ) ;
63- let func_kind = FuncKind :: Method ( receiver) ;
64- let params = match ctx. completion . config . snippet_cap {
65- Some ( _) => match dot_access {
66- DotAccess { kind : DotAccessKind :: Method { has_parens : true } , .. } => None ,
67- _ => params ( ctx. completion , func, & func_kind, true ) ,
68- } ,
69- _ => None ,
70- } ;
71-
72- render ( ctx, local_name, func, func_kind, params, false )
40+ render ( ctx, local_name, func, FuncKind :: Method ( dot_access, receiver) )
7341}
7442
7543fn render (
7644 ctx @ RenderContext { completion, .. } : RenderContext < ' _ > ,
7745 local_name : Option < hir:: Name > ,
7846 func : hir:: Function ,
7947 func_kind : FuncKind ,
80- params : Option < ( Option < hir:: SelfParam > , Vec < hir:: Param > ) > ,
81- qualified_path : bool ,
8248) -> Builder {
8349 let db = completion. db ;
8450
8551 let name = local_name. unwrap_or_else ( || func. name ( db) ) ;
8652
8753 let call = match & func_kind {
88- FuncKind :: Method ( Some ( receiver) ) => format ! ( "{}.{}" , receiver, & name) . into ( ) ,
54+ FuncKind :: Method ( _ , Some ( receiver) ) => format ! ( "{}.{}" , receiver, & name) . into ( ) ,
8955 _ => name. to_smol_str ( ) ,
9056 } ;
9157 let mut item = CompletionItem :: new (
@@ -111,11 +77,14 @@ fn render(
11177 } ) ;
11278
11379 if let Some ( ref_match) = compute_ref_match ( completion, & ret_type) {
114- // FIXME For now we don't properly calculate the edits for ref match
115- // completions on methods or qualified paths, so we've disabled them.
116- // See #8058.
117- if matches ! ( func_kind, FuncKind :: Function ) && !qualified_path {
118- item. ref_match ( ref_match) ;
80+ match func_kind {
81+ FuncKind :: Function ( path_ctx) => {
82+ item. ref_match ( ref_match, path_ctx. path . syntax ( ) . text_range ( ) . start ( ) ) ;
83+ }
84+ FuncKind :: Method ( DotAccess { receiver : Some ( receiver) , .. } , _) => {
85+ item. ref_match ( ref_match, receiver. syntax ( ) . text_range ( ) . start ( ) ) ;
86+ }
87+ _ => ( ) ,
11988 }
12089 }
12190
@@ -124,12 +93,34 @@ fn render(
12493 . detail ( detail ( db, func) )
12594 . lookup_by ( name. to_smol_str ( ) ) ;
12695
127- match completion. config . snippet_cap . zip ( params) {
128- Some ( ( cap, ( self_param, params) ) ) => {
129- add_call_parens ( & mut item, completion, cap, call, self_param, params) ;
96+ match ctx. completion . config . snippet_cap {
97+ Some ( cap) => {
98+ let complete_params = match func_kind {
99+ FuncKind :: Function ( PathCompletionCtx {
100+ kind : PathKind :: Expr { .. } ,
101+ has_call_parens : false ,
102+ ..
103+ } ) => Some ( false ) ,
104+ FuncKind :: Method (
105+ DotAccess {
106+ kind :
107+ DotAccessKind :: Method { has_parens : false } | DotAccessKind :: Field { .. } ,
108+ ..
109+ } ,
110+ _,
111+ ) => Some ( true ) ,
112+ _ => None ,
113+ } ;
114+ if let Some ( has_dot_receiver) = complete_params {
115+ if let Some ( ( self_param, params) ) =
116+ params ( ctx. completion , func, & func_kind, has_dot_receiver)
117+ {
118+ add_call_parens ( & mut item, completion, cap, call, self_param, params) ;
119+ }
120+ }
130121 }
131122 _ => ( ) ,
132- }
123+ } ;
133124
134125 match ctx. import_to_add {
135126 Some ( import_to_add) => {
@@ -291,7 +282,7 @@ fn params(
291282 }
292283 }
293284
294- let self_param = if has_dot_receiver || matches ! ( func_kind, FuncKind :: Method ( Some ( _) ) ) {
285+ let self_param = if has_dot_receiver || matches ! ( func_kind, FuncKind :: Method ( _ , Some ( _) ) ) {
295286 None
296287 } else {
297288 func. self_param ( ctx. db )
0 commit comments