Community
Participate
Working Groups
When compiling AspectJ enabled projects in Java 5.0 source mode with "Indirect access to static modifier" warnings on, the following code incorrectly gives a compiler warning (this doesn't occur in non-AspectJ enabled projects): public class Test { enum Foo { Wibble, Wobble, Woo; } public static void main(String[] args) { EnumSet<Foo> set = EnumSet.noneOf(Foo.class); } }
Passing over to compiler
this is a regression it seems, with AJDT 1.2.1.20050704111033 we don't report the problem, but with the latest 1.3.0.20050912161038 - we do... still investigating.
The error is produced at this line of code in MessageSend.java: if (!receiver.isImplicitThis() && binding.declaringClass != actualReceiverType) { scope.problemReporter().indirectAccessToStaticMethod(this, binding); } It comes out if binding.declaringClass != actualReceiverType. At the point it comes out: actualReceiverType is a RawTypeBinding (id 211) for EnumSet#RAW binding is a ParameterizedGenericMethodBinding (id 218) containing: declaringClass BinaryTypeBinding (id 234) for EnumSet originalMethod ParameterizedMethodBinding containing: declaringClass RawTypeBinding (id 211) EnumSet#RAW So, if we had compared originalMethod.declaringClass with actualReceiverType - the warning wouldn't be produced. But we compared actualReceiverType (id211) with binding.declaringClass (id234) and they don't match. We also have an aspect in affect for references to declaringClass that is needed for working with ITDs - however the advice doesn't do anything in this case as its not an ITD. I think when the original method is on a raw type the ParameterizedGenericMethodBinding should also have the raw as its declaring class - but debugging this is darn tricky.
Ok... the complexity here is due to the nesting of: ParameterizedGenericMethodBinding having an originalMethod that is a ParameterizedMethodBinding that has an originalMethod that is a MethodBinding. Excluding ITDs, the time when the declaringClass for a ParameterizedMethodBinding is different to that for its containing originalMethod seems to be when the parameterized method is being created for a 'raw type' - see RawTypeBinding.getMethodsBase(). Effectively the originalMethod remains with a declaring class that is the generic type, whilst the parameterizedMethodBinding has a declaring class that is the raw type. When working with these methods, our aspect for managing declaring class references breaks. Basically the aspect currently says 'whenever someone accesses the declaring class for a ParameterizedMethodBinding, return the declaring class for the original', in the case in this bug we end up retrieving the generic type when we really wanted the raw type.
Hmmmmm.... these changes to the aspect appear to fix the problem: instead of: pointcut redirectedDeclaringClassAccesses(MethodBinding aBinding) : accessingDeclaringTypeOfAMethodBinding(aBinding) && !within(OwningClassSupportForMethodBindings) && !withincode(* MethodBinding.canBeSeenBy(..)) && // must be based on aspect type here !withincode(MethodBinding.new(..)); // allow binding to initialise properly we now have: pointcut redirectedDeclaringClassAccesses(MethodBinding aBinding) : accessingDeclaringTypeOfAMethodBinding(aBinding) && !within(OwningClassSupportForMethodBindings) && !withincode(* MethodBinding.canBeSeenBy(..)) && // must be based on aspect type here !withincode(MethodBinding.new(..))&& // allow binding to initialise properly !within(ParameterizedGenericMethodBinding) && !target(ParameterizedGenericMethodBinding); with the two extra conditions on the end ... it effectively says if working with a ParameterizedGenericMethodBinding, assume the fiddling to set the right declaring class has already been done when we built the ParameterizedMethodBinding, so we don't need to fiddle again... I can't build the org.eclipse.jdt.core shadows project right now so I've had to hack up a way to test it - until I've thought about it a little more, discussed it with Adrian and checked what it does in the real shadows module - I won't check it in...
Fixed by changing the ITD'd method we make on ParameterizedMethodBinding to take account of the situation where the declaringClass in the PMB is different to the declaringClass in this.original(). We no longer give back the ITD owningClass in that this situation. Will close bug once fix is available in build on download page.
fix now available.