Bug 562668 - [1.8][extract method] Extract Method could produce records
Summary: [1.8][extract method] Extract Method could produce records
Status: NEW
Alias: None
Product: JDT
Classification: Eclipse Project
Component: UI (show other bugs)
Version: 4.16   Edit
Hardware: PC Windows 10
: P3 enhancement (vote)
Target Milestone: ---   Edit
Assignee: JDT-UI-Inbox CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2020-04-30 10:24 EDT by Róbert Kitlei CLA
Modified: 2020-05-19 21:13 EDT (History)
1 user (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Róbert Kitlei CLA 2020-04-30 10:24:32 EDT
Supposing the user selects the two variable declaration statements and runs Extract Method, currently (as of Eclipse 4.16M1) the refactoring is denied with the message "Ambiguous return value", as both i and s are used later in the code.

public class ExtractMethod {
	public static void main(String[] args) {
		var i = 1;
		var s = "abc";
		System.out.println(i + s);
	}
}

Using the (preview) Java 14 feature of records, doing Extract Method is feasible. This is possibly the shortest variant.

public class ExtractMethod {
	public static void main(String[] args) {
		record I_S(int i, String s) {}

		var i_S = new I_S(1, "abc");
		System.out.println(i_S.i + i_S.s);
	}
}

Another possibility.

public class ExtractMethod {
	public static void main(String[] args) {
		var i_s = new I_S(1, "abc");
		System.out.println(i_s.i + i_s.s);
	}

	static record I_S(int i, String s) {}
}


Yet another possibility, putting the record in its own file.

public class ExtractMethod {
	public static void main(String[] args) {
		var i_s = new I_S(1, "abc");
		System.out.println(i_s.i() + i_s.s());
	}
}

// new file: I_S.java
public record I_S(int i, String s) {}
Comment 1 Stephan Herrmann CLA 2020-04-30 13:51:18 EDT
silly question: how is this "Extract Method", i.e., where is the extracted method?
Comment 2 Róbert Kitlei CLA 2020-05-19 21:13:40 EDT
You're right in pointing out that the method is missing. I take it that you didn't mean to be rude: it's not a silly request at all, only somewhat mislabeled. The feature described in my original question could be a new refactoring called Introduce Record.

Anyway, here's a possible output of Extract Method applied to the two vars in the original code where the method does make its appearance.

public class ExtractMethod {
	public static void main(String[] args) {
		var i_S = i_s();
		System.out.println(i_S.i + i_S.s);
	}

	static record I_S(int i, String s) {}

	private static I_S i_s() {
		var i = 1;
		var s = "abc";
		return new I_S(i, s);
	}
}

Using Inline on both i and s in the new method gives us:

private static I_S i_s() {
	return new I_S(1, "abc");
}

... and inlining the invocation of i_s() gives us:

public class ExtractMethod {
	public static void main(String[] args) {
		var i_S = new I_S(1, "abc");
		System.out.println(i_S.i + i_S.s);
	}

	static record I_S(int i, String s) {}
}

... which is effectively the second version that I've listed previously.