diff --git a/lib/class_builder.js b/lib/class_builder.js index 89948eb..a75863f 100644 --- a/lib/class_builder.js +++ b/lib/class_builder.js @@ -492,7 +492,7 @@ function attachPropInit( prototype, properties, members, cid ) { util.defineSecureProp( prototype, '__initProps', function( inherit ) { - // defaults to false, sid = super identifier + // defaults to false inherit = !!inherit; var iid = this.__iid; @@ -514,8 +514,11 @@ function attachPropInit( prototype, properties, members, cid ) this, this.___$$vis$$, properties[ 'public' ] ); - // if we're inheriting, perform a setup that doesn't include everything - // that we don't want (e.g. private properties) + // Copies all public and protected members into inst_props and stores + // private in a separate object, which adds inst_props to its prototype + // chain and is returned. This is stored in a property referenced by the + // class id, so that the private members can be swapped on each method + // request, depending on calling context. var vis = this.___$$vis$$[ cid ] = propobj.setup( inst_props, properties, members ); diff --git a/lib/propobj.js b/lib/propobj.js index 647cb19..561e48c 100644 --- a/lib/propobj.js +++ b/lib/propobj.js @@ -56,6 +56,11 @@ exports.setup = function( dest, properties, methods ) obj_ctor.prototype = dest; obj = new obj_ctor(); + + // all private protected proxies need to be proxied from the private + // object (which will be passed as the context) to the object containing + // protected values + exports.createPropProxy( dest, obj, properties[ 'protected' ] ); } // initialize each of the properties for this instance to diff --git a/test/test-class-visibility.js b/test/test-class-visibility.js index 7fdc59b..0d6fa69 100644 --- a/test/test-class-visibility.js +++ b/test/test-class-visibility.js @@ -692,3 +692,36 @@ var common = require( './common' ), ); } )(); + +/** + * There was an issue where the private property object was not proxying values + * to the true protected values. This would mean that when the parent + * initialized protected values, those values would be unavailable to the + * subtype. Instead, the value available to the subtype was the value that was + * assigned as the default value in the class definition. + */ +( function testProtectedValuesAreAvailableToSubtypesWhenSetByParentMethod() +{ + var expected = 5, + result = Class( + { + 'protected val': 0, + + 'public __construct': function() + { + this.val = expected; + }, + } ).extend( + { + 'public getVal': function() + { + return this.val; + }, + } )().getVal(); + + assert.equal( result, expected, + "Subtypes should have acess to protected properties values set by " + + "super methods" + ); +} )(); +