[#25] Moved getter/setter validation logic into MemberBuilderValidator
- Tests have not yet been movedclosure/master
parent
05df0b485c
commit
ad0343fb9b
|
@ -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
|
||||||
*
|
*
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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 = {},
|
||||||
|
|
||||||
|
// 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' )
|
method = ( ( type === 'get' )
|
||||||
? _self.sut.buildGetter
|
? _self.sut.buildGetter.bind( _self.sut )
|
||||||
: _self.sut.buildSetter
|
: _self.sut.buildSetter.bind( _self.sut )
|
||||||
)
|
)
|
||||||
;
|
;
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue