Skip to content

Commit 8b33b93

Browse files
T713-012: Completion for generic package parameters
Fix PP offset and adapt tests. Add tests.
1 parent 148f6af commit 8b33b93

File tree

18 files changed

+1357
-11
lines changed

18 files changed

+1357
-11
lines changed

source/ada/lsp-ada_completions-generic_assoc.adb

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,9 @@ package body LSP.Ada_Completions.Generic_Assoc is
5252
Prefix : VSS.Strings.Virtual_String;
5353
-- The whole string before the snippet (including whitespaces)
5454

55+
Column : Langkit_Support.Slocs.Column_Number;
56+
-- Use Column as the block indentation
57+
5558
Prefix_Span : LSP.Messages.Span;
5659
-- The span covering Prefix.
5760

@@ -275,8 +278,10 @@ package body LSP.Ada_Completions.Generic_Assoc is
275278
(Context => Self.Context.all,
276279
Prefix =>
277280
VSS.Strings.Conversions.To_UTF_8_String (Prefix),
281+
-- "column = offset - 1"
282+
Offset => Integer (Column) - 1,
278283
Span => Prefix_Span,
279-
Rule => Libadalang.Common.Param_Assoc_Rule,
284+
Rule => Pretty_Print_Rule,
280285
Result => Item);
281286
Unsorted_Res.Append (Item);
282287
end;
@@ -292,7 +297,8 @@ package body LSP.Ada_Completions.Generic_Assoc is
292297
Prefix_Span :=
293298
Self.Document.To_LSP_Range
294299
(Langkit_Support.Slocs.Make_Range
295-
(Langkit_Support.Slocs.Start_Sloc (Node.Parent.Sloc_Range),
300+
(Langkit_Support.Slocs.Start_Sloc
301+
(Get_Prefix_Node (Elem_Node, Column => Column).Sloc_Range),
296302
Sloc));
297303
Prefix := Self.Document.Get_Text_At
298304
(Prefix_Span.first, Prefix_Span.last);

source/ada/lsp-ada_completions-generic_assoc.ads

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,15 @@ generic
4646
return LSP.Ada_Completions.Generic_Assoc_Utils.Assoc_Data_Lists.List;
4747
-- Return all the specs matching E
4848

49+
Pretty_Print_Rule : Libadalang.Common.Grammar_Rule;
50+
-- Rule used to pretty print the completion item
51+
52+
with function Get_Prefix_Node
53+
(E : Element;
54+
Column : out Langkit_Support.Slocs.Column_Number)
55+
return Libadalang.Analysis.Ada_Node'Class;
56+
-- Get the node needed to match Pretty_Print_Rule
57+
-- Column represent the block indentation level
4958
package LSP.Ada_Completions.Generic_Assoc is
5059
procedure Propose_Completion
5160
(Self :

source/ada/lsp-ada_completions-parameters.adb

Lines changed: 187 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,11 +36,17 @@ package body LSP.Ada_Completions.Parameters is
3636
(C : Libadalang.Analysis.Call_Expr;
3737
Context : not null LSP.Ada_Handlers.Context_Access)
3838
return LSP.Ada_Completions.Generic_Assoc_Utils.Assoc_Data_Lists.List;
39+
function Get_Prefix_Node
40+
(C : Libadalang.Analysis.Call_Expr;
41+
Column : out Langkit_Support.Slocs.Column_Number)
42+
return Libadalang.Analysis.Ada_Node'Class;
3943

4044
package Call_Expr_Completion is new
4145
LSP.Ada_Completions.Generic_Assoc
4246
(Element => Libadalang.Analysis.Call_Expr,
4347
Null_Element => Libadalang.Analysis.No_Call_Expr,
48+
Pretty_Print_Rule => Libadalang.Common.Param_Assoc_Rule,
49+
Get_Prefix_Node => Get_Prefix_Node,
4450
Search_Element => LSP.Lal_Utils.Get_Call_Expr,
4551
Get_Designators => LSP.Lal_Utils.Get_Call_Designators,
4652
Get_Spec_Designators => Get_Spec_Call_Expr_Designators);
@@ -55,15 +61,52 @@ package body LSP.Ada_Completions.Parameters is
5561
(A : Libadalang.Analysis.Aggregate;
5662
Context : not null LSP.Ada_Handlers.Context_Access)
5763
return LSP.Ada_Completions.Generic_Assoc_Utils.Assoc_Data_Lists.List;
64+
function Get_Prefix_Node
65+
(A : Libadalang.Analysis.Aggregate;
66+
Column : out Langkit_Support.Slocs.Column_Number)
67+
return Libadalang.Analysis.Ada_Node'Class;
5868

5969
package Aggregate_Completion is new
6070
LSP.Ada_Completions.Generic_Assoc
6171
(Element => Libadalang.Analysis.Aggregate,
6272
Null_Element => Libadalang.Analysis.No_Aggregate,
73+
Pretty_Print_Rule => Libadalang.Common.Param_Assoc_Rule,
74+
Get_Prefix_Node => Get_Prefix_Node,
6375
Search_Element => Get_Aggregate,
6476
Get_Designators => Get_Designators,
6577
Get_Spec_Designators => Get_Spec_Aggregate_Designators);
6678

79+
function Get_Generic_Package
80+
(N : Libadalang.Analysis.Ada_Node'Class)
81+
return Libadalang.Analysis.Generic_Package_Instantiation;
82+
function Get_Designators
83+
(G : Libadalang.Analysis.Generic_Package_Instantiation)
84+
return Laltools.Common.Node_Vectors.Vector;
85+
function Get_Decl_Designators
86+
(G : Libadalang.Analysis.Generic_Package_Instantiation;
87+
Context : not null LSP.Ada_Handlers.Context_Access)
88+
return LSP.Ada_Completions.Generic_Assoc_Utils.Assoc_Data_Lists.List;
89+
function Get_Prefix_Node
90+
(G : Libadalang.Analysis.Generic_Package_Instantiation;
91+
Column : out Langkit_Support.Slocs.Column_Number)
92+
return Libadalang.Analysis.Ada_Node'Class;
93+
94+
package Generic_Package_Completion is new
95+
LSP.Ada_Completions.Generic_Assoc
96+
(Element =>
97+
Libadalang.Analysis.Generic_Package_Instantiation,
98+
Null_Element =>
99+
Libadalang.Analysis.No_Generic_Package_Instantiation,
100+
-- GNATpp is having trouble formatting a LAL tree representing
101+
-- Generic_Package_Instanciation_Rule
102+
-- => retrieve the nested Assoc_List and format it as a function
103+
-- call.
104+
Pretty_Print_Rule => Libadalang.Common.Param_Assoc_Rule,
105+
Get_Prefix_Node => Get_Prefix_Node,
106+
Search_Element => Get_Generic_Package,
107+
Get_Designators => Get_Designators,
108+
Get_Spec_Designators => Get_Decl_Designators);
109+
67110
------------------------------------
68111
-- Get_Spec_Call_Expr_Designators --
69112
------------------------------------
@@ -428,6 +471,140 @@ package body LSP.Ada_Completions.Parameters is
428471
return Res;
429472
end Get_Spec_Aggregate_Designators;
430473

474+
-------------------------
475+
-- Get_Generic_Package --
476+
-------------------------
477+
478+
function Get_Generic_Package
479+
(N : Libadalang.Analysis.Ada_Node'Class)
480+
return Libadalang.Analysis.Generic_Package_Instantiation
481+
is
482+
begin
483+
if N.Kind in Ada_Generic_Package_Instantiation_Range then
484+
return N.As_Generic_Package_Instantiation;
485+
end if;
486+
487+
declare
488+
N_Parent : constant Libadalang.Analysis.Ada_Node'Class := N.Parent;
489+
begin
490+
if not N_Parent.Is_Null
491+
and then N_Parent.Kind in Ada_Generic_Package_Instantiation_Range
492+
then
493+
return N_Parent.As_Generic_Package_Instantiation;
494+
end if;
495+
end;
496+
return No_Generic_Package_Instantiation;
497+
end Get_Generic_Package;
498+
499+
---------------------
500+
-- Get_Designators --
501+
---------------------
502+
503+
function Get_Designators
504+
(G : Libadalang.Analysis.Generic_Package_Instantiation)
505+
return Laltools.Common.Node_Vectors.Vector
506+
is
507+
Designator : Libadalang.Analysis.Ada_Node;
508+
Res : Laltools.Common.Node_Vectors.Vector;
509+
begin
510+
for Assoc of G.F_Params loop
511+
Designator := Assoc.As_Param_Assoc.F_Designator;
512+
if Designator /= No_Ada_Node then
513+
Res.Append (Designator);
514+
end if;
515+
end loop;
516+
517+
return Res;
518+
end Get_Designators;
519+
520+
--------------------------
521+
-- Get_Decl_Designators --
522+
--------------------------
523+
524+
function Get_Decl_Designators
525+
(G : Libadalang.Analysis.Generic_Package_Instantiation;
526+
Context : not null LSP.Ada_Handlers.Context_Access)
527+
return LSP.Ada_Completions.Generic_Assoc_Utils.Assoc_Data_Lists.List
528+
is
529+
Res :
530+
LSP.Ada_Completions.Generic_Assoc_Utils.Assoc_Data_Lists.List;
531+
Name_Node : constant Libadalang.Analysis.Name := G.F_Generic_Pkg_Name;
532+
begin
533+
for N of reverse Context.Find_All_Env_Elements (Name_Node) loop
534+
if N.Kind in Ada_Generic_Package_Decl_Range then
535+
declare
536+
Assoc : LSP.Ada_Completions.Generic_Assoc_Utils.Assoc_Data;
537+
Decl : constant Libadalang.Analysis.Generic_Package_Decl
538+
:= N.As_Generic_Package_Decl;
539+
begin
540+
Assoc.Title.Append ("Params of ");
541+
Assoc.Title.Append
542+
(VSS.Strings.To_Virtual_String (Name_Node.Text));
543+
Assoc.Decl := N.As_Basic_Decl;
544+
545+
for Param of Decl.F_Formal_Part.F_Decls loop
546+
if Param.Kind in Ada_Generic_Formal then
547+
declare
548+
Gen_Formal : constant Generic_Formal :=
549+
Param.As_Generic_Formal;
550+
Param_Name : constant Name :=
551+
Gen_Formal.F_Decl.P_Defining_Name.F_Name;
552+
begin
553+
Assoc.Param_Types.Include
554+
(Gen_Formal.F_Decl.P_Defining_Name.F_Name,
555+
(Node => Gen_Formal.As_Ada_Node,
556+
Is_Value => False));
557+
Assoc.Param_Vector.Append (Param_Name.As_Ada_Node);
558+
end;
559+
end if;
560+
end loop;
561+
Res.Append (Assoc);
562+
end;
563+
end if;
564+
end loop;
565+
566+
return Res;
567+
end Get_Decl_Designators;
568+
569+
---------------------
570+
-- Get_Prefix_Node --
571+
---------------------
572+
573+
function Get_Prefix_Node
574+
(C : Libadalang.Analysis.Call_Expr;
575+
Column : out Langkit_Support.Slocs.Column_Number)
576+
return Libadalang.Analysis.Ada_Node'Class is
577+
begin
578+
Column := C.Parent.Sloc_Range.Start_Column;
579+
return C.Parent;
580+
end Get_Prefix_Node;
581+
582+
---------------------
583+
-- Get_Prefix_Node --
584+
---------------------
585+
586+
function Get_Prefix_Node
587+
(A : Libadalang.Analysis.Aggregate;
588+
Column : out Langkit_Support.Slocs.Column_Number)
589+
return Libadalang.Analysis.Ada_Node'Class is
590+
begin
591+
Column := A.Parent.Sloc_Range.Start_Column;
592+
return A.Parent;
593+
end Get_Prefix_Node;
594+
595+
----------------
596+
-- Get_Prefix --
597+
----------------
598+
599+
function Get_Prefix_Node
600+
(G : Libadalang.Analysis.Generic_Package_Instantiation;
601+
Column : out Langkit_Support.Slocs.Column_Number)
602+
return Libadalang.Analysis.Ada_Node'Class is
603+
begin
604+
Column := G.Sloc_Range.Start_Column;
605+
return G.F_Generic_Pkg_Name;
606+
end Get_Prefix_Node;
607+
431608
------------------------
432609
-- Propose_Completion --
433610
------------------------
@@ -464,6 +641,16 @@ package body LSP.Ada_Completions.Parameters is
464641
Names => Names,
465642
Unsorted_Res => Unsorted_Res);
466643

644+
Generic_Package_Completion.Propose_Completion
645+
(Self => Self,
646+
Sloc => Sloc,
647+
Token => Token,
648+
Node => Node,
649+
Limit => Self.Named_Notation_Threshold,
650+
Filter => Filter,
651+
Names => Names,
652+
Unsorted_Res => Unsorted_Res);
653+
467654
declare
468655
Min_Width : constant Natural := Unsorted_Res.Length'Img'Length - 1;
469656
begin

source/ada/lsp-ada_completions.adb

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,7 @@ package body LSP.Ada_Completions is
145145
procedure Pretty_Print_Snippet
146146
(Context : LSP.Ada_Contexts.Context;
147147
Prefix : String;
148+
Offset : Natural;
148149
Span : LSP.Messages.Span;
149150
Rule : Libadalang.Common.Grammar_Rule;
150151
Result : in out LSP.Messages.CompletionItem)
@@ -396,11 +397,7 @@ package body LSP.Ada_Completions is
396397
Filename => "",
397398
Buffer => Full,
398399
Rule => Rule);
399-
-- -2 because:
400-
-- - align using the column before the cursor
401-
-- - and "column = offset - 1"
402-
Pp.Actions.Set_Partial_Gnatpp_Offset
403-
(Integer (Span.first.character) - 2);
400+
Pp.Actions.Set_Partial_Gnatpp_Offset (Offset);
404401
Pp.Actions.Format_Vector
405402
(Cmd => Cmd,
406403
Input => Input,

source/ada/lsp-ada_completions.ads

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,7 @@ package LSP.Ada_Completions is
115115
procedure Pretty_Print_Snippet
116116
(Context : LSP.Ada_Contexts.Context;
117117
Prefix : String;
118+
Offset : Natural;
118119
Span : LSP.Messages.Span;
119120
Rule : Libadalang.Common.Grammar_Rule;
120121
Result : in out LSP.Messages.CompletionItem);
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
project Default is
2+
for Main use ("foo.adb");
3+
for Source_Dirs use ("src");
4+
end Default;
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
with G;
2+
3+
procedure Foo
4+
is
5+
procedure Foo (I : Integer);
6+
procedure Foo (I : Integer) is
7+
begin
8+
null;
9+
end Foo;
10+
begin
11+
null;
12+
end Foo;
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
-- Source:
2+
3+
generic
4+
type Elt_Type(<>) is limited private;
5+
type Elt_Ptr is access all Elt_Type;
6+
package G is
7+
type T(Length: Natural) is private;
8+
type T_Ptr is access all T;
9+
private
10+
type Elt_Array is array(Positive range <>) of Elt_Ptr;
11+
type T(Length: Natural) is
12+
record
13+
Elts: Elt_Array(1..Length);
14+
end record;
15+
end G;
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
2+
with G;
3+
package Inst is
4+
type String_Ptr is access all String;
5+
-- package I is new G (String, String_Ptr);
6+
package I is new G (Elt_Type => String, Elt_Ptr => String_Ptr);
7+
end Inst;
8+

0 commit comments

Comments
 (0)