Integrating the Ada Analyzer into a Software Development Process
The following paper describes how use of the Ada Analyzer can be integrated into a software development process. It describes the commands that each group within a software development team would use during various phases of the lifecycle.
Developers
Coding and Testing:
During coding, developers should execute the Locate_Coding_Violations_Interactively command often to check their Ada units for standards-conformance violations. This will ensure that emerging implementations do not contain coding violations that are more expensive to identify and remove later in the lifecycle. The interactive nature of this command can be used to immediately identify and repair violations.
The Display_Subprogram_Branch_Points command can be used to aid the developer in generating test driver programs. It can identify all paths and the variables that are used (inputs) and set (outputs) along each path.
Before Code Review or Internal Release:
One of the most effective ways to engineer quality into software is through some form of peer review process. A formal code review allows each developer the opportunity to get feedback from other members of the development team. It is important, however, that the code submitted for review be as high quality as possible so that reviewers focus on more substantive issues than the presence of coding violations or statically locatable problems. It should be mandatory that developers bring the results of the following commands to code review.
- Locate_Coding_Violations - Use of the batch form of standards-conformance checking can be used as a final check to ensure that no coding violations are presented for code review or for release. Some checks are not appropriate for the interactive form of this command due to their high computation requirements and are better checked here.
- Display_Set_Use_Problems - Locates uninitialized variables and out parameters that are not set along each subprogram path.
- Display_Subprogram_Execution_Problems - Locates function paths for which no return or raise is present and the propagation of non-visible exceptions.
- Locate_Potential_Programming_Errors - Locates a series of potential programming errors (see the Ada Analyzer User's Guide for details).
- Locate_Static_Constraint_Violations - Locates constraint violations that can be computed statically (i.e. that will always raise the constraint_error exception).
- Locate_Unused_With_Clauses - Locates unused and misplaced with clauses.
- Locate_Unused_Declarations - Locates declarations that are not referenced.
- Locate_Compatibility_Problems - Locates potential compiler compatibility problems when the code is intended for another target.
- Locate_Annotations - When customized to local requirements, this command can be used to recognize missing annotations and/or collect condensed annotation content.
- Locate_Misspellings - Locates all misspelled words in comments, string literals, and segments of declarative names.
When preparing for code review, developers should also use the Generate_Listing command to create a postscript listing of their software. This listing will contain line numbers and be pretty printed in fancy format (key words bold, comments in italics) making it easier to read. Documentation tools (Framemaker, Interleaf, or other word processoring software) can be used to generate a table of contents for easy reference. Use of the Ada Analyzer Include_Line_Numbers switch will generate reports with line numbers correlated to the line numbers in the listing.
Code Reviewers
Preparing for Code Review:
Preparation for code review can be a difficult and time consuming process, especially since the reviewer is not the author of the code and likely has little understanding of its organization and content. The Ada Analyzer can be used to minimize the amount of time it takes to prepare for code review. Since developers are required to execute most of the code correctness and coding-standard verification commands, reviewers need not re-execute those commands. They can review these reports at code review, if necessary. Since no developer wants to present code that contains standards violations or defects, reviewers can be assured that the code under review is substantially free of those problems. They can, however, use the Ada Analyzer in other ways.
The following commands can be used to locate key constructs. This will give the reviewer some insight into the structure and content of the code. Since these constructs are often critical to the design of the code, locating them will help reviewers focus analysis on these key constructs.
- Locate_Tasking - Locates all tasks, entries, entry accepts, and entry calls (rendezvous points).
- Locate_Exceptions - Locates all exception declarations, handlers, and raises.
- Locate_Generics - Locates all generics and their instantiations.
- Display_Unit_Relationships - Displays all with relationships between Ada units.
- Locate_Packages_With_State - Locates all static variables (state) within the program.
The following commands can be used to locate complexity in a program. Areas of high complexity are more likely to contain code that requires external review. Output from these commands can help a reviewer focus on the places of highest return for the time they have to invest.
- Locate_Subprogram_Complexities - Locates subprograms with a large number of execution paths, subprograms whose statements are deeply nested, subprograms that have a high number of exit points, and subprograms with a large number of parameters.
- Locate_Generic_Complexities - Locates nested generics, generics instantiated with other generic instantiations, and generics instantiation in dynamic scopes.
- Locate_Complex_Expressions - Locates expressions that are deeply nested, have a high number of operators, and/or variable references.
Once a single instance of a problem is found during analysis, the Ada Analyzer can be used to locate all occurrences of that problem. The commands designated to analyze Program Content would be the most likely candidates. Similarly, if the reviewer notices some interesting characteristic (like implementation specific constructs or a particular kind of construct usage), the Program Content commands can be used to focus analysis on those features.
Designers
Preparing For Design Review:
In addition to code reviews that focus on specific implementation of functional requirements, design reviews should be held to ensure quality of the system as a whole. At this level, review should focus on the structure of the software and the inter-relationship of the Ada features it uses. The following commands support analysis of the software structure:
- Display_Inter_Subsystem_References - Generates a cross-referenced listing of inter-subsystem dependencies for use in analyzing subsystem partitioning.
- Display_Unit_Relationships - A cross-reference of the with dependencies between each compilation unit.
- Locate_External_Dependencies - Generates a cross-referenced listing of inter-unit dependencies (references to unit declarations) for use in analyzing unit partitioning.
- Display_Call_Tree - Can be used to display hierarchical calling relationships of each main program or task.
The following commands support analysis of global software content and the inter-relationship of features.
- Locate_Type_Declarations - Locates all type declarations sorted by kind. This can be used to analyze the appropriateness of the type model and find redundancy.
- Locate_Tasking - Locates all tasks, entries, entry accepts, and entry calls (rendezvous points).
- Locate_Exceptions - Locates all exception declarations, handlers, and raises.
- Locate_Subprograms_Propagating_Exceptions - Determines which exceptions could possibly be propagated from each system subprogram.
- Locate_Generics - Locates all generics and their instantiations.
- Locate_Named_Declarations - Lists all program declarations sorted by kind.
Some code correctness analysis must be performed on a global level to locate problems. The following commands support analysis of global software defects and inconsistencies.
- Locate_Unused_Declarations - Locates declarations that are not referenced.
- Locate_Data_Synchronization_Points - Locates variables that are set and used along multiple threads of control. Objects that are modified by two or more threads may require synchronization.
- Locate_Renames - Can be used to analyze if renaming is used consistently throughout the software.
- Locate_Objects_Set_And_Used - A list of all objects and where they are set and used. This analysis can help to locate variables that are never set or never used.
During Optimization:
Most software systems reach a point where they generally work as specified, but execute too slowly or take too much memory. The following commands can be used to assist the designer in analyzing the potential for optimization.
- Locate_Inline_Candidates - Locates subprograms that may be candidates for inlining by counting the number of local variables, the number of local statements, and the number of call sites.
- Display_Set_Twice_Before_Use - Locates variables that are set more than one time before they are used. When all variabless are initialized at declaration, this inefficiency can creep in.
- Locate_Generic_Formal_Dependencies - Locates parts of generic units that are not dependent on the generic formals and thus could be separated out into non-generic components. This can save space when the generic is instantiated multiple times.
- Locate_Recursive_Subprograms - Locates all recursive subprograms. Recursion can be expensive and can sometimes be replaced with iterative algorithms.
- Locate_Short_Circuit_Opportunities - Locates areas where use of short circuit operators may be appropriate.
- Locate_Loop_Nesting - Identifies where loops are nested so that optimization efforts can be concentrated where they will do the most good.
- Locate_Constants - Identifies redundant constant declarations.
- Locate_Operators - Analyzes operator selection and potentially indicates redundant algorithms.
Managers
Analyzing Project Status:
Most Managers will not focus on the detailed Ada content of the system but on the management of the development process. Collecting and comparing metrics at significant release points can indicate trends that may suggest reallocation of resources. Line counting metrics can indicate progress toward completion and be used as an estimate for the amount of testing resources required.
- Collect_Metrics - Collects a set of complexity and configuration management based metrics.
- Compare_Metrics - Allows comparison of metrics collected over time to analyze trends.
- Count_Lines_Of_Code - Collects many dimensions of "Source Lines of Code" or (SLOC).
Documentation Personnel
Generating Documentation Deliverables:
The Ada Analyzer can be used to create part of the deliverable documentation for a software system. Providing reference documentation on the content and structure of the delivered software can help the customer perform acceptance testing and/or perform future maintenance. Software projects can propose delivery of this additional documentation for little additional cost when it can be automatically generated. Although almost any Ada Analyzer report could be delivered as documentation, the following reference oriented commands may be the most likely:
- Locate_Objects_Set_And_Used - Display all system variables and where they are set and used.
- Locate_Named_Declarations - Lists all program declarations sorted by kind.
- Display_Call_Tree - Displays a call tree for all main programs and/or program threads.
- Locate_Subprograms_Propagating_Exceptions - Determines which exceptions could possibly be propagated from each system subprogram. Note that there is no way to document this using the Ada language itself.
- Display_Unit_Relationships - Displays all with relationships (dependencies) between units.
Quality Assurance Personnel
In addition to these commands, an IV&V team would execute the following Ada Analyzer commands to ensure that customer releases are of the highest quality:
- Locate_Coding_Violations - A final check should be made to ensure that no coding violations are delivered in the release to the customer.
- Display_Set_Use_Problems - Locates uninitialized variables and out parameters that are not set along each subprogram path.
- Display_Subprogram_Execution_Problems - Locates function paths for which no return or raise is present and the propagation of non-visible exceptions.
- Locate_Potential_Programming_Errors - Locates a series of potential programming errors (see the Ada Analyzer User's Guide for details).
- Locate_Static_Constraint_Violations - Locates constraint violations that can be computed statically (i.e. that will always raise the constraint_error exception).
- Locate_Unused_With_Clauses - Locates unused and misplaced with clauses.
- Locate_Compatibility_Problems - Locates potential compiler compatibility problems when the code is intended for another target.
- Locate_Annotations - When customized to local requirements, this command can be used to recognize missing annotations and/or collect condensed annotation content.
- Locate_Misspellings - Locates all misspelled words in comments, string literals, and segments of declarative names.
Analyzing Legacy Code
The approach to analyzing legacy code can be treated as one big design and code review. The commands that are specified above for these activities can also be used effectively in this context. This information can be used to estimate the cost of maintaining software or adding new features to the code.
Use of the Ada repair tool can be especially effective when beginning management of legacy code. Ada Repair can be used to remove inconsistencies in the code and transform it into a state that is easier and less costly to manage. Readability, consistency, and maintainability can be dramatically improved with a small set of semantically benign transformations.
One additional aspect of analyzing legacy code is the question of portability. The following commands support this analysis:
- Locate_Compatibility_Problems - Locates potential compiler compatibility problems when the code is being moved to a new compilation system.
- Locate_System_Address_Usage - Locates all usage of the System.Address type and address attributes.
- Locate_Attributes - Locate potentially non-portable attributes.
- Locate Pragmas - Locate potentially non-portable pragmas.
- Locate_Rep_Specs - Locate potentially non-portable representation specifications.
Finally, legacy code is often analyzed for reusable pieces. Although the determination of real reusability is beyond the scope of static analysis tools, indicators such as generic units and the use of private types can identify units with higher probability for reuse. In addition, the following considerations apply:
- Subprograms that operate only on their parameters and not on external variables may be good candidates for general utilities.
- Reusable units should have a limited dependency closure. If they depend on too many other units, the entire closure may be difficult to use in other contexts.
- Named numbers should be declared and referenced instead of literals sprinkled throughout the program.
- Units that have any host/target dependencies (see previous objective) generally will not be reusable.
- Packages containing static variables must either support synchronized access to these variables or state that they are not generally usable in multitasking applications.
The following commands can be used to assist in analyzing reusability:
- Display_With_Closure: Displays the compilation closure of any unit presenting all dependent units in an indented hierarchy.
- Locate_Expressions: Locates the use of literals within a unit. Literals generally should be replaced with references to named numbers or type attributes.
- Locate_Generics: Locates all generics and their instantiations.
- Locate_Packages_With_State: Locates packages that contain static variables. Access to these variables may require synchronization in multitasking applications.
- Locate_Subprogram_References: Locates all references to objects (including parameters) within a subprogram. Subprograms with many external references generally will not be portable.
- Locate_Type_Declarations: Locates all type declarations, especially private and tagged type declarations. The information-hiding aspects of private types generally improve a unit's abstraction and thus its potential for reuse. Tagged types indicate the specification of classes which can be extended.
little tree home | about little tree | technical articles | products | email