Bug 80472 - Binding of parameterized return type List<E> subList(...) should not be generic binding
Summary: Binding of parameterized return type List<E> subList(...) should not be gener...
Status: VERIFIED FIXED
Alias: None
Product: JDT
Classification: Eclipse Project
Component: Core (show other bugs)
Version: 3.1   Edit
Hardware: PC Windows XP
: P3 normal (vote)
Target Milestone: 3.2 M4   Edit
Assignee: Philipe Mulet CLA
QA Contact:
URL:
Whiteboard:
Keywords:
: 107788 (view as bug list)
Depends on:
Blocks: 99963
  Show dependency tree
 
Reported: 2004-12-08 09:56 EST by Markus Keller CLA
Modified: 2005-12-13 07:46 EST (History)
4 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Markus Keller CLA 2004-12-08 09:56:20 EST
I20041207-0800

The interface java.util.List declares as its last method:
    List<E> subList(int fromIndex, int toIndex);

The type binding of the return type List<E> is currently the same as the type
binding of the interface's declaration (see e.g. new ASTView, choose "Add to
comparison tray" from context menu of one binding, then select the other one).

The return type of method subList(..) should be a parameterized type, not a
generic type. (That getJavaElement() is null for the generic binding is bug
80466). Compare to the (correct) parameterized return type binding of method
    ListIterator<E> listIterator(int index);
Comment 1 Philipe Mulet CLA 2004-12-08 10:04:14 EST
Inside the compiler they are the same type. The type of 'this' is the generic
type, and thus:

List<E> l = this; 

requires that these be the same type.
Now, on DOM AST, they could both be a param type.
Comment 2 Markus Keller CLA 2004-12-08 10:29:03 EST
I see; it's just strange for clients that

    class Generic<T> {
        Generic<T> list= this;
        Generic<? super T> list2= this;
    }

results in different kinds of bindings.
Comment 3 Olivier Thomann CLA 2004-12-08 14:11:22 EST
Philippe, what do you propose for the DOM/AST binding?
Right now I use the compiler's bindings.
Comment 4 Markus Keller CLA 2004-12-14 07:23:48 EST
In fact, it's not just strange, it is wrong. The List<E> in

    List<E> subList(int fromIndex, int toIndex);

is a type reference where E is the type *argument* of the List. In contrast, the
binding of the generic type List<E> has E as type *parameter*. This is wrong
since E is not declared in the return type.
Comment 5 Markus Keller CLA 2005-06-02 14:23:07 EDT
This bug is causing me trouble when I try to play assignment rules. In the
DOM/AST, the bindings for 'this' and 'List<E>' should be parameterized types and
not generic types. Is this very difficult or can you do something here?
Comment 6 Olivier Thomann CLA 2005-06-02 14:53:09 EDT
Philippe, could you please let me know you plan for this one?
Right now the DOM/AST is exposing compiler's binding. So fixing this might
require fixing the compiler's bindings.
Comment 7 Philipe Mulet CLA 2005-06-02 15:36:48 EDT
No action planned on compiler end. Generic types are assimilated to
parameterized types using their own parameters as arguments.

Maybe the DOM spec should clarify these, and likely not refrain from changing
this in the future.

Markus - the entire compiler relies on this assumption for other reasons,
changing this would be quite a lot of work. Now the DOM could hide this, but
this feels to late to change this.
Comment 8 Dirk Baeumer CLA 2005-06-03 04:25:38 EDT
Philippe, IMO the DOM ast should provide a view which is consistent with the
spec. The example: 

class Generic<T> {
        Generic<T> list= this;
        Generic<? super T> list2= this;
}

really shows that we have a problem here in the DOM AST which we should fix
(from a client point of view it is not understandable why list is a generic type
and list2 is a parameterized type). I can understand that it is very late in the
game to fix this so a couple of questions:

- how risky is this to be fix in the DOM/AST level only ?

- Markus, do we already have workaround code in place for this. If not how
  expensive is it to add this.

I am not a fan of specing this and always returning the false answer here. This
requires that every client that deals with generic/parameterized types has to be
aware of this and has to work around the bug.
Comment 9 Philipe Mulet CLA 2005-06-03 06:58:24 EDT
I don't think the DOM could survive such a change. It relies a lot on compiler
bindings, and provides a 1:1 mapping. A good approach would be to reconsider
this in the compiler, but this is not going to occur within 3.1 (and possibly
never).

I understand the complexity for clients of DOM APIs. One nice characteristics
still is that the type of 'this' is the generic type, which wouldn't be the case
any longer if generic types were hidden.
Comment 10 Dirk Baeumer CLA 2005-06-03 09:00:31 EDT
The 'this' case might be discussable however for me the list versus list2 case
it not. For clients it will never be understandable why one is a parameterized
type and one a generic.

Markus will look into if we can workaround for 3.1. I would appreciate if
Olivier could look into converting this in the DOM world as well. As far as I
understand the problem a generic type binding can only occur on the declaration
of a type (e.g public class GenericTypes<E> {...} ). All others occurences must
be parameterized types. So if we have a generic type binding and it is not the
name of a declaration it should be parameterized. 
Comment 11 Olivier Thomann CLA 2005-06-03 09:38:31 EDT
The problem is that there is no creation of compiler's binding during the
conversion to DOM bindings. It is a 1:1 mapping.
DOM API are calls to compiler's method.
There is no way right now to emulate such behavior without getting a support
from the compiler's binding.
Comment 12 Dirk Baeumer CLA 2005-06-03 09:44:46 EDT
Can the compiler create both bindings and DOM simply uses the other one ?
Comment 13 Philipe Mulet CLA 2005-06-03 10:05:30 EDT
I'd rather change the compiler, but this is far too big of a change. Especially
after 9 months of surviving in this situation.
Comment 14 Philipe Mulet CLA 2005-06-07 06:08:47 EDT
No action planned for 3.1, may reconsider later.
Comment 15 Philipe Mulet CLA 2005-11-16 07:41:31 EST
Reconsidering for 3.2
Comment 16 Philipe Mulet CLA 2005-11-16 07:50:16 EST
All references to a generic type are now parameterized type bindings, no matter
where the reference occurs (inside/outside).
Tuned various existing tests.

Fixed

Olivier - would you pls add a specific test for this one ?
Comment 17 Philipe Mulet CLA 2005-11-16 07:52:22 EST
*** Bug 107788 has been marked as a duplicate of this bug. ***
Comment 18 Markus Keller CLA 2005-11-17 13:54:32 EST
Just for the records (i.e. such that I remember when I read this bug again):
This fix also has subtle consequences on bindings for members of a type, since
'this' inside a generic type has a parameterized type now.

In the example below,
- the binding for the declaration of foo() has a getDeclaringClass() with
    isGenericType() == true, but
- the binding for the invocation of method foo() has a getDeclaringClass() with
    isParameterizedType() == true

class G<E> {
    void foo() {}
    void use() {
        foo();
    }
}

The same applies for all members, also e.g. for static methods.

Before the fix, the two bindings were identical. The fix for failing clients
usually is to compare get{Method|Variable|Type}Declaration() of two bindings.
Comment 19 Olivier Thomann CLA 2005-11-21 09:47:18 EST
Added regression test org.eclipse.jdt.core.tests.dom.ASTConverter15Test.test0203
Comment 20 Frederic Fusier CLA 2005-12-13 07:46:11 EST
Verified for 3.2 M4 using build I20051213-0010