From b8a6aa2af6f4cf7c01c91ddbabf9320ddb50a233 Mon Sep 17 00:00:00 2001 From: Mike Gerwitz Date: Fri, 21 Jan 2011 21:53:31 -0500 Subject: [PATCH] Method builder does not permit overriding properties with methods --- lib/member_builder.js | 10 ++++++++++ test/test-member_builder-method.js | 29 +++++++++++++++++++++++++++++ 2 files changed, 39 insertions(+) diff --git a/lib/member_builder.js b/lib/member_builder.js index b28405c..decca44 100644 --- a/lib/member_builder.js +++ b/lib/member_builder.js @@ -63,6 +63,16 @@ exports.initMembers = function( mpublic, mprotected, mprivate ) */ exports.buildMethod = function( members, meta, name, value, keywords ) { + var prev = scanMembers( members, name ); + + // disallow overriding properties with methods + if ( prev && !( prev instanceof Function ) ) + { + throw new TypeError( + "Cannot override property '" + name + "' with method" + ); + } + getMemberVisibility( members, keywords )[ name ] = value; }; diff --git a/test/test-member_builder-method.js b/test/test-member_builder-method.js index 5fb35d3..69feefa 100644 --- a/test/test-member_builder-method.js +++ b/test/test-member_builder-method.js @@ -23,6 +23,7 @@ */ var common = require( './common' ), + assert = require( 'assert' ), mb_common = require( './inc-member_builder-common' ) ; @@ -32,3 +33,31 @@ mb_common.buildMember = common.require( 'member_builder' ).buildMethod; // do assertions common to all member builders mb_common.assertCommon(); + +/** + * One may question the purpose of this assertion. Why should we not permit + * overriding properties with methods? It's useful to be able to store callbacks + * and such within properties. + * + * Yes, it is. However, that would be misinterpreting the purpose of the method + * builder. Here, we are working with prototypes, not class instances. If the + * user wishes to assign a function to the property (so long as it's permitted + * by the type definition) after the class is instantiated, he/she may go right + * ahead. However, if we modify the prototype to use a function, then the + * prototype will interpret the function as a method. As such, the method cannot + * be overridden with a property in the future. To avoid this confusing + * scenario, we'll prevent it from occurring entirely. + */ +( function testCannotOverridePropertyWithMethod() +{ + mb_common.value = 'moofoo'; + mb_common.buildMemberQuick(); + + assert.throws( function() + { + // attempt to override with function + mb_common.value = function() {}; + mb_common.buildMemberQuick( {}, true ); + }, TypeError, "Cannot override property with method" ); +} )(); +