1
0
Fork 0

Added support for `weak' keyword

Note that, even though it's permitted, the validator still needs to be
modified to permit useful cases. In particular, I need weak abstract and
strong concrete methods for use in traits.
perfodd
Mike Gerwitz 2014-01-23 23:43:34 -05:00
parent 00c76c69df
commit 18ac37c871
4 changed files with 72 additions and 7 deletions

View File

@ -338,7 +338,7 @@ exports.prototype.build = function extend( _, __ )
// increment class identifier
this._classId++;
// build the various class components (xxx: this is temporary; needs
// build the various class components (XXX: this is temporary; needs
// refactoring)
try
{
@ -464,8 +464,11 @@ exports.prototype.buildMembers = function buildMembers(
}
// if a member was defined multiple times in the same class
// declaration, throw an error
if ( hasOwn.call( defs, name ) )
// declaration, throw an error (unless the `weak' keyword is
// provided, which exists to accomodate this situation)
if ( hasOwn.call( defs, name )
&& !( keywords['weak'] || defs[ name ].weak )
)
{
throw Error(
"Cannot redefine method '" + name + "' in same declaration"
@ -474,7 +477,7 @@ exports.prototype.buildMembers = function buildMembers(
// keep track of the definitions (only during class declaration)
// to catch duplicates
defs[ name ] = 1;
defs[ name ] = keywords;
},
property: function( name, value, keywords )

View File

@ -33,6 +33,7 @@ var _keywords = {
'virtual': true,
'override': true,
'proxy': true,
'weak': true,
};

View File

@ -23,8 +23,18 @@ require( 'common' ).testCase(
{
caseSetUp: function()
{
// XXX: the Sut is not directly tested; get rid of these!
this.Class = this.require( 'class' );
this.AbstractClass = this.require( 'class_abstract' );
this.Sut = this.require( 'ClassBuilder' );
// weak flag test data
this.weak = [
[ 'weak foo', 'foo' ], // former weak
[ 'foo', 'weak foo' ], // latter weak
[ 'weak foo', 'weak foo' ], // both weak
];
},
@ -227,4 +237,55 @@ require( 'common' ).testCase(
}, Error, "Forced-public methods must be declared as public" );
}
},
/**
* If different keywords are used, then a definition object could
* contain two members of the same name. This is probably a bug in the
* user's implementation, so we should flip our shit.
*
* But, see the next test.
*/
'Cannot define two members of the same name': function()
{
var _self = this;
this.assertThrows( function()
{
// duplicate foos
_self.Class(
{
'public foo': function() {},
'protected foo': function() {},
} );
} );
},
/**
* Code generation tools may find it convenient to declare a duplicate
* member without knowing whether or not a duplicate will exist; this
* may save time and complexity when ease.js has been designed to handle
* certain situations. If at least one of the conflicting members has
* been flagged as `weak', then we should ignore the error.
*
* As an example, this is used interally with ease.js to inherit
* abstract members from traits while still permitting concrete
* definitions.
*/
'@each(weak) Can define members of the same name if one is weak':
function( weak )
{
// TODO: this makes assumptions about how the code works; the code
// needs to be refactored to permit more sane testing (since right
// now it'd be a clusterfuck)
var dfn = {};
dfn[ 'abstract ' + weak[ 0 ] ] = [];
dfn[ 'abstract ' + weak[ 1 ] ] = [];
var _self = this;
this.assertDoesNotThrow( function()
{
_self.AbstractClass( dfn );
} );
},
} );

View File

@ -100,7 +100,7 @@ require( 'common' ).testCase(
parse(
'public protected private ' +
'virtual abstract override ' +
'static const proxy ' +
'static const proxy weak ' +
'var'
);
}, Error );