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

Reply via email to