Community
Participate
Working Groups
RC2 isn't correctly generating methods signatures for methods involving the concrete non-static inner class of a generic method. The problem is that ParameterizedTypeBinding is being initialized with a zero length number of arguments, but every test inside that class is testing for null. Since the arguments are substituted from a MemberTypeBinding which uses TypeConstants.NoTypeVariables, ParameterizedTypeBinding is being initialized with a zero length array for its arguments which causes the following problem. If you have the following classes in different files public class Parent<K extends Parent.Key> { public abstract static class Key { public abstract String getName(); } public class Holder(); } Methods that refer to Holder are sometimes generating method signatures of the form (LParent<LKey;>.Holder<>;)V The Holder<> is incorrect and causes all of my code that refers to the inner class to break. However, I'm finding it nearly impossible to create a reduction for this test case. But I tracked it down to internal.compiler.lookup.ParameterizedTypeBinding.genericTypeSignature (line330) is testing for this.arguments != null. this.arguments is set to a zero length array for the inner type. Tracing back, it seems that the problem is in Scope.substitute in the case Binding.GENERIC_TYPE. The originalGenericType is a MemberTypeBinding which has it's typeVariable set to NoTypeVariables. This is being directly substituted into the ParamaterizedTypeBinding. The quickest fix for me was to change ParameterizeTypeBinding.initialize() to test for someArguments != null && someArguments.length > 0. However this is probably just a symptom.
Good find. This is another symptom of bug 98322, however the consequence is more drastic. Need to investigate for RC3.
It's very much related to 98322, When I try the proposed fix for 98322, it still fails because someArguments != null, but someArguments.length == 0.
I would fix both at once. Reproducing test would be: public class X<K extends X.Key> { public abstract static class Key { public abstract String getName(); } public class Holder {} X<K>.Holder foo() { return null; } static void bar() { Object o = new X<Key>().foo(); class Local<U> { X<Key>.Holder field; } } } The generic signature for 'field' gets the offending trailing '<>' incorrectly. I am enclined to think that the fix should occur in code performing the substitution (Scope) since it shouldn't rely on ParameterizedTypeBinding to clear the mess. Senders have to behave.
Problem comes from a caching issue. In order to cause grief, the offending parameterized type needs to get cached before it gets used elsewhere in a visible spot where its signature would get corrupted and persisted in some classfile construct. 1) Object o = new X<Key>().foo(); performs the offending substitution from X<K>.Holder (for msg return type)into: X<Key>.Holder, and caches it. 2) class Local<U> { X<Key>.Holder field; } finds binding for 'X<Key>.Holder' already in the cache (as it treats 0 arg as if null), and thus reuses it. From thereon offending binding (and thus signature) can get persisted into a classfile.
+1 for RC3 Dani - pls cast your vote. Without a fix for it, we generate bogus signatures which can break incremental compile or tooling rendering signatures.
(Forgot to CC Dani) Dani - pls cast your vote. Without a fix for it, we generate bogus signatures which can break incremental compile or tooling rendering signatures.
Added GenericTypeSignatureTest#test019
+1 for 3.1 RC3.
Fixed
The signature of the field is: // Signature: LX<LX$Key;>.Holder; instead of: // Signature: LX<LX$Key;>.Holder<>; using RC2. Verified using N20050616-0010 + JDT/Core HEAD