with Ada.Containers.Vectors;
with Ada.Strings; use Ada.Strings;
with Put_Title;

procedure LAL_DDA is
Collection : Repinfo_Collection;

A_Basic_Record : Basic_Record := Basic_Record'(A => 42);
Another_Basic_Record : Basic_Record := (A => 42);
Nix : constant Null_Record := (null record);

procedure Process_Type_Decl (Decl : Base_Type_Decl);
-- Display all representation information that is available in
-- ``Collection`` for this type declaration.

procedure Process_Variants
(Variants : Variant_Representation_Array; Prefix : String);
-- Display all representation information for the given record variants.
-- ``Prefix`` is used as a prefix for all printed lines.

package Expr_Vectors is new Ada.Containers.Vectors (Positive, Expr);
use type Expr_Vectors.Vector;
package Expr_Vector_Vectors is new Ada.Containers.Vectors
(Positive, Expr_Vectors.Vector);

function Test_Discriminants
(Decl : Base_Type_Decl) return Expr_Vector_Vectors.Vector;
-- Fetch the vector of discriminants to use for testing from nearby Test
-- pragmas.

procedure Error (Node : Ada_Node'Class; Message : String) with No_Return;
-- Abort the App with the given error ``Message``, contextualized using
-- ``Node`` 's source location.

package App is new Libadalang.Helpers.App
(Name => "lal_dda",
Description =>
"Exercize Libadalang's Data_Decomposition API on type declarations",
App_Setup => App_Setup,
Process_Unit => Process_Unit);

package Args is
use GNATCOLL.Opt_Parse;

package Rep_Info_Files is new Parse_Option_List
(App.Args.Parser, "-i", "--rep-info-file",
Arg_Type => Unbounded_String,
Accumulate => True,
Help => "Output for the compiler's -gnatR4j option");

end Args;

---------------
-- App_Setup --
---------------

procedure App_Setup (Context : App_Context; Jobs : App_Job_Context_Array) is
pragma Unreferenced (Context, Jobs);
begin
Collection := Load (Filename_Array (Args.Rep_Info_Files.Get));
exception
when Exc : Loading_Error =>
Put_Line
("Loading_Error raised while loading representation information:");
Put_Line (Exception_Message (Exc));
New_Line;
end App_Setup;

------------------
-- Process_Unit --
------------------

procedure Process_Unit (Context : App_Job_Context; Unit : Analysis_Unit) is
pragma Unreferenced (Context);

function Process (Node : Ada_Node'Class) return Visit_Status;

function Process (Node : Ada_Node'Class) return Visit_Status is
begin
case Node.Kind is
when Ada_Base_Type_Decl =>
Process_Type_Decl (Node.As_Base_Type_Decl);

when Ada_Pragma_Node =>
declare
PN : constant Pragma_Node := Node.As_Pragma_Node;
Name : constant Text_Type := To_Lower (PN.F_Id.Text);
Decl : Ada_Node;
begin
if Name = "test_object_type" then
Decl := PN.Previous_Sibling;
if Decl.Kind /= Ada_Object_Decl then
Error
(Node,
"previous declaration must be an object"
& " declaration");
end if;
Process_Type_Decl
(Decl.As_Object_Decl
.F_Type_Expr
.P_Designated_Type_Decl);
end if;
if I > 1 then
Put (", ");
end if;
end;

when others =>
null;
end case;
return Into;
end Process;

begin
Put_Title
('#', "Analyzing " & Ada.Directories.Simple_Name (Unit.Get_Filename));
if Unit.Has_Diagnostics then
for D of Unit.Diagnostics loop
Put_Line (Unit.Format_GNU_Diagnostic (D));
end loop;
New_Line;
return;

elsif not Unit.Root.Is_Null then
Unit.Root.Traverse (Process'Access);
end if;
end Process_Unit;
end LAL_DDA;

type Car is record
Identity : Long_Long_Integer;
Number_Wheels : Positive range 1 .. 16#FF#E1;
Number_Wheels : Positive range 16#F.FF#E+2 .. 2#1111_1111#;
Paint : Color;
Horse_Power_kW : Float range 0.0 .. 2_000.0;
Consumption : Float range 0.0 .. 100.0;
end record;

type Null_Record is null record;

type Traffic_Light_Access is access Mutable_Variant_Record;
Any_Traffic_Light : Traffic_Light_Access :=
new Mutable_Variant_Record;
Aliased_Traffic_Light : aliased Mutable_Variant_Record;

pragma Unchecked_Union (Union);
pragma Convention (C, Union); -- optional

type Programmer is new Person
and Printable
with
record
Skilled_In : Language_List;
end record;

3#12.112#e3
3#12.11 use
-- ^ invalid
3#12.23#e3
-- ^ invalid
3#12.11ds#
-- ^ invalid
1211ds
-- ^ invalid