[bug fix] Corrected bug with implicit visibility escalation
See test case comments for details. This wasted way too much of my time.perfodd
parent
5047d895c0
commit
bcada87240
|
@ -80,7 +80,7 @@ exports.prototype.setup = function setup( dest, properties, methods )
|
|||
this._doSetup( dest,
|
||||
properties[ 'protected' ],
|
||||
methods[ 'protected' ],
|
||||
'public'
|
||||
true
|
||||
);
|
||||
|
||||
// then add the private parts
|
||||
|
@ -127,20 +127,21 @@ exports.prototype._createPrivateLayer = function( atop_of, properties )
|
|||
/**
|
||||
* Set up destination object by copying over properties and methods
|
||||
*
|
||||
* The prot_priv parameter can be used to ignore both explicitly and
|
||||
* implicitly public methods.
|
||||
*
|
||||
* @param {Object} dest destination object
|
||||
* @param {Object} properties properties to copy
|
||||
* @param {Object} methods methods to copy
|
||||
* @param {boolean} unless_keyword do not set if keyword is set on existing
|
||||
* method
|
||||
* @param {boolean} prot_priv do not set unless protected or private
|
||||
*
|
||||
* @return {undefined}
|
||||
*/
|
||||
exports.prototype._doSetup = function(
|
||||
dest, properties, methods, unless_keyword
|
||||
dest, properties, methods, prot_priv
|
||||
)
|
||||
{
|
||||
var hasOwn = Array.prototype.hasOwnProperty,
|
||||
pre = null;
|
||||
var hasOwn = Array.prototype.hasOwnProperty;
|
||||
|
||||
// copy over the methods
|
||||
if ( methods !== undefined )
|
||||
|
@ -149,7 +150,8 @@ exports.prototype._doSetup = function(
|
|||
{
|
||||
if ( hasOwn.call( methods, method_name ) )
|
||||
{
|
||||
pre = dest[ method_name ];
|
||||
var pre = dest[ method_name ],
|
||||
kw = pre && pre.___$$keywords$$;
|
||||
|
||||
// If requested, do not copy the method over if it already
|
||||
// exists in the destination object. Don't use hasOwn here;
|
||||
|
@ -163,9 +165,9 @@ exports.prototype._doSetup = function(
|
|||
// protected). This is the *last* check to ensure a performance
|
||||
// hit is incured *only* if we're overriding protected with
|
||||
// protected.
|
||||
if ( !unless_keyword
|
||||
if ( !prot_priv
|
||||
|| ( pre === undefined )
|
||||
|| !( pre.___$$keywords$$[ unless_keyword ] )
|
||||
|| ( kw[ 'private' ] || kw[ 'protected' ] )
|
||||
)
|
||||
{
|
||||
dest[ method_name ] = methods[ method_name ];
|
||||
|
|
|
@ -267,6 +267,36 @@ require( 'common' ).testCase(
|
|||
},
|
||||
|
||||
|
||||
/**
|
||||
* This test addresses a particularily nasty bug that wasted hours of
|
||||
* development time: When a visibility modifier keyword is omitted, then
|
||||
* it should be implicitly public. In this case, however, the keyword is
|
||||
* not automatically added to the keyword list (maybe one day it will
|
||||
* be, but for now we'll maintain the distinction); therefore, we should
|
||||
* not be checking for the `public' keyword when determining if we
|
||||
* should write to the protected member object.
|
||||
*/
|
||||
'Public methods are not overwritten when keyword is omitted': function()
|
||||
{
|
||||
var f = function() {};
|
||||
f.___$$keywords$$ = {};
|
||||
|
||||
// no keywords; should be implicitly public
|
||||
var dest = { fpub: f };
|
||||
|
||||
// add duplicate method to protected
|
||||
this.methods[ 'protected' ].fpub = function() {};
|
||||
|
||||
this.sut.setup( dest, this.props, this.methods );
|
||||
|
||||
// ensure our public method is still referenced
|
||||
this.assertStrictEqual( dest.fpub, f,
|
||||
"Public methods should not be overwritten by protected methods"
|
||||
);
|
||||
},
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Same situation with private members as protected, with the exception that
|
||||
* we do not need to worry about the overlay problem (in regards to
|
||||
|
|
Loading…
Reference in New Issue