From dac4b9b3a112872aaaa7c939fbd675449e30584c Mon Sep 17 00:00:00 2001 From: Mike Gerwitz Date: Wed, 29 Jan 2014 00:20:08 -0500 Subject: [PATCH] The `weak' keyword can now apply to overrides Well, technically anything, but we're leaving that behavior as undefined for now (the documentation will say the same thing). --- lib/MemberBuilder.js | 14 +++++----- lib/MemberBuilderValidator.js | 2 +- test/MemberBuilder/MethodTest.js | 47 ++++++++++++++++++++++++++++++++ 3 files changed, 55 insertions(+), 8 deletions(-) diff --git a/lib/MemberBuilder.js b/lib/MemberBuilder.js index 0f12c51..ce7883e 100644 --- a/lib/MemberBuilder.js +++ b/lib/MemberBuilder.js @@ -140,19 +140,19 @@ exports.buildMethod = function( } else if ( prev ) { - if ( keywords[ 'override' ] || prev_keywords[ 'abstract' ] ) + if ( keywords.weak ) + { + // another member of the same name has been found; discard the + // weak declaration + return false; + } + else if ( keywords[ 'override' ] || prev_keywords[ 'abstract' ] ) { // override the method dest[ name ] = this._overrideMethod( prev, value, instCallback, cid ); } - else if ( keywords.weak && keywords[ 'abstract' ] ) - { - // another member of the same name has been found; discard the - // weak declaration - return false; - } else { // by default, perform method hiding, even if the keyword was not diff --git a/lib/MemberBuilderValidator.js b/lib/MemberBuilderValidator.js index 707ff88..ffe657c 100644 --- a/lib/MemberBuilderValidator.js +++ b/lib/MemberBuilderValidator.js @@ -187,7 +187,7 @@ exports.prototype.validateMethod = function( // warning to default to method hiding. Note the check for a if ( !( keywords[ 'override' ] || prev_keywords[ 'abstract' ] - || ( keywords[ 'abstract' ] && keywords.weak ) + || keywords.weak ) ) { throw TypeError( diff --git a/test/MemberBuilder/MethodTest.js b/test/MemberBuilder/MethodTest.js index 4ca7200..ca2dcb7 100644 --- a/test/MemberBuilder/MethodTest.js +++ b/test/MemberBuilder/MethodTest.js @@ -231,4 +231,51 @@ require( 'common' ).testCase( this.members[ 'public' ].foo(); this.assertOk( called, "Concrete method unkept" ); }, + + + /** + * Same concept as the above, but with virtual methods (which have a + * concrete implementation available by default). + */ + 'Weak virtual methods are not processed if override is available': + function() + { + var _self = this, + called = false, + + cid = 1, + name = 'foo', + oval = function() { called = true; }, + vval = function() + { + _self.fail( true, false, "Method not overridden." ); + }, + + okeywords = { 'override': true }, + vkeywords = { weak: true, 'virtual': true }, + + instCallback = function() {} + ; + + // define the virtual method + this.assertOk( this.sut.buildMethod( + this.members, {}, name, vval, vkeywords, instCallback, cid, {} + ) ); + + // override should take precedence + this.assertOk( this.sut.buildMethod( + this.members, {}, name, oval, okeywords, instCallback, cid, {} + ) ); + + this.members[ 'public' ].foo(); + this.assertOk( called, "Override did not take precedence" ); + + // now try virtual again to ensure this works from both directions + this.assertOk( this.sut.buildMethod( + this.members, {}, name, vval, vkeywords, instCallback, cid, {} + ) === false ); + + this.members[ 'public' ].foo(); + this.assertOk( called, "Override unkept" ); + }, } );