-- C730001.A -- -- Grant of Unlimited Rights -- -- Under contracts F33600-87-D-0337, F33600-84-D-0280, MDA903-79-C-0687, -- F08630-91-C-0015, and DCA100-97-D-0025, the U.S. Government obtained -- unlimited rights in the software and documentation contained herein. -- Unlimited rights are defined in DFAR 252.227-7013(a)(19). By making -- this public release, the Government intends to confer upon all -- recipients unlimited rights equal to those held by the Government. -- These rights include rights to use, duplicate, release or disclose the -- released technical data and computer software in whole or in part, in -- any manner and for any purpose whatsoever, and to have or permit others -- to do so. -- -- DISCLAIMER -- -- ALL MATERIALS OR INFORMATION HEREIN RELEASED, MADE AVAILABLE OR -- DISCLOSED ARE AS IS. THE GOVERNMENT MAKES NO EXPRESS OR IMPLIED -- WARRANTY AS TO ANY MATTER WHATSOEVER, INCLUDING THE CONDITIONS OF THE -- SOFTWARE, DOCUMENTATION OR OTHER INFORMATION RELEASED, MADE AVAILABLE -- OR DISCLOSED, OR THE OWNERSHIP, MERCHANTABILITY, OR FITNESS FOR A -- PARTICULAR PURPOSE OF SAID MATERIAL. --* -- -- OBJECTIVE: -- Check that the full view of a private extension may be derived -- indirectly from the ancestor type (i.e., the parent type of the full -- type may be any descendant of the ancestor type). Check that, for -- a primitive subprogram of the private extension that is inherited from -- the ancestor type and not overridden, the formal parameter names and -- default expressions come from the corresponding primitive subprogram -- of the ancestor type, while the body comes from that of the parent -- type. Check both dispatching and non-dispatching cases. -- -- TEST DESCRIPTION: -- Consider: -- -- package P is -- type Ancestor is tagged ... -- procedure Op (P1: Ancestor; P2: Boolean := True); -- end P; -- -- with P; -- package Q is -- type Derived is new P.Ancestor with ... -- procedure Op (X: Ancestor; Y: Boolean := False); -- end Q; -- -- with P, Q; -- package R is -- type Priv_Ext is new P.Ancestor with private; -- (A) -- -- Inherits procedure Op (P1: Priv_Ext; P2: Boolean := True); -- -- But body executed is that of Q.Op. -- private -- type Priv_Ext is new Q.Derived with record ... -- (B) -- end R; -- -- The ancestor type in (A) differs from the parent type in (B); the -- parent of the full type is descended from the ancestor type of the -- private extension. For a call to Op (from outside the scope of the -- full view) with an operand of type Priv_Ext, the formal parameter -- names and default expression come from that of P.Op (the ancestor -- type's version), but the body executed will be that of -- Q.Op (the parent type's version) -- -- One half of the test mirrors the above template, where an inherited -- subprogram (Set_Display) is called using the formal parameter -- name (C) and default parameter expression of the ancestor type's -- version (type Clock), but the version of the body executed is from -- the parent type. -- -- The test also includes an examination of the dynamic evaluation -- case, where correct body associations are required through dispatching -- calls. As described for the non-dispatching case above, the formal -- parameter name and default values of the ancestor type's (Phone) -- version of the inherited subprogram (Answer) are used in the -- dispatching call, but the body executed is from the parent type. -- -- -- CHANGE HISTORY: -- 06 Dec 94 SAIC ACVC 2.0 -- --! package C730001_0 is type Display_Kind is (None, Analog, Digital); type Illumination_Type is (None, Light, Phosphorescence); type Capability_Type is (Available, In_Use, Call_Waiting, Conference); type Indicator_Type is (None, Light, Bell, Buzzer, Click, Modem); type Clock is abstract tagged record -- ancestor type associated Display : Display_Kind := None; -- with non-dispatching case. Illumination : Illumination_Type := None; end record; type Phone is tagged record -- ancestor type associated Status : Capability_Type := Available; -- with dispatching case. Indicator : Indicator_Type := None; end record; -- The Set_Display procedure for type Clock implements a basic, no-frills -- clock display. procedure Set_Display (C : in out Clock; Disp: in Display_Kind := Digital); -- The Answer procedure for type Phone implements a phone status change -- operation. procedure Answer (The_Phone : in out Phone; Ind : in Indicator_Type := Light); -- ...Other general clock and/or phone operations (not specified in this -- test scenario). end C730001_0; --==================================================================-- package body C730001_0 is procedure Set_Display (C : in out Clock; Disp: in Display_Kind := Digital) is begin C.Display := Disp; C.Illumination := Light; end Set_Display; procedure Answer (The_Phone : in out Phone; Ind : in Indicator_Type := Light) is begin The_Phone.Status := In_Use; The_Phone.Indicator := Ind; end Answer; end C730001_0; --==================================================================-- with C730001_0; use C730001_0; package C730001_1 is type Power_Supply_Type is (Spring, Battery, AC_Current); type Speaker_Type is (None, Present, Adjustable, Stereo); type Wall_Clock is new Clock with record Power_Source : Power_Supply_Type := Spring; end record; type Office_Phone is new Phone with record Speaker : Speaker_Type := Present; end record; -- Note: Both procedures below, parameter names and defaults differ from -- parent's version. -- The Set_Display procedure for type Wall_Clock improves upon the -- basic Set_Display procedure of type Clock. procedure Set_Display (WC: in out Wall_Clock; D : in Display_Kind := Analog); procedure Answer (OP : in out Office_Phone; OI : in Indicator_Type := Buzzer); -- ...Other wall clock and/or Office_Phone operations (not specified in -- this test scenario). end C730001_1; --==================================================================-- package body C730001_1 is -- Note: This body is the one that should be executed in the test block -- below, not the version of the body corresponding to type Clock. procedure Set_Display (WC: in out Wall_Clock; D : in Display_Kind := Analog) is begin WC.Display := D; WC.Illumination := Phosphorescence; end Set_Display; procedure Answer (OP : in out Office_Phone; OI : in Indicator_Type := Buzzer) is begin OP.Status := Call_Waiting; OP.Indicator := OI; end Answer; end C730001_1; --==================================================================-- with C730001_0; use C730001_0; with C730001_1; use C730001_1; package C730001_2 is type Alarm_Type is (Buzzer, Radio, Both); type Video_Type is (None, TV_Monitor, Wall_Projection); type Alarm_Clock is new Clock with private; -- Inherits proc Set_Display (C : in out Clock; -- Disp: in Display_Kind := Digital); -- (A) -- -- Would also inherit other general clock operations (if present). type Conference_Room_Phone is new Office_Phone with record Display : Video_Type := TV_Monitor; end record; procedure Answer (CP : in out Conference_Room_Phone; CI : in Indicator_Type := Modem); function TC_Get_Display (C: Alarm_Clock) return Display_Kind; function TC_Get_Display_Illumination (C: Alarm_Clock) return Illumination_Type; private -- ...however, certain of the wall clock's operations (Set_Display, in -- this example) improve on the implementations provided for the general -- clock. We want to call the improved implementations, so we -- derive from Wall_Clock in the private part. type Alarm_Clock is new Wall_Clock with record Alarm : Alarm_Type := Buzzer; end record; -- Inherits proc Set_Display (WC: in out Wall_Clock; -- D : in Display_Kind := Analog); -- (B) -- The implicit Set_Display at (B) overrides the implicit Set_Display at -- (A), but only within the scope of the full view. -- -- Outside the scope of the full view, only (A) is visible, so calls -- from outside the scope will get the formal parameter names and default -- from (A). Both inside and outside the scope, however, the body executed -- will be that corresponding to Set_Display of the parent type. end C730001_2; --==================================================================-- package body C730001_2 is procedure Answer (CP : in out Conference_Room_Phone; CI : in Indicator_Type := Modem)is begin CP.Status := Conference; CP.Indicator := CI; end Answer; function TC_Get_Display (C: Alarm_Clock) return Display_Kind is begin return C.Display; end TC_Get_Display; function TC_Get_Display_Illumination (C: Alarm_Clock) return Illumination_Type is begin return C.Illumination; end TC_Get_Display_Illumination; end C730001_2; --==================================================================-- with C730001_0; use C730001_0; with C730001_1; use C730001_1; with C730001_2; use C730001_2; package C730001_3 is -- Types extended from the ancestor (Phone) type in the specification. type Secure_Phone_Type is new Phone with private; type Auditorium_Phone_Type is new Phone with private; -- Inherit versions of Answer from ancestor (Phone). function TC_Get_Phone_Status (P : Phone'Class) return Capability_Type; function TC_Get_Indicator (P : Phone'Class) return Indicator_Type; private -- Types extended from descendents of Phone_Type in the private part. type Secure_Phone_Type is new Office_Phone with record Scrambled_Communication : Boolean := True; end record; type Auditorium_Phone_Type is new Conference_Room_Phone with record Volume_Control : Boolean := True; end record; end C730001_3; --==================================================================-- package body C730001_3 is function TC_Get_Phone_Status (P : Phone'Class) return Capability_Type is begin return P.Status; end TC_Get_Phone_Status; function TC_Get_Indicator (P : Phone'Class) return Indicator_Type is begin return P.Indicator; end TC_Get_Indicator; end C730001_3; --==================================================================-- with C730001_0; use C730001_0; with C730001_1; use C730001_1; with C730001_2; use C730001_2; with C730001_3; use C730001_3; with Report; procedure C730001 is begin Report.Test ("C730001","Check that the full view of a private extension " & "may be derived indirectly from the ancestor " & "type. Check that, for a primitive subprogram " & "of the private extension that is inherited from " & "the ancestor type and not overridden, the " & "formal parameter names and default expressions " & "come from the corresponding primitive " & "subprogram of the ancestor type, while the body " & "comes from that of the parent type"); Test_Block: declare Alarm : Alarm_Clock; Hot_Line : Secure_Phone_Type; TeleConference_Phone : Auditorium_Phone_Type; begin -- Evaluate non-dispatching case: -- Call Set_Display using formal parameter name from -- C730001_0.Set_Display. -- Give no 2nd parameter so that default expression must be used. Set_Display (C => Alarm); -- The value of the Display component should equal Digital, which is -- the default value from the ancestor's version of Set_Display, -- and not the default value from the parent's version of Set_Display. if TC_Get_Display (Alarm) /= Digital then Report.Failed ("Default expression for ancestor op not used " & "in non-dispatching case"); end if; -- However, the value of the Illumination component should equal -- Phosphorescence, which is assigned in the parent type's version of -- the body of Set_Display. if TC_Get_Display_Illumination (Alarm) /= Phosphorescence then Report.Failed ("Wrong body was executed in non-dispatching case"); end if; -- Evaluate dispatching case: declare Hot_Line : Secure_Phone_Type; TeleConference_Phone : Auditorium_Phone_Type; procedure Answer_The_Phone (P : in out Phone'Class) is begin -- Give no 2nd parameter so that default expression must be used. Answer (P); end Answer_The_Phone; begin Answer_The_Phone (Hot_Line); Answer_The_Phone (TeleConference_Phone); -- The value of the Indicator field shold equal "Light", the default -- value from the ancestor's version of Answer, and not the default -- from either of the parent versions of Answer. if TC_Get_Indicator(Hot_Line) /= Light or TC_Get_Indicator(TeleConference_Phone) /= Light then Report.Failed("Default expression from ancestor operation " & "not used in dispatching case"); end if; -- However, the value of the Status component should equal -- Call_Waiting or Conference respectively, based on the assignment -- in the parent type's version of the body of Answer. if TC_Get_Phone_Status(Hot_Line) /= Call_Waiting then Report.Failed("Wrong body executed in dispatching case - 1"); end if; if TC_Get_Phone_Status(TeleConference_Phone) /= Conference then Report.Failed("Wrong body executed in dispatching case - 2"); end if; end; exception when others => Report.Failed ("Exception raised in Test_Block"); end Test_Block; Report.Result; end C730001;