1
0
Fork 0

Added virtual and override restrictions to getters/setters

perfodd
Mike Gerwitz 2011-12-22 23:10:01 -05:00
parent 9942ac9743
commit db84c6fc6e
4 changed files with 56 additions and 6 deletions

View File

@ -321,6 +321,21 @@ exports.prototype.validateGetterSetter = function(
); );
} }
if ( !( prev_keywords[ 'virtual' ] ) )
{
throw TypeError(
"Cannot override non-virtual getter/setter '" + name + "'"
);
}
if ( !( keywords[ 'override' ] ) )
{
throw TypeError(
"Attempting to override getter/setter '" + name +
"' without 'override' keyword"
);
}
// do not permit visibility de-escalation // do not permit visibility de-escalation
if ( this._getVisibilityValue( prev_keywords || {} ) if ( this._getVisibilityValue( prev_keywords || {} )
< this._getVisibilityValue( keywords ) < this._getVisibilityValue( keywords )

View File

@ -40,7 +40,8 @@ require( 'common' ).testCase(
this.quickKeywordTest = function( keywords, identifier, prev ) this.quickKeywordTest = function( keywords, identifier, prev )
{ {
shared.quickKeywordTest.call( this, shared.quickKeywordTest.call( this,
'validateGetterSetter', keywords, identifier, prev 'validateGetterSetter', keywords, identifier, prev,
{ get: function() {}, set: function() {} }
); );
}; };
@ -49,6 +50,9 @@ require( 'common' ).testCase(
shared.quickVisChangeTest.call( _self, start, override, failtest, shared.quickVisChangeTest.call( _self, start, override, failtest,
function( name, startobj, overrideobj ) function( name, startobj, overrideobj )
{ {
startobj.virtual = true;
overrideobj.override = true;
_self.sut.validateGetterSetter( _self.sut.validateGetterSetter(
name, {}, overrideobj, name, {}, overrideobj,
{ get: function() {}, set: function() {} }, { get: function() {}, set: function() {} },
@ -165,4 +169,33 @@ require( 'common' ).testCase(
{ {
this.quickKeywordTest( [ 'const' ], 'const' ); this.quickKeywordTest( [ 'const' ], 'const' );
}, },
/**
* Getters/setters can be overridden just like methods, so long as they
* follow the same keyword restrictions.
*/
'Can override virtual getter/setter with override keyword': function()
{
this.quickKeywordTest( [ 'override' ], null, [ 'virtual' ] );
},
/**
* The 'override' keyword must be provided if a member is being overridden.
*/
'Must provide override keyword when overriding getter/setter': function()
{
this.quickKeywordTest( [], 'override', [ 'virtual' ] );
},
/**
* Just like methods, getters/setters may only be overridden if they have
* been declared 'virtual'.
*/
'Cannot override non-virtual getter/setter': function()
{
this.quickKeywordTest( [ 'override' ], 'non-virtual', [] );
},
} ); } );

View File

@ -82,11 +82,13 @@ exports.quickFailureTest = function( name, identifier, action )
* To test overrides, specify keywords for 'prev'. To test for success instead * To test overrides, specify keywords for 'prev'. To test for success instead
* of failure, set identifier to null. * of failure, set identifier to null.
*/ */
exports.quickKeywordTest = function( type, keywords, identifier, prev ) exports.quickKeywordTest = function(
type, keywords, identifier, prev, prev_data
)
{ {
var keyword_obj = {}, var keyword_obj = {},
prev_obj = {}, prev_obj = {},
prev_data = {}, prev_data = prev_data || {},
name = exports.testName, name = exports.testName,
_self = this; _self = this;
@ -106,7 +108,7 @@ exports.quickKeywordTest = function( type, keywords, identifier, prev )
} }
// define a dummy previous method value // define a dummy previous method value
prev_data = { member: function() {} }; prev_data.member = function() {};
} }
var testfunc = function() var testfunc = function()

View File

@ -52,7 +52,7 @@ Object.defineProperty( foo_def, 'foo', {
enumerable: true, enumerable: true,
} ); } );
Object.defineProperty( foo_def, 'bar', { Object.defineProperty( foo_def, 'virtual bar', {
get: function () get: function ()
{ {
return 'durp'; return 'durp';
@ -64,7 +64,7 @@ Object.defineProperty( foo_def, 'bar', {
enumerable: true, enumerable: true,
} ); } );
Object.defineProperty( sub_foo_def, 'bar', { Object.defineProperty( sub_foo_def, 'override bar', {
get: function () get: function ()
{ {
return this.bar2; return this.bar2;