Bug 109283 - Invalid "indirect static access" warning on EnumSet.noneOf
Summary: Invalid "indirect static access" warning on EnumSet.noneOf
Status: RESOLVED FIXED
Alias: None
Product: AspectJ
Classification: Tools
Component: Compiler (show other bugs)
Version: unspecified   Edit
Hardware: PC Windows XP
: P3 normal (vote)
Target Milestone: 1.5.0 M4   Edit
Assignee: Adrian Colyer CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2005-09-12 08:37 EDT by Andrew Brett CLA
Modified: 2005-09-24 05:46 EDT (History)
0 users

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Andrew Brett CLA 2005-09-12 08:37:45 EDT
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);
    }
}
Comment 1 Matt Chapman CLA 2005-09-12 11:01:45 EDT
Passing over to compiler
Comment 2 Andrew Clement CLA 2005-09-13 03:49:52 EDT
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.
Comment 3 Andrew Clement CLA 2005-09-15 06:12:48 EDT
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.
Comment 4 Andrew Clement CLA 2005-09-15 08:50:35 EDT
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.

Comment 5 Andrew Clement CLA 2005-09-15 09:09:51 EDT
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...
Comment 6 Adrian Colyer CLA 2005-09-22 11:46:34 EDT
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.
Comment 7 Adrian Colyer CLA 2005-09-24 05:46:25 EDT
fix now available.