Bug 101938 - [refactoring] extact method: missing call to extracted method
Summary: [refactoring] extact method: missing call to extracted method
Status: VERIFIED FIXED
Alias: None
Product: JDT
Classification: Eclipse Project
Component: UI (show other bugs)
Version: 3.1   Edit
Hardware: PC Windows XP
: P3 normal (vote)
Target Milestone: 3.1.1   Edit
Assignee: Dirk Baeumer CLA Friend
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2005-06-27 16:59 EDT by Adam Kiezun CLA Friend
Modified: 2007-07-23 19:32 EDT (History)
1 user (show)

See Also:


Attachments
Code patch (2.24 KB, patch)
2005-07-11 08:35 EDT, Dirk Baeumer CLA Friend
no flags Details | Diff
Additional test cases (2.47 KB, patch)
2005-07-11 08:35 EDT, Dirk Baeumer CLA Friend
no flags Details | Diff
Improved code patch (1.27 KB, patch)
2005-07-11 09:01 EDT, Dirk Baeumer CLA Friend
no flags Details | Diff
Additional test cases (4.37 KB, patch)
2005-07-11 09:02 EDT, Dirk Baeumer CLA Friend
no flags Details | Diff
New code patch (1.66 KB, patch)
2005-07-26 12:11 EDT, Dirk Baeumer CLA Friend
no flags Details | Diff
New test cases (9.16 KB, patch)
2005-07-26 12:11 EDT, Dirk Baeumer CLA Friend
no flags Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Adam Kiezun CLA Friend 2005-06-27 16:59:27 EDT
3.1RC4
public class AA {
	boolean foo(boolean b, Object x, List l){
		if (b){
			/*[*/
			if (x instanceof Integer)
				return false;
			return true;
			/*]*/
		} else {
			for (Iterator iter = l.iterator(); iter.hasNext();) {
				Object next= iter.next();
				if (next instanceof Integer)
					return false;
			}
			return true;
		}
	}
}

'Replace duplicate fragments'
In the loop, the call to the new method is missing
Comment 1 Martin Aeschlimann CLA Friend 2005-06-28 04:51:03 EDT
the code in the loop shouldn't be replaced at all

code loss, but not a stop ship
candidate for 3.1.1
Comment 2 Martin Aeschlimann CLA Friend 2005-06-28 05:16:36 EDT
bug is in the SnippetFinder: It matches the extracted code although the last 
statements is in an outer scope (block). The ending of a block seems to be ignored.
This bug seems to occur with all kind of scopes: blocks, if statements..., even
over more than one scope.

When replacing, a list rewriter on block is used, but doesn't work for the last
node which isn't in the block.
bug 99113 has been filed that the rewriter should throw an
IllegalArgumentException when this happens.

This example is also matched and fails with an assertion exception:
	boolean foo(boolean b, Object x, List l){
		if (b){
			/*[*/
			if (x instanceof Integer)
				l.add(null);
			l.add(new Object());
			l.add(new Object());
			/*]*/
		} else {
			Iterator iter = l.iterator();
			Object next= iter.next();
			{
				if (true)
					if (x instanceof Integer)
						l.add(null);
				
			
				l.add(new Object());
			}
			l.add(new Object());
		}
		return true;
	}

	at org.eclipse.jdt.internal.corext.Assert.isTrue(Assert.java:139)
	at org.eclipse.jdt.internal.corext.Assert.isTrue(Assert.java:124)
	at
org.eclipse.jdt.internal.corext.dom.ReplaceRewrite.<init>(ReplaceRewrite.java:42)
	at
org.eclipse.jdt.internal.corext.dom.StatementRewrite.<init>(StatementRewrite.java:26)
	at
org.eclipse.jdt.internal.corext.refactoring.code.ExtractMethodRefactoring.replaceDuplicates(ExtractMethodRefactoring.java:710)
	at
org.eclipse.jdt.internal.corext.refactoring.code.ExtractMethodRefactoring.createChange(ExtractMethodRefactoring.java:451)
	at
org.eclipse.ltk.core.refactoring.CreateChangeOperation.run(CreateChangeOperation.java:117)
	at org.eclipse.core.internal.resources.Workspace.run(Workspace.java:1719)
	at
org.eclipse.ltk.internal.ui.refactoring.WorkbenchRunnableAdapter.run(WorkbenchRunnableAdapter.java:86)
	at
org.eclipse.jface.operation.ModalContext$ModalContextThread.run(ModalContext.java:113)
Comment 3 Dirk Baeumer CLA Friend 2005-07-11 08:35:37 EDT
Created attachment 24526 [details]
Code patch
Comment 4 Dirk Baeumer CLA Friend 2005-07-11 08:35:52 EDT
Created attachment 24527 [details]
Additional test cases
Comment 5 Dirk Baeumer CLA Friend 2005-07-11 08:37:06 EDT
Fix is low is and very local. The missing piece is that the snippet finder
doesn't handle endVisit blocks and therefore skipped the closing block in th
snippet.
Comment 6 Martin Aeschlimann CLA Friend 2005-07-11 08:43:45 EDT
I haven't tested it, but it seems to me that this still ignores the problem with
for/if/while statements that are not blocks.
Comment 7 Dirk Baeumer CLA Friend 2005-07-11 09:00:01 EDT
Good catch ! I will attach a new patch that checks for the parent of the found
snippet instead of checking for blocks. That's what the extract refactoring does
for the selected statements as well to ensure that they don't spawn scope
boundaries.
Comment 8 Dirk Baeumer CLA Friend 2005-07-11 09:01:44 EDT
Created attachment 24528 [details]
Improved code patch
Comment 9 Dirk Baeumer CLA Friend 2005-07-11 09:02:40 EDT
Created attachment 24529 [details]
Additional test cases
Comment 10 Dirk Baeumer CLA Friend 2005-07-26 11:35:12 EDT
REviewed with Tom Eicher and Martin Aeschlimann. Found another case that needs
special treatment.

	public void foo() {
		foo();
		foo();
		
		
		if (true)
			foo();
		else
			foo();
	}

Selecting foo(); foo(); will match against the foo in the if statements. 
Comment 11 Dirk Baeumer CLA Friend 2005-07-26 12:11:12 EDT
Created attachment 25300 [details]
New code patch
Comment 12 Dirk Baeumer CLA Friend 2005-07-26 12:11:27 EDT
Created attachment 25301 [details]
New test cases
Comment 13 Dirk Baeumer CLA Friend 2005-07-26 12:21:27 EDT
New fix reviewed by Martin Aeschlimann again and discussed with Tom Eicher.
Added 5 new test cases 965 - 969.
Comment 14 Martin Aeschlimann CLA Friend 2005-08-09 09:40:23 EDT
verified in M20050808-2000 (3.1.1)
Comment 15 Martin Aeschlimann CLA Friend 2005-08-09 09:45:14 EDT
also verified in I20050808-2000 (3.2 M1)
Comment 16 Stephan Herrmann CLA Friend 2007-07-23 19:32:21 EDT
Not a bug, but I just noticed, that the class names in test cases 965 - 969
are constantly A_test964, which is probably not intended ;-)