diff --git a/lib/interface.js b/lib/interface.js index 209beec..a3b2227 100644 --- a/lib/interface.js +++ b/lib/interface.js @@ -177,6 +177,23 @@ function createNamedInterface( name, def ) } +/** + * Augment an exception with interface name and then throw + * + * @param {string} iname interface name or empty string + * @param {Error} e exception to augment + */ +function _ithrow( iname, e ) +{ + // alter the message to include our name + e.message = "Failed to define interface " + + ( ( iname ) ? iname : '(anonymous)' ) + ": " + e.message + ; + + throw e; +} + + var extend = ( function( extending ) { return function extend() @@ -211,50 +228,43 @@ var extend = ( function( extending ) var new_interface = createInterface( iname ); - try - { - util.propParse( props, { - assumeAbstract: true, + util.propParse( props, { + assumeAbstract: true, - property: function() + // override default exceptions from parser errors + _throw: function( e ) + { + _ithrow( iname, e ); + }, + + property: function() + { + // should never get to this point because of assumeAbstract + _ithrow( iname, TypeError( "Unexpected internal error" ) ); + }, + + getset: function() + { + // should never get to this point because of assumeAbstract + _ithrow( iname, TypeError( "Unexpected internal error" ) ); + }, + + method: function( name, value, is_abstract, keywords ) + { + // all members must be public + if ( keywords[ 'protected' ] || keywords[ 'private' ] ) { - // should never get to this point because of assumeAbstract - throw TypeError( 'Unexpected internal error' ); - }, + _ithrow( iname, TypeError( + "Member " + name + " must be public" + ) ); + } - getset: function() - { - // should never get to this point because of assumeAbstract - throw TypeError( 'Unexpected internal error' ); - }, - - method: function( name, value, is_abstract, keywords ) - { - // all members must be public - if ( keywords[ 'protected' ] || keywords[ 'private' ] ) - { - throw TypeError( - iname + " member " + name + " must be public" - ); - } - - member_builder.buildMethod( - members, null, name, value, keywords, - null, 0, {}, vstate - ); - }, - } ); - } - catch ( e ) - { - // alter the message to include our name - e.message = "Failed to define interface " + - ( ( iname ) ? iname : '(anonymous)' ) + ": " + e.message - ; - - // re-throw - throw e; - } + member_builder.buildMethod( + members, null, name, value, keywords, + null, 0, {}, vstate + ); + }, + } ); attachExtend( new_interface ); attachStringMethod( new_interface, iname ); diff --git a/lib/util.js b/lib/util.js index cd4367a..6c35ba7 100644 --- a/lib/util.js +++ b/lib/util.js @@ -246,6 +246,19 @@ exports.copyTo = function( dest, src, deep ) }; +/** + * Throw an exception + * + * Yes, this function has purpose; see where it's used. + * + * @param {Error} e exception to throw + */ +function _throw( e ) +{ + throw e; +} + + /** * Parses object properties to determine how they should be interpreted in an * Object Oriented manner @@ -268,6 +281,8 @@ exports.propParse = function( data, options, context ) callbackGetSet = options.getset || fvoid, keywordParser = options.keywordParser || propParseKeywords, + throwf = options._throw || _throw, + hasOwn = Object.prototype.hasOwnProperty, parse_data = {}, @@ -315,12 +330,12 @@ exports.propParse = function( data, options, context ) if ( !( value instanceof Array ) ) { - throw TypeError( + throwf( TypeError( "Missing parameter list for abstract method: " + name - ); + ) ); } - verifyAbstractNames( name, value ); + verifyAbstractNames( throwf, name, value ); value = exports.createAbstractMethod.apply( this, value ); } @@ -363,22 +378,24 @@ exports.propParse = function( data, options, context ) * In the future, we may add additional functionality, so it's important to * restrict this as much as possible for the time being. * + * @param {function(Error)} throwf function to call with error + * * @param {string} name name of abstract member (for error) * @param {Object} params parameter list to check * * @return {undefined} */ -function verifyAbstractNames( name, params ) +function verifyAbstractNames( throwf, name, params ) { var i = params.length; while ( i-- ) { if ( params[ i ].match( /^[a-z_][a-z0-9_]*$/i ) === null ) { - throw SyntaxError( + throwf( SyntaxError( "Member " + name + " contains invalid parameter '" + params[ i ] + "'" - ); + ) ); } } }