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 )
{
validateGetterSetter( members, keywords, name, base );
var prev_data = scanMembers( members, name, base );
this._validate.validateGetterSetter(
name, members, keywords, base, prev_data
);
Object.defineProperty(
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 )
{
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(
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
*

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
* private

View File

@ -65,9 +65,13 @@ require( 'common' ).testCase(
this.buildStubGetterSetter = function( name, val, visibility, type )
{
var keywords = {},
// we can use bind() here because these tests will only be run
// in an ES5 environment (since pre-ES5 doesn't support
// getters/setters)
method = ( ( type === 'get' )
? _self.sut.buildGetter
: _self.sut.buildSetter
? _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' )(),
buildGetter = builder.buildGetter,
buildSetter = builder.buildSetter,
buildGetter = function()
{
builder.buildGetter.apply( builder, arguments );
},
buildSetter = function()
{
builder.buildSetter.apply( builder, arguments );
},
// member visibility types are quoted because they are reserved keywords
members = {},
@ -145,7 +152,7 @@ testEach( function testCannotOverrideMethodWithGetterOrSetter( type, build )
catch ( e )
{
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;
}