Community
Participate
Working Groups
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.
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.
fixed