@@ -29,6 +29,18 @@ pub(crate) enum PatternRefutability {
2929 Irrefutable ,
3030}
3131
32+ #[ derive( Debug ) ]
33+ pub ( crate ) struct PathCompletionContext {
34+ /// If this is a call with () already there
35+ call_kind : Option < CallKind > ,
36+ }
37+
38+ #[ derive( Copy , Clone , Debug , PartialEq , Eq ) ]
39+ pub ( crate ) enum CallKind {
40+ Pat ,
41+ Mac ,
42+ Expr ,
43+ }
3244/// `CompletionContext` is created early during completion to figure out, where
3345/// exactly is the cursor, syntax-wise.
3446#[ derive( Debug ) ]
@@ -68,6 +80,7 @@ pub(crate) struct CompletionContext<'a> {
6880 pub ( super ) prev_sibling : Option < ImmediatePrevSibling > ,
6981 pub ( super ) attribute_under_caret : Option < ast:: Attr > ,
7082
83+ pub ( super ) path_context : Option < PathCompletionContext > ,
7184 /// FIXME: `ActiveParameter` is string-based, which is very very wrong
7285 pub ( super ) active_parameter : Option < ActiveParameter > ,
7386 /// A single-indent path, like `foo`. `::foo` should not be considered a trivial path.
@@ -78,12 +91,6 @@ pub(crate) struct CompletionContext<'a> {
7891 pub ( super ) can_be_stmt : bool ,
7992 /// `true` if we expect an expression at the cursor position.
8093 pub ( super ) is_expr : bool ,
81- /// If this is a call (method or function) in particular, i.e. the () are already there.
82- pub ( super ) is_call : bool ,
83- /// Like `is_call`, but for tuple patterns.
84- pub ( super ) is_pattern_call : bool ,
85- /// If this is a macro call, i.e. the () are already there.
86- pub ( super ) is_macro_call : bool ,
8794 pub ( super ) is_path_type : bool ,
8895 pub ( super ) has_type_args : bool ,
8996 pub ( super ) locals : Vec < ( String , Local ) > ,
@@ -153,9 +160,7 @@ impl<'a> CompletionContext<'a> {
153160 path_qual : None ,
154161 can_be_stmt : false ,
155162 is_expr : false ,
156- is_call : false ,
157- is_pattern_call : false ,
158- is_macro_call : false ,
163+ path_context : None ,
159164 is_path_type : false ,
160165 has_type_args : false ,
161166 previous_token : None ,
@@ -250,14 +255,14 @@ impl<'a> CompletionContext<'a> {
250255 pub ( crate ) fn has_dot_receiver ( & self ) -> bool {
251256 matches ! (
252257 & self . completion_location,
253- Some ( ImmediateLocation :: FieldAccess { receiver, .. } ) | Some ( ImmediateLocation :: MethodCall { receiver } )
258+ Some ( ImmediateLocation :: FieldAccess { receiver, .. } ) | Some ( ImmediateLocation :: MethodCall { receiver, .. } )
254259 if receiver. is_some( )
255260 )
256261 }
257262
258263 pub ( crate ) fn dot_receiver ( & self ) -> Option < & ast:: Expr > {
259264 match & self . completion_location {
260- Some ( ImmediateLocation :: MethodCall { receiver } )
265+ Some ( ImmediateLocation :: MethodCall { receiver, .. } )
261266 | Some ( ImmediateLocation :: FieldAccess { receiver, .. } ) => receiver. as_ref ( ) ,
262267 _ => None ,
263268 }
@@ -316,6 +321,10 @@ impl<'a> CompletionContext<'a> {
316321 ) || self . attribute_under_caret . is_some ( )
317322 }
318323
324+ pub ( crate ) fn path_call_kind ( & self ) -> Option < CallKind > {
325+ self . path_context . as_ref ( ) . and_then ( |it| it. call_kind )
326+ }
327+
319328 fn fill_impl_def ( & mut self ) {
320329 self . impl_def = self
321330 . sema
@@ -568,17 +577,21 @@ impl<'a> CompletionContext<'a> {
568577 } ;
569578
570579 if let Some ( segment) = ast:: PathSegment :: cast ( parent) {
580+ let mut path_ctx = PathCompletionContext { call_kind : None } ;
571581 let path = segment. parent_path ( ) ;
572- self . is_call = path
573- . syntax ( )
574- . parent ( )
575- . and_then ( ast:: PathExpr :: cast)
576- . and_then ( |it| it. syntax ( ) . parent ( ) . and_then ( ast:: CallExpr :: cast) )
577- . is_some ( ) ;
578- self . is_macro_call = path. syntax ( ) . parent ( ) . and_then ( ast:: MacroCall :: cast) . is_some ( ) ;
579- self . is_pattern_call =
580- path. syntax ( ) . parent ( ) . and_then ( ast:: TupleStructPat :: cast) . is_some ( ) ;
581582
583+ if let Some ( p) = path. syntax ( ) . parent ( ) {
584+ path_ctx. call_kind = match_ast ! {
585+ match p {
586+ ast:: PathExpr ( it) => it. syntax( ) . parent( ) . and_then( ast:: CallExpr :: cast) . map( |_| CallKind :: Expr ) ,
587+ ast:: MacroCall ( _it) => Some ( CallKind :: Mac ) ,
588+ ast:: TupleStructPat ( _it) => Some ( CallKind :: Pat ) ,
589+ _ => None
590+ }
591+ } ;
592+ }
593+ self . path_context = Some ( path_ctx) ;
594+ dbg ! ( & self . path_context) ;
582595 self . is_path_type = path. syntax ( ) . parent ( ) . and_then ( ast:: PathType :: cast) . is_some ( ) ;
583596 self . has_type_args = segment. generic_arg_list ( ) . is_some ( ) ;
584597
@@ -623,8 +636,6 @@ impl<'a> CompletionContext<'a> {
623636 . unwrap_or ( false ) ;
624637 self . is_expr = path. syntax ( ) . parent ( ) . and_then ( ast:: PathExpr :: cast) . is_some ( ) ;
625638 }
626- self . is_call |=
627- matches ! ( self . completion_location, Some ( ImmediateLocation :: MethodCall { .. } ) ) ;
628639 }
629640}
630641
0 commit comments