Thanks Andy.. On Sun, Nov 2, 2008 at 5:06 PM, Andy Clement <[EMAIL PROTECTED]>wrote:
> sounds like it could be a bug to me, i will take a look before 1.6.3 is > finished. > > > 2008/11/2 Fernando Rubbo <[EMAIL PROTECTED]> > >> Hi Eric, >> >> Thanks for your help.. I've created an bug for this >> https://bugs.eclipse.org/bugs/show_bug.cgi?id=253109 >> >> Thanks, >> Fernando >> >> >> On Sun, Nov 2, 2008 at 3:41 PM, Eric Bodden <[EMAIL PROTECTED]>wrote: >> >>> Thanks for the clarification. To me this seems like a bug in the sense >>> that it is certainly a violation of the "principle of least >>> astonishment" ;-) >>> >>> If I was you I would open a bug report, even if it's just for the sake >>> for clarifying (non?)existing documentation. >>> >>> Eric >>> >>> 2008/11/2 Fernando Rubbo <[EMAIL PROTECTED]>: >>> > Hi Eric, >>> > >>> > first of all, thanks for your fast response. >>> > Please, see the comments inline >>> > >>> >> *However* no List<Y> is ever subtype of a List<X> for any two >>> >> different concrete types X and Y, regardless of whether Y is a subtype >>> >> of X! As a consequence, also List<Integer> cannot possibly be an >>> >> ArrayList<Number>. >>> > >>> > For Java I 100% agree with you. >>> > For AspectJ what I've seen so far for args(..) and after(..) >>> returning(..) >>> > constructions is that it does not follow the Java subtyping for generic >>> > types. Actually it would be a lot easer to understand if they had used >>> the >>> > same behavior, but... >>> > Note that the same issue happens also for <? extends Number>. >>> > >>> >> What surprises me is the fact that the first advice in BC matches. >>> >> Actually this should not match either, I believe, because also a >>> >> List<Integer> can never be a List<Number>. I am not sure... could this >>> >> have to do with type erasure? >>> > >>> > If args(..) constructions followed the Java subtyping, again, I would >>> agree >>> > 100% with you. >>> > But according to some experiments I did, unfortunately it does not work >>> at >>> > the same way (may be a bug, I don't know). >>> > >>> > About the erasure.. >>> > In the byte code on the signature attribute, the Java compiler stores >>> the >>> > generic information. So it is possible to the AspectJ compiler to check >>> the >>> > right generic type to match. >>> > // Method descriptor #15 (Ljava/util/List;)V >>> > // Signature: (Ljava/util/List<Ljava/lang/Integer;>;)V >>> > // Stack: 4, Locals: 3 >>> > void m(java.util.List arg0); >>> > >>> > For me it seems to be understandable why they have decided to implement >>> the >>> > args(..) stuff in that way (although I don't like it). If the method m >>> > receives a List of integers in the Java code, it will cause no runtime >>> error >>> > (after type erasure) into the advice when an integer be assign to >>> number >>> > variable. but, what does not make sense for me is: When AspectJ uses a >>> > runtime test to check if it is an ArrayList the matching is totally >>> > different. I've shown only one example, but there are others cases >>> where it >>> > change the behavior because of the runtime test. Does not make sense. >>> > >>> > I need to understand if this design were planned by the AspectJ >>> developer or >>> > if it is a bug. If it were planned, what is the correct semantics for >>> this? >>> > how args(..) should work? Shouldn't be better (and a lot easer) if it >>> > followed the same Java subtyping? >>> > >>> > Thanks a lot, >>> > Fernando Rubbo >>> > >>> >> >>> >> >>> >> Eric >>> >> >>> >> 2008/11/1 Fernando Rubbo <[EMAIL PROTECTED]>: >>> >> > Hi all, >>> >> > >>> >> > I have a question about args(..) and after(..) returning(..) >>> >> > construction >>> >> > semantics when generic types are applied. >>> >> > Actually, it is not clear for me how it is working and why it is >>> working >>> >> > this way. Let me show an example to help to depict my thoughts. >>> >> > >>> >> > class C{ >>> >> > void m(List<Integer> e){} >>> >> > } >>> >> > >>> >> > aspect AC { >>> >> > void around():execution(* C.*(..)) && args(List<Integer>) {} // >>> >> > Matchs >>> >> > C.m >>> >> > void around():execution(* C.*(..)) && args(ArrayList<Integer>) >>> {} // >>> >> > Unchecked match C.m - uses rRuntime check >>> >> > } >>> >> > >>> >> > In this simple example, it is easy to notice that both advices will >>> >> > match >>> >> > the method C.m. Note that the second one will make a runtime test to >>> >> > check >>> >> > if the method caller has passed, as a parameter, an ArrayList >>> object. >>> >> > Since >>> >> > actual type parameters are erasured during compile-time, the AspectJ >>> >> > compiler just warn the programmer that this is an unchecked match >>> >> > (however, >>> >> > it is easy to notice that in this case it will never cause a >>> >> > ClassCastException during runtime). >>> >> > >>> >> > To show my question, take a look on the below aspect: >>> >> > >>> >> > aspect BC { >>> >> > void around():execution(* C.*(..)) && args(List<Number>) {} // >>> >> > Matchs >>> >> > C.m >>> >> > void around():execution(* C.*(..)) && args(ArrayList<Number>) {} >>> // >>> >> > DOES >>> >> > NOT MATCH C.m >>> >> > } >>> >> > >>> >> > This is exactly the same aspect I've shown before, just changing >>> type >>> >> > parameter from Integer to Number in both args(..) constructions. >>> >> > Note that in BC aspect, the first advice follows the same semantics >>> than >>> >> > the >>> >> > AC one, and then, matches the method C.m. However, the second >>> advice >>> >> > DOES >>> >> > NOT follow the same semantics (that the AC one), and then, DOES NOT >>> >> > MATCH >>> >> > C.m AT ALL. >>> >> > >>> >> > My question is: >>> >> > Should not the second advice of BC aspect match the method C.m and >>> use a >>> >> > runtime check to verify if the given parameter is an ArrayList? Some >>> one >>> >> > can >>> >> > explain to me why the second advice is not matching the method C.m? >>> >> > >>> >> > The same problem is found in the following using the <? extends >>> Number> >>> >> > aspect CC { >>> >> > void around():execution(* C.*(..)) && args(List<? extends >>> Number>) >>> >> > {} >>> >> > // Matchs C.m >>> >> > void around():execution(* C.*(..)) && args(ArrayList<? extends >>> >> > Number>) >>> >> > {} // DOES NOT MATCH C.m >>> >> > } >>> >> > >>> >> > >>> >> > There exists a formal description saying how args(..) and after(..) >>> >> > returning (..) must works? >>> >> > >>> >> > >>> >> > Thanks in advance >>> >> > Fernando Rubbo >>> >> > >>> >> > _______________________________________________ >>> >> > aspectj-users mailing list >>> >> > aspectj-users@eclipse.org >>> >> > https://dev.eclipse.org/mailman/listinfo/aspectj-users >>> >> > >>> >> > >>> >> >>> >> >>> >> >>> >> -- >>> >> Eric Bodden >>> >> Sable Research Group, McGill University, Montréal, Canada >>> >> Got an interesting job offer? http://www.bodden.de/hire-me/ >>> >> _______________________________________________ >>> >> aspectj-users mailing list >>> >> aspectj-users@eclipse.org >>> >> https://dev.eclipse.org/mailman/listinfo/aspectj-users >>> > >>> > >>> > _______________________________________________ >>> > aspectj-users mailing list >>> > aspectj-users@eclipse.org >>> > https://dev.eclipse.org/mailman/listinfo/aspectj-users >>> > >>> > >>> >>> >>> >>> -- >>> Eric Bodden >>> Sable Research Group, McGill University, Montréal, Canada >>> Got an interesting job offer? http://www.bodden.de/hire-me/ >>> _______________________________________________ >>> aspectj-users mailing list >>> aspectj-users@eclipse.org >>> https://dev.eclipse.org/mailman/listinfo/aspectj-users >>> >> >> >> _______________________________________________ >> aspectj-users mailing list >> aspectj-users@eclipse.org >> https://dev.eclipse.org/mailman/listinfo/aspectj-users >> >> > > _______________________________________________ > aspectj-users mailing list > aspectj-users@eclipse.org > https://dev.eclipse.org/mailman/listinfo/aspectj-users > >
_______________________________________________ aspectj-users mailing list aspectj-users@eclipse.org https://dev.eclipse.org/mailman/listinfo/aspectj-users