Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.
Bug 365129 - [extract method] [refactoring] The Extract Method refactoring tool could be more flexible with respect to the "Ambiguous return value: ..." problem
Summary: [extract method] [refactoring] The Extract Method refactoring tool could be m...
Status: CLOSED WONTFIX
Alias: None
Product: JDT
Classification: Eclipse Project
Component: UI (show other bugs)
Version: 3.7   Edit
Hardware: PC Linux
: P3 minor (vote)
Target Milestone: ---   Edit
Assignee: JDT-UI-Inbox CLA
QA Contact:
URL:
Whiteboard: stalebug
Keywords: needinfo
Depends on:
Blocks:
 
Reported: 2011-11-29 15:13 EST by Mohsen Vakilian CLA
Modified: 2019-10-26 01:08 EDT (History)
5 users (show)

See Also:


Attachments
The Extract Method refactoring tool may report the "Ambiguous return value: ..." problem. (13.30 KB, image/png)
2011-11-29 15:15 EST, Mohsen Vakilian CLA
no flags Details

Note You need to log in before you can comment on or make changes to this bug.
Description Mohsen Vakilian CLA 2011-11-29 15:13:08 EST
Build Identifier: M20110909-1335

We have analyzed the refactoring usage data captured by CodingSpectator <http://codingspectator.cs.illinois.edu> to find the frequent problems that the refactoring tool reports to programmers. We have studied the reaction of programmers to a few problems that the refactoring tool reports. As a result, we have some suggestions for improving the usability of the refactoring tool based on our observations.

Reproducible: Always

Steps to Reproduce:
1. Invoke the Extract Method refactoring by selecting the statements marked in the code below:
----
public class C {
  private int m() {
    int a;
    int b;
    // START SELECTION
    a = 1;
    b = 2;
    // END SELECTION
    return a + b;
  }
}
----
2. The refactoring tool will report the "Ambiguous return value:..." message and prevent the user from continuing the refactoring.
Comment 1 Mohsen Vakilian CLA 2011-11-29 15:15:28 EST
Created attachment 207687 [details]
The Extract Method refactoring tool may report the "Ambiguous return value: ..." problem.

If multiple local variables are assigned inside the set of selected statements and used outside the selected statements, the Extract Method refactoring tool will report the following error message and prevent the user from continuing the refactoring:

> Ambiguous return value: Selected block contains more than one assignment to local variables. Affected variables are: {0} and {1}.
Comment 2 Mohsen Vakilian CLA 2011-11-29 15:43:52 EST
The Extract Method refactoring is popular and frequently used. CodingSpectator reported that the Extract Method refactoring reported a total of 59 problems of 11 different kinds to our participants. The above error message accounted for 34% of the problems that Extract Method refactoring reported to our participants. This was the most common problem that the Extract Method refactoring tool reported to our participants. Five of our participants received this error message at least once from the Extract Method refactoring tool.

We have analyzed the CodingSpectator data to see how our participants have reacted to this problem. We've also asked some of our participants how they generally handled this problem of the Extract Method refactoring tool. We've found that our participants reacted to this problem in the following ways:

1. The programmer just quits the refactoring when the refactoring tool fails to perform it.
2. The programmer removes the uses of the local variables outside the selected statements.
3. The programmer narrows the selection and tries the refactoring tool again to select a different set of statements into a method.
4. The programmer widens the selection and tries the refactoring tool again to select a different set of statements into a method.
5. The programmer converts some of the local variables into fields and tries to extract the same list of statements into a method.
6. The programmer extracts the selected statements into a method and makes the new method return an object whose fields hold the values assigned to the local variables in the selected statements.

Eclipse Help <http://help.eclipse.org/indigo/index.jsp?topic=/org.eclipse.jdt.doc.user/reference/ref-refactoring-extract-method.htm> suggests techniques 3 and 4 for this problem.

One of the conclusions of our study was that programmers prefer flexible refactoring tools that allow programmers to perform the change even if some pre-conditions fail. Our participants performed refactorings that reported errors (as opposed to warnings or fatal errors) 66% of the time. Our participants' explanation for this behavior was that it was easier for them to perform a possibly unsafe refactoring and fix its outcome than start over, satisfy the preconditions, and reconfigure the tool. For example, one of our participants said:

>Usually, I might even like that the tool would do the refactoring and I would continue to adapt the remaining things manually. I kind of don't like the fact that it doesn't allow me to perform the refactoring.

Is it possible to make the Extract Method refactoring tool more flexible with respect to the "Ambiguous return value: ..." problem? That is, can the tool still let the programmer perform the refactoring and fix the resulting code manually? Letting the programmers perform an unsafe refactoring might give them a better opportunity to understand the problem.

The Extract Method refactoring could go beyond just reporting the problem and suggest some of the techniques we listed above to satisfy the precondition of the refactoring tool. A smart refactoring tool could even propose the programmer to automatically apply one of the fix strategies and let the programmer evaluate the fix and choose the best one. For example, if the programmer decides to try the widening strategy (strategy #4), the tool would automatically extend the selection to cover the uses of the selected local variables. Then, the programmer will reevaluate the refactoring with the new selection.
Comment 3 Deepak Azad CLA 2011-12-02 10:51:44 EST
(In reply to comment #2)
> One of the conclusions of our study was that programmers prefer flexible
> refactoring tools that allow programmers to perform the change even if some
> pre-conditions fail. Our participants performed refactorings that reported
> errors (as opposed to warnings or fatal errors) 66% of the time. Our
> participants' explanation for this behavior was that it was easier for them to
> perform a possibly unsafe refactoring and fix its outcome than start over,
> satisfy the preconditions, and reconfigure the tool. For example, one of our
> participants said:
> 
> >Usually, I might even like that the tool would do the refactoring and I would continue to adapt the remaining things manually. I kind of don't like the fact that it doesn't allow me to perform the refactoring.

In the example from comment 0 I think it is better to simply change the selection and invoke the refactoring again. Do you have examples where it would make sense to allow an unsafe refactoring? 

> Is it possible to make the Extract Method refactoring tool more flexible with
> respect to the "Ambiguous return value: ..." problem? That is, can the tool
> still let the programmer perform the refactoring and fix the resulting code
> manually? Letting the programmers perform an unsafe refactoring might give them
> a better opportunity to understand the problem.

Extract Method refactoring allows to change semantics in one case, though you get the following warning first..
"Selected statements contain a return statement but not all possible execution flows end in a return. Semantics may not be preserved if you proceed."

But this needs to be done on a case by case basis. Do you have concrete examples? :-)

> The Extract Method refactoring could go beyond just reporting the problem and
> suggest some of the techniques we listed above to satisfy the precondition of
> the refactoring tool. A smart refactoring tool could even propose the
> programmer to automatically apply one of the fix strategies and let the
> programmer evaluate the fix and choose the best one. For example, if the
> programmer decides to try the widening strategy (strategy #4), the tool would
> automatically extend the selection to cover the uses of the selected local
> variables. Then, the programmer will reevaluate the refactoring with the new
> selection.
Given the number of alternatives available to the user to fix the problem, I think implementing this would add unnecessary complexity to the refactoring, especially because the error message clearly states which variables cause the problem.
Comment 4 Mohsen Vakilian CLA 2011-12-05 16:19:34 EST
(In reply to comment #3)
> In the example from comment 0 I think it is better to simply change the
> selection and invoke the refactoring again. Do you have examples where it would
> make sense to allow an unsafe refactoring? 

It's always safer to quit a refactoring that has reported a problem, go back to the source code, change the code and selection to satisfy the preconditions of the refactoring, and invoke the refactoring again. Surprisingly, we've found that this is not how programmers prefer to deal with refactoring problems. Instead, programmers prefer to perform a broken refactoring and fix the resulting code. This is because the overhead of quitting the refactoring and reconfiguring the tool is perceived to be high. The programmer has to understand the error message and its underlying cause, quit the refactoring, make the necessary corrections, invoke, and reconfigure the refactoring. Nonetheless, if the programmer hasn't made the right changes, the refactoring tool might still report a problem. At this point, the value of the refactoring tool begins to diminish. As a result, most programmers prefer to perform a broken refactoring and fix the resulting code manually. This strategy works specially well for refactorings such as Extract Method because they affect a narrow piece of the code and the resulting broken code can be easily fixed.

In summary, there are two ways of dealing with a refactoring problem. Sometimes programmers quit the refactoring tool and start over. Other times, programmers preform the refactoring and fix the resulting broken code manually. I think both strategies are reasonable for different people in different situations. Therefore, it would be nice to make the refactoring tool more flexible to support both strategies. The Extract Method refactoring could still report the error message "Ambiguous return value: ..." but also allow programmers to continue the refactoring if they prefer to fix the problem afterwards.
Comment 5 Mohsen Vakilian CLA 2011-12-05 16:32:07 EST
(In reply to comment #3)
> (In reply to comment #2)
> > The Extract Method refactoring could go beyond just reporting the problem and
> > suggest some of the techniques we listed above to satisfy the precondition of
> > the refactoring tool. A smart refactoring tool could even propose the
> > programmer to automatically apply one of the fix strategies and let the
> > programmer evaluate the fix and choose the best one. For example, if the
> > programmer decides to try the widening strategy (strategy #4), the tool would
> > automatically extend the selection to cover the uses of the selected local
> > variables. Then, the programmer will reevaluate the refactoring with the new
> > selection.
> Given the number of alternatives available to the user to fix the problem, I
> think implementing this would add unnecessary complexity to the refactoring,
> especially because the error message clearly states which variables cause the
> problem.

I agree that it is nontrivial to propose automated fixers for the "Ambiguous return value: ..." problem. How about giving some hints to the programmer on how to go about fixing the problem? The following is my attempt to include the main fix strategies in the message:

"Selected statements contain more than one assignment to local variables that are used in the following code. Assigned local variables are: int a, int b. The new method can return at most one value. Convert some of the local variables to fields, narrow your selection to exclude some of the assignments to local variables, or widen your selection to include uses of some local variables in the code following the selection."
Comment 6 Mohsen Vakilian CLA 2011-12-05 16:35:05 EST
Bug 365664 is related to this bug.
Comment 7 Deepak Azad CLA 2011-12-06 12:06:57 EST
I have had instances when I have had to perform a refactoring manually because Eclipse would not proceed because of an error. On such occasions I do wish for things to be a bit more flexible.

(In reply to comment #3)
> Extract Method refactoring allows to change semantics in one case, though you
> get the following warning first..
> "Selected statements contain a return statement but not all possible execution
> flows end in a return. Semantics may not be preserved if you proceed."

Markus, similar to above case maybe we can also allow the refactoring in case of Ambiguous return value, and just return the first local variable. (Of course we will have to duly warn the user and give an option to cancel or continue)

i.e. for the example from comment 0 the result could be transformed to
	private int m() {
		int a;
		int b;
		// START SELECTION
		a = extracted();
		// END SELECTION
		return a + b;    // this line will have an error, but it is ok
	}

	private int extracted() {
		int a;
		int b;
		a = 1;
		b = 2;
		return a;
	}
Comment 8 Eclipse Genie CLA 2019-10-26 01:08:36 EDT
This bug hasn't had any activity in quite some time. Maybe the problem got resolved, was a duplicate of something else, or became less pressing for some reason - or maybe it's still relevant but just hasn't been looked at yet.

If you have further information on the current state of the bug, please add it. The information can be, for example, that the problem still occurs, that you still want the feature, that more information is needed, or that the bug is (for whatever reason) no longer relevant.

--
The automated Eclipse Genie.