4. ASIS Overview¶
This chapter contains a short overview of the ASIS definition as given in the ISO/IEC 15291:1999 ASIS Standard. This overview is aimed at helping an ASIS newcomer find needed information in the ASIS definition.
For more details, please refer to the ASIS definition itself. To gain some initial experience with ASIS, try the examples in ASIS Tutorials.
4.1. Main ASIS Abstractions¶
ASIS is based on three main abstractions used to describe Ada programs; these abstractions are implemented as Ada private types:
Contextis a logical handle to an Ada environment, as defined in the Ada Reference Manual, Chapter 10. An ASIS application developer may view an ASIS
Contextas a way to define a set of compilation units available through the ASIS queries.
Compilation_Unitis a logical handle to an Ada compilation unit. It reflects practically all the properties of compilation units defined by the Ada Reference Manual, and it also reflects some properties of ‘physical objects’ used by an underlying Ada implementation to model compilation units. Examples of such properties are the time of the last update, and the name of the object containing the unit’s source text. An ASIS
Compilation_Unitprovides the ‘black-box’ view of a compilation unit, considering the unit as a whole. It may be decomposed into ASIS
Elements and then analyzed in ‘white-box’ fashion.
Elementis a logical handle to a syntactic component of an ASIS
Compilation_Unit(either explicit or implicit).
Some ASIS components use additional abstractions (private types) needed for specific pieces of functionality:
Container(defined by the
Asis.Ada_Environments.Containerspackage) provides a means for structuring the content of an ASIS
Context; i.e., ASIS
Compilation_Units are grouped into
Line(defined by the
Asis.Textpackage) is the abstraction of a line of code in an Ada source text. An ASIS
Linehas a length, a string image and a number.
Span(defined by the
Asis.Textpackage) defines the location of an
Compilation_Unit, or a whole compilation in the corresponding source text.
Id(defined by the
Asis.Idspackage) provides a way to store some ‘image’ of an ASIS
Elementoutside an ASIS application. An application may create an
Idvalue from an
Elementand store it in a file. Subsequently the same or another application may read this
Idvalue and convert it back into the corresponding
4.2. ASIS Package Hierarchy¶
ASIS is defined as a hierarchy of Ada packages. Below is a short description of this hierarchy.
The root package of the hierarchy. It defines the main ASIS abstractions —
Element— as Ada private types. It also contains a set of enumeration types that define the classification hierarchy for ASIS
Elements (which closely reflects the Ada syntax defined in the Ada Reference Manual) and the classification of ASIS
Compilation_Units. This package does not contain any queries.
Contains subprograms that control an ASIS implementation: initializing and finalizing it, retrieving and resetting diagnosis information. Its child package
Asis.Implementation.Permissionscontains boolean queries that reflect how ASIS implementation-specific features are implemented.
Contains queries that deal with an ASIS
Context: associating and dissociating, opening and closing a
Contains queries that work with ASIS
Compilation_Units: obtaining units from a
Context, getting semantic dependencies between units and ‘black-box’ unit properties.
Contains queries that return integrated semantic dependencies among ASIS
Compilation_Units; e.g., all the units needed by a given unit to be included in a partition.
Contains queries working on
Elements and implementing general
Elementproperties: gateway queries from ASIS Compilation Units to ASIS
Elements, queries defining the position of an
Elementclassification hierarchy, queries which define for a given
Compilation_Unitand its enclosing
Element. It also contains queries for processing pragmas.
Packages working on specific
This group contains the following packages:
ASIS.Clauses. Each of these packages contains queries working on
Elements of the corresponding kind — that is, representing Ada declarations, definitions, statements, expressions and clauses respectively.
Contains queries returning information about the source representation of ASIS
Compilation_Units and ASIS
Defines ASIS exceptions.
Defines possible ASIS error status values.
4.3. Structural and Semantic Queries¶
Queries working on
Elements and returning
are divided into structural and semantic queries.
Each structural query (except
implements one step of
the parent-to-child decomposition of an Ada program according to the ASIS
Element classification hierarchy.
implements the reverse child-to-parent step. (For implicit
as results of semantic queries,
Enclosing_Element might not correspond to what
could be expected from the Ada syntax and semantics; in
this case the documentation of a semantic query also defines the effect of
Enclosing_Element applied to its result).
A semantic query for a given
Element returns the
Element or the list of
Elements representing some semantic property — e.g., a type
declaration for an expression as the expression’s type, a defining identifier as a
definition for a simple name, etc.
For example, if we have
El representing an assignment statement:
X := A + B;
then we can retrieve the structural components of this assignment statement by applying the appropriate structural queries:
El_Var := Asis.Statements.Assignment_Variable_Name (El); -- X El_Expr := Asis.Statements.Assignment_Expression (El); -- A + B
Then we can analyze semantic properties of the variable name represented by
El_Var and of the expression represented by
El_Expr by means of
appropriate semantic queries:
El_Var_Def := Asis.Expressions.Corresponding_Name_Definition (El_Var); El_Expt_Type := Asis.Expressions.Corresponding_Expression_Type (El_Expr);
As a result,
El_Var_Def will be of
and will represent the defining occurrence of
El_Expt_Type of a kind
represent the declaration of the type of the expression
A + B.
If we apply
El_Var or to
El_Expr, we will get back to the
Element representing the
An important difference between classifying queries working on
semantic is that all the structural queries must be within one ASIS
Compilation_Unit, but for semantic queries it is typical for the
argument of a query to be in one ASIS
Compilation_Unit, while the result of this
query is in another ASIS
4.4. ASIS Error Handling Policy¶
Only ASIS-defined exceptions (and the Ada predefined
exception) propagate out from ASIS queries. ASIS exceptions
are defined in the
When an ASIS exception is raised, ASIS sets the Error Status (the possible
ASIS error conditions are defined as the values of the
and forms the
An application can query the current value of the ASIS Error Status by the
and the current content of the
Diagnosis string by
can reset the Error Status and the
Diagnosis string by
Caution: The ASIS way of providing error information is not tasking safe.
Diagnosis string and Error Kind are global to an entire partition,
and are not ‘per task’.
If ASIS exceptions are raised in more then
one task of a multi-tasking ASIS application, the result of
querying the error information in a particular task may be incorrect.
4.5. Dynamic Typing of ASIS Queries¶
The ASIS type
covers all Ada syntactic constructs,
covers all Ada compilation
units. ASIS defines an
Element classification hierarchy (which reflects
very closely the hierarchy of Ada syntactic categories defined in the
Ada Reference Manual,
and ASIS similarly defines a classification scheme for ASIS
Element you can get its position in the
classification hierarchy by means of classification queries defined in the
The classification queries for
are defined in the package
Many of the queries working on
Compilation_Units can be applied
only to specific kinds of
Compilation_Units respectively. For
example, it does not make sense to query
Assignment_Variable_Name for an
An attempt to perform such an operation will be detected at run-time, and
an exception will be raised as explained in the next paragraph.
ASIS may be viewed as a dynamically typed interface. For any
or semantic query (that is, for a query having an
Element as an argument and
returning either an
Element list as a result) a list of appropriate
Element kinds is explicitly defined in the query documentation which
immediately follows the declaration of the corresponding subprogram in the
code of the ASIS package. This means that the query can be applied only to
Elements being of the kinds from this list. If the kind of the
Element does not belong to this list, the corresponding call to this
query raises the
Asis.Errors.Value_Error error status set.
The situation for the queries working on
Compilation_Units is similar. If a
query lists appropriate unit kinds in its documentation, then this query can
work only on
Compilation_Units of the kinds from this list. The query should
Asis.Errors.Value_Error error status set when called for any
Compilation_Unit with a kind not from the list of the appropriate unit kinds.
If a query has a list of expected
Element kinds or expected
kinds in its documentation, this query does not raise any exception when
called with any argument, but it produces a meaningful result only when called
with an argument with the kind from this list. For example, if
is called for an argument of
A_Declaration kind, it just returns
Not_A_Statement, but without
raising any exception.
4.6. ASIS Iterator¶
ASIS provides a powerful mechanism to traverse an Ada unit, the generic
This procedure makes a top-down
left-to-right (or depth-first) traversal of the ASIS tree (that is, of
the syntax structure of the Ada code viewed as the hierarchy of ASIS
Elements). In the course of this traversal, it applies to each
Pre_Operation procedure when visiting this
Element for the first
time, and the formal
Post_Operation procedure when leaving this
By providing specific procedures for
Post_Operation when instantiating the generic unit, you
can automatically process all ASIS
in a given ASIS tree.
For example, suppose we have an assignment statement:
X := F (Y);
When called for an
Element representing this statement, a
Traverse_Element instantiation does the following (below
Post_Op stand for actual procedures provided for formal
Post_Operation, and numbers indicate the
sequence of calls to
Post_Op during traversal):
(1 Pre_Op) X := F (Y) (10 Post_Op) | | ----------------------------------- | | (2 Pre_Op) X (3 Post_Op) | | (4 Pre_Op) F(Y) (9 Post_Op) | | --------------------------- | | (5 Pre_Op) F (6 Post_Op) (7 Pre_Op) Y (8 Post_Op)
To see in more detail how
Traverse_Element may be used for rapid
development of a number of useful ASIS applications, try the examples in