Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

child packages and nested packages

23 views
Skip to first unread message

Oliver Kellogg

unread,
Mar 23, 2002, 10:02:49 AM3/23/02
to
Hello CLA,

How come child packages are only possible for library level packages?

I now encountered a situation where I'd like to create a child
package of a nested package:

-- file: pkg.ads
package Pkg is
package Nested is
type Object is tagged null record;
end Nested;
end Pkg;

-- file: pkg-nested-child.ads
package Pkg.Nested.Child is
type Derived is new Object with null record;
end Pkg.Nested.Child;


(The only thing that crosses my naive mind is that this makes
life harder for the Ada compiler in that if a file pkg-nested.ads
cannot be found then the compiler would need to look inside pkg.ads
to see if the parent to which the child refers can be found there.)

Thanks,

O. Kellogg

Ted Dennison

unread,
Mar 25, 2002, 10:01:22 AM3/25/02
to
okel...@freenet.de (Oliver Kellogg) wrote in message news:<6a6390b8.02032...@posting.google.com>...

> I now encountered a situation where I'd like to create a child
> package of a nested package:
>
> -- file: pkg.ads
> package Pkg is
> package Nested is
> type Object is tagged null record;
> end Nested;
> end Pkg;
>
> -- file: pkg-nested-child.ads
> package Pkg.Nested.Child is
> type Derived is new Object with null record;
> end Pkg.Nested.Child;

It looks like you tried to create a *grandchild* package without first
creating a child package. Sort of a double immaculate conception. :-)

Try declaring Pkg.Nested.Child within Pkg.


--
T.E.D.
Home - mailto:denn...@telepath.com (Yahoo: Ted_Dennison)
Homepage - http://www.telepath.com/dennison/Ted/TED.html

Oliver Kellogg

unread,
Mar 25, 2002, 2:26:06 PM3/25/02
to
denn...@telepath.com (Ted Dennison) wrote:
>
> Try declaring Pkg.Nested.Child within Pkg.

Well, my point was not wanting to do that.
Imagine Pkg to be the production of a code generator, potentially
containing hundreds of these nested packages, while Pkg.Nested.Child
is a human written extension.

One reason for wanting nested packages might be to reduce the number
of files.
Another, more important reason is that further declarations in
Pkg might depend on things from the nested packages, for example

-- near the end of package Pkg:
type Object_Array array (1 .. 2) of Nested.Object;

Thanks,

Oliver Kellogg

Stephen Leake

unread,
Mar 25, 2002, 5:31:43 PM3/25/02
to
okel...@freenet.de (Oliver Kellogg) writes:

> denn...@telepath.com (Ted Dennison) wrote:
> >
> > Try declaring Pkg.Nested.Child within Pkg.
>
> Well, my point was not wanting to do that.
> Imagine Pkg to be the production of a code generator, potentially
> containing hundreds of these nested packages, while Pkg.Nested.Child
> is a human written extension.

I hope you can influence the automatic tool to produce code that lets
you do what you need to do :). This is the base of automatic tools;
they always need tweeking, and some don't allow the user sufficient
power to do the tweeking.

You might consider using separate subunits, declared in the body of
Pkg. But you probably need tool support for that as well.

--
-- Stephe

Marin David Condic

unread,
Mar 26, 2002, 9:21:06 AM3/26/02
to
"Ted Dennison" <denn...@telepath.com> wrote in message
news:4519e058.02032...@posting.google.com...

> okel...@freenet.de (Oliver Kellogg) wrote in message
news:<6a6390b8.02032...@posting.google.com>...
>
> It looks like you tried to create a *grandchild* package without first
> creating a child package. Sort of a double immaculate conception. :-)
>
Except that "Immaculate Conception" refers to the Virgin Mary being born
without Original Sin - not the Virgin Birth. A *very* common
"mis-conception", if you will... :-)

MDC
--
Marin David Condic
Senior Software Engineer
Pace Micro Technology Americas www.pacemicro.com
Enabling the digital revolution
e-Mail: marin....@pacemicro.com


Oliver Kellogg

unread,
Mar 28, 2002, 4:51:50 AM3/28/02
to
Some background:

The CORBA IDL to Ada mapping prescribes that nested IDL modules,
interfaces, and valuetypes be mapped to child packages.
This mapping is fundamentally flawed.
Example:

// IDL
module A {
interface B {
typedef short type_in_b;
void my_method ();
};

typedef B::type_in_b type_in_a;
};

Since the interface B is mapped to a child package A.B, it is not
possible to map type_in_a to Ada.

The solution is to map nested IDL units to nested Ada packages.

However, IDL interfaces and valuetypes require implementations.
For example, the IDL to Ada mapping prescribes that the
implementation of interface A::B be done in a child package of
A.B named A.B.Impl. It would certainly be the preferable to
maintain this mapping, but that's not possible with Ada right now.

-- Oliver Kellogg

Ted Dennison

unread,
Mar 28, 2002, 9:49:22 AM3/28/02
to
okel...@freenet.de (Oliver Kellogg) wrote in message news:<6a6390b8.02032...@posting.google.com>...
> Some background:
>
> The CORBA IDL to Ada mapping prescribes that nested IDL modules,
> interfaces, and valuetypes be mapped to child packages.
> This mapping is fundamentally flawed.
> Example:
>
> // IDL
> module A {
> interface B {
> typedef short type_in_b;
> void my_method ();
> };
>
> typedef B::type_in_b type_in_a;
> };
>
> Since the interface B is mapped to a child package A.B, it is not
> possible to map type_in_a to Ada.
>
> The solution is to map nested IDL units to nested Ada packages.

Why can't "type_in_a" be put inside the same "A" package as "B"? That
would compile, and would seem to be the natural mapping of this.

Oliver Kellogg

unread,
Mar 28, 2002, 1:30:40 PM3/28/02
to
denn...@telepath.com (Ted Dennison) wrote in message news:<4519e058.02032...@posting.google.com>...

>
> Why can't "type_in_a" be put inside the same "A" package as "B"? That
> would compile, and would seem to be the natural mapping of this.

Sorry, I don't understand. What exactly do you mean?

As soon as interface B is mapped as a child package A.B,
there is no way A can "with" its own child A.B ?

Ted Dennison

unread,
Mar 28, 2002, 5:13:15 PM3/28/02
to
okel...@freenet.de (Oliver Kellogg) wrote in message news:<6a6390b8.02032...@posting.google.com>...

No. I didn't say to make B a child package of A. Instead I am talking
about nesting B's child inside of A along with B.

Oliver Kellogg

unread,
Mar 29, 2002, 12:30:41 AM3/29/02
to
denn...@telepath.com (Ted Dennison) wrote:
>
> No. I didn't say to make B a child package of A. Instead I am talking
> about nesting B's child inside of A along with B.

In the CORBA context, this would mean intertwining hand written code
with automatically generated code:
A.B is automatically generated while A.B.Impl is hand written.

--

Sergey Koshcheyev

unread,
Mar 29, 2002, 6:59:30 AM3/29/02
to

Er, sorry, I've just clicked the wrong button and sent this to Oliver by
e-mail:

Just a quick idea - maybe using "is separate" in some right places would
solve it? Like having the spec of A.B.Impl inside A.B, and having the body
separate.

Sergey Koshcheyev.

Oliver Kellogg

unread,
Mar 29, 2002, 8:05:01 AM3/29/02
to
Sergey Koshcheyev <ser...@hotmail.com> wrote:

> Just a quick idea - maybe using "is separate" in some right places would
> solve it? Like having the spec of A.B.Impl inside A.B, and having the body
> separate.

That's definitely possible, but still only a workaround solution.
The real solution IMO is to permit nested packages as units that are
interchangeable with child packages in package hierarchies.
I.e. everywhere that a child package may appear, also a nested
package could appear.

It should be at the software archtiect's freedom how he chooses to
physically lay out a unit in the hierarchy - as a child package or as
a nested package.

Oliver Kellogg

Ted Dennison

unread,
Mar 29, 2002, 10:14:11 AM3/29/02
to
"Sergey Koshcheyev" <ser...@hotmail.com> wrote in message news:<a81kui$16q8$1...@ns.felk.cvut.cz>...

> > In the CORBA context, this would mean intertwining hand written code
> > with automatically generated code:
> > A.B is automatically generated while A.B.Impl is hand written.
>
> Er, sorry, I've just clicked the wrong button and sent this to Oliver by
> e-mail:
>
> Just a quick idea - maybe using "is separate" in some right places would
> solve it? Like having the spec of A.B.Impl inside A.B, and having the body
> separate.

I don't know enough about nested packages and separates to say if/how
this would work. But issues like this are the reason "is separate" is
in the language.

Oliver Kellogg

unread,
Apr 23, 2002, 5:44:49 PM4/23/02
to
I'm attempting to implement this feature (permitting a nested
package as the parent the of a child package) in GNAT.
Since it's just a proof of concept, I'm doing this only for the
simple case where the parent is nested exactly one deep.
However, I'm having a problem. It seems to relate to

Names : List_Id := New_List (Defining_Unit_Name (Specification (Decl)));

in the bottom page of the added code block below.
Later, while Analyze_Use_Package loops through the Names, the Nkind
of the (first and only) name node appears not to have been set.
I'm sure there's something wrong with the way I synthesize the use
clause. Help, anyone?


*** par-load.adb.orig Thu Mar 14 10:59:36 2002
--- par-load.adb Tue Apr 23 22:25:25 2002
***************
*** 290,301 ****
Unum :=
Load_Unit
(Load_Name => Spec_Name,
! Required => True,
Subunit => False,
Error_Node => Curunit);

if Unum /= No_Unit then
Set_Parent_Spec (Unit (Curunit), Cunit (Unum));
end if;
end if;

--- 290,383 ----
Unum :=
Load_Unit
(Load_Name => Spec_Name,
! Required => False,
Subunit => False,
Error_Node => Curunit);

if Unum /= No_Unit then
Set_Parent_Spec (Unit (Curunit), Cunit (Unum));
+ else
+ -- The Spec_Name may refer to a nested package.
+ Spec_Name := Get_Parent_Spec_Name (Spec_Name);
+ if Spec_Name /= No_Name then
+ Unum :=
+ Load_Unit
+ (Load_Name => Spec_Name,
+ Required => True,
+ Subunit => False,
+ Error_Node => Curunit);
+ if Unum /= No_Unit then
+ Set_Parent_Spec (Unit (Curunit), Cunit (Unum));
+ -- Check that the referenced nested package exists.
+ declare
+ function Infix (Threefix : String) return String;
+ -- Given a name "A.B.C", returns "B".
+ -- Returns "" if the input name does not contain
+ -- two periods.
+ function Infix (Threefix : String) return String is
+ I1 : Natural := Threefix'First;
+ I2 : Natural;
+ begin
+ while I1 <= Threefix'Last
+ and then Threefix (I1) /= '.' loop
+ I1 := I1 + 1;
+ end loop;
+ if I1 = Threefix'Last then
+ return "";
+ end if;
+ I1 := I1 + 1;
+ I2 := I1;
+ while I2 <= Threefix'Last
+ and then Threefix (I2) /= '.' loop
+ I2 := I2 + 1;
+ end loop;
+ if I2 = Threefix'Last then
+ return "";
+ end if;
+ return Threefix (I1 .. I2 - 1);
+ end Infix;
+ Found : Boolean := False;
+ Spec : Node_Id := Specification (Unit (Cunit (Unum)));
+ Decls : List_Id := Visible_Declarations (Spec);
+ Decl : Node_Id := First (Decls);
+ Nested_Name : String
+ := Infix (Get_Name_String (Unit_Name (Cur_Unum)));
+ Pkg_Name : Name_Id;
+ begin
+ while Present (Decl) loop
+ if Nkind (Decl) = N_Package_Declaration then
+ Pkg_Name :=
+ Chars (Defining_Unit_Name (Specification (Decl)))
;
+ if Get_Name_String (Pkg_Name) = Nested_Name then
+ Found := True;
+ exit;
+ end if;
+ end if;
+ Next (Decl);
+ end loop;
+ if Found then
+ Set_Parent_Spec (Unit (Curunit), Cunit (Unum));
+ -- Synthesize a use clause for the parent package.
+ declare
+ Names : List_Id
+ := New_List
+ (Defining_Unit_Name (Specification (Decl)));
+ Use_Nested_Parent : Node_Id
+ := Make_Use_Package_Clause (Loc, Names);
+ begin
+ Prepend_To
+ (Visible_Declarations
+ (Specification (Unit (Curunit))),
+ Use_Nested_Parent);
+ Mark_Rewrite_Insertion (Use_Nested_Parent);
+ end;
+ else
+ Error_Msg ("parent package not found", Loc);
+ end if;
+ end;
+
+ end if;
+ end if;
end if;
end if;

Oliver Kellogg

unread,
Apr 24, 2002, 10:52:36 AM4/24/02
to
Nevermind, problem solved.

FYI:
Turned out that during parsing, one should never directly assign a
synthesized node from already constructed nodes.
Reason: The constructed nodes have additional fields set that make the
compiler assume the new node has already been semantically analyzed.
Instead, use New_Node (or the Nmake.Make_ methods) in combination with
Chars and other accessors to copy the individual node fields.

I'll refrain from attaching the corrected diff, mail me if you
want it.

Next, I'll look at how to make visible to the child the nested parent's
private part.

0 new messages