Bug 98901 - Must copy annotations to *public* intertype declarations
Summary: Must copy annotations to *public* intertype declarations
Status: RESOLVED FIXED
Alias: None
Product: AspectJ
Classification: Tools
Component: Compiler (show other bugs)
Version: DEVELOPMENT   Edit
Hardware: PC Windows XP
: P3 normal (vote)
Target Milestone: 1.5.1   Edit
Assignee: Andrew Clement CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2005-06-08 05:53 EDT by Andrew Clement CLA
Modified: 2012-04-03 16:08 EDT (History)
2 users (show)

See Also:


Attachments
tests for the above five cases (8.73 KB, patch)
2005-06-10 08:07 EDT, Andrew J Huff CLA
no flags Details | Diff
tests for the 29 cases (38.03 KB, patch)
2005-06-23 11:57 EDT, Andrew J Huff CLA
aclement: iplog+
Details | Diff
fixes all the cases for fields (16.28 KB, patch)
2005-06-29 07:23 EDT, Andrew J Huff CLA
no flags Details | Diff
fixes all 29 cases (27.53 KB, patch)
2005-07-06 10:28 EDT, Andrew J Huff CLA
no flags Details | Diff
fixes all 29 cases again (7.93 KB, patch)
2005-07-28 05:39 EDT, Andrew J Huff CLA
no flags Details | Diff
fix which doesn't use interMethodBody (8.78 KB, patch)
2005-08-05 07:18 EDT, Andrew J Huff CLA
aclement: iplog+
Details | Diff
Test Case for 1.5.0 brakes described use cases 8 and 9 (1002 bytes, application/octet-stream)
2006-03-27 04:46 EST, Vincenz Braun CLA
no flags Details

Note You need to log in before you can comment on or make changes to this bug.
Description Andrew Clement CLA 2005-06-08 05:53:25 EDT
Some users are declaring public ITDs with annotations on and then, post weaving,
another tool is consuming the annotations on the members created in the target
type.  We don't currently copy the annotations from the ITD that exists in the
aspect to the public member created in the target type - this needs fixing.
Comment 1 Andrew Clement CLA 2005-06-08 10:34:20 EDT
Fixed the case for public ITD'd methods onto a class.  

I have not tested/fixed these other 'interesting' cases:

- public ITD method with no annotation that has declare @method annotation on it.
- public ITD field with annotation on it.
- public ITD field with no annotation that has declare @field annotation on it.
- public ITD method with annotation on it which is made onto an interface.
- public abstract ITD method with annotations on it.

I also wonder if there are bugs lurking in our matching on ITDs using annotation
patterns when the ITDs are either abstract or made onto an interface - a quick
look seems to suggest 'holder' methods for the annotations aren't being produced
by the compiler, which would cause the annotations to disappear...  

I don't propose to look at these cases for M3 but will do before 1.5.0 final.
Comment 2 Andrew J Huff CLA 2005-06-10 08:07:17 EDT
Created attachment 22786 [details]
tests for the above five cases

All five cases currently fail...

in the first case the annotation can by seen with runtime "@annotation(a)"
matching in a pointcut, but not through java.lang.reflect.
Comment 3 Andrew J Huff CLA 2005-06-13 09:52:26 EDT
fixed case 4...
Comment 4 Barry Kaplan CLA 2005-06-13 10:09:14 EDT
Why only *public*? If there is an ITD for a methods -- of any scope -- with
annotations, I would expect those annotations to exist on the target. (But I
will admit that just now I have only found a use case for public scope.)
Comment 5 Andrew Clement CLA 2005-06-13 10:20:37 EDT
public ITD members are the only ones added 'as-is' to the target type - if you
write public void A.m() then type A will get a public member 'm'.  Other ITD
forms with 'default' or 'private' visibility are added as mangled members that
really shouldn't be getting looked-at by tools searching for members - these
members have names starting ajc$ indicating they are artifacts of the AJ
compiler, effectively they are synthetic members, we just haven't tagged them as
such yet.

There could be use cases for the annotations to get copied across in those cases
- but I can't think of any.  I raised this bug to cover the cases that I think
do have reasonable use cases right now, doesn't mean we wont fix the others
later...   Copying annotations around is not free, it impacts performance of the
compiler as annotations have to be discovered - all the other information about
a member is captured in its signature.  If there is a reason to copy them, then
we will.
Comment 6 Andrew J Huff CLA 2005-06-15 06:14:05 EDT
fixed case 5, broken case 4.. can't remember how I got case 4 working previously
Comment 7 Andrew J Huff CLA 2005-06-21 07:57:11 EDT
case 4 and 5 are now both working...
Comment 8 Andrew J Huff CLA 2005-06-21 09:22:52 EDT
2,4 and 5 working..
just 1 and 3 to go
Comment 9 Andrew J Huff CLA 2005-06-22 09:40:46 EDT
hmm... my fix for case2 causes annotations to be put on twice if it's a non-ITD
field.. I think that in order for case2 to be fixed properly I'll need to fix a
"case 6"

- public non-ITD field with declare @field annotation on it
Comment 10 Andrew J Huff CLA 2005-06-23 06:14:05 EDT
Now it looks like there are about 26 cases, not even looking at static fields
and methods (that would double the number of cases again). By annotated I mean
it has an annotation on it rather than declared remotely on it. By ITD-on-itself
I mean an aspect declaring an ITD on itself.

1.  public method with declare @method
2.  public annotated method

3.  public ITD method with declare @method
4.  public annotated ITD method
5.  public ITD-on-itself method with declare @method
6.  public annotated ITD-on-itself method

7.  public method on an Interface with declare @method
8.  public annotated method on an Interface
9.  public ITD method onto an Interface with declare @method
10. public annotated ITD method onto an Interface

11. public abstract method with declare @method
12. public abstract annotated method

13. public abstract ITD method with declare @method
14. public abstract annotated ITD method
15. public abstract ITD-on-itself method with declare @method
16. public abstract annotated ITD-on-itself method

17. public abstract method on an Interface with declare @method
18. public abstract annotated method on an Interface
19. public abstract ITD method onto an Interface with declare @method
20. public abstract annotated ITD method onto an Interface

21. public field with declare @field
22. public annotated field

23. public ITD field with declare @field
24. public annotated ITD field
25. public ITD-on-itself field with declare @field
26. public annotated ITD-on-itself field
Comment 11 Andrew J Huff CLA 2005-06-23 06:28:55 EDT
No wait, missed a few.. now 29 cases

1.  public method with declare @method
2.  public method on the aspect that declares @method on it
3.  public annotated method

4.  public ITD method with declare @method
5.  public annotated ITD method
6.  public ITD-on-itself method with declare @method
7.  public annotated ITD-on-itself method

8.  public method on an Interface with declare @method
9.  public annotated method on an Interface
10.  public ITD method onto an Interface with declare @method
11. public annotated ITD method onto an Interface

12. public abstract method with declare @method
13. public abstract method on the aspect that declares @method on it
14. public abstract annotated method

15. public abstract ITD method with declare @method
16. public abstract annotated ITD method
17. public abstract ITD-on-itself method with declare @method
18. public abstract annotated ITD-on-itself method

19. public abstract method on an Interface with declare @method
20. public abstract annotated method on an Interface
21. public abstract ITD method onto an Interface with declare @method
22. public abstract annotated ITD method onto an Interface

23. public field with declare @field
24. public field on the aspect that declares @field on it
25. public annotated field

26. public ITD field with declare @field
27. public annotated ITD field
28. public ITD-on-itself field with declare @field
29. public annotated ITD-on-itself field
Comment 12 Barry Kaplan CLA 2005-06-23 10:34:15 EDT
Sorry (little fib) to have started you on this crusade Andy, but you seem to be
having fun ;-) 
Comment 13 Andrew J Huff CLA 2005-06-23 11:57:27 EDT
Created attachment 23871 [details]
tests for the 29 cases

11 fail in my workspace at the moment (suprisingly few!)
Comment 14 Andrew J Huff CLA 2005-06-29 07:23:44 EDT
Created attachment 24121 [details]
fixes all the cases for fields
Comment 15 Andrew J Huff CLA 2005-07-01 10:05:56 EDT
I've now fixed all of the cases for fields and methods apart from cases 6 and 17
(which are pretty obscure)..

I'm going to be working on these two now...
Comment 16 Andrew J Huff CLA 2005-07-06 10:28:35 EDT
Created attachment 24382 [details]
fixes all 29 cases
Comment 17 Andrew Clement CLA 2005-07-18 04:35:47 EDT
I've now committed the testcase patch - it isnt wired into the full suite yet.
Comment 18 Andrew Clement CLA 2005-07-18 05:39:44 EDT
Patch for the fix includes changes to:

LazyClassGen
AjcMemberMaker
NewMethodTypeMunger
NewConstructorTypeMunger
BcelClassWeaver
BcelTypeMunger

I've now done:

LazyClassGen patched   - added 'replaceField()'
AjcMemberMaker patched - added comments on inter**() methods to better explain
how they hang together.
NewConstructorTypeMunger - commented out the 'getDispatchMethod()' - not used
NewMethodTypeMunger - changed the name of getDispatchMethod() to better reflect
what it actually returns (now it is getInterMethodBody())

still to do:

BcelClassWeaver
BcelTypeMunger
Comment 19 Andrew Clement CLA 2005-07-18 06:18:23 EDT
Hmmm.  Running the new tests with no fix, 21 fail.  Applying the patches to the
two remaining files causes those two modified files to no longer compile.  I had
to put in some modifications of my own to get them to compile again - and even
then it brings the number of failures down to 6, not to 0.  I'm not sure what is
missing from the patch?  It seems odd that the only patch required to make them
work was for weaver - as I seem to need to change org.aspectj.ajdt.core because
of  some of the changes?
Comment 20 Andrew Clement CLA 2005-07-18 06:23:19 EDT
These two comments also concern me from the patch:

// ajh02: stupid method added.
// this method is only needed because it's still looking on the old annotation
// holder (the interMethodBody) when doing pointcut matching for annotated 
// methods.

// ajh02: this is kind of stupid. Because we still need the annotations on the
// interMethodBody for pointcut matching to work we have to put them there as
// well as on the interMethodDispatch. Really the code should be changed so
// that the pointcut matching code looks at the intermethod dispatch
// rather than the intermethodbody

I thought we had modified all the logic throughout the system to look on the
generated dispatch method for the annotations?  Although I don't necessarily
mind the annotations being on both the dispatch method and the actual body
method - we really should be using the dispatch method to find the annotations
(or match them), since the body method is not always created (abstract ITDs).
Comment 21 Andrew J Huff CLA 2005-07-18 06:52:38 EDT
yep, those comments concern me too.

I have no idea why the patch doesn't seem to work for you...
When you're not busy we should discuss this and try to work out whats different 
between our workspaces
Comment 22 Andrew J Huff CLA 2005-07-28 05:39:46 EDT
Created attachment 25399 [details]
fixes all 29 cases again

this patch has been synchronised with the latest AspectJ
Comment 23 Andrew J Huff CLA 2005-08-05 07:18:29 EDT
Created attachment 25739 [details]
fix which doesn't use interMethodBody

this fix doesn't use the interMethodBody as an annotation holder
Comment 24 Andrew Clement CLA 2005-08-08 06:04:40 EDT
Fix checked in (shock horror) - waiting on build.
Comment 25 Andrew Clement CLA 2005-08-09 10:00:14 EDT
Fix available on AJ downloads page.

For anyone feeling brave and attempting to modify current AJDT builds to plug in
this AJ dev build - be aware that we have seen some incompatibilities with
recent dev builds and AJDT so it may misbehave.
Comment 26 Vincenz Braun CLA 2006-03-27 04:46:09 EST
Created attachment 36976 [details]
Test Case for 1.5.0 brakes described use cases 8 and 9
Comment 27 Vincenz Braun CLA 2006-03-27 04:48:37 EST
This testcase breaks use cases 8 and 9 under 1.5.0.
Please reopen.

// source 1

@Retention(RetentionPolicy.RUNTIME)

@Target(ElementType.METHOD)

public @interface TestAnnotation {

 

            public boolean value() default true;

}

// source 2

public aspect TestAspect {

 

            declare parents: TestClass implements TestInterface;

 

// this also does not work (even when removing annotation in the following ITD)

//          declare @method: public void TestInterface.foo(): @TestAnnotation;

            

            @TestAnnotation

            public void TestInterface.foo() {

                        System.err.println("foo");

            }

}

// source 3

public interface TestInterface {

 

            public void foo();

}

// source 4

public class TestClass {

 

            public static void main(String[] args) throws Exception {

                        // returns null

                        System.err.println(TestClass.class.getMethod("foo").getAnnotation(TestAnnotation.class)); 

            }

}

Comment 28 Andrew Clement CLA 2006-03-27 15:27:59 EST
not quite the same as cases 8 and 9 since they have testcases and the testcases pass.  Reopening for investigation of these new problems.
Comment 29 Andrew Clement CLA 2006-03-27 16:16:56 EST
The new case covered is related to providing a *default implementation* for an interface method via ITD and expecting the class getting the default implementation to also get the annotation.  The annotation copying code we have to get the annotation from the ITD in the aspect to the affected target class had to be copied from where it existed for munging new interface methods to where we munge topmost implementors.

testcases and fixes checked in (both the 'normal' case and the case where the annotation is added via declare)
Comment 30 Andrew Clement CLA 2006-03-28 08:52:24 EST
extra fixes available in latest AJ build:
Date of build: 03/28/2006 13:39:48