Visibility object is now encapsulated in symbol key
Note that this patch temporarily breaks encapsulation via ClassBuilder.___$$privsym$$ to expose necessary internal details to Trait; this will be resolved.protolib
parent
a35a9c6ed3
commit
13b0bd2fb3
|
@ -233,11 +233,11 @@ exports.getForcedPublicMethods = function()
|
|||
*
|
||||
* @param {Function|Object} cls class from which to retrieve metadata
|
||||
*
|
||||
* @return {__class_meta}
|
||||
* @return {__class_meta} or null if unavailable
|
||||
*/
|
||||
exports.getMeta = function( cls )
|
||||
{
|
||||
return ( cls[ _priv ] || {} ).meta || {};
|
||||
return ( cls[ _priv ] || {} ).meta || null;
|
||||
}
|
||||
|
||||
|
||||
|
@ -338,7 +338,7 @@ exports.prototype.build = function extend( _, __ )
|
|||
props: this._memberBuilder.initMembers(),
|
||||
},
|
||||
|
||||
meta = exports.getMeta( base ),
|
||||
meta = exports.getMeta( base ) || {},
|
||||
|
||||
abstract_methods =
|
||||
util.clone( meta.abstractMethods )
|
||||
|
@ -387,7 +387,7 @@ exports.prototype.build = function extend( _, __ )
|
|||
// properties initialized by the ctor are implicitly public; otherwise,
|
||||
// proxying will fail to take place
|
||||
// TODO: see Class.isA TODO
|
||||
if ( prototype.___$$vis$$ === undefined )
|
||||
if ( ( prototype[ _priv ] || {} ).vis === undefined )
|
||||
{
|
||||
this._discoverProtoProps( prototype, prop_init );
|
||||
}
|
||||
|
@ -1006,7 +1006,8 @@ exports.prototype._attachPropInit = function(
|
|||
inherit = !!inherit;
|
||||
|
||||
var iid = this.__iid,
|
||||
parent = prototype.___$$parent$$;
|
||||
parent = prototype.___$$parent$$,
|
||||
vis = this[ _priv ].vis;
|
||||
|
||||
// first initialize the parent's properties, so that ours will overwrite
|
||||
// them
|
||||
|
@ -1022,7 +1023,7 @@ exports.prototype._attachPropInit = function(
|
|||
// this will return our property proxy, if supported by our environment,
|
||||
// otherwise just a normal object with everything merged in
|
||||
var inst_props = _self._visFactory.createPropProxy(
|
||||
this, this.___$$vis$$, properties[ 'public' ]
|
||||
this, vis, properties[ 'public' ]
|
||||
);
|
||||
|
||||
// Copies all public and protected members into inst_props and stores
|
||||
|
@ -1030,7 +1031,7 @@ exports.prototype._attachPropInit = function(
|
|||
// chain and is returned. This is stored in a property referenced by the
|
||||
// class id, so that the private members can be swapped on each method
|
||||
// request, depending on calling context.
|
||||
var vis = this.___$$vis$$[ cid ] = _self._visFactory.setup(
|
||||
var vis = vis[ cid ] = _self._visFactory.setup(
|
||||
inst_props, properties, members
|
||||
);
|
||||
|
||||
|
@ -1232,6 +1233,10 @@ exports.prototype.attachStatic = function( ctor, members, base, inheriting )
|
|||
}
|
||||
|
||||
|
||||
// FIXME: this is *temporary* during refactoring!
|
||||
module.exports.___$$privsym$$ = _priv;
|
||||
|
||||
|
||||
/**
|
||||
* Initializes class metadata for the given class
|
||||
*
|
||||
|
@ -1325,8 +1330,12 @@ function initInstance( instance )
|
|||
var prot = function() {};
|
||||
prot.prototype = instance;
|
||||
|
||||
// initialize our *own* private metadata store; do not use the
|
||||
// prototype's
|
||||
instance[ _priv ] = {};
|
||||
|
||||
// add the visibility objects to the data object for this class instance
|
||||
instance.___$$vis$$ = new prot();
|
||||
instance[ _priv ].vis = new prot();
|
||||
}
|
||||
|
||||
|
||||
|
@ -1380,9 +1389,10 @@ exports.getMethodInstance = function( inst, cid )
|
|||
}
|
||||
|
||||
var iid = inst.__iid,
|
||||
data = inst.___$$vis$$;
|
||||
priv = inst[ _priv ],
|
||||
data;
|
||||
|
||||
return ( iid && data )
|
||||
return ( iid && priv && ( data = priv.vis ) )
|
||||
? data[ cid ]
|
||||
: null
|
||||
;
|
||||
|
|
|
@ -680,6 +680,9 @@ function addTraitInst( T, dfn, tc, base )
|
|||
*/
|
||||
function tctor( tc, base )
|
||||
{
|
||||
// FIXME: this is temporary during refactoring!
|
||||
var cbpriv = ClassBuilder.___$$privsym$$;
|
||||
|
||||
// instantiate all traits and assign the object to their
|
||||
// respective fields
|
||||
for ( var t in tc )
|
||||
|
@ -693,7 +696,7 @@ function tctor( tc, base )
|
|||
// (but not private); in return, we will use its own protected
|
||||
// visibility object to gain access to its protected members...quite
|
||||
// the intimate relationship
|
||||
this[ f ] = C( base, this.___$$vis$$ ).___$$vis$$;
|
||||
this[ f ] = C( base, this[ cbpriv ].vis )[ cbpriv ].vis;
|
||||
}
|
||||
|
||||
// if we are a subtype, be sure to initialize our parent's traits
|
||||
|
|
25
lib/class.js
25
lib/class.js
|
@ -169,6 +169,8 @@ var _dummyinst = { constructor: { prototype: {} } };
|
|||
/**
|
||||
* Determines whether the provided object is a class created through ease.js
|
||||
*
|
||||
* TODO: delegate to ClassBuilder
|
||||
*
|
||||
* @param {Object} obj object to test
|
||||
*
|
||||
* @return {boolean} true if class (created through ease.js), otherwise false
|
||||
|
@ -182,10 +184,11 @@ module.exports.isClass = function( obj )
|
|||
return false;
|
||||
}
|
||||
|
||||
// TODO: this just checks one of many internal fields; we need something
|
||||
// more formal (cannot use a strict ClassBase check because it will fail
|
||||
// when extending prototypes)
|
||||
return ( ( obj.prototype.___$$vis$$ !== undefined )
|
||||
var meta = ClassBuilder.getMeta( obj );
|
||||
|
||||
// TODO: we're checking a random field on the meta object; do something
|
||||
// proper
|
||||
return ( ( ( meta !== null ) && meta.implemented )
|
||||
|| ( obj.prototype instanceof ClassBuilder.ClassBase ) )
|
||||
? true
|
||||
: false
|
||||
|
@ -197,6 +200,8 @@ module.exports.isClass = function( obj )
|
|||
* Determines whether the provided object is an instance of a class created
|
||||
* through ease.js
|
||||
*
|
||||
* TODO: delegate to ClassBuilder
|
||||
*
|
||||
* @param {Object} obj object to test
|
||||
*
|
||||
* @return {boolean} true if instance of class (created through ease.js),
|
||||
|
@ -206,16 +211,8 @@ module.exports.isClassInstance = function( obj )
|
|||
{
|
||||
obj = obj || _dummyinst;
|
||||
|
||||
if ( !obj.constructor || !obj.constructor.prototype )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// TODO: see isClass TODO
|
||||
return ( ( obj.constructor.prototype.___$$vis$$ !== undefined )
|
||||
|| ( obj instanceof ClassBuilder.ClassBase ) )
|
||||
? true
|
||||
: false;
|
||||
// if the constructor is a class, then we must be an instance!
|
||||
return module.exports.isClass( obj.constructor );
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -492,10 +492,13 @@ function attachInstanceOf( iface )
|
|||
*/
|
||||
function _isInstanceOf( type, instance )
|
||||
{
|
||||
// we are interested in the class's metadata, not the instance's
|
||||
var proto = instance.constructor;
|
||||
|
||||
// if no metadata are available, then our remaining checks cannot be
|
||||
// performed
|
||||
var meta;
|
||||
if ( !instance.__cid || !( meta = ClassBuilder.getMeta( instance ) ) )
|
||||
if ( !instance.__cid || !( meta = ClassBuilder.getMeta( proto ) ) )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue