From 12e5b48a7d077a61f635a3f8e5f8ed53708e398d Mon Sep 17 00:00:00 2001 From: Mike Gerwitz Date: Fri, 21 Jan 2011 21:43:18 -0500 Subject: [PATCH] Cannot override method with property --- lib/member_builder.js | 37 +++++++++++++++++++++++++++++++ test/inc-member_builder-common.js | 7 ++++-- test/test-member_builder-prop.js | 16 +++++++++++++ 3 files changed, 58 insertions(+), 2 deletions(-) diff --git a/lib/member_builder.js b/lib/member_builder.js index c11ab06..b28405c 100644 --- a/lib/member_builder.js +++ b/lib/member_builder.js @@ -22,6 +22,8 @@ * @package core */ +var visibility = [ 'public', 'protected', 'private' ]; + /** * Initializes member object @@ -81,6 +83,14 @@ exports.buildMethod = function( members, meta, name, value, keywords ) */ exports.buildProp = function( members, meta, name, value, keywords ) { + // disallow overriding methods with properties + if ( scanMembers( members, name ) instanceof Function ) + { + throw new TypeError( + "Cannot override method '" + name + "' with property" + ); + } + getMemberVisibility( members, keywords )[ name ] = value; }; @@ -164,3 +174,30 @@ function getMemberVisibility( members, keywords ) } } + +/** + * Scan each level of visibility for the requested member + * + * @param {{public: Object, protected: Object, private: Object}} members + * + * @param {string} name member to locate + * + * @return {*} member, if located, otherwise undefined + */ +function scanMembers( members, name ) +{ + var i = visibility.length, + member = null; + + // locate requested member by scanning each level of visibility + while ( i-- ) + { + if ( member = members[ visibility[ i ] ][ name ] ) + { + return member; + } + } + + return undefined; +} + diff --git a/test/inc-member_builder-common.js b/test/inc-member_builder-common.js index 1fe7b48..9a61d19 100644 --- a/test/inc-member_builder-common.js +++ b/test/inc-member_builder-common.js @@ -37,12 +37,15 @@ exports.buildMember = null; /** * Partially applied function to quickly build properties using common test data */ -exports.buildMemberQuick = function( keywords ) +exports.buildMemberQuick = function( keywords, preserve_prior ) { keywords = keywords || {}; // clear out the members for a fresh start - exports.members = { 'public': {}, 'protected': {}, 'private': {} }; + if ( !preserve_prior ) + { + exports.members = { 'public': {}, 'protected': {}, 'private': {} }; + } return exports.buildMember( exports.members, diff --git a/test/test-member_builder-prop.js b/test/test-member_builder-prop.js index 95bc3d7..57b829f 100644 --- a/test/test-member_builder-prop.js +++ b/test/test-member_builder-prop.js @@ -23,6 +23,7 @@ */ var common = require( './common' ), + assert = require( 'assert' ), mb_common = require( './inc-member_builder-common' ) ; @@ -32,3 +33,18 @@ mb_common.buildMember = common.require( 'member_builder' ).buildProp; // do assertions common to all member builders mb_common.assertCommon(); + +( function testCannotOverrideMethodWithProperty() +{ + // this will be considered a method, as it is a function + mb_common.value = function() {}; + mb_common.buildMemberQuick(); + + assert.throws( function() + { + // attempt to override with property + mb_common.value = 'foo'; + mb_common.buildMemberQuick( {}, true ); + }, TypeError, "Cannot override method with property" ); +} )(); +