1
0
Fork 0

Remove global _extending state

The previous implementation could not survive recursive applications, which
I did know about.  But that was before the system was brutally abused by
traits.
master
Mike Gerwitz 2015-05-13 00:18:08 -04:00
parent 69e9828beb
commit e866f53d4c
1 changed files with 11 additions and 23 deletions

View File

@ -144,15 +144,6 @@ function ClassBuilder( warn_handler, member_builder, visibility_factory )
*/ */
this._instanceId = 0; this._instanceId = 0;
/**
* Set to TRUE when class is in the process of being extended to ensure that
* a constructor can be instantiated (to use as the prototype) without
* invoking the class construction logic
*
* @type {boolean}
*/
this._extending = false;
/** /**
* A flag to let the system know that we are currently attempting to access * A flag to let the system know that we are currently attempting to access
* a static property from within a method. This means that the caller should * a static property from within a method. This means that the caller should
@ -345,9 +336,6 @@ exports.prototype.build = function extend( _, __ )
{ {
var build = this; var build = this;
// ensure we'll be permitted to instantiate abstract classes for the base
this._extending = true;
var a = arguments, var a = arguments,
an = a.length, an = a.length,
props = ( ( an > 0 ) ? a[ an - 1 ] : 0 ) || {}, props = ( ( an > 0 ) ? a[ an - 1 ] : 0 ) || {},
@ -500,15 +488,13 @@ exports.prototype.build = function extend( _, __ )
// (intended for use in prototype chains) // (intended for use in prototype chains)
new_class.asPrototype = function() new_class.asPrototype = function()
{ {
build._extending = true; new_class[ _priv ].extending = true;
var inst = new_class(); var inst = new new_class();
build._extending = false; new_class[ _priv ].extending = false;
return inst; return inst;
}; };
// we're done with the extension process
this._extending = false;
return new_class; return new_class;
}; };
@ -522,7 +508,9 @@ exports.prototype._getBase = function( base )
// constructor (we could also check to ensure that the return value of // constructor (we could also check to ensure that the return value of
// the constructor is an object, but that is not our concern) // the constructor is an object, but that is not our concern)
case 'function': case 'function':
return new base(); return ( base[ _priv ] )
? base.asPrototype()
: new base();
// we can use objects as the prototype directly // we can use objects as the prototype directly
case 'object': case 'object':
@ -865,8 +853,8 @@ exports.prototype.createCtor = function( cname, abstract_methods, members )
*/ */
exports.prototype.createConcreteCtor = function( cname, members ) exports.prototype.createConcreteCtor = function( cname, members )
{ {
var args = null, var args = null,
_self = this; _self = this;
/** /**
* Constructor function to be returned * Constructor function to be returned
@ -896,7 +884,7 @@ exports.prototype.createConcreteCtor = function( cname, members )
// If we're extending, we don't actually want to invoke any class // If we're extending, we don't actually want to invoke any class
// construction logic. The above is sufficient to use this class in a // construction logic. The above is sufficient to use this class in a
// prototype, so stop here. // prototype, so stop here.
if ( _self._extending ) if ( ClassInstance[ _priv ].extending )
{ {
return; return;
} }
@ -992,7 +980,7 @@ exports.prototype.createAbstractCtor = function( cname )
var __abstract_self = function() var __abstract_self = function()
{ {
if ( !_self._extending ) if ( !__abstract_self[ _priv ].extending )
{ {
throw Error( throw Error(
"Abstract class " + ( cname || '(anonymous)' ) + "Abstract class " + ( cname || '(anonymous)' ) +