1
0
Fork 0
easejs/lib
Mike Gerwitz d9b86c1544
Support for trait class supertype overrides
Traits can now override methods of their class supertypes.  Previously, in
order to override a method of some class `C` by mixing in some trait `T`,
both had to implement a common interface.  This had two notable downsides:

  1. A trait that was only compatible with details of `C` could only work
     with `C#M` if it implemented an interface `I` that declared `I#M`.
     This required the author of `C` to create interfaces where they would
     otherwise not be necessary.

  2. As a corollary of #1---since methods of interfaces must be public, it
     was not possible for `T` to override any protected method of `C`; this
     meant that `C` would have to declare such methods public, which may
     break encapsulation or expose unnecessary concerns to the outside
     world.

Until documentation is available---hopefully in the near future---the test
cases provide detailed documentation of the behavior.  Stackable traits work
as you would expect:

```javascript
var C = Class(
{
    'virtual foo': function()
    {
        return 'C';
    },
} );

var T1 = Trait.extend( C,
{
    'virtual abstract override foo': function()
    {
        return 'T1' + this.__super();
    },
} );

var T2 = Trait.extend( C,
{
    'virtual abstract override foo': function()
    {
        return 'T2' + this.__super();
    },
} );

C.use( T1 )
    .use( T1 )
    .use( T2 )
    .use( T2 )
    .foo();
// result: "T2T2T1T1C"
```

If the `override` keyword is used without `abstract`, then the super method
is statically bound to the supertype, rather than being resolved at runtime:

```javascript
var C = Class(
{
    'virtual foo': function()
    {
        return 'C';
    },
} );

var T1 = Trait.extend( C,
{
    'virtual abstract override foo': function()
    {
        return 'T1' + this.__super();
    },
} );

var T2 = Trait.extend( C,
{
    // static override
    'virtual override foo': function()
    {
        return 'T2' + this.__super();
    },
} );

C.use( T1 )
    .use( T1 )
    .use( T2 )
    .use( T2 )
    .foo();
// result: "T2C"
```

This latter form should be discouraged in most circumstances (as it prevents
stackable traits), but the behavior is consistent with the rest of the
system.

Happy hacking.
2015-10-24 23:53:23 -04:00
..
util [copyright] Copyright update 2015-05-28 01:01:51 -04:00
warn [copyright] Copyright update 2015-05-28 01:01:51 -04:00
ClassBuilder.js Support for trait class supertype overrides 2015-10-24 23:53:23 -04:00
FallbackMemberBuilder.js [copyright] Copyright update 2015-05-28 01:01:51 -04:00
FallbackVisibilityObjectFactory.js [copyright] Copyright update 2015-05-28 01:01:51 -04:00
MemberBuilder.js Extracted warning handlers into their own prototypes 2014-06-11 23:42:20 -04:00
MemberBuilderValidator.js Support for trait class supertype overrides 2015-10-24 23:53:23 -04:00
MethodWrapperFactory.js [copyright] Copyright assignment to the FSF 2014-04-09 19:05:07 -04:00
MethodWrappers.js method.super references now ES3-compatible 2014-08-07 22:24:25 -04:00
Trait.js Support for trait class supertype overrides 2015-10-24 23:53:23 -04:00
VisibilityObjectFactory.js No longer using __dirname in requires 2014-04-20 21:11:38 -04:00
VisibilityObjectFactoryFactory.js [copyright] Copyright update 2015-05-28 01:01:51 -04:00
class.js [copyright] Copyright update 2015-05-28 01:01:51 -04:00
class_abstract.js No longer using __dirname in requires 2014-04-20 21:11:38 -04:00
class_final.js [copyright] Copyright update 2015-05-28 01:01:51 -04:00
interface.js Class is not a needed dependency for Interface 2015-05-28 01:23:52 -04:00
prop_parser.js Alias `constructor` member to `__construct` 2015-09-16 00:02:00 -04:00
util.js Added Global prototype 2014-06-11 23:08:48 -04:00
version.js.in [copyright] Copyright assignment to the FSF 2014-04-09 19:05:07 -04:00
warn.js Extracted warning handlers into their own prototypes 2014-06-11 23:42:20 -04:00