1
0
Fork 0

Implemented private static properties

closure/master
Mike Gerwitz 2011-05-13 00:55:09 -04:00
parent 9b20cdff48
commit 775438c1b6
2 changed files with 57 additions and 2 deletions

View File

@ -693,7 +693,15 @@ function attachStatic( ctor, members, base, inheriting )
// Determine if we were invoked in the context of a class. If // Determine if we were invoked in the context of a class. If
// so, use that. Otherwise, use ourself. // so, use that. Otherwise, use ourself.
context = ( this.___$$sprops$$ ) ? this : ctor context = ( this.___$$sprops$$ ) ? this : ctor,
// We are in a subtype if the context does not match the
// constructor. This works because, when invoked for the first
// time, this method is not bound to the constructor. In such a
// case, we default the context to the constructor and pass that
// down the line to each recursive call. Therefore, recursive
// calls to subtypes will have a context mismatch.
in_subtype = ( context !== ctor )
; ;
// Attempt to locate the property. First, we check public. If not // Attempt to locate the property. First, we check public. If not
@ -703,7 +711,14 @@ function attachStatic( ctor, members, base, inheriting )
found = has.call( props[ 'public' ], prop ) && 'public'; found = has.call( props[ 'public' ], prop ) && 'public';
if ( !found && sprop_internal ) if ( !found && sprop_internal )
{ {
found = has.call( props[ 'protected' ], prop ) && 'protected'; // Check for protected/private. We only check for private
// properties if we are not currently checking the properties of
// a subtype. This works because the context is passed to each
// recursive call.
found = has.call( props[ 'protected' ], prop ) && 'protected'
|| !in_subtype
&& has.call( props[ 'private' ], prop ) && 'private'
;
} }
// if we don't own the property, let the parent(s) handle it // if we don't own the property, let the parent(s) handle it

View File

@ -594,6 +594,9 @@ var common = require( './common' ),
var val = 'foo', var val = 'foo',
Foo = builder.build( Foo = builder.build(
{ {
'private static prop': val,
// the same rules should apply to methods // the same rules should apply to methods
'private static baz': function() 'private static baz': function()
{ {
@ -611,6 +614,16 @@ var common = require( './common' ),
{ {
return this.__self.baz(); return this.__self.baz();
}, },
'public static staticGetProp': function()
{
return this.$('prop');
},
'public instGetProp': function()
{
return this.__self.$('prop');
},
} ); } );
assert.equal( Foo.baz, undefined, assert.equal( Foo.baz, undefined,
@ -624,6 +637,14 @@ var common = require( './common' ),
assert.equal( Foo().instBaz(), val, assert.equal( Foo().instBaz(), val,
"Private methods are accessible to instance methods" "Private methods are accessible to instance methods"
); );
assert.equal( Foo.staticGetProp(), val,
"Private static properties are accessible to static methods"
);
assert.equal( Foo().instGetProp(), val,
"Private static properties are accessible to instance methods"
);
} )(); } )();
@ -635,6 +656,7 @@ var common = require( './common' ),
{ {
var Foo = builder.build( var Foo = builder.build(
{ {
'private static prop': 'foo',
'private static priv': function() {}, 'private static priv': function() {},
} ), } ),
@ -644,12 +666,30 @@ var common = require( './common' ),
{ {
return this.priv; return this.priv;
}, },
'public static staticGetProp': function()
{
return this.$('prop');
},
'public instGetProp': function()
{
return this.__self.$('prop');
},
} ) } )
; ;
assert.equal( SubFoo.getPriv(), undefined, assert.equal( SubFoo.getPriv(), undefined,
"Private static methods should not be inherited by subtypes" "Private static methods should not be inherited by subtypes"
); );
assert.equal( SubFoo().instGetProp(), undefined,
"Private static properties should not be inherited by subtypes (inst)"
);
assert.equal( SubFoo.staticGetProp(), undefined,
"Private static properties should not be inherited by subtypes (static)"
);
} )(); } )();