1
0
Fork 0

Writes to public static properties now work properly

closure/master
Mike Gerwitz 2011-04-13 23:06:24 -04:00
parent 44cd8db82d
commit e3c526b89d
2 changed files with 76 additions and 7 deletions

View File

@ -614,13 +614,34 @@ function attachStatic( ctor, members, base, inheriting )
{
ctor.___$$sprops$$ = props;
ctor.$ = function( prop )
// provide a method to access static properties
ctor.$ = function( prop, val )
{
// attempt to return property if it is our own, otherwise look up on
// parent (the parent will look up its parent as well, if necessary)
return props[ 'public' ][ prop ]
|| base.$( prop )
;
// we use hasOwnProperty to ensure that undefined values will not
// cause us to continue checking the parent, thereby potentially
// failing to set perfectly legal values
var has = Object.prototype.hasOwnProperty.call(
props[ 'public' ], prop
);
// if we don't own the property, let the parent(s) handle it
if ( !has )
{
return base.$.apply( this, arguments );
}
// if a value was provided, this method should be treated as a
// setter rather than a getter
if ( val )
{
props[ 'public' ][ prop ] = val;
return;
}
else
{
// return the value
return props[ 'public' ][ prop ];
}
};
}

View File

@ -308,7 +308,9 @@ var common = require( './common' ),
*/
( function testPublicStaticPropertyReferencesAreInheritedBySubtypes()
{
var val = [ 1, 2, 3 ],
var val = [ 1, 2, 3 ],
val2 = [ 'a', 'b', 'c' ],
Foo = builder.build(
{
'public static bar': val,
@ -320,5 +322,51 @@ var common = require( './common' ),
assert.ok( SubFoo.$('bar') === Foo.$('bar'),
"Inherited static properties should share references"
);
// setting a property on Foo should set the property on SubFoo and
// vice-versa
Foo.$( 'bar', val2 );
assert.deepEqual( Foo.$( 'bar' ), val2,
"Can set static property values"
);
assert.ok( Foo.$( 'bar' ) === SubFoo.$( 'bar' ),
"Setting a static property value on a supertype also sets the value " +
"on subtypes"
);
SubFoo.$( 'bar', val );
assert.ok( Foo.$( 'bar' ) === SubFoo.$( 'bar' ) );
} )();
/**
* Static members do not have the benefit of prototype chains. We must
* implement our own means of traversing the inheritance tree. This is done by
* checking to see if a class has defined the requested property, then
* forwarding the call to the parent if it has not.
*
* The process of looking up the property is very important. hasOwnProperty is
* used rather than checking for undefined, because they have drastically
* different results. Setting a value to undefined (if hasOwnProperty were not
* used) would effectively forward all requests to the base class (since no
* property would be found), thereby preventing it from ever being written to
* again.
*/
( function testSettingsStaticPropertiesToUndefinedWillNotCorruptLookupProcess()
{
var val = 'baz',
Foo = builder.build(
{
'public static foo': '',
} )
;
Foo.$( 'foo', undefined );
Foo.$( 'foo', val );
assert.equal( Foo.$( 'foo' ), val,
"Setting static property to undefined does not corrupt lookup process"
);
} )();