Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.
Bug 318127 - [extract method] "Extract Method" into an enclosing class fails when the inner class has a method of the same name
Summary: [extract method] "Extract Method" into an enclosing class fails when the inne...
Status: VERIFIED FIXED
Alias: None
Product: JDT
Classification: Eclipse Project
Component: UI (show other bugs)
Version: 3.7   Edit
Hardware: PC Windows XP
: P3 minor (vote)
Target Milestone: 3.7 M1   Edit
Assignee: Deepak Azad CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2010-06-27 10:57 EDT by Missing name CLA
Modified: 2010-08-03 06:20 EDT (History)
3 users (show)

See Also:
markus.kell.r: review+


Attachments
fix + test (7.78 KB, patch)
2010-06-27 17:14 EDT, Deepak Azad CLA
no flags Details | Diff
fix + tests (15.15 KB, patch)
2010-07-01 03:39 EDT, Deepak Azad CLA
no flags Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Missing name CLA 2010-06-27 10:57:06 EDT
Build Identifier: 20100218-1602

When using "Extract Method" on an expression in an inner class to extract it into a method in the enclosing class, and the name of the new method is the same as the name of some method of the inner class, the refactoring fails although there is no name clash.

Reproducible: Always

Steps to Reproduce:
1.

package sandbox;

import java.util.HashSet;
import java.util.Set;

public class A {
	
	private class B {
		private void g() {}
		private int f() {
			return 2 + 3;
		}
	}
}

2.
Use Extract Method on the expression "2 + 3" choosing the function name g and destination type A.

3. 
The refactoring fails with message "Method 'g' already exists in type 'B'."
Comment 1 Deepak Azad CLA 2010-06-27 13:46:44 EDT
(In reply to comment #0)
> 3. 
> The refactoring fails with message "Method 'g' already exists in type 'B'."
True, but on clicking continue it produces the following result which has a compilation error

public class A {

    private class B {
        private void g() {}
        private int f() {
            return g();  // compilation error here
        }
    }

	private int g() {
		return 2+3;
	}
}
Comment 2 Deepak Azad CLA 2010-06-27 17:14:12 EDT
Created attachment 172861 [details]
fix + test

The problem was that we always checked for the new method name in the same type itself instead of the destinaiton type - see ExtractMethodAnalyzer#checkInput(...)

Markus, the patch looks good?
Comment 3 Markus Keller CLA 2010-06-30 14:34:54 EDT
The patch does not work if the expression is inside an anonymous, e.g. extract
"2 + 3" to g in A here:

import java.util.concurrent.Callable;

public class A {
	private class B {
		private void g() {}
		private int f() {
			return new Callable<Integer>() {
				public Integer call() {
					return 2 + 3;
				}
			}.call();
		}
	}
}

Is there a special reason why you didn't use
    ITypeBinding type= ASTNodes.getEnclosingType(destination)
in ExtractMethodAnalyzer#checkInput(RefactoringStatus, String, ASTNode)? I always prefer less code and less changes in working code.
Comment 4 Deepak Azad CLA 2010-07-01 03:39:13 EDT
Created attachment 173166 [details]
fix + tests

(In reply to comment #3)
> The patch does not work if the expression is inside an anonymous, 
The patch fails when there is more than one level of nesting, and also when the inner class is a static class. Fixed all these issues.
Comment 5 Deepak Azad CLA 2010-07-01 03:43:23 EDT
(In reply to comment #4)
> Created an attachment (id=173166) [details] [diff]
> fix + tests
Fixed in HEAD.
Comment 6 Deepak Azad CLA 2010-07-01 03:43:51 EDT
.
Comment 7 Markus Keller CLA 2010-07-01 10:30:33 EDT
Looks good. Filed and fixed bug 318609 for a problem with enum types.
Comment 8 Dani Megert CLA 2010-08-03 06:20:49 EDT
Verified in I20100802-1800.