diff --git a/README.md b/README.md index 733efc3..84186a3 100644 --- a/README.md +++ b/README.md @@ -209,12 +209,12 @@ be considered abstract and must be declared as such. ### Interfaces Interfaces can be declared in a very similar manner to classes. All members of -an interface must be declared as abstract. +an interface are implicitly abstract. ````javascript var MyType = Interface( { - 'abstract public foo': [] + 'public foo': [] }); ```` diff --git a/lib/interface.js b/lib/interface.js index a23370e..5798f0a 100644 --- a/lib/interface.js +++ b/lib/interface.js @@ -210,34 +210,22 @@ var extend = ( function( extending ) var new_interface = createInterface( iname ); util.propParse( props, { + assumeAbstract: true, + property: function() { - throw TypeError( - "Property not permitted within definition of " + - "Interface '" + iname + "' (did you forget the " + - "'abstract' keyword?)" - ); + // should never get to this point because of assumeAbstract + throw TypeError( 'Unexpected internal error' ); }, getset: function() { - throw TypeError( - "Getters/setters are not permitter within definition " + - "of Interface '" + iname + "'" - ); + // should never get to this point because of assumeAbstract + throw TypeError( 'Unexpected internal error' ); }, method: function( name, value, is_abstract, keywords ) { - if ( !is_abstract ) - { - throw TypeError( - "Concrete method not permitted in declaration of " + - "Interface '" + iname + "'; please declare as " + - "abstract." - ); - } - // all members must be public if ( keywords[ 'protected' ] || keywords[ 'private' ] ) { diff --git a/lib/util.js b/lib/util.js index 65dd9e1..cf4b4d6 100644 --- a/lib/util.js +++ b/lib/util.js @@ -297,7 +297,7 @@ exports.propParse = function( data, options ) name = parse_data.name || prop; keywords = parse_data.keywords || {}; - if ( keywords['abstract'] ) + if ( options.assumeAbstract || keywords['abstract'] ) { if ( !( value instanceof Array ) ) { diff --git a/test/Interface/ExtendTest.js b/test/Interface/ExtendTest.js index 8932fd2..9dbeb0a 100644 --- a/test/Interface/ExtendTest.js +++ b/test/Interface/ExtendTest.js @@ -38,11 +38,11 @@ common.testCase( this.baseTypes = [ Interface.extend( { - 'abstract method': [], + method: [], } ), Interface( { - 'abstract method': [], + method: [], } ) ]; @@ -113,14 +113,20 @@ common.testCase( }, - 'Abstract method declarations are permitted': function() + /** + * Declaring (but not defining) methods by specifying their arguments as + * arrays is supported, much like one would would declare an abstract method + * in a class. We do not require the abstract keyword, as it would be + * redundant. + */ + 'Method declarations (using arrays) are permitted': function() { this.assertDoesNotThrow( function() { Interface.extend( { - 'abstract method': [], + method: [], } ); }, TypeError, @@ -200,7 +206,7 @@ common.testCase( { var SubType = Interface.extend( T, { - 'abstract second': [], + second: [], } ); this.assertOk( @@ -247,7 +253,7 @@ common.testCase( { var SubType = T.extend( { - 'abstract second': [], + second: [], } ); this.assertOk( @@ -319,7 +325,7 @@ common.testCase( { // am = access modifier var dfn = {}; - dfn[ 'abstract ' + am + ' foo' ] = []; + dfn[ am + ' foo' ] = []; Interface( dfn ); }, Error, "Interface members should not be able to be " + am );