Ada Repair is a separate product that complements the Ada Analyzer. Ada Repair supports two capabilities: repair of coding violations and renaming of declarations within some body of Ada code.
This component of Ada Repair takes static analysis of coding violations a step further. It automatically creates new versions of Ada programs that no longer contain violations. The resulting code is semantically equivalent to the original but with improved maintainability, consistency, and readability.
For example, the following procedure call embedded in a case statement
could be updated to add the missing named parameter association and the default parameter to the procedure call. The addition of named parameter association makes the call more readable; the addition of the default parameter reduces the risk of future defects when the default is changed. Expanding the case range and when others will make the software more robust and less prone to future defects.
The following repairs can be made to Ada software. Each update is a separate option in the dialog box of the Analyzer:Ada Repair:Repair Violations command.
Code Modification Benefits
1. Add named parameter association to procedure calls. Makes procedure calls more readable and maintainable.
2. Add named association to aggregates. Makes aggregates more readable and maintainable.
3. Add named association to generic instantiations. Makes generic instantiations more readable and maintainable.
4. Add explicit default parameters to calls using the default. Makes procedure calls less susceptible to errors resulting from future changes.
5. Add missing in mode specifications to subprogram parameters. Makes procedure declarations more explicit and thus more understandable.
6. Adjust in out parameters when they are only set (to out mode) or only used (to in mode) Makes parameters consistent with their actual use.
7. Move representation clauses immediately after the type they represent. Makes the software more readable; required by Ada 95.
8. Generate named number declarations for literals in subprogram bodies and replace the literal with a reference to the named number. Makes the software less susceptible to errors resulting from future changes to literal values.
9. Name loops that are nested. Makes the software more readable and allows exit statements to be made explicit.
10. Name blocks that are nested. Makes software more readable.
11. Replace or and and operators with their short-circuit forms. Can make software more efficient.
12. Replace when others in case statements with actual values (enumeration only). Makes case statements less susceptible to errors resulting from future changes.
13. Replace literal ranges in case statements with actual values (enumeration only). Makes case statements less susceptible to errors resulting from future changes.
14. Replace when others in record aggregates when enumerated. Makes record aggregates less susceptible to errors resulting from future changes.
15. Replace if then exit with exit when. Makes the software more readable and less complex.
16. Add explicit loop names to exit when possible. Makes the software more readable and less susceptible to errors from future changes.
17. Qualify references that are not already fully qualified. Makes the software more readable, more robust, and can lead to the removal of use clauses.
18. Add rename declarations for all infix operators used in a unit. Makes the software more readable and can lead to the removal of use clauses.
19. Replace anonymous array type specifications with an explicit array type declaration. Makes the software more explicit and readable.
20. Generate explicit index types for array types when required. Makes the software more readable and allows for use of lower-bound, upper-bound, and range attributes.
21. Replace raise; with an explicit raise. Makes the software more readable and robust.
22. Remove unused and redundant with clauses. Move with clauses from the spec to the body when possible. Reduces dependencies and complexity to minimal requirements. Can reduce recompilation time. Improves program structure.
23. Alphabetize context clauses. Makes location of specific with clauses easier.
24. Alphabetize rename clauses. Makes location of specific rename clauses easier.
25. Replace multi-name context clauses with a series of single-name context clauses. Makes the software more consistent and readable. Allows for better ordering.
26. Replace multi-name declarations with a series of single-name declarations. Makes the software more consistent and readable. Allows for separate default values.
27. Remove use clauses Removes the open naming that use clauses introduce.
The Update Process
Ada Repair will replace the current version of an Ada unit with one that no longer contains the specified coding violations. If necessary, Ada Repair will also checkout controlled units before they are updated. It will also recompile and checkin units after they have been updated, when requested. Each unit specified for update will be traversed to locate all occurrences of the specified coding violations.
Since Ada Repair modifies the files containing Ada units, it is important to ensure that all changes made are desired changes. As users continue to use Ada Repair, they will gradually gain confidence that the updates are made correctly and are consistent with their coding standards. Several safeguards capture the updates and allow one to revert to the previous version of a unit when the updates are not desired.
- 1. All units should be placed under CMVC control. Before units are updated they should be checked-in to ensure that a baseline version is recorded. Ada Repair will then check the units out (when the Allow_Check_Out option is enabled), creating a new updated version. The differences between the two versions can then be displayed for inspection and acceptance. If the new version is unacceptable, the user can revert to the previous version or make manual changes to the new version to correct any problems. Alternatively, a user could not enable the Allow_Check_Out option, and then check out only those units for which updates are desired. Differences could still be computed using the Control:Show:Differences operation.
- 2. If the Replace_Existing_Units option is not selected, the new version of the unit will be saved in a file called <ada_unit_name>.new, and the Ada unit file will remain untouched. Files can then be copied or deleted as desired to accept or reject the updates made by Ada Repair. This provides a manual method of version control that is automated with the CMVC approach in step 1.
- 3. An Effort_Only option is available to list in the log all changes that would be made without actually making the updates to the Ada files. This allows the user to view potential change before requesting that they be made.
It is possible that two or more updates will attempt to modify the same span of code in an Ada unit. Ada Repair recognizes when updates would conflict with each other and makes only the first update. When conflicting updates are found, they are noted in the log and no conflicting updates are not made to the software. It is possible to run Ada Repair again in this case (after the new units are recompiled). The second execution will not have the original conflict and the update rejected during the first execution will be made.
-Use_Configuration [string-expression, default = ""]
<list of units>
- Replace_Existing_Units: Specifies whether or not to write updates directly into the Ada unit files specified in the <list of units>. If this option is not enabled, a file called <ada_unit_name>.new will be created containing the new, updated version of the unit.
- Allow_Check_Out: Specifies whether or not to check out controlled units that are checked in before updates are made. If this option is not enabled, only those units that are already checked out will be updated.
- Compile_After_Update: Specifies whether or not to recompile all units that are updated by Ada Repair.
- Checkin_After_Update: Specifies whether or not to check in all units that were checked out for update. If units are not checked back in, the changes made by Ada Repair can be abandoned and the unit reverted to the previous version.
- Effort_Only: Specifies whether or not to announce all updates that Ada Repair finds necessary in the log for review, without actually performing any updates.
- Announce_Updates: Specifies whether or not to announce all updates in the log for review. If this option is not enabled, updates will be made with notification to the log. If the Effort_Only option is enabled, enabling this option is redundant.
Note: The following options enable the updates described in section "Supported Updates".
- Name_Parameter_Associations: Adds named parameter association to subprogram calls that do not already have them.
- Name_Aggregate_Associations: Adds named association to record aggregate components that do not already have them.
- Name_Instance_Associations: Adds named parameter association to generic instantiations that do not already have them.
- Add_Default_Parameters: Adds default parameters to subprogram calls that do not already have explicit values for those parameters. The value of the current default defined in the subprogram specification is added.
- Add_Parameter_Modes: Adds explicit in modes to parameter specifications that do not already have them.
- Adjust_In_Out_Parameters: Changes the mode of any in out parameter to out if the parameter is set but never used within the containing subprogram body. The mode will be changed to in if the parameter is used but never set within the containing subprogram body.
- Expand_Multi_Name_Declarations: Changes declarations with multiple name definitions into a series of declarations with a single name definition.
- Expand_Multi_Name_Withs: Changes a with clause or use clause with multiple name references into a series of with clauses or use clauses with single name references.
- Move_Representation_Clauses: Moves representation clauses immediately after the type that the represent.
- Name_Literals: Creates a named number declaration for each integer and real literal within a compilation unit. Literals are then replaced with a reference to the named number.
- Name_Nested_Loops: Adds a name to any loop nested within another loop that does not already have one.
- Name_Nested_Blocks: Adds a name to any block nested with another block that does not already have one.
- Add_Short_Circuits: Replaces and and or operators with their short-circuit equivalents and then and or else.
- Replace_Case_Others: Replaces a when others alternative in a case statement with an alternative containing a list of explicit values. The items included are all values not listed in the preceeding case alternatives.
- Replace_Case_Ranges: Replaces a case range alternative with a list of explicit values that correspond to the values in the range.
- Replace_Aggregate_Others: Replaces a when others clause in a record aggregate with a list of explicit values that are not listed in the preceeding aggregate associations.
- Convert_To_Exit_When: Converts an if <condition> then exit; end if; construct into the equivalent exit when <condition>; form.
- Add_Loop_Name_To_Exit: Adds an explicit loop name to an exit statement if the loop that is exited is a named loop.
- Qualify_References: Replaces all references that are not fully qualified with their fully qualified form. This can be used to prepare for the removal of use clauses.
- Add_Operator_Renames: Adds explicit renaming declarations for predefined operators that are called within a compilation unit. Renaming declarations are only added if they do not already exist.
- Remove_Use_Clauses: Deletes all use clauses. It is only possible to enable this option when both the Qualify_References and Add_Operator_Renames options and no other are enabled.
- Make_Anonymous_Array_Types_Explicit: Converts an anonymous array type definition into an explicit array type declaration. The anonymous portion of the type specification is then replaced with a reference to the explicit array type declaration.
- Add_Explicit_Index_Types: Creates an explicit type declaration for an array index that is a subtype definition. The subtype definition is then replaced with a reference to the new type declaration.
- Make_Raises_Explicit: Adds the name of an exception to a raise statement that does not name an explicit exception. This is only performed if the raise statement appears in a handler which itself names a single exception.
- Repair_With_Clauses: Removes unused and repeated with clauses. Moves with clauses to a body unit if the with is not required in the specification and the with clause is not already present in the body.
- Alphabetize_Context_Clauses: Replaces a set of context clauses with the same set in alphabetical order.
- Alphabetize_Rename_Declarations: Replaces a set of renaming declarations with the same set in alphabetical order.
Ada Repair also provides a separate but related capability to move and/or rename declarations within some body of code. Declarations can be given a new name within a specified unit, moved to another existing compilation unit, or moved to and simultaneously renamed within an existing compilation unit. This capability is invoked with the Analyzer:Ada Repair:Rename Declarations menu item. This capability can be used to restructure code to improve its organization, reduce cross dependencies, and improve architectural integrity.
All references to the new declaration names will be updated to maintain compilation integrity. All views that have potential references must be specified in the list of units to repair. Units in views left out of the list will not be updated and may be inconsistent with the new declarations. Such inconsistencies must be repaired by hand. As a precaution, most declarations will be copied (not renamed in place) to ensure that unmodified references will still compile. This will allow subsequent processing of units with obsolete references. Some declarations must be renamed in place as specified below. Eventually, the renamed or moved declarations will have no remaining dependencies and can then be deleted. Options are available to comment out or delete the renamed or moved declarations.
Additional with clauses will be added to units where required to compile newly added references. Obsolete with clauses no longer required due to modified references will not be removed. This can be performed with the Repair Violations capability in another command invocation.
Usage Tip: It is possible to specify that more than one declaration be renamed or moved with a single command invocation. In some cases, multiple declarations must be moved to avoid cross-withing of specifications. It is recommended that the user limit to a reasonable number the number of declarations specified in any one command invocation. This will avoid undue complexity that may result in inconsistent code. Note that all modifications can be undone by abandoning changes in controlled units.
<list of views>
- Rename_Declarations: This option is used to enable the declaration renaming process. If this option is not present, Ada Repair assumes that the command will be used to repair coding violations listed on page 333. No Ada Repair options other than those listed above can be enabled if this option is also enabled.
- Replace_References_Only: Specifies whether to replace references to previously moved and/or renamed declarations. If this option is enabled, no declarations will be moved or renamed. It will only replace references to the declarations listed in the ada_repair/declaration_mapping configuration-policy file.
- Remove_Renamed_Declarations: Specifies whether to delete declarations that are renamed or moved. By default, declarations that are renamed or moved are accomplished with an updated copy of the declaration, leaving the original declaration unchanged. This allows for correct compilation of units that may have been accidently left out of the analysis. Exceptions to this rule are listed below. If this option is enabled, the original declaration will be deleted after copy. It is possible to use this option with the Replace_References_Only option.
- Comment_Out_Renamed_Declarations: Specifies whether the original declaration should be commented out after copy (see Remove_Renamed_Declarations option above). It is possible to use this option with the Replace_References_Only option.
- Copy_Preceeding_Attached_Comments: Specifies whether all attached comments that precede a renamed declaration should be copied and attached immediately before the new declaration.
- Copy_Succeeding_Attached_Comments: Specifies whether all attached comments that succeed a renamed declaration should be copied and attached immediately after the new declaration.
- <list of views>: Specifies the list of views that contain possible references to the declarations being renamed or moved. Ada units in views left out of this list will not be updated and could contain inconsistent references to update declarations. It is possible to include Ada units or view directories in this list. Their containing view will be added to the list of views to process.
Specifying Declarations to Rename or Move
The configuration-policy file ada_repair/declaration_mapping is used to specify the declarations that should be renamed or moved. All entries in this file should be of the form:
The source_pkg_name must be an Ada library unit within the set of views specified for processing and the source_decl_name must be a declaration within that package. It need not be in the specification. Additional nesting is allowed:
If the source_pkg_name and the destination_pkg_name are the same, then the mapping is considered a rename of the declaration. If the source_pkg_name and the destination_pkg_name are different, the declaration is specified to be moved from one unit to another. It is possible to both move and rename a declaration at the same time.
The destination_pkg_name must be an existing library unit and be either a package or package body declaration. If the Replace_References_Only option is enabled, the destination_decl_name must already exist within that package. If this option is not enabled, the destination_decl_name must not already exist within that package. If a declaration is being moved to a specific destination package, that package may not itself be renamed or moved.
By default, source declarations located in a specification will be moved to the specification of the destination container. Declarations located in the body will be moved into the body part of the destination container. It is possible to override this default placement with the `spec and `body attributes to specifically designate a specification or body of the destination container.
Some Ada declarations are two-part declarations. Package, procedure, function, task, entry, deferred constant, and incomplete type declarations are all two-part. Packages, subprograms, and tasks may also be subunits with an additional subunit stub declaration in the body. If the specification part of any two-part declaration is specified to be renamed or moved, then its corresponding body-part declaration and subunit stub (if present) will be treated similarly. Subunits will be created if necessary, but never deleted since they are normally controlled objects. Removal of obsolete subunits is left to the user.
Any declaration (including parameter, record discriminant, record component, generic formal, enumeration literal, or declarations declared locally within a subprogram) can be referenced by a qualified name containing all intervening declaration names. For example, it is possible to reference subprogram parameters with the following reference:
Record components can be referenced with:
Enumeration literals can be referenced with:
It is possible to move or rename any declaration, with the following exceptions:
- Multiple mappings from the same source declaration are not allowed in one execution of Ada Repair.
- It is not possible to move or rename declarations that are part of a multi-name declaration of the form a, b : Integer;
- It is not possible to move the following kinds of declarations:
- record component
- deferred constant
- record discriminant
- enumeration literal
- incomplete type
- private type
- abstract procedures and function
- generic formal parameter
- all declarations located in the private part of a package
- All declarations can be renamed within the same compilation unit. Some declarations must be renamed inplace and are not copied as specified above. Those declarations are:
Note: This can result in inconsistencies. Units that are not processed may reference the old declaration name that has been replaced. Other declarations that are copied may contain references to the old declaration name as well. The new copy of the declaration should not contain such references, but the old declaration from which the copy is made may have such references.
Renaming Compilation Units
Normally, it is only possible to move and rename declarations within compilation units. It is possible to rename compilation units with the following process. The user must first copy the compilation unit to a new name and compile it. The entire family (unit body and all subunits) must be included in the copy. Next, the declaration_mapping configuration-policy file should be updated with an entry of the form old_comp_unit_name => new_comp_unit_name. In this case, an exception is made to the format requirements of this file. Finally, the rename declarations capability of Ada Repair should be invoked with the Replace_References_Only option. This will replace all references to the old compilation unit with references to the new one.
|Rational Software Corporation
Copyright © 1993-2000, Rational Software Corporation. All rights reserved.