If programs access types and members through reflection, refactoring tools cannot guarantee that refactorings on those programs are behavior preserving. Refactoring approaches for highly reflective languages like Smalltalk therefore check behavior preservation using regression testing.
In this paper we propose RefaFlex, a novel and more defensive approach towards the refactoring of reflective (Java) programs. RefaFlex uses a dynamic program analysis to log reflective calls during test runs and then uses this information to proactively prevent the programmer from executing refactorings that could otherwise alter the program’s behavior. This makes re-running test cases obsolete: when a refactoring is permitted, tests passing originally are guaranteed to pass for the refactored program as well. In some cases, we further re-write reflective calls, permitting refactorings that would otherwise have to be rejected.
We have implemented RefaFlex as an open source Eclipse plugin and offer extensions for six Eclipse refactoring tools addressing naming, typing, and accessibility issues. Our evaluation with 21,524 refactoring runs on three open source programs shows that our tool successfully prevents 1,358 non-behaviour-preserving refactorings which the plain Eclipse refactorings would have incorrectly permitted.