On use of dependency and semantics information in incremental change
Václav Rajlich, Maksym Petrenko · 2009
Software evolution is the stage of software lifecycle during which an existing software product is extended with new features. It is also the longest and the most expensive stage in the lifecycle of the modern software systems. Incremental change [Rajlich'04] provides a convenient model for software evolution, where programmers add new features to software in small increments. Program dependencies glue together components (i.e. classes, methods and variables in OOP) within software. Good understanding of the dependencies is crucial to the many activities of incremental change. Furthermore, effective approaches and tools for dependency analysis are a necessity as they help to discover dependencies in the software; this reduces the effort required to understand the software, and thus reduces the overall cost of the software evolution. For example, to be able to assess an effect of a change to a component, it is important to understand the dependencies of this component to the rest of the system. In this thesis, we study the role of the dependencies in concept location and impact analysis activities of incremental change. Impact analysis is the process that examines how a change to a software component may affect other software components. One of the conservative approaches [Rajlich'04] to impact analysis is to discover all classes that interact with the changed class, and then inspect them one-by-one for a necessity of a secondary change; if an interacting class is determined to be also impacted by the change, the impact analysis process has to be repeated for the neighbors of this class as well. The major drawback of this approach is that in some programs the programmer has to inspect a very large number of interacting classes. In order to alleviate this problem, we proposed a more precise dependency analysis which is able to assess to which components the change propagates and to which it does not. This more precise analysis spares the programmer the extra effort that is needed for inspection of the components to which the change does not propagate. In the thesis, we tackled this problem in two ways. First, we used the intuition that the finer-grained components are likely to interact with fewer other components, and hence the finer-grained granularity of the dependency analysis may be used in the situations where a class interacts with many other classes. For this purpose, we expanded approach in [Rajlich'04] to variable granularity which includes granularities of classes, class members (member classes, methods and variables), and code fragments. To be able to model software and its components at different granularities, we used a notion of class-member dependency graph (CMDG); this graph models software as a collection of program and dependencies between them. The second approach examined in this work relies on heuristics that can be used to guide programmers to the most relevant neighbors: the programmers can inspect neighbors based on the probabilities of their change calculated by heuristics, and quickly identify the impacted components. We implemented the proposed approaches within the framework of the tool JRipples, and verify them by case studies in open-source software.