Began adding protected static members (supported for instance methods)
- No inheritance support yetclosure/master
parent
56ba57511b
commit
a246dd67e0
|
@ -234,7 +234,7 @@ exports.build = function extend()
|
||||||
}
|
}
|
||||||
staticInit( new_class, false );
|
staticInit( new_class, false );
|
||||||
|
|
||||||
attachPropInit( prototype, prop_init, members, class_id );
|
attachPropInit( prototype, prop_init, members, static_members, class_id );
|
||||||
|
|
||||||
new_class.prototype = prototype;
|
new_class.prototype = prototype;
|
||||||
new_class.constructor = new_class;
|
new_class.constructor = new_class;
|
||||||
|
@ -533,12 +533,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 {number} cid class id
|
||||||
*
|
*
|
||||||
* @return {undefined}
|
* @return {undefined}
|
||||||
*/
|
*/
|
||||||
function attachPropInit( prototype, properties, members, cid )
|
function attachPropInit( prototype, properties, members, static_members, cid )
|
||||||
{
|
{
|
||||||
util.defineSecureProp( prototype, '__initProps', function( inherit )
|
util.defineSecureProp( prototype, '__initProps', function( inherit )
|
||||||
{
|
{
|
||||||
|
@ -573,6 +574,9 @@ function attachPropInit( prototype, properties, members, cid )
|
||||||
inst_props, properties, members
|
inst_props, properties, members
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// give internal methods access to protected/private static members
|
||||||
|
initStaticVisibilityObj.call( this, vis, static_members );
|
||||||
|
|
||||||
// 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
|
||||||
// this.__inst from within a method), but only if we're on our final
|
// this.__inst from within a method), but only if we're on our final
|
||||||
|
@ -585,6 +589,32 @@ function attachPropInit( prototype, properties, members, cid )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates and populates the static visibility object
|
||||||
|
*
|
||||||
|
* This function should be called in the context of the class.
|
||||||
|
*
|
||||||
|
* @param {Object} vis class visibility object to attach to (override __self)
|
||||||
|
* @param {{public: Object, protected: Object, private: Object}} static_members
|
||||||
|
*
|
||||||
|
* @return {undefined}
|
||||||
|
*/
|
||||||
|
function initStaticVisibilityObj( vis, static_members )
|
||||||
|
{
|
||||||
|
// the object will simply be another layer in the prototype chain to
|
||||||
|
// prevent protected/private members from being mixed in with the public
|
||||||
|
var sobj = function() {};
|
||||||
|
sobj.prototype = this;
|
||||||
|
|
||||||
|
var sobji = new sobj();
|
||||||
|
util.copyTo( sobji, static_members.methods[ 'protected' ] );
|
||||||
|
|
||||||
|
// override __self on the instance's visibility object, giving internal
|
||||||
|
// methods access to the restricted static methods
|
||||||
|
vis.__self = sobji;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Attaches static members to a constructor (class)
|
* Attaches static members to a constructor (class)
|
||||||
*
|
*
|
||||||
|
|
|
@ -43,7 +43,9 @@ var common = require( './common' ),
|
||||||
},
|
},
|
||||||
} );
|
} );
|
||||||
|
|
||||||
assert.deepEqual( Foo().test(), Foo,
|
// we must use instanceof here because the __self object has the class in
|
||||||
|
// its prototype chain
|
||||||
|
assert.ok( Foo().test() instanceof Foo,
|
||||||
"__self property references class definition"
|
"__self property references class definition"
|
||||||
);
|
);
|
||||||
} )();
|
} )();
|
||||||
|
@ -427,3 +429,35 @@ var common = require( './common' ),
|
||||||
);
|
);
|
||||||
} )();
|
} )();
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Protected members should be available from within the class but shouldn't be
|
||||||
|
* exposed to the world
|
||||||
|
*/
|
||||||
|
( function testProtectedStaticMembersAreAvailableInsideClassOnly()
|
||||||
|
{
|
||||||
|
var val = 'foo',
|
||||||
|
Foo = builder.build(
|
||||||
|
{
|
||||||
|
// the same rules should apply to methods
|
||||||
|
'protected static baz': function()
|
||||||
|
{
|
||||||
|
return val;
|
||||||
|
},
|
||||||
|
|
||||||
|
// ensure method is accessible to instance methods
|
||||||
|
'public instBaz': function()
|
||||||
|
{
|
||||||
|
return this.__self.baz();
|
||||||
|
},
|
||||||
|
} );
|
||||||
|
|
||||||
|
assert.equal( Foo.baz, undefined,
|
||||||
|
"Protected methods should not be accessible outside the class"
|
||||||
|
);
|
||||||
|
|
||||||
|
assert.equal( Foo().instBaz(), val,
|
||||||
|
"Protected methods are accessible to instance methods"
|
||||||
|
);
|
||||||
|
} )();
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue