Bug 344005 - binding type pattern matching sometimes misses decps affecting generic types
Summary: binding type pattern matching sometimes misses decps affecting generic types
Status: RESOLVED FIXED
Alias: None
Product: AspectJ
Classification: Tools
Component: Compiler (show other bugs)
Version: DEVELOPMENT   Edit
Hardware: PC Mac OS X - Carbon (unsup.)
: P3 normal (vote)
Target Milestone: 1.6.12   Edit
Assignee: aspectj inbox CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2011-04-27 13:34 EDT by Andrew Clement CLA
Modified: 2011-04-27 17:01 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 Clement CLA 2011-04-27 13:34:50 EDT
Uncovered by the spring-data project.  Here:

@Foo
class Clazz {}

@Foo 
class OtherClass<T> {}

interface Marker {}

aspect X {
  declare parents: (@Foo *) implements Marker;

  before(Marker m): this(m) {
  }
}

the advice can miss applying to OtherClass because the matching for this() is done against the raw type when the affect of the decp is stored on the generic form.
Comment 1 Andrew Clement CLA 2011-04-27 16:53:24 EDT
I ended up making two key changes:

1) ReferenceType.getDeclaredInterfaces() now recognizes if it is being called on a raw type and grabs the interfaces from the generic type.

2) Each referencetype caches the result of the question 'getDeclaredInterfaces()' this means when a new interface is added to the generic type, the raw and any parameterized forms need their caches clearing.  The set of 'derivativetypes' is stored in a generic type and should point to the raw form and any parameterizations.  The raw form was not being tracked properly, so I fixed that and ensured when the parents are modified that the derivative types have their caches cleared.

I only fixed the interface case, I bet there is something similar for superclasses but that is much much rarer, ignoring for now.

Interestingly it isn't so easy to construct a testcase.  In many scenarios when the isAssignable call fails we fall through to an isCoerceable call and that was passing.  In order for that to fail you need a sophisticated combination of generics (declare parents and itds involved), which then cause the method checking at the end of the coerceable check to fail.
Comment 2 Andrew Clement CLA 2011-04-27 17:01:00 EDT
fixed