Bug 100546 - reference to static nested class inside generic type has wrong binding
Summary: reference to static nested class inside generic type has wrong binding
Status: CLOSED WONTFIX
Alias: None
Product: JDT
Classification: Eclipse Project
Component: Core (show other bugs)
Version: 3.1   Edit
Hardware: All All
: P3 normal (vote)
Target Milestone: ---   Edit
Assignee: Srikanth Sankaran CLA
QA Contact:
URL:
Whiteboard: stalebug
Keywords:
: 432724 (view as bug list)
Depends on:
Blocks: 432689 436997
  Show dependency tree
 
Reported: 2005-06-17 05:37 EDT by Markus Keller CLA
Modified: 2020-01-20 20:12 EST (History)
2 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 2005-06-17 05:37:52 EDT
I20050617-0010

In a 1.5 library, look at the static class MethodArray inside java.lang.Class<T>.

The class declaration has
KEY: 'Ljava/lang/Class<TT;>.MethodArray;',
but the reference to MethodArray in void addAll(MethodArray ma) { .. } has
KEY: 'Ljava/lang/Class$MethodArray;'.
I would expect that the two bindings are identical.

Also strange is that when I ask the declaration.isEqualTo(the reference), then I
get true, but when I ask the reference.isEqualTo(the declaration), then I get false.

Furthermore, when I ask any method binding of a non-constructor method of
MethodArray about #getJavaElement(), then I get a non-existing java element.

The observations above are made from within an editor for class file
java.lang.Class. When I open an editor for java.lang.Class$MethodArray, then I
run into different problems. I'll file another bug for that.

I don't have an example where eclipse fails because of this, so I don't know how
severe this is.
Comment 1 Olivier Thomann CLA 2007-02-13 15:19:09 EST
DOM side is only reflecting the compiler bindings.
Philipe, I don't know if we can do anything about this one.
Comment 2 Philipe Mulet CLA 2007-02-13 19:41:30 EST
A declaration denotes a generic type binding, whereas a reference denotes a parameterized type binding.

List<T> can either mean the generic type with type param T,
or the parameterized type List with argument type T (i.e. substituting T by T).
Comment 3 Philipe Mulet CLA 2007-02-13 19:44:59 EST
I admit that the static member scenario is interesting, but generally speaking the declaration of the static member is enclosed by a generic type, which is the answer to binding.getEnclosingType() (which you wouldn't get from the reference). So if you navigate in declarations, I believe the current behavior makes sense.

As stated in previous comment, bindings for declarations and references are not meant to be identical since generics any longer.
Comment 4 Markus Keller CLA 2007-02-14 05:32:40 EST
This is an old bug; the problems with declaration and reference bindings, and the wrong results from isEqualTo(..) have been clarified and fixed in latest builds.

The only problem I still see in Class.MethodArray is IMethodBinding#getJavaElement() on the constructor. The IMethod does not exist. Its handleIdentifier ends with .../rt.jar<java.lang(Class$MethodArray.class[MethodArray~MethodArray~Ljava.lang.Class\<TT;>;
whereas the existing IMethod's handleIdentifier ends with
.../rt.jar<java.lang(Class$MethodArray.class[MethodArray~MethodArray
Comment 5 Philipe Mulet CLA 2009-01-21 07:36:35 EST
Passing onto Jerome for key assessment
Comment 6 Jerome Lanneluc CLA 2009-02-10 07:23:46 EST
Srikanth, can you please investigate?
Comment 7 Markus Keller CLA 2014-04-14 15:29:11 EDT
*** Bug 432724 has been marked as a duplicate of this bug. ***
Comment 8 Markus Keller CLA 2014-04-14 16:01:48 EDT
It doesn't make sense to make a difference between reference and declaration bindings for a non-generic static type, even if it is nested in a generic type.

Noopur's self-contained example from bug 432724 (with a few additions):

package test.bugzilla;

public class A<T> {
	public static class B { // [1] - B - KEY: "Ltest/bugzilla/A<TT;>.B;"
		public B get() {    // [2] - B - KEY: "Ltest/bugzilla/A<>.B;"
			return new A.B(); [3]
		}
	}
	static void foo() {}
}

At [1], the declaring type of B is the generic type A<T>. That's OK, and it's consistent with the declaring type of method foo(). But the declaring type of the reference to B at [2] and [3] is currently the raw type A. That's wrong, since there's nothing raw about that reference to B. No type argument is dropped.

A type import has the same problem:

import test.bugzilla.A; // A is generic (good)
import test.bugzilla.A.B; // A is raw, should be generic
import static test.bugzilla.A.foo; // A is generic (good)


(In reply to Markus Keller from comment #4)
I don't see that problem any more.
Comment 9 Noopur Gupta CLA 2014-06-11 06:00:13 EDT
(In reply to Markus Keller from comment #4)
> This is an old bug; the problems with declaration and reference bindings,
> and the wrong results from isEqualTo(..) have been clarified and fixed in
> latest builds.

Does it mean that isEqualTo returns 'false' now in both the cases mentioned in comment #0? See bug 436997 also.
Comment 10 Markus Keller CLA 2014-06-12 12:13:28 EDT
(In reply to Noopur Gupta from comment #9)
> (In reply to Markus Keller from comment #4)
> > This is an old bug; the problems with declaration and reference bindings,
> > and the wrong results from isEqualTo(..) have been clarified and fixed in
> > latest builds.
> 
> Does it mean that isEqualTo returns 'false' now in both the cases mentioned
> in comment #0? See bug 436997 also.

It means that IBinding#isEqualTo(..) seems to work fine now.

But the resolved bindings are still as written in comment 0 and comment 8, and it's still wrong that the reference to the static nested class returns a raw type when asked for #getDeclaringClass().

=> isEqualTo correctly returns 'false' when comparing the two bindings, but the bindings are wrong. The bindings needs to be identical (and then isEqualTo will return 'true').


(In reply to Philipe Mulet from comment #3)
> As stated in previous comment, bindings for declarations and references are
> not meant to be identical since generics any longer.

Nobody objected to that. But for static nested types, the genericity of the declaring class is never relevant, so #getDeclaringClass() always needs to return the declaration binding in this case, and not an arbitrary reference binding (i.e. raw type 'Class' is wrong, and parameterized type 'Class<T>' would also be wrong).
Comment 11 Eclipse Genie CLA 2020-01-20 20:12:53 EST
This bug hasn't had any activity in quite some time. Maybe the problem got resolved, was a duplicate of something else, or became less pressing for some reason - or maybe it's still relevant but just hasn't been looked at yet. As such, we're closing this bug.

If you have further information on the current state of the bug, please add it and reopen this bug. The information can be, for example, that the problem still occurs, that you still want the feature, that more information is needed, or that the bug is (for whatever reason) no longer relevant.

--
The automated Eclipse Genie.