1
0
Fork 0

[#25] Moved getter/setter validation logic into MemberBuilderValidator

- Tests have not yet been moved
closure/master
Mike Gerwitz 2011-10-28 00:08:22 -04:00
parent 05df0b485c
commit ad0343fb9b
4 changed files with 70 additions and 45 deletions

View File

@ -207,7 +207,11 @@ exports.buildProp = function( members, meta, name, value, keywords, base )
*/ */
exports.buildGetter = function( members, meta, name, value, keywords, base ) exports.buildGetter = function( members, meta, name, value, keywords, base )
{ {
validateGetterSetter( members, keywords, name, base ); var prev_data = scanMembers( members, name, base );
this._validate.validateGetterSetter(
name, members, keywords, base, prev_data
);
Object.defineProperty( Object.defineProperty(
getMemberVisibility( members, keywords, name ), getMemberVisibility( members, keywords, name ),
@ -243,7 +247,13 @@ exports.buildGetter = function( members, meta, name, value, keywords, base )
*/ */
exports.buildSetter = function( members, meta, name, value, keywords, base ) exports.buildSetter = function( members, meta, name, value, keywords, base )
{ {
validateGetterSetter( members, keywords, name, base ); var prev_data = scanMembers( members, name, base );
this._validate.validateGetterSetter(
name, members, keywords, base, prev_data
);
this._validate.validateGetterSetter( name, members, keywords, base );
Object.defineProperty( Object.defineProperty(
getMemberVisibility( members, keywords, name ), getMemberVisibility( members, keywords, name ),
@ -259,43 +269,6 @@ exports.buildSetter = function( members, meta, name, value, keywords, base )
}; };
/**
* Performs common validations on getters/setters
*
* If a problem is found, an exception will be thrown.
*
* @param {{public: Object, protected: Object, private: Object}} members
*
* @param {Object.<string,boolean>} keywords parsed keywords
* @param {string} name getter/setter name
* @param {Object} base optional base to parse
*/
function validateGetterSetter( members, keywords, name, base )
{
var prev_data = scanMembers( members, name, base ),
prev = ( prev_data ) ? prev_data.member : null,
prev_keywords = ( prev && prev.___$$keywords$$ )
? prev.___$$keywords$$
: {}
;
if ( prev )
{
// To speed up the system we'll simply check for a getter/setter, rather
// than checking separately for methods/properties. This is at the
// expense of more detailed error messages. They'll live.
if ( !( prev_data.get || prev_data.set ) )
{
throw TypeError(
"Cannot override method or property '" + name +
"' with getter/setter"
);
}
}
}
/** /**
* Returns member prototype to use for the requested visibility * Returns member prototype to use for the requested visibility
* *

View File

@ -231,6 +231,47 @@ exports.prototype.validateProperty = function(
}; };
/**
* Performs common validations on getters/setters
*
* If a problem is found, an exception will be thrown.
*
* @param {string} name getter/setter name
*
* @param {{public: Object, protected: Object, private: Object}} members
*
* @param {Object.<string,boolean>} keywords parsed keywords
* @param {Object} base optional base to parse
*
* @return {undefined}
*/
exports.prototype.validateGetterSetter = function(
name, members, keywords, base, prev_data
)
{
var prev = ( prev_data ) ? prev_data.member : null,
prev_keywords = ( prev && prev.___$$keywords$$ )
? prev.___$$keywords$$
: {}
;
if ( prev )
{
// To speed up the system we'll simply check for a getter/setter, rather
// than checking separately for methods/properties. This is at the
// expense of more detailed error messages. They'll live.
if ( !( prev_data.get || prev_data.set ) )
{
throw TypeError(
"Cannot override method or property '" + name +
"' with getter/setter"
);
}
}
}
/** /**
* 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

@ -65,9 +65,13 @@ require( 'common' ).testCase(
this.buildStubGetterSetter = function( name, val, visibility, type ) this.buildStubGetterSetter = function( name, val, visibility, type )
{ {
var keywords = {}, var keywords = {},
method = ( ( type === 'get' )
? _self.sut.buildGetter // we can use bind() here because these tests will only be run
: _self.sut.buildSetter // in an ES5 environment (since pre-ES5 doesn't support
// getters/setters)
method = ( ( type === 'get' )
? _self.sut.buildGetter.bind( _self.sut )
: _self.sut.buildSetter.bind( _self.sut )
) )
; ;

View File

@ -28,8 +28,15 @@ var common = require( './common' ),
builder = common.require( 'MemberBuilder' )(), builder = common.require( 'MemberBuilder' )(),
buildGetter = builder.buildGetter, buildGetter = function()
buildSetter = builder.buildSetter, {
builder.buildGetter.apply( builder, arguments );
},
buildSetter = function()
{
builder.buildSetter.apply( builder, arguments );
},
// member visibility types are quoted because they are reserved keywords // member visibility types are quoted because they are reserved keywords
members = {}, members = {},
@ -145,7 +152,7 @@ testEach( function testCannotOverrideMethodWithGetterOrSetter( type, build )
catch ( e ) catch ( e )
{ {
assert.ok( e.message.search( name ) !== -1, assert.ok( e.message.search( name ) !== -1,
"Method override error message should contain getter/setter name" "Method override error message should contain " + type + " name"
); );
return; return;
} }