diff --git a/lib/member_builder.js b/lib/member_builder.js index 4cc138b..eef4c11 100644 --- a/lib/member_builder.js +++ b/lib/member_builder.js @@ -76,6 +76,15 @@ exports.buildMethod = function( members, meta, name, value, keywords ) ); } + // do not allow overriding concrete methods with abstract + if ( keywords[ 'abstract' ] && !( util.isAbstractMethod( prev ) ) ) + { + throw TypeError( + "Cannot override concrete method '" + name + "' with " + + "abstract method" + ); + } + // ensure parameter list is at least the length of its supertype if ( ( value.__length || value.length ) < ( prev.__length || prev.length ) diff --git a/test/test-member_builder-method.js b/test/test-member_builder-method.js index 571cd5b..c5c711d 100644 --- a/test/test-member_builder-method.js +++ b/test/test-member_builder-method.js @@ -134,3 +134,20 @@ mb_common.assertCommon(); mb_common.members[ 'public' ][ mb_common.name ](); } )(); + +/** + * Once a concrete implementation has been defined for a method, a subtype + * cannot make it abstract. + */ +( function testCannotOverrideConcreteMethodWithAbstractMethod() +{ + // concrete method + mb_common.value = function() {}; + mb_common.buildMemberQuick(); + + assert.throws( function() + { + mb_common.buildMemberQuick( { 'abstract': true }, true ); + }, TypeError, "Cannot override concrete method with abstract method" ); +} )(); +