1
0
Fork 0

Method builder does not permit overriding properties with methods

closure/master
Mike Gerwitz 2011-01-21 21:53:31 -05:00
parent 12e5b48a7d
commit b8a6aa2af6
2 changed files with 39 additions and 0 deletions

View File

@ -63,6 +63,16 @@ exports.initMembers = function( mpublic, mprotected, mprivate )
*/ */
exports.buildMethod = function( members, meta, name, value, keywords ) 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; getMemberVisibility( members, keywords )[ name ] = value;
}; };

View File

@ -23,6 +23,7 @@
*/ */
var common = require( './common' ), var common = require( './common' ),
assert = require( 'assert' ),
mb_common = require( './inc-member_builder-common' ) 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 // do assertions common to all member builders
mb_common.assertCommon(); 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" );
} )();