1
0
Fork 0

Subtypes now inherit public static members from their supertype

closure/master
Mike Gerwitz 2011-04-05 23:11:25 -04:00
parent a1ed610681
commit fad503422e
2 changed files with 102 additions and 2 deletions

View File

@ -203,13 +203,20 @@ exports.build = function extend()
// set up the new class // set up the new class
var new_class = createCtor( cname, abstract_methods, members ); var new_class = createCtor( cname, abstract_methods, members );
attachStatic( new_class, static_members ); // closure to hold static initialization to be used later by subtypes
var staticInit = function( ctor )
{
attachStatic( ctor, static_members, base );
}
staticInit( new_class );
attachPropInit( prototype, prop_init, members, class_id ); attachPropInit( prototype, prop_init, members, class_id );
new_class.prototype = prototype; new_class.prototype = prototype;
new_class.constructor = new_class; new_class.constructor = new_class;
new_class.___$$props$$ = prop_init; new_class.___$$props$$ = prop_init;
new_class.___$$methods$$ = members; new_class.___$$methods$$ = members;
new_class.___$$sinit$$ = staticInit;
// We reduce the overall cost of this definition by defining it on the // We reduce the overall cost of this definition by defining it on the
// prototype rather than during instantiation. While this does increase the // prototype rather than during instantiation. While this does increase the
@ -558,8 +565,16 @@ function attachPropInit( prototype, properties, members, cid )
* *
* @return {undefined} * @return {undefined}
*/ */
function attachStatic( ctor, members ) function attachStatic( ctor, members, base )
{ {
// "inherit" the parent's static members by running the parent's static
// initialization method
var baseinit = base.___$$sinit$$;
if ( baseinit )
{
baseinit( ctor );
}
// copy over public static members // copy over public static members
util.copyTo( ctor, members[ 'public' ] ); util.copyTo( ctor, members[ 'public' ] );
} }

View File

@ -201,3 +201,88 @@ var common = require( './common' ),
); );
} )(); } )();
/**
* We don't have the benefit of static members being part of the prototype
* chain. Inheritance is not automatic. This test deals only with ensuring that
* *public* static members are inherited by subtypes.
*/
( function testPublicStaticMembersAreInheritedBySubtypes()
{
var def = {
'public static foo': 'val',
'public static func': function() {},
'public bla': 'moo',
};
// also test getters/setters if supported
if ( !fallback )
{
Object.defineProperty( def, 'public static bar', {
get: function() {},
set: function() {},
enumerable: true,
} );
}
var baz = 'foobar',
Foo = builder.build( def ),
// extends from the parent and adds an additional
SubFoo = builder.build( Foo, { 'public static baz': baz } ),
// simply extends from the parent (also serves as a check to ensure that
// static members of *all* parents are inherited, not just the
// immediate)
SubSubFoo = builder.build( SubFoo, {} )
;
// properties
assert.equal( SubFoo.foo, Foo.foo,
"Public static properties are inherited by subtypes"
);
assert.equal( SubSubFoo.foo, Foo.foo,
"Public static properties are inherited by sub-subtypes"
);
// methods
assert.deepEqual( SubFoo.func, Foo.func,
"Public static methods are inherited by subtypes"
);
assert.deepEqual( SubSubFoo.func, Foo.func,
"Public static methods are inherited by sub-subtypes"
);
// merge
assert.equal( SubFoo.baz, baz,
"Subtypes contain both inherited static members as well as their own"
);
// getters/setters (if supported by engine)
if ( !fallback )
{
var super_data = Object.getOwnPropertyDescriptor( Foo, 'bar' ),
sub_data = Object.getOwnPropertyDescriptor( SubFoo, 'bar' ),
sub_sub_data = Object.getOwnPropertyDescriptor( SubFoo, 'bar' )
;
// getters
assert.deepEqual( super_data.get, sub_data.get,
"Public static getters are inherited by subtypes"
);
assert.deepEqual( super_data.get, sub_sub_data.get,
"Public static getters are inherited by sub-subtypes"
);
// setters
assert.deepEqual( super_data.set, sub_data.set,
"Public static setters are inherited by subtypes"
);
assert.deepEqual( super_data.set, sub_sub_data.set,
"Public static setters are inherited by sub-subtypes"
);
}
} )();