Bug 95684 - [1.5][compiler] Type handling on concrete inner class of super class is incorrect
Summary: [1.5][compiler] Type handling on concrete inner class of super class is incor...
Status: CLOSED FIXED
Alias: None
Product: JDT
Classification: Eclipse Project
Component: Core (show other bugs)
Version: 3.1   Edit
Hardware: PC Windows XP
: P3 critical (vote)
Target Milestone: 3.1 RC2   Edit
Assignee: Philipe Mulet CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2005-05-17 19:06 EDT by Steven Tamm CLA
Modified: 2005-06-10 10:36 EDT (History)
1 user (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Steven Tamm CLA 2005-05-17 19:06:06 EDT
There are three main classes, an class called UserClass which is parameterized
based on KeyClass, and a child class that extends UserClass concretized with a
child inner class:

abstract public class UserClass<K extends KeyClass> {
    protected class DataHolder {
        private final Map<K, Object> singleData = new HashMap<K,Object>();
        public void put(K key, Object value) {this.singleData.put(key, value); }
    }
    private final DataHolder data = new DataHolder();
    public Object get(K key) { return data.singleData.get(key); }
    protected void loadHook(DataHolder data) {}
}

abstract public class KeyClass {
    public abstract String getName();        
    public static class Named extends KeyClass {
        private final String paramName;
        protected Named(String paramName) {this.paramName = paramName;}
        @Override public final String getName() {return this.paramName;
        }
    }
}

public class ChildClass extends UserClass<ChildClass.Key> {
    public static class Key extends KeyClass.Named {
        public static final Key instance = new Key("1");
        private Key(String n) { super(n); }
    }
    @Override protected void loadHook(DataHolder data) {
    }
}

The @Override in the last class causese

Name clash: The method loadHook(UserClass<ChildClass.Key>.DataHolder) of type
ChildClass has the same erasure as loadHook(UserClass.DataHolder) of type
UserClass<K> but does not override it

If you remove the @Override, it works but gives a warning.  It compiles
correctly in javac.  This behavior is a regression from M6.
Comment 1 Philipe Mulet CLA 2005-05-18 04:28:26 EDT
Your example doesn't compile for quite a few other errors. Syntax error,
unexpected static modifiers.

Please correct your testcase to only expose the issue described in this PR; then
reopen.
Comment 2 Steven Tamm CLA 2005-05-18 11:22:21 EDT
I had assumed incorrectly that you would have pasted each of the classes into
three separate files, which would automatically add in the import.  You cannot
reproduce the bug in a single class because of its use of statics.  I.e. if you
place them all in the same class, it works correctly.  Here is the example that
works correctly:
// Reduction.java
import java.util.*;
public class Reduction {
    abstract static public class UserClass<K extends KeyClass> {
        protected class DataHolder {
            private final Map<K, Object> singleData = new HashMap<K,Object>();
            public void put(K key, Object value) {this.singleData.put(key, value); }
        }
        private final DataHolder data = new DataHolder();
        public Object get(K key) { return data.singleData.get(key); }
        protected void loadHook(DataHolder data) {}
    }
    abstract static public class KeyClass {
        public abstract String getName();        
        public static class Named extends KeyClass {
            private final String paramName;
            protected Named(String paramName) {this.paramName = paramName;}
            @Override public final String getName() {return this.paramName;
            }
        }
    }
    public static class ChildClass extends UserClass<ChildClass.Key> {
        public static class Key extends KeyClass.Named {
            public static final Key instance = new Key("1");
            private Key(String n) { super(n); }
        }
        @Override protected void loadHook(DataHolder data) {
        }
    }
}


However, when it is placed in three separate files, it doesn't work
//UserClass.java
import java.util.*;
abstract public class UserClass<K extends KeyClass> {
    protected class DataHolder {
        private final Map<K, Object> singleData = new HashMap<K,Object>();
        public void put(K key, Object value) {this.singleData.put(key, value); }
    }
    private final DataHolder data = new DataHolder();
    public Object get(K key) { return data.singleData.get(key); }
    protected void loadHook(DataHolder data) {}
}
//KeyClass.java
abstract public class KeyClass {
    public abstract String getName();        
    public static class Named extends KeyClass {
        private final String paramName;
        protected Named(String paramName) {this.paramName = paramName;}
        @Override public final String getName() {return this.paramName;
        }
    }
}
//ChildClass.java
public class ChildClass extends UserClass<ChildClass.Key> {
    public static class Key extends KeyClass.Named {
        public static final Key instance = new Key("1");
        private Key(String n) { super(n); }
    }
    @Override protected void loadHook(DataHolder data) {
    }
}
Comment 3 Kent Johnson CLA 2005-05-25 14:26:04 EDT
This works fine when compiled from source... its a binary issue with 
parameterized types.

The testcase can be reduced to 2 files:

public class UserClass<K> {
    protected class DataHolder {}
    protected void loadHook(DataHolder data) {}
}

public class ChildClass extends UserClass<Object> {
    @Override protected void loadHook(DataHolder data) {}
}

When ChildClass is compiled & picks up UserClass as a binary, we end up 
comparing 2 parameterized types:

protected class DataHolder
	extends NULL TYPENULL SUPERINTERFACES
	enclosing type : UserClass<java.lang.Object>NULL FIELDSNULL METHODS

and for the inherited method:

protected class DataHolder
	extends NULL TYPENULL SUPERINTERFACES
	enclosing type : UserClass#RAWNULL FIELDSNULL METHODS
Comment 4 Philipe Mulet CLA 2005-05-25 15:19:25 EDT
Feels my bug.
Comment 5 Philipe Mulet CLA 2005-06-01 17:57:35 EDT
Seems similar to bug 96085
Comment 6 Philipe Mulet CLA 2005-06-03 04:57:36 EDT
Added GenericTypeTest#test709.
Problem was along the same line as bug 96085, but on a different path.
Fixed by using LookupEnvironment#convertToRawType(...) during
UnresolvedReferenceBinding resolution.

Fixed
Comment 7 Frederic Fusier CLA 2005-06-07 09:34:14 EDT
Verified for 3.1 RC2 using build N20050607-0010 +JDT/Core HEAD
Comment 8 Jerome Lanneluc CLA 2005-06-10 10:36:53 EDT
Verified with I20050610-0010