#126 Named super

brian Sat 23 Dec 2006

I fixed a tricky boundary condition regarding how super works when you might be inheriting more than one implementation of a method from your mixins. Fan now supports "named supers" with a syntax of "<type>.super". Let's take a look at some sample code:

mixin X
{
  virtual Str f(Int a) { return "X.f" }
}

mixin Y
{
  virtual Str f(Int a) { return "Y.f" }
}

class A
{
  virtual Str f(Int a) { return "A.f" }
}

class B : A
{
  virtual override Str f(Int a) { return "B.f" }
}

class C : B, Z, Y
{
  virtual override Str f(Int a)
  {
    switch (a)
    {
      case 'C': return "C.f"
      case 'S': return super.f(a)
      case 'B': return B.super.f(a)
      case 'A': return A.super.f(a)
      case 'X': return X.super.f(a)
      case 'Y': return Y.super.f(a)
    }
    throw Err.make
  }
}

In the C.f method notice how we can select which of the four super class implementations of f() to invoke. Couple of rules to keep in mind:

  • An unnamed super is always on your super class, never a super mixin
  • Obviously you can't use a named super on something which isn't one of your super types
  • Named supers allow you to jump up multiple levels of inheritance like C.f does to access A.f (you can't do that in Java)
  • Mixins cannot use unnamed super because that would be a non-virtual call on Obj (which is itself really just a problem with Java's lame rules on invokespecial)
  • Mixins can use named supers on their super mixins

In order to support this feature I've added a new opcode called CallMixinNonVirtual which is easy to implement because it's basically just a direct static call to the Mixin$ implementation class.

Login or Signup to reply.