Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.

Bug 318127

Summary: [extract method] "Extract Method" into an enclosing class fails when the inner class has a method of the same name
Product: [Eclipse Project] JDT Reporter: Missing name <harely>
Component: UIAssignee: Deepak Azad <deepakazad>
Status: VERIFIED FIXED QA Contact:
Severity: minor    
Priority: P3 CC: daniel_megert, deepakazad, markus.kell.r
Version: 3.7Flags: markus.kell.r: review+
Target Milestone: 3.7 M1   
Hardware: PC   
OS: Windows XP   
Whiteboard:
Attachments:
Description Flags
fix + test
none
fix + tests none

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.