@@ -3370,6 +3370,8 @@ package body LSP.Ada_Handlers is
33703370 -- --------------------
33713371
33723372 procedure Compute_Response is
3373+ use Libadalang.Common;
3374+
33733375 Context : constant LSP.Ada_Context_Sets.Context_Access :=
33743376 Self.Contexts.Get_Best_Context (Value.textDocument.uri);
33753377 Document : constant LSP.Ada_Documents.Document_Access :=
@@ -3379,15 +3381,9 @@ package body LSP.Ada_Handlers is
33793381
33803382 Position : LSP.Structures.Position := Value.position;
33813383 Node : Libadalang.Analysis.Ada_Node;
3382-
3384+ Token : Libadalang.Common.Token_Reference :=
3385+ Document.Get_Token_At (Context.all , Position);
33833386 begin
3384- -- Move the cursor to the previous character: this is more resilient
3385- -- to invalid code.
3386-
3387- if Position.character > 0 then
3388- Position.character := @ - 1 ;
3389- end if ;
3390-
33913387 Node := Document.Get_Node_At (Context.all , Position);
33923388
33933389 declare
@@ -3414,8 +3410,8 @@ package body LSP.Ada_Handlers is
34143410 end if ;
34153411 end ;
34163412
3417- -- Try to get signatures before the cursor location
3418- -- i.e "Foo (1,|" => "Foo (1|,"
3413+ -- Try to get signatures at the the cursor location
3414+ -- i.e "Foo (1,|"
34193415
34203416 LSP.Ada_Completions.Parameters.Propose_Signatures
34213417 (Context => Context,
@@ -3424,37 +3420,41 @@ package body LSP.Ada_Handlers is
34243420 Prev_Signatures => Value.context,
34253421 Res => Response.Value);
34263422
3427- -- Retry to get signature in the previous non whitespace token
3428- -- i.e. "Foo (1, 2 + |" => "Foo (1, 2 +|"
3429-
34303423 if Response.Value.signatures.Is_Empty then
3431- declare
3432- use all type Libadalang.Common.Token_Kind;
3433- use type Libadalang.Common.Token_Reference;
34343424
3435- Token : Libadalang.Common.Token_Reference :=
3436- Document.Get_Token_At (Context.all , Position);
3425+ -- Retry to get matching signatures from the previous non whitespace/non comma
3426+ -- token.
3427+ -- This is more resilient on invalid code, since we'll have more chances to
3428+ -- retrieve a valid CallExpr node, rather than an ErrorStmt one.
3429+ -- i.e. "Foo (1, 2 + |" => "Foo (1, 2 +|" or "Foo (1, 2,|" => "Foo (1, 2|,"
34373430
3438- begin
3439- if Token /= Libadalang.Common.No_Token
3440- and then Libadalang.Common.Kind
3441- (Libadalang.Common.Data (Token)) = Ada_Whitespace
3442- then
3431+ if Token /= No_Token
3432+ and then Position.character > 0
3433+ and then (Token.Data.Is_Trivia
3434+ or else Token.Data.Kind = Ada_Comma)
3435+ then
3436+ declare
3437+ Prev_Token : constant Token_Reference :=
3438+ Libadalang.Common.Previous (Token, Exclude_Trivia => True);
3439+ begin
34433440 Token :=
3444- Libadalang.Common.Previous
3445- (Token, Exclude_Trivia => True);
3446- end if ;
3447-
3448- Position := LSP.Ada_Handlers.Locations.Start_Position (Token);
3449- end ;
3450-
3451- Node := Document.Get_Node_At (Context.all , Position);
3452- LSP.Ada_Completions.Parameters.Propose_Signatures
3453- (Context => Context,
3454- Node => Node,
3455- Cursor => Location,
3456- Prev_Signatures => Value.context,
3457- Res => Response.Value);
3441+ (if Prev_Token /= No_Token then Prev_Token else Token);
3442+
3443+ -- Recompute the position from the new token and retrieve
3444+ -- the corresponding node.
3445+ Position :=
3446+ LSP.Ada_Handlers.Locations.Start_Position (Token);
3447+ Node := Document.Get_Node_At (Context.all , Position);
3448+
3449+ -- Get the matching signatures
3450+ LSP.Ada_Completions.Parameters.Propose_Signatures
3451+ (Context => Context,
3452+ Node => Node,
3453+ Cursor => Location,
3454+ Prev_Signatures => Value.context,
3455+ Res => Response.Value);
3456+ end ;
3457+ end if ;
34583458 end if ;
34593459
34603460 -- Retry to get signatures in the cursor position.
0 commit comments