Libadalang 27 Release Notes

We present here a few highlights of the new features in Libadalang 27. You can access the complete list in the Libadalang 27 feature file.

Static expression evaluator

Support evaluation of 'Range_Length

The static expression evaluator now supports the Range_Length attribute.

Support evaluation of 'Width on discerte types

Libadalang’s expression evaluator now supports evaluation of the ‘Width attribute. This initial support is limited to discrete types.

Support evaluation of 'Size on standard types

This improvement in Libadalang’s expression evaluator allows it to evaluate expressions that involve occurrences of the ‘Size attribute, when applied to predefined types from the Standard package (Boolean, Integer, etc.).

Support evaluation of 'First/'Last/'Length on arrays

This improvement in Libadalang’s expression evaluator allows it to evaluate expressions that contain occurrences of the ‘First, ‘Last or ‘Length attributes applied to statically constrained arrays.

New properties

New property is_statically_predicated

This property can be used to determine whether a static predicate applies to the given type. The static predicate can be defined either by a Static_Predicate aspect or by a Predicate pragma whose expression is static.

New property is_nameres_ambiguous

This new property allows querying whether multiple semantic interpretations are possible for a given resolution context, for example if the name of a call expression can designate two different semantically valid subprograms.

New property corresponding_neq_subprogram

Return the corresponding "/=" synthesized subprogram of a "=" subprogram. This property should only be called on a subprogram with the name "=", otherwise a PreconditionFailure will be raised.

New property discrete_static_values

If applicable, return the values that this discrete subtype can take as an array of concrete ranges, by taking into account static predicates that apply to this subtype.

New property is_classwide

A new property is_classwide has been added that returns whether a type is a class-wide type.

Improvements

Support of recent SPARK features

Libadalang’s syntactic and semantic support for the SPARK subset was updated to include:

  • Multiple levels of ghost code

  • The Initializes aspect

  • The Exceptional_Cases and Exit_Cases aspects

  • The Modifies aspect

Robustness to incremental changes

Libadalang’s lexical environments were made more robust to incremental changes (e.g. re-analyzing a unit after it was edited and reparsed), fixing latent issues where cache invalidation could be missed in certain circumstances (which could lead to invalid name resolution).

Partial reformatting of rewritten source sections

Libadalang’s rewriting API now allows applying the edit such that it will be formatted using a provided unparsing configuration, without impacting the existing formatting of the sources for sections that were not modified.

Unparsing

General branching constructs

The unparsing DSL was extended to support a small subset of expressions (comparisons, invoking node properties, etc.) and a generic constructs, instead of the previous hard-wired ifEmpty and ifKind constructs. This allows much more flexibility in describing how formatting must apply under specific contexts.

Allow overridings of the unparsing config

The unparsing API for loading an unparsing configuration now allows users to pass extra partial configurations that can override parts of the base configuration, in order to ease customization: users can re-define how a specific node is formatted without having to provide an entire unparsing configuration.

API breaking changes

Op node is not a token node anymore

The Op node kind was previously declared as deriving from the SingleTokNode kind (itself deriving from Name), but this was unnecessary, as the symbol of an operator can always be determined by its kind (e.g. OpAnd’s symbol is and), meaning it’s useless to store with it the source string that was used to parse it. But it was also wrong, as some operators are actually composed of multiple tokens (e.g. OpAndThen).

Thus, Op was modified to derive directly from Name, and property signatures impacted by this change were adapted accordingly.