Community
Participate
Working Groups
When the declaring class of enclosing instances is "generic", the precondition for checking references to enclosing instances does not work. Applying move-instance-method to method m() results in an error below. ------------------------------ BEFORE ------------------------------ class A<T> { int i; class C { B b = null; void m() { i = 0; } } } ------------------------------ AFTER ------------------------------ class A<T> { int i; class C { B b = null; } } import p.A.C; class B{ void m(C c) { i = 0; //ERROR } } ------------------------------ Here is the error location. JDT Classic version: 4.2.2 Class Name: org.eclipse.jdt.internal.corext.refactoring.structure.MoveInstanceMethodProcessor Source code: ... public final class EnclosingInstanceReferenceFinder extends AstNodeFinder { ... @Override public final boolean visit(final SimpleName node) { Assert.isNotNull(node); final IBinding binding= node.resolveBinding(); ITypeBinding declaring= null; if (binding instanceof IVariableBinding) { final IVariableBinding variable= (IVariableBinding) binding; if (Flags.isStatic(variable.getModifiers())) return false; declaring= variable.getDeclaringClass(); //getDeclaringClass() returns NULL when the declaring class is "generic". ...
In the meantime, I found that member i and its reference have different type-binding keys in AST: class A<T> { int i; // Lp/A;.i)I class C { B b = null; void m() { i = 0; // Lp/A<Lp/A;:TT;>;.i)I } } } Hope that it's helpful for debugging.
The issue is reproducible with Eclipse 3.8.1 also. (In reply to Jongwook Kim from comment #0) > declaring= variable.getDeclaringClass(); //getDeclaringClass() > returns NULL when the declaring class is "generic". I don't see null being returned for i's declaring class in the example. (In reply to Jongwook Kim from comment #1) > In the meantime, I found that member i and its reference have different > type-binding keys in AST: For A<T> in the example, we get bindings as mentioned in bug 100546 comment #2. But the isEqualTo method (invoked by: Bindings.equals(enclosing, declaring) at MoveInstanceMethodProcessor: line 342) returns 'false', which causes the bug. As per bug 100546 comment #4, the wrong results from isEqualTo(..) have been clarified and fixed. Does it mean that the client should handle the difference in bindings, as in the given example?
(In reply to Jongwook Kim from comment #1) > In the meantime, I found that member i and its reference have different > type-binding keys in AST: Yes, that's expected: The reference to i has a parameterized type as declaring class. (In reply to Noopur Gupta from comment #2) No, that comment was referring to other bugs in isEqualTo(..) that were present at the time that bug was opened. Note that bug 100546 is about a *static* nested class, but comment 0 is about a (non-static) inner class. The fix for comment 0 is in EnclosingInstanceReferenceFinder#visit(SimpleName): Call getTypeDeclaration() on the declaring class (or, equivalently, call getVariable|MethodDeclaration() before calling getDeclaringClass()). I've also fixed a similar problem if the field is static, see test67. Fixed with http://git.eclipse.org/c/jdt/eclipse.jdt.ui.git/commit/?id=cc3cd91f01de9a50ef638d7b21d42084449dcda0