Refactoring Benchmarks For Extract Method


The simplest one:

 class Test1 {

int field = 0;

void fun() { int i; // ---------- i = 0; System.out.println("i, field == " + i++ + ", " + field); // ---------- } }

Here, the field is not a local variable, so it is not concerned by extraction. The local variable i is modified inside the block, but not used after, so it should be a new local variable in the new method. The extraction should give something like:

 class Test1 {

int field = 0;

void newmethod() { int i; i = 0; System.out.println("i, field == " + i++ + ", " + field); }

void fun() { int i; // this may be deleted as i is no longer used // ---------- newmethod(); // ---------- } }


In the following case the variable i is used after the extracted block, so it must be passed as an argument as well as the return value.

 class Test2 {
	int field = 0;
	void fun() {
		int i = 0;
		// ----- 
		System.out.println("i, field == " + i++ + ", " + field);
		// ----- 
		System.out.println("i == " + i);
	}
 }

an extraction should give:

 class Test2 {

int field = 0;

int newmethod(int i) { System.out.println("i, field == " + i++ + ", " + field); return(i); }

void fun() { int i = 0; // ----- i = newmethod(i); // ----- System.out.println("i == " + i); } }


The third benchmark is checking control flow analysis. Local variable i is affected before being used in the 'then' branch of the 'if' statement, it seems that it may be classified as local variable for the extracted method. However, the original value of the variable can be used in the 'else' branch, so it has to be definitely classified as a parameter.

 class Test3 {

int field = 0;

void fun() { int i = 0; // ----- if (field == 1) { i = 1; System.out.println("i, field == " + i + ", " + field); } else { System.out.println("i, field == " + i + ", " + field); } // ----- } }

the extraction should give:

 class Test3 {

int field = 0;

void newmethod(int i) { if (field == 1) { i = 1; System.out.println("i, field == " + i + ", " + field); } else { System.out.println("i, field == " + i + ", " + field); } }

void fun() { int i = 0; // ----- newmethod(i); // ----- }
}


In the fourth benchmark, the variable i is not used outside the extracted block, but its value has to be returned to the main function due to loop reentrance.

 class Test4 {

int field = 0;

void fun() { int i = 0; while (field < 2) { field ++; // ----- System.out.println("i, field == " + i++ + ", " + field); // ----- } } }

the extraction should give:

 class Test4 {

int field = 0;

int newmethod(int i) { System.out.println("i, field == " + i++ + ", " + field); return(i); }

void fun() { int i = 0; while (field < 2) { field ++; // ----- i = newmethod(i); // ----- } } }


The fifth benchmark is checking exception handling in Java. The extracted method should declare all thrown exceptions. After a small discussion about RuntimeExceptions?, the following benchmark should be unambiguous:

 class Test5 {

static void fun() throws IOException {}

public static void main(String args[]) { try { // ---- fun(); // ---- } catch (Exception e) { } } }

the extraction should give:

 class Test5 {

static void fun() throws IOException {}

static void newmethod() throws IOException { fun(); }

public static void main(String args[]) { try { // ---- newmethod(); // ---- } catch (Exception e) { } } }


What about this?

Ability to keep certain subexpressions in the original method:

 public class BadIdea
 {
    public static void sad(char c)
    {
	double th = 4;
	double x=0;
	// ----
	if (c == 's') {
	    x = -Math.cos(th+Math.PI/2);
	} else if (c == 'c') {
	    x = Math.sin(th+Math.PI/2);
	}
	// ----
	System.out.println(x);
    }
 }

/** can become */

 class NewBadIdea
 {
    public static double newmethod(char c, double th_)
    {
	double x=0;
	if (c == 's') {
	    x = -Math.cos(th_);
	} else if (c == 'c') {
	    x = Math.sin(th_);
	}
	return x;
    }

public static void sad(char c) { double th = 4; double x = newmethod(c, th+Math.PI/2);

System.out.println(x); } }

Or is this an ExtractMethod combined with a refactoring?

Actually, I think this is an IntroduceExplainingVariable followed by an ExtractMethod. --JohnLindsey


See also: RefactoringBrowserForJava


Browsers that pass this benchmark: Browsers that don't pass this benchmark:

EditText of this page (last edited July 19, 2002) or FindPage with title or text search