Sunday, October 16, 2016

JDeodorant: Clone Refactoring Support beyond IDEs

By: Nikolaos Tsantalis, Concordia University, Montreal, Canada (@NikosTsantalis)
Associate Editor: Sonia Haiduc, Florida State University, USA (@soniahaiduc)

Why should I bother to refactor duplicated code in my project?
Duplicated code (also known as code clones) can be a potential big trouble for the maintenance of your project. Not all clones are harmful [1] or equally harmful [2]. However, if you find yourself repeatedly applying the same changes (e.g., bug fix) in multiple places in your code, you should definitely consider to refactor [3] this duplication. Merging such clones into a single copy will make future maintenance faster and less error-prone.

Why is tool support necessary for the refactoring of clones?
Software clones tend to diverge after the initial copy-and-paste. This happens because developers have to adjust the copied code to a new context and/or different requirements. Therefore, clones tend to have non-trivial differences as the project evolves (e.g., different methods being called, or completely different logic in parts of the implemented algorithm). Unfortunately, the current state-of-the-art IDEs support the refactoring of clones with trivial differences (i.e., identical clones with variations in whitespace, layout, comments, and variable identifiers).

JDeodorant [4] is an Eclipse plugin that can help developers to inspect the differences between clones in Java projects, and refactor them safely, if possible. More specifically, JDeodorant applies a sophisticated static source code analysis to examine whether the parameterization of the differences appearing in the clones is free of side effects. We refer to this feature as refactorability analysis [5]. If all examined preconditions pass successfully, JDeodorant can proceed with the refactoring of the clones.

Feature 1: Clone import and clone group exploration
  • JDeodorant can import results from 5 popular clone detection tools, namely CCFinder, ConQAT, NiCad, Deckard, and CloneDR. In addition, JDeodorant can analyze any pair of methods selected by the developer from the Eclipse Package Explorer view.
  • While importing the results, JDeodorant automatically checks the syntactic correctness of the clone fragments, and fixes any discrepancies by removing incomplete statements and adding the missing closing brackets from incomplete blocks of code. Additionally, the tool filters out the clones that extend beyond the body of a method (i.e., class-level clones).
  • The imported results are presented to the user in a tree-like view, as shown in Figure 1. The clones are organized into groups based on their similarity (i.e., a clone group contains two or more clone instances).
  • The clone groups are also analyzed to discover subclone relationships between them. Group A is a subclone of group B, if every clone instance in A is a sub-clone (i.e., a partial code fragment) of an instance in B. The subclone information appears as a link in the last column of the clone group table to help the user navigate between clone groups having such a relationship.
  • By clicking on the “Show only clone groups for the files opened in the editor” checkbox, the user can filter the clone groups table to display only the clones being relevant to the context (i.e., appearing in the files) he/she is currently working on.
  • All clones are constantly monitored for modifications. If the developer refactors or updates some code associated with the imported clones, the clone group table is automatically updated by disabling the clones affected by the modification (disabled clones appear with strikethrough text), and by re-computing the offsets of other clones belonging to the same modified Java files (shifted clones appear with text highlighted in green). In this way, the user can continue with the inspection and refactoring of other clone groups without having to import new results from external tools. 

Figure 1: Presentation of the imported clone detection results to the user

Feature 2: Clone visualization and refactorability analysis
The user can right-click on any pair of clones from the same clone group, or any pair of methods from the Eclipse Package Explorer and select “Refactor Duplicated Code…” from the popup menu. The outcome of the clone pair analysis is presented to the user as shown in Figure 2.

Figure 2: Clone pair visualization and refactorability analysis

The analyzed clone fragments appear as two side-by-side trees, where each pair of tree nodes in the same row represents a pair of mapped statements in the first and second clone fragment, respectively. The user can inspect the clones in a synchronized manner, by expanding and collapsing the nodes corresponding to control statements (i.e., loops, conditionals, try blocks). The code is highlighted in 3 different colors to help the developer inspect and understand the differences between the clones.
  • Yellow: Represents differences in expressions between matched statements. These expressions are evaluated to the same type, but have a different syntactic structure or identifier.
  • Red: Represents unmapped statements that do not have a matching statement in the other clone fragment (also known as clone gaps).
  • Green: Represents semantically equivalent statements, i.e., statements of different AST types performing exactly the same functionality. In Figure 2, we can see a for loop in the left clone matched with a while loop in the right clone having the same initializer and updater as separate statements.
By hovering over a pair of statements highlighted in yellow, a tooltip appears providing semantic information about the type of each difference based on the program elements (e.g., variables, method calls, literals, class instantiations) appearing in the difference. Currently, JDeodorant supports over 20 difference types, including some more advanced ones, such as the replacement of a direct field access with the corresponding getter method call, and the replacement of a direct field assignment with the corresponding setter method call. In addition, the tooltip may also include information about precondition violations, if the expressions appearing in the differences cannot be safely parameterized.

Semantically equivalent differences, and renamed variables are not examined against preconditions, since they should not be parameterized. JDeodorant automatically detects the local variables that have been consistently renamed between the clone fragments (as shown in the bottom-right side of Figure 2).

Feature 3: Clone refactoring
Based on the location of the clones, JDeodorant determines automatically the best refactoring strategy:

1.  Extract Method (clones belong to the same Java file)
2.  Extract and Pull Up Method (clones have a common superclass)
a) Introduce Template Method (clones call local methods from the subclasses)
b) Extract Superclass (clones have an external common superclass, or the common superclass has additional subclasses)
3.  Introduce Utility Method (clones access/call only static fields/methods)

As shown in Figure 3, JDeodorant can generate a detailed preview of the refactoring to be applied, where the developer can inspect all the changes that will take place at a fine-grained level. Finally, the user can undo and redo the applied refactorings, since they are recorded in the change history of Eclipse.

Figure 3: Clone refactoring preview

JDeodorant is an open-source project hosted on GitHub.
Videos demonstrating the use and features of JDeodorant can be found on YouTube.

[1] Cory J. Kapser and Michael W. Godfrey, ""Cloning considered harmful" considered harmful: patterns of cloning in software," Empirical Software Engineering, vol. 13, no. 6, pp. 645-692, December 2008.
[2] Foyzur Rahman, Christian Bird, and Premkumar Devanbu, "Clones: what is that smell?," Empirical Software Engineering, vol. 17, no. 4-5, pp. 503-530, August 2012.
[3] Emerson Murphy-Hill, Don Roberts, Peter Sommerlad, and William F. Opdyke, "Refactoring [Guest editors' introduction]," IEEE Software, vol. 32, no. 6, pp. 27-29, November-December 2015.
[4] Davood Mazinanian, Nikolaos Tsantalis, Raphael Stein, and Zackary Valenta, "JDeodorant: Clone Refactoring," 38th International Conference on Software Engineering (ICSE'2016), Formal Tool Demonstration Session, Austin, Texas, USA, May 14-22, pp. 613-616, 2016.
[5] Nikolaos Tsantalis, Davood Mazinanian, and Giri Panamoottil Krishnan, "Assessing the Refactorability of Software Clones," IEEE Transactions on Software Engineering, vol. 41, no. 11, pp. 1055-1090, November 2015.