![]() |
Making Program Refactoring Safer |
Home | Download | User Manual | Examples | Publications | Members | Contact Us |
Here is a list of non behavior-preserving transformations applied by the Refactoring Engine of Eclipse 3.4. These cases were reported by: PTG. SafeRefactor was successful in detecting all of the expected errors
The source code of the examples can be downloaded here.
public class A {
public int k() {
return 23;
}
}
public class B extends A {
public int k() {
return 42;
}
public int m() {
return super.k();
}
}
public class C extends B {
public int test() {
return m();
}
}
The method C.test returns 23. Pushing down B.m into C just moves the method without any adjustments, so in the resulting program, the method C.test returns 42.
SafeRefactor generates 550 tests cases, of which 496 tests had failed
public class A {
protected int x = 23;
public int m() {
return x;
}
}
public class B extends A {
protected int x = 42;
public int test() {
return new B().m();
}
}
The method B.test returns 23. Pushing down A.m into B just moves the method without any adjustments, so in resulting program, B.test returns 42.
SafeRefactor generates 102 tests cases, of which 99 tests had failed
public class A {
class B {
public int getTamanho() {
return 23;
}
}
public int m() {
return new B().getTamanho();
}
}
public class C extends A {
class B {
public int getTamanho() {
return 42;
}
}
public int test() {
return new C().m();
}
}
The method C.test returns 23. Pushing down A.m into B just moves the method without any adjustments, so in the resulting program, C.test returns 42.
SafeRefactor generates 97 tests cases, of which 94 tests had failed
public class A {
public int m() {
final int i = 23;
return new Object() {
int j = 42;
public int getSize() {
return i;
}
}.getSize();
}
public int test() {
return new A().m();
}
}
The A.test returns 23. Renaming the local variable i in method A.m to j does not notice that the reference in the getSize() method of the anonymous class will now refer to the field j, so in the resulting program, A.test returns 42.
SafeRefactor generates 298 tests cases, of which 296 tests had failed
public class A {
public String m(int i) {
return "42";
}
public String test() {
return valueOf(23);
}
}
The method A.test returns "23". Renaming the method A.m to valueOf shadows the statically imported method String.valueOf, so in the resulting program, A.test returns "42".
SafeRefactor generates 100 tests cases, of which 98 tests had failed
public class A {
public int m(boolean b) {
int x = 42;
try {
// from
if (b) {
x = 23;
throw new Exception();
}
// to
} catch (Exception e) {
return x;
}
return x;
}
public int test() {
return m(true);
}
}
The method A.test returns 23. Extracting the statement between the comments to a method n in Eclipse yields
public class A {
public int m(boolean b) {
int x = 42;
try {
// from
x = n(b, x);
// to
} catch (Exception e) {
return x;
}
return x;
}
private int n(boolean b, int x) throws Exception {
if (b) {
x = 23;
throw new Exception();
}
return x;
}
public int test() {
return m(true);
}
}
Eclipse has n return the value of x, which is unnecessary, but not our main concern. More importantly, note that the value returned in the catch clause is the unmodified value of x, hence in the refactored program, A.test returns 42.
SafeRefactor generates 91 tests cases, of which 89 tests had failed