I think, AspectJ should support the super.m() call part of the proposal restricted to situations where the super.m() can be unambiguously deduced. Essentially, the m() method must be *implemented* in only one of the direct parent types (class or interfaces with implementation-introducing aspects). We can leave out the A.super.m() kind of support for now. I believe that will cover the majority of the cases that require augmentative override. -Ramnivas
On Sat, Nov 1, 2008 at 5:32 PM, Dave Whittaker <[EMAIL PROTECTED]> wrote: > Thanks Ramnivas. It's good to know that I'm not the only one who is > interested in this type of feature. Since a few years have passed since > that thread ended, what are your thoughts on how this could best be > accomplished now? > > > On Oct 31, 2008, at 4:17 PM, Ramnivas Laddad wrote: > > Dave, > > I had the same question a long time back, so I am pasting that discussion > (obtained from the old list archive at > http://dev.eclipse.org/viewcvs/indextech.cgi/~checkout~/aspectj-home/archives/users.zip; > I couldn't find a direct link to posts in it on the Internet). > The follow ups have some ideas and flaws with them, should we consider this > feature once again. > > -Ramnivas > > == Orig == > From [EMAIL PROTECTED] Mon Sep 10 14:14:04 2001 > Received: from alpha.xerox.com (alpha.Xerox.COM [13.1.64.93]) > by aspectj.org (8.9.3/8.8.7) with SMTP id OAA10522 > for <[EMAIL PROTECTED]>; Mon, 10 Sep 2001 14:14:04 -0700 > Received: from web10403.mail.yahoo.com ([216.136.130.95]) by > alpha.xerox.com with SMTP id <130077(1)>; Mon, 10 Sep 2001 14:19:22 PDT > Message-ID: <[EMAIL PROTECTED]> > Received: from [207.181.251.173] by web10403.mail.yahoo.com via HTTP; Mon, > 10 Sep 2001 14:19:22 PDT > Date: Mon, 10 Sep 2001 14:19:22 PDT > From: Ramnivas Laddad <[EMAIL PROTECTED]> > Subject: Behavior of super.method() w.r.t. introduced method in an > interface > To: [EMAIL PROTECTED] > MIME-Version: 1.0 > Content-Type: text/plain; charset=us-ascii > Sender: [EMAIL PROTECTED] > Errors-To: [EMAIL PROTECTED] > X-BeenThere: [EMAIL PROTECTED] > X-Mailman-Version: 2.0.5 > Precedence: bulk > List-Help: <mailto:[EMAIL PROTECTED]> > List-Post: <mailto:[EMAIL PROTECTED]> > List-Subscribe: <http://aspectj.org/mailman/listinfo/users>, > <mailto:[EMAIL PROTECTED]> > List-Id: <users.aspectj.org> > List-Unsubscribe: <http://aspectj.org/mailman/listinfo/users>, > <mailto:[EMAIL PROTECTED]> > List-Archive: <http://aspectj.org/pipermail/users/> > > Hello, > > With AspectJ, a method implementation may be introduced to an > interface. I have a question related to the way it behaves and > wondering if it is the right behavior/specification or a bug? > > For example, consider: > > interface MyIf { > } > > class MyClass implements MyIf { > } > > aspect IntroduceFooToMyIf { > public void MyIf.foo() { > System.out.println("This is MyIf.foo()"); > } > } > > This results in a foo() in MyIf and foo() with implementation > in MyClass. So far so good. > > Now I change MyClass to: > class MyClass implements MyIf { > public void foo() { > System.out.println("This is MyClass.foo()"); > } > } > > This result in not replacing MyClass.foo() by one specified in aspect. > This is ok too because, MyClass.foo() overrides introduced > MyIf.foo(). > > Now, I change MyClass to: > class MyClass implements MyIf { > public void foo() { > super.foo(); // <------- !!! > System.out.println("This is MyClass.foo()"); > } > } > > I get a compiler error, saying there is no foo() in super (MyIf). > Now, this would be correct from pure Java point-of-view. But > with AspectJ, I expected to result in _equivalent_ of > class MyClass implements MyIf { > public void foo() { > System.out.println("This is MyIf.foo()"); <------- > System.out.println("This is MyClass.foo()"); > } > } > > That is, super.foo() should have been replaced with the introduced > code. In other words, introducing a method in MyIf should have > behaved as if that method was indeed there. > > The replaced code for super.foo() would probably have to be coded > as a method (just like other code in AspectJ) so that a "return" > statement in it will not result in an incorrect behavior. But, > that's just details. > > I am interested knowing your opinions. > > Thanks and regards. > > -Ramnivas > > == Jim Hugunin's reply == > > This is a great question. What it boils down to is whether or not > "super.m()" in AspectJ should be allowed to see concrete methods in > interfaces or not. In AspectJ-1.0beta1 the answer is no. super.m() has > exactly the same behavior as in pure Java, and it can only see methods in a > super class -- NOT in a super-interface. > > <The rest of this message is my personal opinion and not necessarily those > of the rest of the AspectJ team.> > > I think that you're probably right and that super.m() should be allowed to > access concrete methods in interfaces. However, I don't think that we > should add this functionality until after AspectJ-1.0. Multiple-inheritance > is a well-known quagmire of complexity in OO language design, and is > something that should be approached carefully. I'd like to have some calm > time to think carefully about any proposal that would expand the power (and > the complexity) of AspectJ's current very limited and simple form of > multiple-inheritance. As an example of increasing complexity, if we provide > the power you suggest here, I can easily see people asking for qualified > super calls to disambiguate multiply inherited methods of the same name, > something like "ColorMixin.super.getColor()". > Fortunately, your proposal for increasing the power of super can be added > to AspectJ-1.1 or some other future version in a mostly backwards compatible > way. Therefore, my recommendation is that we mostly table this discussion > until after AspectJ-1.0.0 is released. > > The part that I'd like to talk about today is the mostly-backwards > compatible issue. In order to be able to add this proposal in a completely > backwards compatible way to a future version of AspectJ, there is one > situation that we are not treating as an error that we should be treating > so. I believe that the following (currently legal in AspectJ-1.0beta1) > program should be illegal in AspectJ-1.0: > > class SuperC { > public void m() { ... } > } > > interface I { > aspect BODY { > public void I.m() { ... } > } > } > > class SubC extends SuperC implements I { > public void m() { > super.m(); //ERROR: ambiguous reference to either I.m() or SuperC.m() > } > } > > This change to AspectJ-1.0 would give us the most room to design a clean > solution for super and multiple-inheritance at some future time. It might > break some existing AspectJ-1.0beta1 programs; however, I don't believe the > odds of that are very high. If you have existing code or designs that this > would break, please let me know. > > -Jim > > == My follow up == > Jim, > > Thanks for replying. > > I think by simply allowing interfaces to have introduced-implemented > -methods, the whole problem of multiple-inheritance is already > opened. > > I have two particular problems: > The first one is a practical one. The other is somewhat academic > (assuming it is not common for a class to implemente multiple > interface with a method of exacly same signature), although important > to consider for the final solution. > > 1. The situation I was trying to use will not be possible > (or atleast elegantly possible) unless super.method() > problem is fixed. > > I have an interface and a default implementation (implemented as > BODY aspect) of it. In most cases, default is fine. There are, > however, a few cases where I need to augment the behavior. > > Unless I can call super.method(), such augmentation is not possible. > > 2. You are right. My next question was going to be about > possibility of "ColorMixin.super.getColor()" :-) > > Consider for example, > public interface A { > public void foo(); > > static aspect BODY { > public void foo() { > System.out.println("A.foo()"); > } > } > } > > public interface B { > public void foo(); > > static aspect BODY { > public void foo() { > System.out.println("B.foo()"); > } > } > } > > public class AB implements A, B { > // No foo() implemented here > } > > Current AspectJ implementation chooses to not introduce foo() in > AB at all. Which is fine, considering that it would not be possible > to determine how foo's implemetation should be implemented. > > However, I would expect AspectJ to allow adding foo() and let user > choose which implementations to inherit and in what order. > Something like: > public void foo() { > A.super.foo(); > // some more code > B.super.foo(); > } > > Thanks and regards. > > -Ramnivas > > == Gregor Kiczales' reponse == > Aargh! our goal was to stear clear of as many of the hard multiple > inheritance (MI) issues as possible. Here's a way of thinking about > the language design that I _think_ can help guide us here. > > Our theory about introduction of public methods is that: > > - its a rare > - it should probably only be done when introducing an > implementation for a well-known interface > > In addition, remember that in our language we have advice. > > it seems like we can drive our answer to this issue off of > these combined facts, and that the answer, at least for now, is > that we do not support the full case of _multiple_ inheritance. > We support a weaker thing, which allows a class to get orthogonal > sets of methods from classes and interfaces. > > I'm less sure about whether we support overiding of methods inherited > from an interface. > > So if you someone wants to do the additive multiple inheritance thing > they can use around/before/after. That means we have less need for the > full power of MI. > > I think what I'm saying is that: > > - we should signal an error in this case: > > > > > > > class SuperC { > > > public void m() { ... } > > > } > > > > > > interface I { > > > aspect BODY { > > > public void I.m() { ... } > > > } > > > } > > > > > > class SubC extends SuperC implements I { > > > public void m() { > > > super.m(); //ERROR: ambiguous reference to either I.m() or > > > SuperC.m() > > > } > > > } > > - and we could allow super.method() to work in the simple case, > but we could also prohibit it, at least for now, and point > people to around. > > > Ramnivas, how does this rationale and set of proposed design decisions > fit for you. Can you use advice the way I mention to get the MI effect > you need?. > > == end responses == > > On Fri, Oct 31, 2008 at 11:27 AM, Dave Whittaker <[EMAIL PROTECTED]> wrote: > >> I've been using ITDs as a big time saver in defining common actions that >> can be performed on objects. This is great in that the default code defined >> in the aspect applies a majority of the time. The problem is that in the >> cases where it doesn't apply, almost every time what I want to do is extend >> the code defined in the ITD and do something before and/or after the default >> rather than completely replace it, like a typical object hierarchy would do >> with a call to super.method(), and I can't find a good way to do that with >> ITDs. The best way I've come up with to handle this is to create an >> abstract superclass from which the interfaces are implemented so the >> abstract class inherits the default functionality and then in the concrete >> subclass I can call super.method(). >> >> I had posted a similar message a few months ago and someone suggested >> placing a second method in each ITD interface that would just be used to >> inherit the default functionality, ie: >> >> public void method(); >> >> public void _method(); >> >> and then in the ITD _method would define the code and method() would just >> delegate to _method(), but that just seems like an awful lot of ugly code to >> perform a simple pattern, which is very anti AspectJ. >> >> So I guess my question is.... is there a better way to do this? If not, >> shouldn't their be? I'd be satisfied with a way to call the method on the >> aspect, but since it's written out as something like public static void >> ajc$interMethod$... even if I knew the naming pattern and it wasn't subject >> to change those calls wouldn't lead to very readable code. I realize I >> could also use before/after/around advise on the method but that adds a >> whole new issue of what order the advice will fire in if the object >> structure becomes complex. So has this been an issue for anyone else? If >> there isn't a good solution, is there interest from any one else in a new >> feature to make this type of thing easier? >> >> _______________________________________________ >> aspectj-users mailing list >> [email protected] >> https://dev.eclipse.org/mailman/listinfo/aspectj-users >> > > _______________________________________________ > aspectj-users mailing list > [email protected] > https://dev.eclipse.org/mailman/listinfo/aspectj-users > > > > _______________________________________________ > aspectj-users mailing list > [email protected] > https://dev.eclipse.org/mailman/listinfo/aspectj-users > >
_______________________________________________ aspectj-users mailing list [email protected] https://dev.eclipse.org/mailman/listinfo/aspectj-users
