From 2e930482d27c3fa31d614d3bad028c6fa788e652 Mon Sep 17 00:00:00 2001 From: Mike Gerwitz Date: Wed, 1 Dec 2010 21:34:57 -0500 Subject: [PATCH] Abstract methods of subtypes overriding abstract methods must be compatiable with the previous definition --- lib/util.js | 23 +++++++++++++++-------- test/test-class-abstract.js | 24 ++++++++++++++++++++++++ 2 files changed, 39 insertions(+), 8 deletions(-) diff --git a/lib/util.js b/lib/util.js index 7ef5600..323a55f 100644 --- a/lib/util.js +++ b/lib/util.js @@ -255,17 +255,19 @@ function method_override( throw new TypeError( "Cannot override method with non-method" ); } - // if we were given a concrete method to an abstract method, - // then the method should no longer be considered abstract - if ( ( abstract_map[ name ] !== undefined ) - && ( exports.isAbstractMethod( new_method.abstractFlag ) === false ) - ) + if ( abstract_map[ name ] !== undefined ) { + var is_abstract = exports.isAbstractMethod( new_method ); + if ( super_method.definition instanceof Array ) { + var arg_len = ( is_abstract ) + ? new_method.definition.length + : new_method.length; + // ensure the concrete definition is compatible with // that of its supertype - if ( new_method.length < super_method.definition.length ) + if ( arg_len < super_method.definition.length ) { throw new Error( "Declaration of " + name + " must be compatiable" + @@ -274,8 +276,13 @@ function method_override( } } - delete abstract_methods[ abstract_map[ name ] ]; - data.abstractModified = true; + // if this was a concrete method, then it should no longer be marked as + // abstract + if ( is_abstract === false ) + { + delete abstract_methods[ abstract_map[ name ] ]; + data.abstractModified = true; + } } // this is the method that will be invoked when the requested diff --git a/test/test-class-abstract.js b/test/test-class-abstract.js index 96c84f6..98ebd59 100644 --- a/test/test-class-abstract.js +++ b/test/test-class-abstract.js @@ -172,6 +172,30 @@ assert.throws( function() }); }, Error, "Concrete methods must implement the proper number of argments" ); +assert.throws( function() +{ + AbstractFoo.extend( + { + // incorrect number of arguments + method: abstractMethod(), + }); +}, Error, "Abstract methods of subtypes must implement the proper number of argments" ); + +assert.doesNotThrow( + function() + { + AbstractFoo.extend( + { + // incorrect number of arguments + method: abstractMethod( 'one', 'two', 'three', 'four' ), + }); + }, + Error, + "Abstract methods of subtypes may implement additional arguments, so long" + + "as they implement at least the required number of arguments as defined by " + + "it supertype" +); + assert.doesNotThrow( function() {