Method builder does not permit overriding properties with methods
parent
12e5b48a7d
commit
b8a6aa2af6
|
@ -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;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -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" );
|
||||||
|
} )();
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue