diff --git a/lib/Trait.js b/lib/Trait.js index cae1a31..cad5e3c 100644 --- a/lib/Trait.js +++ b/lib/Trait.js @@ -22,6 +22,7 @@ var AbstractClass = require( './class_abstract' ), Class = require( './class' ), ClassBuilder = require( './ClassBuilder' ), + FinalClass = require( './class_final' ), Interface = require( './interface' ); @@ -123,9 +124,19 @@ Trait.extend = function() type = _getTraitType( dfn ), isparam = ( type === 'param' ); - if ( has_extend && !Class.isClass( extend ) ) + if ( has_extend ) { - throw TypeError( "Trait " + name + " cannot extend non-class" ); + if ( !Class.isClass( extend ) ) + { + throw TypeError( "Trait " + name + " cannot extend non-class" ); + } + else if ( extend.___$$final$$ === true ) + { + throw TypeError( + "Trait " + name + " cannot extend final class " + + extend.toString() + ) + } } // augment the parser to handle our own oddities diff --git a/test/Trait/ClassExtendTest.js b/test/Trait/ClassExtendTest.js index 7c4e327..8ce7fd0 100644 --- a/test/Trait/ClassExtendTest.js +++ b/test/Trait/ClassExtendTest.js @@ -25,6 +25,7 @@ require( 'common' ).testCase( { this.Sut = this.require( 'Trait' ); this.Class = this.require( 'class' ); + this.FinalClass = this.require( 'class_final' ); // nonsensical extend bases this.nonsense = [ @@ -259,4 +260,19 @@ require( 'common' ).testCase( _self.Sut.extend( _self.Sut( {} ), {} ); }, TypeError ); }, + + + /** + * For consistency with the rest of the system, final classes are not + * permitted to be extended. + */ + 'Traits cannot extend final classes': function() + { + var _self = this; + + this.assertThrows( function() + { + _self.Sut.extend( _self.FinalClass( {} ), {} ); + }, TypeError ); + }, } );