Subtypes now inherit public static members from their supertype
parent
a1ed610681
commit
fad503422e
|
@ -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' ] );
|
||||||
}
|
}
|
||||||
|
|
|
@ -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"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
} )();
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue