[Up] [SIGAda] [ACM]

ASIS Basic Concepts


Ada compilation environment

ASIS is an interface between an Ada environment as defined by ISO/IEC 8652:1995 (the Ada Reference Manual) and any tool requiring information from this environment, as shown below:

ASIS as interface to Ada compilation environment
ASIS as interface to Ada compilation environment

Ada environment

ISO/IEC 8652:1995, 10.1.4(1) provides a notion for this compilation environment as: "Each compilation unit submitted to the compiler is compiled in the context of an environment declarative_part (or simply environment), which is a conceptual declarative_part that forms the outermost declarative region of the context of any compilation. At run time, an environment forms the declarative_part of the body of the environment task of a partition."

ASIS notion of the Ada compilation environment

However, the mechanisms for creating an environment and for adding and replacing compilation units within an environment are implementation-defined. Some implementor environments create and maintain persistent databases while others do not. Consequently, ASIS requires the user of the interface (i.e., ASIS application) to establish the compilation environment. This is done through the context.

The context defines a set of compilation units and configuration pragmas processed by an ASIS application. ASIS provides any information from a context by treating this set as if its elements make up an environment declarative part by modeling some view (most likely - one of the views of the underlying Ada implementation) on the environment. Context is a view of an Ada environment. ASIS requires an application to identify that view of the environment using the procedure Asis.Ada_Environments.Associate, as shown below. ASIS may process several different contexts at a time.

Application interface to ASIS Context
Application interface to ASIS Context

A context may have one or more Compilation_Units. ASIS has defined Compilation_Unit as an ASIS private type. This type has values which denote an Ada compilation unit or configuration pragma from the environment. Compilation_Unit also is an abstraction, which represents information about some physical object from the "external world". This physical object is treated by the underlying Ada implementation as the corresponding Ada compilation unit or as a result of compiling a configuration pragma. An ASIS compilation unit includes the notion of some implementation-defined way to associate the corresponding ASIS object with some physical external object. This is necessary to support ASIS queries such as Time_Of_Last_Update and Text_Name which have no relation to the Reference Manual-defined notion of an Ada compilation unit.

To facilitate the use of context, implementations may support the use of containers which are logical collections of ASIS compilation units. For example, some containers can hold compilation units which include Ada predefined types; another container can hold implementation-defined packages. Containers provide an implementation-defined way of grouping the compilation units accessible for an ASIS application through the ASIS queries.

Illegal / inconsistent units in the compilation environment

Ada Implementation permissions allow for illegal and inconsistent units to be in the environment. Because the contents of the Ada environment are Ada-implementation-defined, the ASIS context can contain illegal compilation units. The use of ASIS can result in the exception ASIS_Failed being raised if the Ada environment includes such units.

ASIS queries

ASIS queries are provided in the form of structural (syntactic) and semantic queries to the Ada compilation environment.

Structural queries

Structural queries are those ASIS queries which provide the top-down decomposition and reverse bottom-up composition of the compilation unit according to its syntax structure. These structural queries are further characterized as: * "Black-box" queries are those ASIS queries which produce information about compilation units * "White-box" queries are those ASIS queries which produce information about lexical elements of compilation units.

Semantic queries

Semantic queries are those ASIS queries which express semantic properties of ASIS Elements in terms of other Elements. There are three kinds of semantic queries in ASIS:

General ASIS query processing

Both structural (syntactic) and semantic queries are facilitated through the notion of ASIS elements and their kinds. Most ASIS queries provide for the processing of specific constructs with respect to the Ada Reference Manual and the processing of their lists.

Elements and element kinds

The base object in ASIS is the Asis.Element. Element is a common abstraction used to denote the syntax (both explicit and implicit) of ASIS compilation units. Elements correspond to nodes of a hierarchical tree representation of an Ada program. Most elements of the tree have child elements. These children can appear as single elements (possibly with children themselves) or as a list of elements (also possibly with children). As an example, think of an Ada object declaration having three sub-parts or children:

Thus, the declaration: A, B : Latitude := 0.0;

has a corresponding tree as shown below.

Syntactic tree representation of an Ada object declaration
Syntactic tree representation of an Ada object declaration

ASIS Elements are either explicit elements, representing a language construct that appears explicitly in the program text for the compilation unit, or implicit elements, representing a language construct that does not exist in the program text for the compilation unit, but could occur at a given place in the program text as a consequence of the semantics of another construct (e.g., an implicit declaration, a generic instantiation).

ASIS provides the ability to visit elements of the tree and ask questions of each element. One key hierarchy of questions begins with: "What kind of element do I have?" Elements of the highest level of the ASIS hierarchy are classified into kinds. The following table identifies the high level hierarchy of kinds, the primary ASIS package to support processing of those kinds, and the references for those kinds in the Ada Reference Manual.

	A_Defining_Name		Asis.Definitions	Reference Manual  3, 6
	A_Declaration		Asis.Declarations	Reference Manual  3, 5, 6, 7, 8, 9, 10, 11, 12
	A_Definition		Asis.Definitions	Reference Manual  3, 7, 9, 12
	An_Expression		Asis.Expressions	Reference Manual  2, 4
	A_Statement		Asis.Statements		Reference Manual  5, 6, 9, 11, 13
	A_Path			Asis.Statements		Reference Manual  5, 9
	A_Clause		Asis.Clauses		Reference Manual  8, 10, 13
	An_Association		Asis.Expressions	Reference Manual  2, 3, 4, 6, 12
	An_Exception_Handler	Asis.Statements		Reference Manual  11.2
	A_Pragma		Asis.Elements		Reference Manual  2, 10, 11, 13, B, G, H, I, L

The function Asis.Elements.Element_Kind classifies any element into one of these kinds. Once the client knows that an element is a declaration, for example, it can further classify the element as to what kind of declaration it is with the Asis.Elements.Declaration_Kind function. This leads to case structures like the following.

EXAMPLE Case statement to classify elements:

    case Asis.Elements.Element_Kind (My_Element) is               -- 13.6
        when Asis.A_Declaration =>                                --  3.9.1
            case Asis.Elements.Declaration_Kind (My_Element) is   -- 13.9
                when Asis.A_Variable_Declaration =>               --  3.9.4
                    { statement }
                when others =>
                    null;
            end case;
        when Asis.A_Statement =>                                  --  3.9.1
            case Asis.Elements.Statement_Kind (My_Element) is     -- 13.25
                when Asis.A_Block_Statement =>                    --  3.9.20
                    { statement }
                when others =>
                    null;
            end case;
        when others =>
            null;
    end case;

In this example, variable declarations and block statements will presumably be processed further. All other element kinds are ignored by falling into the null when others alternative.

Processing specific constructs

Once this level of classification is determined, ASIS provides a set of functions for processing a specific statement, declaration, or other element kinds. The following functions are available for processing object declarations:
    function Names (Declaration : Asis.Declaration)                       -- 15.1
            return Asis.Defining_Name_List;
    function Object_Declaration_View (Declaration : Asis.Declaration)     -- 15.9
            return Asis.Definition;
    function Initialization_Expression (Declaration : Asis.Declaration)   -- 15.10
            return Asis.Expression;

These functions correspond to each of the three parts of an object declaration. Once it is classified into its kind, each element can be processed further with the provided functions. Some functions "traverse" to other child elements such as the Object_Declaration_View and Initialization_Expression functions above. Since the kind of element that is returned for each of these functions is already known, processing can continue directly with the functions in the Asis.Definitions package that accept A_Type_Definition elements or the Asis.Expressions package that accept An_Expression elements. The exception ASIS_Inappropriate_Element is raised whenever an ASIS function is passed an element it is not intended to process. Parameter names and subtype names in the function specifications indicate what kind of input element is expected and what kind of element is returned.

Element list processing

EXAMPLE Loop iteration scheme
        List : constant Asis.Element_List :=                          -- 3.7
            <ASIS function returning a list>;
        An_Element : Asis.Element;                                    -- 3.6
    begin
        for I in List'Range loop
            An_Element := List (I);
            Process (An_Element);
        end loop;

Functions that return Element_List types generally indicate what type of elements are in the list they return. Thus, processing can sometimes continue with specific calls without first asking what type of element is being processed.

Operations that apply to all elements

The figure below depicts operations which, in general, apply to all elements.
Operations on elements
Operations on elements

The ASIS packages provide some general interfaces that operate on all nodes, such as:

Semantic references

References from one part of an Ada program to another can be traversed with functions whose name begins with "Corresponding_", such as: Corresponding_Children, Corresponding_Declaration, Corresponding_Body, Corresponding_Type_Declaration, Corresponding_Type, Corresponding_Body_Stub, Corresponding_Name_Definition, Corresponding_Name_Declaration, Corresponding_Loop_Exited, Corresponding_Entry, etc. If an element references another element, the user can traverse to the referenced element with this function. A Nil_Element is returned if no definition traversal is possible.

A slightly more precise statement of the operation of this function is that identifier references point to identifier definitions. Traversal arrives at the identifier definition where the Enclosing_Element function is used to arrive at the complete element declaration.

For example, the user can traverse to the type declaration referenced in an object declaration with the Corresponding_Expression_Type function as shown below. This also depicts links using the semantic query Corresponding_Name_Declaration. (Note: the thin lined-arrows depict syntactic queries while the thick-lined arrows depict semantic queries.)

Semantic reference using corresponding queries
Semantic reference using corresponding queries


[Up] [SIGAda] [ACM]

Last update 17 August 1998. Questions, comments to Clyde Roby (CRoby@IDA.Org)