[
Date Prev][
Date Next][
Thread Prev][
Thread Next][
Date Index][
Thread Index]
[
List Home]
Re: [aspectj-users] Inferred method having a generic as argument [ARGHHH SOLVED]
|
Hi Andy,
thanks again for taking the time to investigate.
The problem here is a bit different. I have only one interface, that
uses generics :
public interface Converter<T> {
And only one implementation of it :
public class IntegerConverter implements Converter<Integer> {
then I have a class, that does not uses generics, on which i want to add
a property and a method to add a converter. In java i can write :
public void setConverter(Converter converter);
OR
public void setConverter(Converter<?> converter);
OR
public <T> void setConverter(Converter<T> converter);
While in AspectJ the only possible way to write such a method is the
last one, using an unbound <T>; the other two will give a compilation
error when i try to invoke the method :
weavedclassinstance.setConverter(new IntegerConverter())
even if IntegerConverter is a Converter, is a Converter<?> and is a
Converter<T> with T unbound.
I don't know if there is a motivation for AspectJ to accept only the
last notation. Anyway this is quite difficult for a user to understand :)
Simone
Andy Clement wrote:
> If it is a just a generic method being declared on a target type, then
> the syntax is as you have:
>
> public <T> void TextComponent.setConverter(Converter<T> c) {
>
> If it is a method that will share the type variables (and thus any
> value they are bound to) with the target class then the syntax is:
>
> public void TextComponent<T>.setConverter(Converter<T> c) {
>
> as per:
>
> http://www.eclipse.org/aspectj/doc/released/adk15notebook/generics-inAspectJ5.html#inter-type-declarations
>
> So here is a test program that shows that:
> ---
> class Target<T> {
> public void foo(T t) {}
> }
>
> aspect X {
> public void Target<Z>.goo(Z t) {}
>
> public <Y> void Target.hoo(Y t) {}
> }
>
> class ITarget extends Target<Integer> {}
>
> public class Test {
> public static void main(String []argv) {
> ITarget t= new ITarget();
> t.foo(new Integer(5));
>
> // goo can only take Integers
> t.goo(new Integer(6));
> // t.goo("BANG"); // not allowed
>
>
> // Both OK, hoo is just a generic method
> t.hoo(new Integer(6));
> t.hoo("BANG");
> }
> }
> ---
> Notice goo() cannot be invoked with a String because in ITarget the
> type variable has been bound to Integer. hoo() can take anything as
> it is just an ordinary generic method. Also notice that the letters
> for the type variables dont matter - they are matched by position, so
> an ITD on Target with <Z> says 'within this declaration Z matches the
> first type variable declared in Target'. We don't rely on name
> matching here.
>
> Having said all that, there are open bugs for generic ITDs onto types
> when binary weaving, ie. not all from source like the test program
> above, and I would not be surprised if you are hitting one of those
> when trying to ITD onto TextComponent. That's why I asked if you were
> binary weaving in my first reply...
>
> cheers,
> Andy.
>
>
>
>
>
> On 13/04/2008, Simone Gianni <simoneg@xxxxxxxxxx> wrote:
>
>> Hi All,
>> I solved the thing, but it is a bit strange how to solve it :
>>
>> public <T> void TextComponent.setConverter(Converter<T> c) {
>>
>>
>> This is the way it is done in the AspectJ guide to java 5, they always
>> declare the <T> even if, being used just in one place, it is not needed
>> in a similar java-only method and <?> or nothing could be used instead.
>> So, I think this could be a fix in AspectJ, more than just a
>> clarification in the docs :)
>>
>> Simone
>>
>> Simone Gianni wrote:
>> > Hi Andy,
>> > Thanks for taking the time for reviewing my code!
>> >
>> > A couple of differences :
>> > - I inferred also the Converter field
>> > - TextComponent is a binary class i'm weaving without sources
>> >
>> > I'm not in office now, but will try it again later and see if i figure
>> > out by my self where is the difference.
>> >
>> > Simone
>> >
>> > Andy Clement wrote:
>> >
>> >> >From your description it sounds like a bug, but I can't seem to
>> >> recreate it - this file compiles fine for me:
>> >>
>> >> ---
>> >> class TextComponent {
>> >> Converter converter;
>> >> }
>> >>
>> >> interface Converter<T> {
>> >> public T fromString(String value);
>> >> public String toString(T value);
>> >> }
>> >>
>> >> class IntegerConverter implements Converter<Integer> {
>> >> public Integer fromString(String value) { return null; }
>> >> public String toString(Integer value) { return null; }
>> >> }
>> >>
>> >> aspect X {
>> >> Object Converter.component;
>> >>
>> >> public void TextComponent.setConverter(Converter c) {
>> >> this.converter = c;
>> >> c.component = this;
>> >> }
>> >> }
>> >>
>> >>
>> >>
>> >> public class Test {
>> >> public static void main(String []argv) {
>> >> TextComponent tc = new TextComponent() ;
>> >> IntegerConverter ic = new IntegerConverter();
>> >> tc.setConverter(ic);
>> >> }
>> >> }
>> >> ---
>> >>
>> >> Can you tell me what I have done differently to you? Is your
>> >> TextComponent class generic by any chance? Is it a binary weave into
>> >> a library or everything being compiled from source?
>> >>
>> >> Andy.
>> >>
>> >> On 11/04/2008, Simone Gianni <simoneg@xxxxxxxxxx> wrote:
>> >>
>> >>
>> >>> Hello all,
>> >>> I'm moving my first steps in this beautiful world of AOPized Java, but
>> >>> in the last 3 hours I've been facing a problem I don't know how to
>> >>> solve. Probably it is just a stupid thing, but still ....
>> >>>
>> >>> I have a class, called TextComponent, on which I'm trying to add via
>> >>> AspectJ a field and a couple of methods. One of the methods is declared
>> >>> this way in my aspect :
>> >>>
>> >>> public void TextComponent.setConverter(Converter c) {
>> >>> this.converter = c;
>> >>> c.component = this;
>> >>> }
>> >>>
>> >>> Now, Converter is a generic interface :
>> >>>
>> >>> public interface Converter<T> {
>> >>>
>> >>> public T fromString(String value);
>> >>>
>> >>> public String toString(T value);
>> >>>
>> >>> }
>> >>>
>> >>>
>> >>> Which then has an implementation :
>> >>>
>> >>> public class IntegerConverter implements Converter<Integer> {
>> >>> ....
>> >>> }
>> >>>
>> >>>
>> >>> Now, I weave the project containing TextComponent, i get the method
>> >>> added, but then when i try to do :
>> >>>
>> >>> TextComponent tc = new TextComponent();
>> >>> IntegerConverter ic = new IntegerConverter();
>> >>> tc.setConverter(ic);
>> >>>
>> >>> I get an error, both from AJDT inside Eclipse and from ajc invoked in
>> >>> the Maven build. The error is :
>> >>>
>> >>> The method setConverter(Converter<T>) in the type TextComponent is not
>> >>> applicable for the arguments (IntegerConverter)
>> >>>
>> >>> Mh, I tried this on a plain class, instead than on an inferred method,
>> >>> just to make sure I was not missing something in the generics field. I
>> >>> also tried to declare the method differently (like
>> >>> setConverter(Converter<?> c) etc..) .. but still it does not work.
>> >>>
>> >>> Declaring it as setConverter(Object c) and then casting c to a Converter
>> >>> (or Converter<?>) works perfectly.
>> >>>
>> >>> I'm using version 1.5.4 or AspectJ.
>> >>>
>> >>>
>> >>> Any idea?
>> >>>
>> >>> Simone
>> >>> _______________________________________________
>> >>> aspectj-users mailing list
>> >>> aspectj-users@xxxxxxxxxxx
>> >>> https://dev.eclipse.org/mailman/listinfo/aspectj-users
>> >>>
>> >>>
>> >>>
>> >> _______________________________________________
>> >> aspectj-users mailing list
>> >> aspectj-users@xxxxxxxxxxx
>> >> https://dev.eclipse.org/mailman/listinfo/aspectj-users
>> >>
>> >>
>> >
>> > _______________________________________________
>> > aspectj-users mailing list
>> > aspectj-users@xxxxxxxxxxx
>> > https://dev.eclipse.org/mailman/listinfo/aspectj-users
>> >
>>
>> _______________________________________________
>> aspectj-users mailing list
>> aspectj-users@xxxxxxxxxxx
>> https://dev.eclipse.org/mailman/listinfo/aspectj-users
>>
>>
> _______________________________________________
> aspectj-users mailing list
> aspectj-users@xxxxxxxxxxx
> https://dev.eclipse.org/mailman/listinfo/aspectj-users
>