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
|
||||
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
|
||||
// malicously set by the user
|
||||
this.___$$ctor$pre$$( _priv );
|
||||
haspre = false;
|
||||
}
|
||||
|
||||
// call the constructor, if one was provided
|
||||
|
@ -896,6 +902,12 @@ exports.prototype.createConcreteCtor = function( cname, members )
|
|||
this.__construct.apply( this, ( args || arguments ) );
|
||||
}
|
||||
|
||||
// FIXME: see above
|
||||
if ( haspre )
|
||||
{
|
||||
this.___$$ctor$pre$$( _priv );
|
||||
}
|
||||
|
||||
if ( typeof this.___$$ctor$post$$ === 'function' )
|
||||
{
|
||||
this.___$$ctor$post$$( _priv );
|
||||
|
|
|
@ -366,5 +366,34 @@ require( 'common' ).testCase(
|
|||
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