Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
Re: [aspectj-users] declare parents and generic type parameters

Hey,


So, it's pretty clear that declare parents can't faithfully reproduce normal inheritance for generic type parameters.  Which leaves me wondering:

1. Is it supposed to?
2. Is that even possible?
3. Did this sort of thing really work once upon a time (around about AspectJ 1.6) and then stop working, or am I just imagining it?

To faithfully reproduce the inheritance with the declare parents statement, I think the declare parents statements needs to do the same thing as the original declaration in the source when you have explicit extends. So your:

declare parents: Manager extends SuperManager<BaseObject>;

is the right thing if your goal is to extract the inheritance into an aspect.  Changing that to just:

declare parents: Manager extends SuperManager

means exactly what it means if you had that declaration in the original non-aspect version. ie. the raw type of SuperManager is used as the superclass and T therefore becomes Object. Obviously the code will still do the same thing at runtime either way, i.e. the runtime type of the return value of getSuperInstance() will be a BaseObject. But you can’t write:

BaseObject bo = new Manager().getSuperInstance();

if your Manager does not extend SuperManager<BaseObject>

It is possible something funky used to work and it has been tightened up as fixes have gone in (that is, it never should have worked).

What you would seem to need is that the declare parents infers the type bound for SuperManager based on the differing return values for getInstance() but AspectJ has never done that.  You could use a generic aspect, perhaps:

abstract aspect ThingExtender<Z> {
  declare parents: Manager extends SuperManager<Z>;
  declare parents: BaseObject extends SuperThing;
}

aspect BaseObjectVariant extends ThingExtender<BaseObject> {}

But it isn’t clear to me that’ll meet all your requirements.

cheers,
Andy

On Feb 19, 2016, at 12:20 AM, Jaime Metcher <jmetcher@xxxxxxxxx> wrote:

Hello List,

I've been ruminating about some the problems I've been having with ITD's, and I'm speculating that some of them at least are due to a more rigorous treatment of generics in the last couple of major versions.  More specifically, I don't think it's possible for declare parents to reproduce an inheritance hierachy involving generics with type parameters.

To illustrate, lets consider this class hierarchy.  We have a class and superclass:

public class SuperThing {}
public class BaseObject extends SuperThing {}

And then we have some classes to interact with them:

public abstract class SuperManager<T> {
public T getSuperInstance() {
return getInstance();
}
public abstract T getInstance();
}

public class Manager extends SuperManager<BaseObject> {
public BaseObject getInstance() {
return new BaseObject();
}
}

So then if we call:

new Manager().getSuperInstance();

We get back an instance of type BaseObject, as we'd expect.  The type parameter T turns into BaseObject all the way up the tree.

Now let's replace the top level of inheritance with ITD declare parents statements.  First we remove the explicit inheritance:

public class BaseObject {}
public abstract class Manager {...}

and then reintroduce the inheritance via this aspect:

public aspect ThingExtender {
declare parents: Manager extends SuperManager;
declare parents: BaseObject extends SuperThing;
}

Now, if we call:

new Manager().getSuperInstance();

We get back an instance of type Object.  This is entirely understandable - AspectJ works with the erasure of generic types, and the erasure of T is just Object.

I know I could do:

declare parents: Manager extends SuperManager<BaseObject>;

to fix this particular case.  But in my real project, both Manager and BaseObject have many subclasses themselves, so this solution just pushes the problem down to the next level.

So, it's pretty clear that declare parents can't faithfully reproduce normal inheritance for generic type parameters.  Which leaves me wondering:

1. Is it supposed to?
2. Is that even possible?
3. Did this sort of thing really work once upon a time (around about AspectJ 1.6) and then stop working, or am I just imagining it?

Thanks for listening
Jaime


_______________________________________________
aspectj-users mailing list
aspectj-users@xxxxxxxxxxx
To change your delivery options, retrieve your password, or unsubscribe from this list, visit
https://dev.eclipse.org/mailman/listinfo/aspectj-users


Back to the top