@@ -3370,6 +3370,8 @@ package body LSP.Ada_Handlers is
3370
3370
-- --------------------
3371
3371
3372
3372
procedure Compute_Response is
3373
+ use Libadalang.Common;
3374
+
3373
3375
Context : constant LSP.Ada_Context_Sets.Context_Access :=
3374
3376
Self.Contexts.Get_Best_Context (Value.textDocument.uri);
3375
3377
Document : constant LSP.Ada_Documents.Document_Access :=
@@ -3379,15 +3381,9 @@ package body LSP.Ada_Handlers is
3379
3381
3380
3382
Position : LSP.Structures.Position := Value.position;
3381
3383
Node : Libadalang.Analysis.Ada_Node;
3382
-
3384
+ Token : Libadalang.Common.Token_Reference :=
3385
+ Document.Get_Token_At (Context.all , Position);
3383
3386
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
-
3391
3387
Node := Document.Get_Node_At (Context.all , Position);
3392
3388
3393
3389
declare
@@ -3414,8 +3410,8 @@ package body LSP.Ada_Handlers is
3414
3410
end if ;
3415
3411
end ;
3416
3412
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,|"
3419
3415
3420
3416
LSP.Ada_Completions.Parameters.Propose_Signatures
3421
3417
(Context => Context,
@@ -3424,37 +3420,41 @@ package body LSP.Ada_Handlers is
3424
3420
Prev_Signatures => Value.context,
3425
3421
Res => Response.Value);
3426
3422
3427
- -- Retry to get signature in the previous non whitespace token
3428
- -- i.e. "Foo (1, 2 + |" => "Foo (1, 2 +|"
3429
-
3430
3423
if Response.Value.signatures.Is_Empty then
3431
- declare
3432
- use all type Libadalang.Common.Token_Kind;
3433
- use type Libadalang.Common.Token_Reference;
3434
3424
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|,"
3437
3430
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
3443
3440
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 ;
3458
3458
end if ;
3459
3459
3460
3460
-- Retry to get signatures in the cursor position.
0 commit comments