Bad MutationImmutator: Refactoring for Immutability



Problem Description

It is common for Object-Oriented programs to contain mutable and immutable classes. Immutable classes simplify sequential programing because the programmer does not have to reason about side-effects. Immutable classes also simplify parallel programming because they are embarrassingly thread-safe. Sometimes programmers write immutable classes from scratch, other times they refactor mutable into immutable classes. To refactor a mutable class, programmers must find (i) all methods that mutate its transitive state and (ii) all objects that can enter or escape the state of the class. The programmer must also update client code to use the class in an immutable fashion. The analysis is non-trivial and the rewriting is tedious. Fortunately, this can be automated.

We present Immutator, a technique and tool that enables the programmer to safely refactor a mutable class into an immutable class. Immutator also repairs client code to use the refactored class in an immutable fashion. Experience with refactoring several open-source programs shows that Immutator is useful: (i) it reduces the burden of making classes immutable, (ii) is fast enough to be used interactively, and (iii) is much safer than manual refactorings performed by open-source developers.

Use Immutator

Immutator is implemented as an Eclipse plugin that extends Eclipse's refactoring engine. The programmer accesses Immutator from the refactoring menu of Eclipse. To use Immutator, the programmer selects a class and then selects the option Make Immutable. Immutator will then present three choices: perform and apply the refactoring (no preview), perform the refactoring and show a preview, or cancel the refactoring. If the programmer selects to perform the refactoring then Immutator analyzes and rewrites the code. If the programmer asked for a preview then Immutator shows the changes in a before-and-after pane (see the screenshot below). In this pane the programmer can further select that only a subset of the changes be applied, or let Immutator apply all changes. Before applying any transformations, Immutator checks that the input program meets the refactoring preconditions. Immutator reports to the programmer any preconditions that are not met, and the programmer can decide to ignore the warning and proceed, or can cancel the refactoring, fix the root cause of the warning, and re-run Immutator.

Below is a screenshot of Immutator in action.






As shown in the figure above, Immutator performs the following transformations:

Download and Install

Immutator requires that you use Eclipse (version > 3.5). We are currently working on releasing Immutator as an open-source Eclipse plugin (under the Eclipse Public License).

We are waiting to get clearance from our sponsors (Microsoft and Intel) to release the tool in source code. Meanwhile, you can get the binary release.

To use Immutator, download the distribution archive. Unpack the archive. It contains three jar files: edu.uiuc.immutability (the main Immutator code), and two other jar files, com.ibm.wala.core and com.ibm.wala.shrike, from the WALA open source library for static analysis. Copy these three jar files into your Eclipse's plugins directory, then restart Eclipse. If the installation is successfull, you will see the new menu entry "Concurrency Refactorings > Make Immutable" when you right-click on a selected class name declaration.

Publications

More details about the safety analysis can be found in our ICSE'11 paper.

Fredrik gave a nice presentation on Immutator during UPCRC annual summit.

Experimental Evaluation

We ran Immutator on 346 classes from three open-source projects: Jutil Coal (v 0.3), jpaul (v 2.5.1), and Apache Commons Collections (v 3.2.1). The results show that Immutator (i) is widely applicable (more than 30% of all classes met the refactoring preconditions), (ii) performs correct refactorings, and (iii) is fast (on average, it takes about 3 seconds per class).

We also designed a controlled experiment where 6 programmers refactored 9 classes from the JHotDraw 5.3 framework. Below are the input classes and the programmer-refactored classes.
Mutable Immutable
ArrowTip ArrowTip_Immutable
EllipseFigure EllipseFigure_Immutable
FigureAttributes FigureAttributes_Immutable
ImageFigure ImageFigure_Immutable
LineConnection LineConnection_Immutable
TextFigure TextFigure_Immutable
PertFigure PertFigure_Immutable
NodeFigure NodeFigure_Immutable
ColorMap ColorMap_Immutable

The comparison between programmer-refactored code and the Immutator-refactored code shows that Immutator outperforms programmers. Refactoring with Immutator is faster (1.5 min vs. 220 min programmer time) and is safer (programmers made 51 errors).

Team

Acknowledgements

This work is partially funded by Intel and Microsoft through the UPCRC Center at Illinois. We are also thankful to IBM for providing the WALA program analysis library. Immutator builds its safety analysis on top of the WALA infrastructure.

Feedback

If you found Immutator useful, we would love to hear from you. Please send constructive feedback to Danny Dig.