1
0
Fork 0

[#25] Moved MethodBuilder property validation into MemberBuilderValidator

- Tests have not yet been moved
closure/master
Mike Gerwitz 2011-10-23 00:43:08 -04:00
parent 5e46298e39
commit a91cb01998
3 changed files with 86 additions and 57 deletions

View File

@ -175,57 +175,12 @@ exports.buildProp = function( members, meta, name, value, keywords, base )
// TODO: We can improve performance by not scanning each one individually // TODO: We can improve performance by not scanning each one individually
// every time this method is called // every time this method is called
var prev_data = scanMembers( members, name, base ), var prev_data = scanMembers( members, name, base ),
prev = ( prev_data ) ? prev_data.member : null; prev = ( prev_data ) ? prev_data.member : null,
prev_keywords = ( prev ) ? prev[ 1 ] : null;
// disallow overriding methods with properties this._validate.validateProperty(
if ( prev instanceof Function ) name, value, keywords, prev_data, prev_keywords
{
throw new TypeError(
"Cannot override method '" + name + "' with property"
); );
}
// do not allow overriding getters/setters
if ( prev_data && ( prev_data.get || prev_data.set ) )
{
throw TypeError(
"Cannot override getter/setter '" + name + "' with property"
);
}
// do not permit visibility de-escalation
if ( prev &&
( this._getVisibilityValue( prev[ 1 ] )
< this._getVisibilityValue( keywords )
)
)
{
throw TypeError(
"Cannot de-escalate visibility of property '" + name + "'"
);
}
// abstract properties do not make sense
if ( keywords[ 'abstract' ] )
{
throw TypeError(
"Property '" + name + "' cannot be declared as abstract"
);
}
if ( keywords[ 'static' ] && keywords[ 'const' ] )
{
throw TypeError(
"Static keyword cannot be used with const for property '" +
name + "'"
);
}
// properties are inherently virtual
if ( keywords['virtual'] )
{
throw TypeError( "Cannot declare property '" + name + "' as virtual" );
}
getMemberVisibility( members, keywords )[ name ] = [ value, keywords ]; getMemberVisibility( members, keywords )[ name ] = [ value, keywords ];
}; };

View File

@ -156,6 +156,80 @@ exports.prototype.validateMethod = function(
}; };
/**
* Validates a property declaration, ensuring that keywords are valid, overrides
* make sense, etc.
*
* Throws exception on validation failure
*
* @param {string} name method name
* @param {*} value method value
*
* @param {Object.<string,boolean>} keywords parsed keywords
*
* @param {Object} prev_data data of member being overridden
* @param {Object} prev_keywords keywords of member being overridden
*
* @return {undefined}
*/
exports.prototype.validateProperty = function(
name, value, keywords, prev_data, prev_keywords
)
{
var prev = ( prev_data ) ? prev_data.member : null;
// disallow overriding methods with properties
if ( prev instanceof Function )
{
throw new TypeError(
"Cannot override method '" + name + "' with property"
);
}
// do not allow overriding getters/setters
if ( prev_data && ( prev_data.get || prev_data.set ) )
{
throw TypeError(
"Cannot override getter/setter '" + name + "' with property"
);
}
// do not permit visibility de-escalation
if ( prev &&
( this._getVisibilityValue( prev_keywords )
< this._getVisibilityValue( keywords )
)
)
{
throw TypeError(
"Cannot de-escalate visibility of property '" + name + "'"
);
}
// abstract properties do not make sense
if ( keywords[ 'abstract' ] )
{
throw TypeError(
"Property '" + name + "' cannot be declared as abstract"
);
}
if ( keywords[ 'static' ] && keywords[ 'const' ] )
{
throw TypeError(
"Static keyword cannot be used with const for property '" +
name + "'"
);
}
// properties are inherently virtual
if ( keywords['virtual'] )
{
throw TypeError( "Cannot declare property '" + name + "' as virtual" );
}
};
/** /**
* Return the visibility level as a numeric value, where 0 is public and 2 is * Return the visibility level as a numeric value, where 0 is public and 2 is
* private * private

View File

@ -41,12 +41,11 @@ var common = require( './common' ),
mb_common.funcVal = null; mb_common.funcVal = null;
mb_common.value = { baj: 'baz' }; mb_common.value = { baj: 'baz' };
mb_common.buildMember = builder.buildProp
// must wrap to call in proper context // must wrap to call in proper context
var builder_method = function() var builder_method = mb_common.buildMember = function()
{ {
builder.buildMethod.apply( builder, arguments ); builder.buildProp.apply( builder, arguments );
} }
// do assertions common to all member builders // do assertions common to all member builders
@ -94,6 +93,7 @@ mb_common.assertCommon();
{ {
try try
{ {
mb_common.buildMember = builder_method;
mb_common.buildMemberQuick( { 'virtual': true } ); mb_common.buildMemberQuick( { 'virtual': true } );
} }
catch ( e ) catch ( e )