!ASIS Issue #024 !topic Class-wide Types in ASIS !reference ASIS !from Sergey Rybin 97-01-11 !keywords class-wide types !discussion Consider the following example (taken from Ada 95 Rationale, page 4-6, the leading declarations are skipped): ... declare A_File : File'Class := Get_File_From_User; begin View (A_File); end; ^ | -------------------------------------------------- and consider the Element (let's call it El) representing this | construct. The corresponding Element is of An_Expression/An_Idenifier kind, it represents a variable, so the Corresponding_Expression_Type should not return a Nil_Element when applying to El (the definition of Corresponding_Expression_Type from 2.0.K is appended to this message) The question is - what kind should Corresponding_Expression_Type (El) have? The problem is that the result should represent (in some way) a *CLASS-WIDE* type, but ASIS has no position in its Element classification hierarchy for class-wide types. Moreover, the multi-file search for the expression "class-wide" or "class wide" gives a null result for ASIS 2.0.K My guess is that if we do not have a special position for classifying class-wide types, then the result of Corresponding_Expression_Type should be of the same ASIS type kind, as the root type of the class. Do you agree? Another problem is that RM95 3.4.1(3) says: Every type is either a specific type, a class-wide type, or a universal type. A specific type is one defined by a type_declaration, a formal_type_declaration, or a full type definition embedded in a declaration for an object. Class-wide and universal types are implicitly defined, to act as ^^^^^^^^^^^^^^^^^^ representatives for an entire class of types, as follows: So if Corresponding_Expression_Type (El) is not a Nil_Element, it is an *implicit* Element. Two questions arise here: 1. If an ASIS implementation does not support implicit Elements, there exists one more case (comparing with what is mentioned in ASIS 2.0.K) when Corresponding_Expression_Type may return a Nil_Element - this is the case when it should return the definition of some class-wide type, but when it cannot do it, because an ASIS implementation does not support implicit Elements. 2. As any other Element, the Element being the result of Corresponding_Expression_Type (El) has the Enclosing Element and it may be traversed by ASIS structural queries. I am afraid, both these aspects need additional explanations for the elements representing class-wide types. This is one more example, when RM is not enough to answer these questions (that is, what is the enclosing construct and what is the syntax structure of the (implicit) definition of a class-wide type) - the language definition simply does not need answers, but ASIS does! And, finally, what do you think about the alternative solutions which would eliminate any implicit elements when querying about expression types? 1. The idea is to add a special value to Type_Kinds (A_Class_Wide_Type) and to have the constant Class_Wide_Type_Element as the only Element value having this kind. Corresponding_Expression_Type should return Class_Wide_Type_Element for any argument of class-wide type, and then we have to add another query (Corresponding_Expression_Root_Type???) to get the *explicit* declaration of the root type of the class. The Class_Wide_Type_Element constant should have no child Elements and a Nil_Element as Enclosing Element, and no span and text image As a result, an application needs two steps to understand that it deals with an expression of a class-wide type, and both these steps deals with explicit Elements 2. Another idea is to add a boolean query Is_Of_Class_Wide type for expressions and to return in Corresponding_Expression_Type not the class-wide type, but its root type. !resolution Accepted, with Modifications. !date 97-03-25 !Notes The following change was made to Subclause 17.1 in ASIS version 2.0.M for clarification: --------------------------------------------------------------------------------------- -- Subclause 17.1 function Corresponding_Expression_Type --------------------------------------------------------------------------------------- function Corresponding_Expression_Type (Expression : in Asis.Expression) return Asis.Declaration; --------------------------------------------------------------------------------------- -- Expression - Specifies the expression to query -- -- Returns the type_declaration for the type of the expression. This query -- does not "unwind" subtypes or derived types to get to the -- Corresponding_First_Subtype or Corresponding_Parent_Subtype declarations. -- -- Returns a Nil_Element for two classes of expressions that do not have a -- Corresponding_Expression_Type: -- -- - Naming expressions that name packages, subprograms, tasks, etc. These -- expressions do have a Corresponding_Name_Definition and a -- Corresponding_Name_Declaration. -- -- - The Actual_Parameter Expression from A_Pragma_Argument_Association for a -- Pragma may or may not have a Corresponding_Expression_Type. If the -- returned declaration is non-nil then the Expression is either a) an -- ordinary expression, or b) a naming expression that names a constant or -- variable object. -- -- Returns a Nil_Element, if statically determinable type of Expression is a -- class-wide type. -- --|AN Application Note: --|AN --|AN If the returned declaration is Nil, an application should make its own analysis --|AN based on Corresponding_Name_Definition or Corresponding_Name_Declaration to get --|AN more information about the argument, including the static type resolution for --|AN class-wide expressions, if needed. Use Enclosing_Element to determine if --|AN Expression is from pragma argument association. If for such an expression --|AN Corresponding_Name_Definition raises Asis_Failed (with a Status of --|AN Value_Error), this An_Expression Element does not represent a normal Ada --|AN expression at all and does not follow normal Ada semantic rules. --|AN For example, "pragma Private_Part (Open => Yes);", the "Yes" expression --|AN may simply be a "keyword" that is specially recognized by the --|AN implementor's compilation system and may not refer to any declared object -- -- Appropriate Element_Kinds: -- An_Expression -- -- Returns Element_Kinds: -- Not_An_Element -- A_Declaration In addition, the following was added to Corresponding_Name_Definition (Subclause 17.6), Corresponding_Called_Function (Subclause 17.29), and Corresponding_Called_Entity (Subclause 18.25): -- Returns a Nil_Element, if the argument is a dispatching call.