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 ),
|
||||
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
|
||||
if ( getter || setter )
|
||||
{
|
||||
|
@ -172,11 +140,32 @@ function prop_copy( props, dest, result_data )
|
|||
// check for method overrides
|
||||
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
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
@ -195,12 +184,18 @@ function prop_copy( props, dest, result_data )
|
|||
*
|
||||
* The given method must be a function or an exception will be thrown.
|
||||
*
|
||||
* @param {Function} super_method method to override
|
||||
* @param {Function} new_method method to override with
|
||||
* @param {Function} super_method method to override
|
||||
* @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
|
||||
*/
|
||||
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
|
||||
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" );
|
||||
}
|
||||
|
||||
// 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
|
||||
// method is called, so note that in the context of this
|
||||
// function, `this` will represent the current class instance
|
||||
|
|
Loading…
Reference in New Issue