diff --git a/lib/MemberBuilder.js b/lib/MemberBuilder.js index dda0086..26ed534 100644 --- a/lib/MemberBuilder.js +++ b/lib/MemberBuilder.js @@ -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.} 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 * diff --git a/lib/MemberBuilderValidator.js b/lib/MemberBuilderValidator.js index 20b8d5d..d184f27 100644 --- a/lib/MemberBuilderValidator.js +++ b/lib/MemberBuilderValidator.js @@ -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.} 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 diff --git a/test/MemberBuilder/VisibilityTest.js b/test/MemberBuilder/VisibilityTest.js index cef16eb..9cf0acf 100644 --- a/test/MemberBuilder/VisibilityTest.js +++ b/test/MemberBuilder/VisibilityTest.js @@ -65,9 +65,13 @@ require( 'common' ).testCase( this.buildStubGetterSetter = function( name, val, visibility, type ) { var keywords = {}, - method = ( ( type === 'get' ) - ? _self.sut.buildGetter - : _self.sut.buildSetter + + // 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.bind( _self.sut ) + : _self.sut.buildSetter.bind( _self.sut ) ) ; diff --git a/test/test-member_builder-gettersetter.js b/test/test-member_builder-gettersetter.js index 382c328..fa93f67 100644 --- a/test/test-member_builder-gettersetter.js +++ b/test/test-member_builder-gettersetter.js @@ -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; }