Skip to content

Commit 3ffcb2f

Browse files
U805-023: use previous context in signatureHelp
If available try to reuse the signatureHelpContext which contains the previous signatures: it's faster to just filter them that recompute a new list of signatures. Edge case for "\b": removing a character can make more signatures valid and they could not be contained in the previous signature => always recompute the list. Adapt tests: retriggerCharacters have changed Add a new test.
1 parent 4c185dc commit 3ffcb2f

File tree

13 files changed

+1555
-21
lines changed

13 files changed

+1555
-21
lines changed

source/ada/lsp-ada_handlers.adb

Lines changed: 156 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -697,7 +697,7 @@ package body LSP.Ada_Handlers is
697697
Response.result.capabilities.signatureHelpProvider :=
698698
(True,
699699
(triggerCharacters => (True, Empty_Vector & (+",") & (+"(")),
700-
retriggerCharacters => (True, Empty_Vector & (+" ")),
700+
retriggerCharacters => (True, Empty_Vector & (+(1 => ASCII.BS))),
701701
workDoneProgress => LSP.Types.None));
702702
Response.result.capabilities.completionProvider :=
703703
(True,
@@ -2494,11 +2494,33 @@ package body LSP.Ada_Handlers is
24942494
Sloc : constant Langkit_Support.Slocs.Source_Location :=
24952495
Document.Get_Source_Location (Value.position);
24962496

2497-
Name_Node : Libadalang.Analysis.Name;
2498-
Designator : Libadalang.Analysis.Ada_Node;
2499-
Active_Position : LSP.Types.LSP_Number;
2497+
Name_Node : Libadalang.Analysis.Name;
2498+
Designator : Libadalang.Analysis.Ada_Node;
2499+
Active_Position : LSP.Types.LSP_Number;
2500+
Active_Signature : LSP.Types.LSP_Number := 0;
25002501

25012502
procedure Add_Signature (Decl_Node : Libadalang.Analysis.Basic_Decl);
2503+
-- Add the signature of Decl_Node if it matches the current context.
2504+
2505+
procedure Filter_Signature
2506+
(Signature_Info : SignatureInformation;
2507+
Designator : Libadalang.Analysis.Ada_Node;
2508+
Position : LSP.Types.LSP_Number;
2509+
Is_Active : Boolean);
2510+
-- Filter the signatures returned by the client using the current
2511+
-- current Position and designator.
2512+
-- Set Active_Signature to 0 when Is_Active and filtered out.
2513+
2514+
function Is_Signature_Active
2515+
(Parameters : ParameterInformation_Vector;
2516+
Sig_Label : LSP.Types.LSP_String;
2517+
Position : LSP.Types.LSP_Number;
2518+
Designator : Libadalang.Analysis.Ada_Node;
2519+
Active_Position : out LSP.Types.LSP_Number)
2520+
return Boolean;
2521+
-- Return True if Parameters is valid for the current Position and
2522+
-- Designator.
2523+
-- Active_Position will point to the active parameter inside Parameters.
25022524

25032525
-------------------
25042526
-- Add_Signature --
@@ -2537,6 +2559,88 @@ package body LSP.Ada_Handlers is
25372559
end;
25382560
end Add_Signature;
25392561

2562+
----------------------
2563+
-- Filter_Signature --
2564+
----------------------
2565+
2566+
procedure Filter_Signature
2567+
(Signature_Info : SignatureInformation;
2568+
Designator : Libadalang.Analysis.Ada_Node;
2569+
Position : LSP.Types.LSP_Number;
2570+
Is_Active : Boolean)
2571+
is
2572+
Active_Position : LSP.Types.LSP_Number;
2573+
begin
2574+
if Is_Signature_Active
2575+
(Parameters => Signature_Info.parameters,
2576+
Sig_Label => Signature_Info.label,
2577+
Position => Position,
2578+
Designator => Designator,
2579+
Active_Position => Active_Position)
2580+
then
2581+
declare
2582+
New_Signature : SignatureInformation := Signature_Info;
2583+
begin
2584+
-- Reuse Signature_Info after updating the active_position
2585+
New_Signature.activeParameter := (Is_Set => True,
2586+
Value => Active_Position);
2587+
Response.result.signatures.Append (New_Signature);
2588+
end;
2589+
elsif Is_Active then
2590+
Active_Signature := 0;
2591+
end if;
2592+
end Filter_Signature;
2593+
2594+
-------------------------
2595+
-- Is_Signature_Active --
2596+
-------------------------
2597+
2598+
function Is_Signature_Active
2599+
(Parameters : ParameterInformation_Vector;
2600+
Sig_Label : LSP.Types.LSP_String;
2601+
Position : LSP.Types.LSP_Number;
2602+
Designator : Libadalang.Analysis.Ada_Node;
2603+
Active_Position : out LSP.Types.LSP_Number)
2604+
return Boolean
2605+
is
2606+
use VSS.Strings;
2607+
begin
2608+
Active_Position := 0;
2609+
if Designator = No_Ada_Node then
2610+
-- Check if Position is valid in Parameters (Note: Position starts
2611+
-- at 0)
2612+
Active_Position := Position;
2613+
return Position < LSP_Number (Parameters.Length);
2614+
else
2615+
declare
2616+
Name : constant Virtual_String :=
2617+
LSP.Lal_Utils.To_Virtual_String (Designator.Text);
2618+
Converted_Name : constant LSP_String :=
2619+
LSP.Types.To_LSP_String (Name);
2620+
begin
2621+
for Param of Parameters loop
2622+
-- Convert to lower case?
2623+
if Param.label.Is_String then
2624+
if Param.label.String = Name then
2625+
return True;
2626+
end if;
2627+
else
2628+
if Slice (Sig_Label,
2629+
Integer (Param.label.From),
2630+
Integer (Param.label.Till))
2631+
= Converted_Name
2632+
then
2633+
return True;
2634+
end if;
2635+
end if;
2636+
Active_Position := Active_Position + 1;
2637+
end loop;
2638+
end;
2639+
end if;
2640+
2641+
return False;
2642+
end Is_Signature_Active;
2643+
25402644
begin
25412645
Response.result := (others => <>);
25422646

@@ -2552,18 +2656,57 @@ package body LSP.Ada_Handlers is
25522656
return Response;
25532657
end if;
25542658

2555-
for N of C.Find_All_Env_Elements (Name_Node) loop
2556-
if N.Kind in Ada_Subp_Decl_Range
2557-
| Ada_Null_Subp_Decl_Range
2558-
| Ada_Expr_Function_Range
2559-
then
2560-
Add_Signature (N.As_Basic_Decl);
2561-
end if;
2562-
end loop;
2659+
if Value.context.Is_Set
2660+
and then Value.context.Value.isRetrigger
2661+
and then Value.context.Value.activeSignatureHelp.Is_Set
2662+
and then
2663+
(Value.context.Value.triggerKind /= TriggerCharacter
2664+
or else
2665+
-- Check if the trigger character is a backspace
2666+
((not Value.context.Value.triggerCharacter.Is_Set)
2667+
or else Value.context.Value.triggerCharacter.Value /=
2668+
(+(1 => ASCII.BS))))
2669+
then
2670+
-- At this point, we are filtering the previous signatures:
2671+
-- * Don't recompute the list of signature
2672+
-- * Keep the previous activeSignature if not filtered out
2673+
2674+
declare
2675+
Prev_Res : SignatureHelp renames
2676+
Value.context.Value.activeSignatureHelp.Value;
2677+
-- Use index to find the activeSignature
2678+
Index : LSP.Types.LSP_Number := 0;
2679+
begin
2680+
if Prev_Res.activeSignature.Is_Set then
2681+
Active_Signature := Prev_Res.activeSignature.Value;
2682+
else
2683+
Active_Signature := 0;
2684+
end if;
2685+
2686+
for Signature_Info of Prev_Res.signatures loop
2687+
Filter_Signature
2688+
(Signature_Info => Signature_Info,
2689+
Designator => Designator,
2690+
Position => Active_Position,
2691+
Is_Active => Index = Active_Signature);
2692+
Index := Index + 1;
2693+
end loop;
2694+
end;
2695+
else
2696+
2697+
for N of C.Find_All_Env_Elements (Name_Node) loop
2698+
if N.Kind in Ada_Subp_Decl_Range
2699+
| Ada_Null_Subp_Decl_Range
2700+
| Ada_Expr_Function_Range
2701+
then
2702+
Add_Signature (N.As_Basic_Decl);
2703+
end if;
2704+
end loop;
2705+
end if;
25632706

25642707
-- Set the active values to default
25652708
Response.result.activeSignature := (Is_Set => True,
2566-
Value => 0);
2709+
Value => Active_Signature);
25672710
-- activeParameter will be ignored because it is properly set in
25682711
-- the signatures.
25692712
Response.result.activeParameter := (Is_Set => True,

testsuite/ada_lsp/T723-027.signatureHelp.nested/test.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@
4949
"("
5050
],
5151
"retriggerCharacters": [
52-
" "
52+
"\b"
5353
]
5454
},
5555
"definitionProvider": true

testsuite/ada_lsp/T723-027.signatureHelp.overloaded/test.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@
4848
"("
4949
],
5050
"retriggerCharacters": [
51-
" "
51+
"\b"
5252
]
5353
},
5454
"definitionProvider": true

testsuite/ada_lsp/T723-027.signatureHelp.simple/test.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@
4848
"("
4949
],
5050
"retriggerCharacters": [
51-
" "
51+
"\b"
5252
]
5353
},
5454
"definitionProvider": true

testsuite/ada_lsp/T826-026.search/test.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@
9393
"("
9494
],
9595
"retriggerCharacters": [
96-
" "
96+
"\b"
9797
]
9898
},
9999
"declarationProvider": true,

testsuite/ada_lsp/U429-030.signatureHelp.dot_call/test.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@
5050
"("
5151
],
5252
"retriggerCharacters": [
53-
" "
53+
"\b"
5454
]
5555
},
5656
"definitionProvider": true

testsuite/ada_lsp/U511-009.refactoring.import_with_use/test.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@
4747
"("
4848
],
4949
"retriggerCharacters": [
50-
" "
50+
"\b"
5151
]
5252
},
5353
"definitionProvider": true

testsuite/ada_lsp/U614-038.edits.no_project/test.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -242,7 +242,7 @@
242242
"("
243243
],
244244
"retriggerCharacters": [
245-
" "
245+
"\b"
246246
]
247247
},
248248
"declarationProvider": true,

testsuite/ada_lsp/U721-012.signatureHelp.null_expr_funcs/test.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@
9494
"("
9595
],
9696
"retriggerCharacters": [
97-
" "
97+
"\b"
9898
]
9999
},
100100
"declarationProvider": true,
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
procedure Foo is
2+
procedure Bar (I, J : Integer);
3+
procedure Bar (I : Integer; F : Float);
4+
function Bar (I : Integer) return Integer is (1);
5+
6+
---------
7+
-- Bar --
8+
---------
9+
10+
procedure Bar (I, J : Integer) is
11+
begin
12+
null;
13+
end Bar;
14+
15+
---------
16+
-- Bar --
17+
---------
18+
19+
procedure Bar (I : Integer; F : Float) is
20+
begin
21+
null;
22+
end Bar;
23+
24+
begin
25+
Bar (1
26+
end Foo;

0 commit comments

Comments
 (0)