Bug 241861 - [plan] [annotations] cannot aspect inner class constructor w/ annotated params
Summary: [plan] [annotations] cannot aspect inner class constructor w/ annotated params
Status: NEW
Alias: None
Product: AspectJ
Classification: Tools
Component: Compiler (show other bugs)
Version: unspecified   Edit
Hardware: PC Windows XP
: P2 major (vote)
Target Milestone: ---   Edit
Assignee: aspectj inbox CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2008-07-23 14:43 EDT by Howard CLA
Modified: 2013-06-24 11:03 EDT (History)
1 user (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Howard CLA 2008-07-23 14:43:01 EDT
cannot aspect inner class constructor w/ annotated params

To Reproduce:

1.	Annotate the parameter of an inner class constructor.  i.e.,

	public @interface Ann { }

	public class Outer {
	   public class Inner {
		  Inner(@Ann String arg) { }
	   }
	}

2.	Aspect the constructor.  i.e.,

	public aspect Asp {
	   before() : execution(new(@Ann (*), ..)){ }
	}

3.	AJDT will report "Internal Compiler Error" with details:

		java.lang.IndexOutOfBoundsException
		at java.util.ArrayList.RangeCheck(ArrayList.java:546)
		at java.util.ArrayList.get(ArrayList.java:321)
		at org.aspectj.apache.bcel.classfile.annotation.RuntimeParameterAnnotations.getAnnotationsOnParameter(RuntimeParameterAnnotations.java:55)
		at org.aspectj.apache.bcel.classfile.Method.ensureParameterAnnotationsUnpacked(Method.java:294)
		at org.aspectj.apache.bcel.classfile.Method.getParameterAnnotations( ... ETURN
			constructor-execution(void Outer$Inner.<init>(Outer, java.lang.String))
		  end void <init>(Outer, String)

		end public class Outer$Inner

This is for:

Eclipse AspectJ Development Tools
Version: 1.5.2.200804241330
AspectJ version: 1.6.0.20080423100000

Eclipse v3.3.2 M20080221-1800
Comment 1 Andrew Clement CLA 2008-07-23 20:41:01 EDT
should be simple fix.
Comment 2 Andrew Clement CLA 2008-07-23 22:19:21 EDT
The problem here is that because the inner type is non-static there is an implicit first parameter to the constructor for the Inner type which gets added by the compiler - this parameter is of type Outer (it is the enclosing instance of the outer type).  The annotation data is only there for the declared parameter and so we get into trouble when iterating over both parameters and attempting to recover the annotation data (which says nothing for the other parameter).

Comment 3 Andrew Clement CLA 2008-07-23 22:20:29 EDT
test committed.
Comment 4 Andrew Clement CLA 2008-09-30 16:16:34 EDT
ok.  the npe won't happen any more.  But the behaviour is still not right.  The extra parameter is still an issue.  There is some missing internal infrastructure for getting the right modifiers for an inner class - and so the fix to do the right thing for a non-static inner class can't be put in until that infrastructure is there.  This means that the behaviour right now is less than perfect:

The code in comment 1 will match fine.

This variant will not:

 @interface Ann { }

class Outer {
   public class Inner {
          Inner(@Ann String arg) { }
   }
}

aspect Asp {
   before() : execution(new(@Ann (String), ..)){ }
}

Because of the rogue extra parameter that shuffles the declared parameter types along, but *not* the declared annotations!

This will match (!):
before() : execution(new(@Ann (*),String)) {}

and this (!!):
before() : execution(new(@Ann (Outer),String)) {}

making high priority for fixing post 1.6.2.  The required infrastructure will disturb things and I don't want to do that so close to release.

Comment 5 Andrew Clement CLA 2008-09-30 16:16:50 EDT
3 testcases committed
Comment 6 Andrew Clement CLA 2013-06-24 11:03:41 EDT
unsetting the target field which is currently set for something already released