Subtype ctor guarantees with parent __mixin or __construct
A solution for this problem took a disproportionally large amount of time, attempting many different approaches, and arriving still at a kluge; this is indicative of a larger issue---we've long since breached the comfort of the original design, and drastic refactoring is needed. I have ideas for this, and have already started in another branch, but I cannot but this implementation off any longer while waiting for it. Sorry for anyone waiting on the next release: this is what held it up, in combination with my attention being directed elsewhere during that time (see the sparse commit timestamps). Including this ordering guarantee is very important for a stable, well-designed [trait] system.textend
parent
90a32a104f
commit
e934338b41
|
@ -880,11 +880,17 @@ exports.prototype.createConcreteCtor = function( cname, members )
|
||||||
// generate and store unique instance id
|
// generate and store unique instance id
|
||||||
attachInstanceId( this, ++_self._instanceId );
|
attachInstanceId( this, ++_self._instanceId );
|
||||||
|
|
||||||
if ( typeof this.___$$ctor$pre$$ === 'function' )
|
// FIXME: this is a bit of a kluge for determining whether the ctor
|
||||||
|
// should be invoked before a child prector...
|
||||||
|
var haspre = ( typeof this.___$$ctor$pre$$ === 'function' );
|
||||||
|
if ( haspre
|
||||||
|
&& ClassInstance.prototype.hasOwnProperty( '___$$ctor$pre$$' )
|
||||||
|
)
|
||||||
{
|
{
|
||||||
// FIXME: we're exposing _priv to something that can be
|
// FIXME: we're exposing _priv to something that can be
|
||||||
// malicously set by the user
|
// malicously set by the user
|
||||||
this.___$$ctor$pre$$( _priv );
|
this.___$$ctor$pre$$( _priv );
|
||||||
|
haspre = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// call the constructor, if one was provided
|
// call the constructor, if one was provided
|
||||||
|
@ -896,6 +902,12 @@ exports.prototype.createConcreteCtor = function( cname, members )
|
||||||
this.__construct.apply( this, ( args || arguments ) );
|
this.__construct.apply( this, ( args || arguments ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FIXME: see above
|
||||||
|
if ( haspre )
|
||||||
|
{
|
||||||
|
this.___$$ctor$pre$$( _priv );
|
||||||
|
}
|
||||||
|
|
||||||
if ( typeof this.___$$ctor$post$$ === 'function' )
|
if ( typeof this.___$$ctor$post$$ === 'function' )
|
||||||
{
|
{
|
||||||
this.___$$ctor$post$$( _priv );
|
this.___$$ctor$post$$( _priv );
|
||||||
|
|
|
@ -366,5 +366,34 @@ require( 'common' ).testCase(
|
||||||
C();
|
C();
|
||||||
} );
|
} );
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The same concept as above, extended to subtypes. In particular, we
|
||||||
|
* need to ensure that the subtype is able to properly initialize or
|
||||||
|
* alter state that __mixin of a supertype depends upon.
|
||||||
|
*/
|
||||||
|
'Subtype invokes ctor before supertype __construct or __mixin':
|
||||||
|
function()
|
||||||
|
{
|
||||||
|
var cok = false;
|
||||||
|
|
||||||
|
var T = this.createParamTrait( function()
|
||||||
|
{
|
||||||
|
if ( !cok ) throw Error(
|
||||||
|
"__mixin called before Sub#__construct"
|
||||||
|
);
|
||||||
|
} );
|
||||||
|
|
||||||
|
var Sub = this.Class( {} ).use( T ).extend(
|
||||||
|
{
|
||||||
|
__construct: function() { cok = true }
|
||||||
|
} );
|
||||||
|
|
||||||
|
this.assertDoesNotThrow( function()
|
||||||
|
{
|
||||||
|
Sub();
|
||||||
|
} );
|
||||||
|
},
|
||||||
} );
|
} );
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue