1
0
Fork 0

Re-implemented mixin error for member name conflicts

perfodd
Mike Gerwitz 2014-01-23 01:00:16 -05:00
parent 71358eab59
commit 3724b1bc0d
2 changed files with 34 additions and 32 deletions

View File

@ -117,6 +117,7 @@ function mixin( trait, dfn )
// retrieve the private member name that will contain this trait object // retrieve the private member name that will contain this trait object
var iname = addTraitInst( trait.__ccls, dfn ); var iname = addTraitInst( trait.__ccls, dfn );
// TODO: protected; ignore abstract
for ( var f in pub ) for ( var f in pub )
{ {
if ( !( Object.hasOwnProperty.call( pub, f ) ) ) if ( !( Object.hasOwnProperty.call( pub, f ) ) )
@ -133,8 +134,18 @@ function mixin( trait, dfn )
continue; continue;
} }
var pname = 'public proxy ' + f;
// if we have already set up a proxy for a field of this name, then
// multiple traits have defined the same concrete member
if ( dfn[ pname ] !== undefined )
{
// TODO: between what traits?
throw Error( "Trait member conflict: `" + f + "'" );
}
// proxy this method to what will be the encapsulated trait object // proxy this method to what will be the encapsulated trait object
dfn[ 'public proxy ' + f ] = iname; dfn[ pname ] = iname;
} }
return dfn; return dfn;

View File

@ -32,36 +32,31 @@ require( 'common' ).testCase(
this.Sut, this.Sut,
]; ];
// trait field name conflicts // trait field name conflicts (methods)
this.fconflict = [ this.fconflict = [
// same name; property [ 'foo', "same name; no keywords",
[ 'foo', { foo: function() {} },
{ foo: 'a' },
{ foo: 'b' },
],
// same name; prop and method
[ 'foo',
{ foo: 'a' },
{ foo: function() {} }, { foo: function() {} },
], ],
// same keywords [ 'foo', "same keywords; same visibility",
[ 'foo', { 'public foo': function() {} },
{ 'public foo': 'a' }, { 'public foo': function() {} },
{ 'public foo': 'b' },
], ],
// different keywords should be (for the time being) picked up // should (at least for the time being) be picked up by existing
// by existing class error checks // class error checks
[ 'foo', [ 'foo', "varying keywords; same visibility",
{ 'public foo': 'a' }, { 'virtual public foo': function() {} },
{ 'protected foo': 'b' }, { 'public virtual foo': function() {} },
], ],
[ 'bar',
{ 'virtual bar': function() {} }, /* TODO
{ 'public bar': function() {} }, [ 'foo', "different visibility",
{ 'public foo': function() {} },
{ 'protected foo': function() {} },
], ],
*/
]; ];
}, },
@ -223,14 +218,10 @@ require( 'common' ).testCase(
'@each(fconflict) Cannot mix in multiple concrete methods of same name': '@each(fconflict) Cannot mix in multiple concrete methods of same name':
function( dfns ) function( dfns )
{ {
// TODO: not yet working with composition approach var fname = dfns[ 0 ],
this.skip(); desc = dfns[ 1 ],
A = this.Sut( dfns[ 2 ] ),
var fname = dfns[ 0 ]; B = this.Sut( dfns[ 3 ] );
// both traits define `foo'
var A = this.Sut( dfns[ 1 ] ),
B = this.Sut( dfns[ 2 ] );
// this, therefore, should error // this, therefore, should error
try try
@ -253,7 +244,7 @@ require( 'common' ).testCase(
return; return;
} }
this.fail( "Mixin must fail on conflict" ); this.fail( false, true, "Mixin must fail on conflict: " + desc );
}, },