Refactored abstract method logic
parent
52944c4207
commit
e26d7971ce
90
lib/class.js
90
lib/class.js
|
@ -124,38 +124,6 @@ function prop_copy( props, dest, result_data )
|
||||||
getter = ( ( getset ) ? props.__lookupGetter__( property ) : null ),
|
getter = ( ( getset ) ? props.__lookupGetter__( property ) : null ),
|
||||||
setter = ( ( getset ) ? props.__lookupSetter__( property ) : null );
|
setter = ( ( getset ) ? props.__lookupSetter__( property ) : null );
|
||||||
|
|
||||||
// did we find an abstract method?
|
|
||||||
if ( prop instanceof Function )
|
|
||||||
{
|
|
||||||
if ( prop.abstractFlag === true )
|
|
||||||
{
|
|
||||||
abstract_methods.push( property );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// if we were given a concrete method to an abstract method,
|
|
||||||
// then the method should no longer be considered abstract
|
|
||||||
if ( abstract_map[ property ] !== undefined )
|
|
||||||
{
|
|
||||||
if ( pre.definition )
|
|
||||||
{
|
|
||||||
// ensure the concrete definition is compatible with
|
|
||||||
// that of its supertype
|
|
||||||
if ( prop.length < pre.definition.length )
|
|
||||||
{
|
|
||||||
throw new Error(
|
|
||||||
"Declaration of " + property + " must be compatiable" +
|
|
||||||
"with that of its supertype"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
delete abstract_methods[ abstract_map[ property ] ];
|
|
||||||
abstract_regen = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// check for getter/setter overrides
|
// check for getter/setter overrides
|
||||||
if ( getter || setter )
|
if ( getter || setter )
|
||||||
{
|
{
|
||||||
|
@ -172,11 +140,32 @@ function prop_copy( props, dest, result_data )
|
||||||
// check for method overrides
|
// check for method overrides
|
||||||
else if ( ( pre !== undefined ) && ( pre instanceof Function ) )
|
else if ( ( pre !== undefined ) && ( pre instanceof Function ) )
|
||||||
{
|
{
|
||||||
dest[ property ] = method_override( pre, prop );
|
var data = { abstractModified: false };
|
||||||
|
|
||||||
|
dest[ property ] = method_override(
|
||||||
|
pre,
|
||||||
|
prop,
|
||||||
|
property,
|
||||||
|
abstract_map,
|
||||||
|
abstract_methods,
|
||||||
|
data
|
||||||
|
);
|
||||||
|
|
||||||
|
if ( data.abstractModified )
|
||||||
|
{
|
||||||
|
abstract_regen = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// just copy over the property
|
// just copy over the property
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
// if we were given an abstract method, add it to our list of
|
||||||
|
// abstract methods
|
||||||
|
if ( ( prop instanceof Function ) && ( prop.abstractFlag === true ) )
|
||||||
|
{
|
||||||
|
abstract_methods.push( property );
|
||||||
|
}
|
||||||
|
|
||||||
dest[ property ] = prop;
|
dest[ property ] = prop;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -195,12 +184,18 @@ function prop_copy( props, dest, result_data )
|
||||||
*
|
*
|
||||||
* The given method must be a function or an exception will be thrown.
|
* The given method must be a function or an exception will be thrown.
|
||||||
*
|
*
|
||||||
* @param {Function} super_method method to override
|
* @param {Function} super_method method to override
|
||||||
* @param {Function} new_method method to override with
|
* @param {Function} new_method method to override with
|
||||||
|
* @param {string} name method name
|
||||||
|
* @param {Object} abstract_map lookup table for abstract methods
|
||||||
|
* @param {Array} abstract_methods list of abstract methods
|
||||||
|
* @param {Object} data object in which to store result data
|
||||||
*
|
*
|
||||||
* @return {Function} overridden method
|
* @return {Function} overridden method
|
||||||
*/
|
*/
|
||||||
function method_override( super_method, new_method )
|
function method_override(
|
||||||
|
super_method, new_method, name, abstract_map, abstract_methods, data
|
||||||
|
)
|
||||||
{
|
{
|
||||||
// ensure we're overriding the method with another method
|
// ensure we're overriding the method with another method
|
||||||
if ( !( new_method instanceof Function ) )
|
if ( !( new_method instanceof Function ) )
|
||||||
|
@ -208,6 +203,29 @@ function method_override( super_method, new_method )
|
||||||
throw new TypeError( "Cannot override method with non-method" );
|
throw new TypeError( "Cannot override method with non-method" );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// if we were given a concrete method to an abstract method,
|
||||||
|
// then the method should no longer be considered abstract
|
||||||
|
if ( ( abstract_map[ name ] !== undefined )
|
||||||
|
&& ( new_method.abstractFlag !== true )
|
||||||
|
)
|
||||||
|
{
|
||||||
|
if ( super_method.definition instanceof Function )
|
||||||
|
{
|
||||||
|
// ensure the concrete definition is compatible with
|
||||||
|
// that of its supertype
|
||||||
|
if ( new_method.length < super_method.definition.length )
|
||||||
|
{
|
||||||
|
throw new Error(
|
||||||
|
"Declaration of " + name + " must be compatiable" +
|
||||||
|
"with that of its supertype"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
delete abstract_methods[ abstract_map[ name ] ];
|
||||||
|
data.abstractModified = true;
|
||||||
|
}
|
||||||
|
|
||||||
// this is the method that will be invoked when the requested
|
// this is the method that will be invoked when the requested
|
||||||
// method is called, so note that in the context of this
|
// method is called, so note that in the context of this
|
||||||
// function, `this` will represent the current class instance
|
// function, `this` will represent the current class instance
|
||||||
|
|
Loading…
Reference in New Issue