Implemented protected static members within static methods
- Still not inheritenceclosure/master
parent
a246dd67e0
commit
3c774a7b16
|
@ -234,7 +234,8 @@ exports.build = function extend()
|
||||||
}
|
}
|
||||||
staticInit( new_class, false );
|
staticInit( new_class, false );
|
||||||
|
|
||||||
attachPropInit( prototype, prop_init, members, static_members, class_id );
|
initStaticVisibilityObj( new_class, static_members );
|
||||||
|
attachPropInit( prototype, prop_init, members, new_class, class_id );
|
||||||
|
|
||||||
new_class.prototype = prototype;
|
new_class.prototype = prototype;
|
||||||
new_class.constructor = new_class;
|
new_class.constructor = new_class;
|
||||||
|
@ -533,13 +534,13 @@ function buildMembers(
|
||||||
* @param {Object} properties properties to initialize
|
* @param {Object} properties properties to initialize
|
||||||
*
|
*
|
||||||
* @param {{public: Object, protected: Object, private: Object}} members
|
* @param {{public: Object, protected: Object, private: Object}} members
|
||||||
* @param {{public: Object, protected: Object, private: Object}} static_members
|
|
||||||
*
|
*
|
||||||
* @param {number} cid class id
|
* @param {function() ctor class
|
||||||
|
* @param {number} cid class id
|
||||||
*
|
*
|
||||||
* @return {undefined}
|
* @return {undefined}
|
||||||
*/
|
*/
|
||||||
function attachPropInit( prototype, properties, members, static_members, cid )
|
function attachPropInit( prototype, properties, members, ctor, cid )
|
||||||
{
|
{
|
||||||
util.defineSecureProp( prototype, '__initProps', function( inherit )
|
util.defineSecureProp( prototype, '__initProps', function( inherit )
|
||||||
{
|
{
|
||||||
|
@ -575,7 +576,7 @@ function attachPropInit( prototype, properties, members, static_members, cid )
|
||||||
);
|
);
|
||||||
|
|
||||||
// give internal methods access to protected/private static members
|
// give internal methods access to protected/private static members
|
||||||
initStaticVisibilityObj.call( this, vis, static_members );
|
vis.__self = ctor.___$$svis$$;
|
||||||
|
|
||||||
// provide a means to access the actual instance (rather than the
|
// provide a means to access the actual instance (rather than the
|
||||||
// property/visibility object) internally (this will translate to
|
// property/visibility object) internally (this will translate to
|
||||||
|
@ -592,26 +593,25 @@ function attachPropInit( prototype, properties, members, static_members, cid )
|
||||||
/**
|
/**
|
||||||
* Creates and populates the static visibility object
|
* Creates and populates the static visibility object
|
||||||
*
|
*
|
||||||
* This function should be called in the context of the class.
|
* @param {function()} class
|
||||||
*
|
*
|
||||||
* @param {Object} vis class visibility object to attach to (override __self)
|
|
||||||
* @param {{public: Object, protected: Object, private: Object}} static_members
|
* @param {{public: Object, protected: Object, private: Object}} static_members
|
||||||
*
|
*
|
||||||
* @return {undefined}
|
* @return {undefined}
|
||||||
*/
|
*/
|
||||||
function initStaticVisibilityObj( vis, static_members )
|
function initStaticVisibilityObj( ctor, static_members )
|
||||||
{
|
{
|
||||||
// the object will simply be another layer in the prototype chain to
|
// the object will simply be another layer in the prototype chain to
|
||||||
// prevent protected/private members from being mixed in with the public
|
// prevent protected/private members from being mixed in with the public
|
||||||
var sobj = function() {};
|
var sobj = function() {};
|
||||||
sobj.prototype = this;
|
sobj.prototype = ctor;
|
||||||
|
|
||||||
var sobji = new sobj();
|
var sobji = new sobj();
|
||||||
util.copyTo( sobji, static_members.methods[ 'protected' ] );
|
util.copyTo( sobji, static_members.methods[ 'protected' ] );
|
||||||
|
|
||||||
// override __self on the instance's visibility object, giving internal
|
// override __self on the instance's visibility object, giving internal
|
||||||
// methods access to the restricted static methods
|
// methods access to the restricted static methods
|
||||||
vis.__self = sobji;
|
ctor.___$$svis$$ = sobji;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -842,7 +842,9 @@ function getMethodInstance( inst, cid )
|
||||||
|
|
||||||
return ( iid && data )
|
return ( iid && data )
|
||||||
? data[ cid ]
|
? data[ cid ]
|
||||||
: null
|
: ( inst.___$$svis$$ )
|
||||||
|
? inst.___$$svis$$
|
||||||
|
: null
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -35,17 +35,20 @@ var common = require( './common' ),
|
||||||
*/
|
*/
|
||||||
( function testSelfPropertyReferencesClassDefinition()
|
( function testSelfPropertyReferencesClassDefinition()
|
||||||
{
|
{
|
||||||
var Foo = builder.build(
|
var val = [ 'baz' ],
|
||||||
{
|
Foo = builder.build(
|
||||||
'public function test': function()
|
|
||||||
{
|
{
|
||||||
return this.__self;
|
'public function test': function()
|
||||||
},
|
{
|
||||||
} );
|
return this.__self;
|
||||||
|
},
|
||||||
|
} );
|
||||||
|
|
||||||
|
Foo.bar = val;
|
||||||
|
|
||||||
// we must use instanceof here because the __self object has the class in
|
// we must use instanceof here because the __self object has the class in
|
||||||
// its prototype chain
|
// its prototype chain
|
||||||
assert.ok( Foo().test() instanceof Foo,
|
assert.ok( ( Foo().test().bar === Foo.bar ),
|
||||||
"__self property references class definition"
|
"__self property references class definition"
|
||||||
);
|
);
|
||||||
} )();
|
} )();
|
||||||
|
@ -198,7 +201,7 @@ var common = require( './common' ),
|
||||||
* available for an instance, it falls back. This serves as a regression test to
|
* available for an instance, it falls back. This serves as a regression test to
|
||||||
* ensure this functionality remains.
|
* ensure this functionality remains.
|
||||||
*/
|
*/
|
||||||
( function testStaticMethodsBoundToClassRatherThanInstance()
|
( function testStaticMethodsNotBoundToInstance()
|
||||||
{
|
{
|
||||||
var result = null,
|
var result = null,
|
||||||
Foo = builder.build(
|
Foo = builder.build(
|
||||||
|
@ -212,7 +215,7 @@ var common = require( './common' ),
|
||||||
// call the static method
|
// call the static method
|
||||||
Foo.foo();
|
Foo.foo();
|
||||||
|
|
||||||
assert.deepEqual( result, Foo,
|
assert.notEqual( result, Foo,
|
||||||
"Static members are bound to class definition rather than instance"
|
"Static members are bound to class definition rather than instance"
|
||||||
);
|
);
|
||||||
} )();
|
} )();
|
||||||
|
@ -445,6 +448,12 @@ var common = require( './common' ),
|
||||||
return val;
|
return val;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// ensure method is accessible to static methods
|
||||||
|
'public static staticBaz': function()
|
||||||
|
{
|
||||||
|
return this.baz();
|
||||||
|
},
|
||||||
|
|
||||||
// ensure method is accessible to instance methods
|
// ensure method is accessible to instance methods
|
||||||
'public instBaz': function()
|
'public instBaz': function()
|
||||||
{
|
{
|
||||||
|
@ -456,6 +465,10 @@ var common = require( './common' ),
|
||||||
"Protected methods should not be accessible outside the class"
|
"Protected methods should not be accessible outside the class"
|
||||||
);
|
);
|
||||||
|
|
||||||
|
assert.equal( Foo.staticBaz(), val,
|
||||||
|
"Protected methods are accessible to static methods"
|
||||||
|
);
|
||||||
|
|
||||||
assert.equal( Foo().instBaz(), val,
|
assert.equal( Foo().instBaz(), val,
|
||||||
"Protected methods are accessible to instance methods"
|
"Protected methods are accessible to instance methods"
|
||||||
);
|
);
|
||||||
|
|
Loading…
Reference in New Issue