Skip to content

Analysis and manipulation of Ada software based on concrete syntax

License

Notifications You must be signed in to change notification settings

TNO/Rejuvenation-Ada

Repository files navigation

Ada Crate Of The Year 2022

Rejuvenation-Ada

The Rejuvenation-Ada library enables analysis and manipulation of Ada code based on concrete patterns. Analysis and manipulation is based on the AST of Ada and hence is insensitive for layout and the presence of comments. Both find- and replace-functionality are specified using an extended version of the well-known concrete syntax of Ada.

The Rejuvenation-Ada library is part of the Renaissance-Ada project that develops tooling for analysis and manipulation of Ada code.

Basic Analysis and Manipulation

With the Rejuvenation-Ada library, you can analyze, for occurrences of the code pattern

ready; set; go;

and you would find the following occurrences (when they appear in your Ada project)

ready; set; go;
ready; 
set; 
go;
ready;   -- first signal to prepare action

set;     -- second signal to acquire resources

go;      -- take action

Note that the analysis is insensitive for layout and the presence of comments.

Furthermore, you can manipulate all found occurrences by replacing them with the code pattern

start;

Powerful Analysis and Manipulation using Placeholders

Since Ada's concrete syntax can be easily extended by using characters, such as $, that are illegal in the Ada programming language (except inside character and string literals), the Rejuvenation-Ada library is able to make the analysis and manipulation of Ada code more powerful, by adding just one extension to Ada's concrete syntax: Placeholders.

There are two types of placeholders, those starting with "$S_" and those starting with "$M_". Any alphanumeric string is allowed to follow after those prefixes.

"$S_" placeholders allow one to match a single AST node, be that a single expression, a single statement, a single argument, or anything else. As long as Ada parses it to a single AST node, the "$S_" placeholders can match it.

"$M_" placeholders allow one to match a list of AST nodes, i.e., zero or more nodes.

placeholders in find patterns

A find pattern might contain multiple different placeholders.

A find pattern might contain the same placeholder multiple times. This adds a constraint to the find process: A match will only be found when all occurrences of the same placeholder are identical. In analogy with Regular Expressions, the term backreference is used to denote a placeholder that reoccurs.

The placeholder $S_Dest in the following find pattern

if $S_Cond then
   $S_Dest := True;
else
   $S_Dest := False;
end if;

ensures that the same destination is used in both branches of the if statement.

placeholders in replace patterns

A placeholder in a replace pattern always refers to that placeholder in the find pattern. A placeholder in a replace pattern that does not occur in the find pattern is thus an error. A placeholder in the replace pattern will be replaced by the value of that placeholder in the match of the find pattern. In analogy with Regular Expressions, all placeholders in a replace pattern can be called backreference.

The following replace pattern

$S_Dest := $S_Cond;

simplifies the code found with the previous find pattern using the backreferences $S_Cond and $S_Dest.

Examples

Double Negation

Find pattern for double negation

not (not $S_Condition)

Replace pattern to remove double negation

$S_Condition

For All

Ada 2012 has quantified expressions. When migrating code from earlier versions of Ada to Ada 2012 or beyond, the code should use these quantified expressions. Furthermore, not all programming languages support quantified expressions. Hence, programmers educated in other languages might not be aware of quantified expressions.

The following find pattern will detect all code that is equivalent to returning a for all expression

for $S_Element of $S_Elements loop 
    if $S_Condition then return false; end if; 
end loop;
return true;

The following replace pattern will change the found code to use the for all expression

return (for all $S_Element of $S_Elements => not ($S_Condition));

Real World

With the previous two find and replace patterns code found in the semantic versioning project:

could be automatically simplified into

 return (for all R of VS => Satisfies (V, R));

More Examples

See the examples, the workshop, and the tests for inspiration to use the Rejuvenation Library.

Design

Dependencies

The rejuvenation crate exploits the power of the abstract syntax as provided by Libadalang, making the analysis and manipulation insensitive for layout and the presence of comments. Yet, its interface does not expose Libadalang's abstract syntax. Instead, its interface is almost identical to the concrete syntax of the Ada programming language.

The Rejuvenation-Ada library delegates the actual pretty-printing to gnatpp from the libadalang-tools. The Rejuvenation-Ada library assumes that gnatpp is accessable on your system PATH. gnatpp can be installed using Alire using the command alr get --build libadalang_tools.

Usage

Starting points for using the Rejuvenation-Ada library include:

Tools made using Rejuvenation

Alire