Skip to content

Commit

Permalink
Merge branch 'mr/1409-find-separate-unit-with-gpr2' into 'master'
Browse files Browse the repository at this point in the history
Add support for separates when looking up sources from unit names

Closes #1409

See merge request eng/libadalang/libadalang!1687
  • Loading branch information
pmderodat committed Jul 8, 2024
2 parents 43a55ba + 3602fe4 commit 7a16d9f
Show file tree
Hide file tree
Showing 8 changed files with 159 additions and 56 deletions.
59 changes: 59 additions & 0 deletions extensions/src/libadalang-gpr_utils.adb
Original file line number Diff line number Diff line change
Expand Up @@ -745,4 +745,63 @@ package body Libadalang.GPR_Utils is
return Result;
end Closure;

-----------------------
-- Unit_Location_For --
-----------------------

function Unit_Location_For
(Self : GPR2.Project.View.Object;
Name : String;
Kind : Analysis_Unit_Kind)
return GPR2.Build.Compilation_Unit.Unit_Location
is
use type GPR2.Name_Type;

Req_Name : constant GPR2.Name_Type := GPR2.Name_Type (Name);
Unit : constant GPR2.Build.Compilation_Unit.Object :=
Self.Unit (Req_Name);
begin
if Unit.Is_Defined then

-- If we got a unit, but not the one we requested, we are likely
-- requesting a subunit: in that case, extract the subunit name and
-- request it separately.

if Req_Name = Unit.Name then
case Kind is
when Unit_Specification =>
if Unit.Has_Part (GPR2.S_Spec) then
return Unit.Spec;
end if;
when Unit_Body =>
if Unit.Has_Part (GPR2.S_Body) then
return Unit.Main_Body;
end if;
end case;

else
pragma Assert (Kind = Unit_Body);
declare
-- Requested unit name is "[ROOT].[SEP]", the name of the unit
-- we got is "[ROOT]": skip it plus the "dot" to extract only
-- the "[SEP]" part.

Prefix_Last : constant Positive :=
Req_Name'First + Unit.Name'Length;

pragma Assert
(Req_Name (Req_Name'First .. Prefix_Last)
= GPR2."&" (Unit.Name, "."));
Subunit_Name : constant GPR2.Name_Type :=
Req_Name (Prefix_Last + 1 .. Req_Name'Last);
begin
return
Unit.Get (GPR2.S_Separate, Subunit_Name);
end;
end if;
end if;

return GPR2.Build.Compilation_Unit.No_Unit;
end Unit_Location_For;

end Libadalang.GPR_Utils;
14 changes: 14 additions & 0 deletions extensions/src/libadalang-gpr_utils.ads
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,14 @@ with Ada.Containers.Vectors;
with GNATCOLL.File_Paths; use GNATCOLL.File_Paths;
with GNATCOLL.Projects;
with GNATCOLL.Strings; use GNATCOLL.Strings;
with GPR2.Build.Compilation_Unit;
with GPR2.Project.Registry.Attribute;
with GPR2.Project.Tree;
with GPR2.Project.View;
with GPR2.Project.View.Vector;

with Libadalang.Common; use Libadalang.Common;

private package Libadalang.GPR_Utils is

package GPR1 renames GNATCOLL.Projects;
Expand Down Expand Up @@ -203,4 +206,15 @@ private package Libadalang.GPR_Utils is
(Self : GPR2.Project.View.Object) return GPR2.Project.View.Vector.Object;
-- Return the list of all views reachable from ``Self``, self included

function Unit_Location_For
(Self : GPR2.Project.View.Object;
Name : String;
Kind : Analysis_Unit_Kind)
return GPR2.Build.Compilation_Unit.Unit_Location;
-- Look in ``Self`` for the location of the ``Name``/``Kind`` unit and
-- return it. Return ``No_Unit`` if it is not found.
--
-- TODO??? (eng/gpr/gpr-issues#338) Remove this function once an equivalent
-- one is included in LibGPR2.

end Libadalang.GPR_Utils;
66 changes: 23 additions & 43 deletions extensions/src/libadalang-project_provider.adb
Original file line number Diff line number Diff line change
Expand Up @@ -747,53 +747,33 @@ package body Libadalang.Project_Provider is
end;

when GPR2_Kind =>
declare
procedure Set (SUI : GPR2.Build.Compilation_Unit.Unit_Location);
-- Set ``Filename`` and ``PLE_Root_Index`` from ``SUI``'s

Unit_Name : constant GPR2.Name_Type := GPR2.Name_Type (Str_Name);

---------
-- Set --
---------
-- Look for the requested unit in all the projects that this
-- provider handles.

procedure Set (SUI : GPR2.Build.Compilation_Unit.Unit_Location) is
for View of Provider.Projects loop
declare
use type GPR2.Build.Compilation_Unit.Unit_Location;
use type GPR2.Unit_Index;
begin
-- GPR2 sets the CU index to 0 when there is no "at N" clause
-- in the project file. This is equivalont to "at 1", which is
-- what we need here since PLE_Root_Index is a Positive.

Filename := US.To_Unbounded_String (String (SUI.Source.Value));
PLE_Root_Index :=
(if SUI.Index = 0 then 1 else Positive (SUI.Index));
end Set;
begin
-- Look for the requested unit in all the projects that this
-- provider handles.

for View of Provider.Projects loop
declare
Unit : constant GPR2.Build.Compilation_Unit.Object :=
View.GPR2_Value.Unit (Unit_Name);
begin
if Unit.Is_Defined then
case Kind is
when Unit_Specification =>
if Unit.Has_Part (GPR2.S_Spec) then
Set (Unit.Spec);
return;
end if;
when Unit_Body =>
if Unit.Has_Part (GPR2.S_Body) then
Set (Unit.Main_Body);
return;
end if;
end case;
end if;
end;
end loop;
end;
Unit : constant GPR2.Build.Compilation_Unit.Unit_Location :=
Unit_Location_For (View.GPR2_Value, Str_Name, Kind);
begin
if Unit /= GPR2.Build.Compilation_Unit.No_Unit then

-- GPR2 sets the CU index to 0 when there is no "at N"
-- clause in the project file. This is equivalont to "at
-- 1", which is what we need here since PLE_Root_Index is
-- a Positive.

Filename :=
US.To_Unbounded_String (String (Unit.Source.Value));
PLE_Root_Index :=
(if Unit.Index = 0 then 1 else Positive (Unit.Index));
return;
end if;
end;
end loop;
end case;

-- If we reach this point, we have not found a unit handled by this
Expand Down
59 changes: 46 additions & 13 deletions testsuite/tests/ada_api/gpr2_project_unit_provider/main.adb
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ with Langkit_Support.Text; use Langkit_Support.Text;

with Libadalang.Analysis; use Libadalang.Analysis;
with Libadalang.Common; use Libadalang.Common;
with Libadalang.Iterators; use Libadalang.Iterators;
with Libadalang.Project_Provider; use Libadalang.Project_Provider;

procedure Main is
Expand Down Expand Up @@ -79,26 +78,59 @@ procedure Main is
-- Resolve --
-------------

procedure Resolve (Project : String; Unit_Name : Text_Type) is
procedure Resolve
(Project : String;
Unit_Name : Text_Type;
Kind : Analysis_Unit_Kind := Unit_Specification)
is
function Process (N : Ada_Node'Class) return Visit_Status;
-- If ``N`` has a reference whose resolution must be tested, do it

-------------
-- Process --
-------------

function Process (N : Ada_Node'Class) return Visit_Status is
Ref, Decl : Ada_Node;
begin
Ref := N.As_Ada_Node;
case N.Kind is
when Ada_Object_Decl =>
Ref :=
N
.As_Object_Decl
.F_Type_Expr
.As_Ada_Node;
Decl :=
Ref
.As_Subtype_Indication
.P_Designated_Type_Decl_From (N.As_Ada_Node)
.As_Ada_Node;

when Ada_Subp_Body_Stub =>
Decl := Ref.As_Subp_Body_Stub.P_Next_Part_For_Decl.As_Ada_Node;

when others =>
Ref := No_Ada_Node;
end case;

if not Ref.Is_Null then
Put_Line (Ref.Image & " resolves to:");
Put_Line (" " & Decl.Image);
end if;

return Into;
end Process;
begin
Put_Line ("== Resolutions in " & Project & " ==");
New_Line;
declare
Ctx : constant Analysis_Context :=
Create_Context (Unit_Provider => Load_Project (Project));
Unit : constant Analysis_Unit :=
Get_From_Provider (Ctx, Unit_Name, Unit_Specification);
Root : constant Ada_Node := Unit.Root;

Subtype_Ind : constant Subtype_Indication := Find_First
(Root, Kind_Is (Ada_Subtype_Indication)).As_Subtype_Indication;
Res_Type : constant Ada_Node_Array :=
Subtype_Ind.F_Name.P_Matching_Nodes;
Get_From_Provider (Ctx, Unit_Name, Kind);
begin
Put_Line (Subtype_Ind.Image & " resolves to:");
for E of Res_Type loop
Put_Line (" " & E.Image);
end loop;
Unit.Root.Traverse (Process'Access);
end;
New_Line;
end Resolve;
Expand All @@ -116,6 +148,7 @@ begin
New_Line;

Resolve ("p.gpr", "p2");
Resolve ("p.gpr", "p3", Unit_Body);
Resolve ("multi_unit_files_1.gpr", "objects");
Resolve ("multi_unit_files_2.gpr", "objects");
Resolve ("extending.gpr", "ext");
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
separate (P3)
procedure P is
begin
null;
end P;
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
package P3 is
procedure P;
end P3;
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
package body P3 is
procedure P is separate;
end;
6 changes: 6 additions & 0 deletions testsuite/tests/ada_api/gpr2_project_unit_provider/test.out
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,12 @@ Loading p.gpr...
<SubtypeIndication p2.ada_specification:4:8-4:22> resolves to:
<ConcreteTypeDecl ["Record_Type"] p1.ada_specification:2:4-2:36>

== Resolutions in p.gpr ==

Loading p.gpr...
<SubpBodyStub ["P"] p3.adb:2:4-2:28> resolves to:
<SubpBody ["P"] p3-p.adb:2:1-5:7>

== Resolutions in multi_unit_files_1.gpr ==

Loading multi_unit_files_1.gpr...
Expand Down

0 comments on commit 7a16d9f

Please sign in to comment.