v8/test/mjsunit/harmony/super.js
arv 4b8051a02a [es6] Super call in arrows and eval
This splits the SuperReference AST node into SuperPropertyReference and
SuperCallReference. The super call reference node consists of three
unresolved vars to this, new.target and this_function. These gets
declared when the right function is entered and if it is in use. The
variables gets assigned in FullCodeGenerator::Generate.

This is a revert of the revert 88b1c9170a

BUG=v8:3768
LOG=N
R=wingo@igalia.com, adamk@chromium.org

Review URL: https://codereview.chromium.org/1168513004

Cr-Commit-Position: refs/heads/master@{#28769}
2015-06-02 22:04:33 +00:00

2206 lines
52 KiB
JavaScript

// Copyright 2014 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Flags: --harmony-classes --harmony-arrow-functions --allow-natives-syntax
// Flags: --harmony-spreadcalls
(function TestSuperNamedLoads() {
function Base() { }
function fBase() { }
Base.prototype = {
f() {
return "Base " + this.toString();
},
x: 15,
toString() {
return "this is Base";
}
};
function Derived() {
this.derivedDataProperty = "xxx";
}
Derived.prototype = {
__proto__: Base.prototype,
toString() { return "this is Derived"; },
x: 27,
f() {
assertEquals("Base this is Derived", super.f());
var a = super.x;
assertEquals(15, a);
assertEquals(15, super.x);
assertEquals(27, this.x);
return "Derived";
}
};
assertEquals("Base this is Base", new Base().f());
assertEquals("Derived", new Derived().f());
}());
(function TestSuperKeyedLoads() {
'use strict';
var x = 'x';
var derivedDataProperty = 'derivedDataProperty';
var f = 'f';
class Base {
f() {
return "Base " + this.toString();
}
toString() {
return "this is Base";
}
}
Base.prototype[x] = 15;
function Derived() {
this[derivedDataProperty] = "xxx";
}
Derived.prototype = {
__proto__: Base.prototype,
toString() { return "this is Derived"; },
x: 27,
f() {
assertEquals("Base this is Derived", super[f]());
var a = super[x];
assertEquals(15, a);
assertEquals(15, super[x]);
assertEquals(27, this[x]);
return "Derived";
}
};
assertEquals("Base this is Base", new Base().f());
assertEquals("Derived", new Derived().f());
}());
(function TestSuperNumericKeyedLoads() {
var x = 1;
var derivedDataProperty = 2;
var f = 3;
function Base() { }
function fBase() { return "Base " + this.toString(); }
Base.prototype[f] = %ToMethod(fBase, Base.prototype);
Base.prototype[x] = 15;
Base.prototype.toString = function() { return "this is Base"; };
function Derived() {
this[derivedDataProperty] = "xxx";
}
Derived.prototype = {
__proto__: Base.prototype,
toString() { return "this is Derived"; },
1: 27,
3() {
assertEquals("Base this is Derived", super[f]());
var a = super[x];
assertEquals(15, a);
assertEquals(15, super[x]);
assertEquals(27, this[x]);
return "Derived";
}
};
assertEquals("Base this is Base", new Base()[f]());
assertEquals("Derived", new Derived()[f]());
}());
(function TestSuperKeywordNonMethod() {
'use strict';
class C {
f() {
super.unknown();
}
}
assertThrows(function() {
new C().f();
}, TypeError);
}());
(function TestGetter() {
function Base() {}
var derived;
Base.prototype = {
constructor: Base,
get x() {
assertSame(this, derived);
return this._x;
},
_x: 'base'
};
function Derived() {}
Derived.__proto__ = Base;
Derived.prototype = {
__proto__: Base.prototype,
constructor: Derived,
_x: 'derived',
testGetter() {
return super.x;
},
testGetterStrict() {
'use strict';
return super.x;
}
};
derived = new Derived();
assertEquals('derived', derived.testGetter());
derived = new Derived();
assertEquals('derived', derived.testGetterStrict());
}());
(function TestGetterKeyed() {
var x = 'x';
function Base() {}
var derived;
Base.prototype = {
constructor: Base,
get x() {
assertSame(this, derived);
return this._x;
},
_x: 'base'
};
function Derived() {}
Derived.__proto__ = Base;
Derived.prototype = {
__proto__: Base.prototype,
constructor: Derived,
_x: 'derived',
testGetter() {
return super[x];
},
testGetterStrict() {
'use strict';
return super[x];
},
testGetterWithToString() {
var toStringCalled;
var o = { toString: function() {
toStringCalled++;
return 'x';
} };
toStringCalled = 0;
assertEquals('derived', super[o]);
assertEquals(1, toStringCalled);
var eToThrow = new Error();
var oThrowsInToString = { toString: function() {
throw eToThrow;
} };
var ex = null;
try {
super[oThrowsInToString];
} catch(e) { ex = e }
assertEquals(eToThrow, ex);
var oReturnsNumericString = { toString: function() {
return "1";
} };
assertEquals(undefined, super[oReturnsNumericString]);
assertEquals(undefined, super[1]);
}
};
derived = new Derived();
assertEquals('derived', derived.testGetter());
derived = new Derived();
assertEquals('derived', derived.testGetterStrict());
derived = new Derived();
derived.testGetterWithToString();
}());
(function TestGetterNumericKeyed() {
var x = 42;
function Base() {}
var derived;
Base.prototype = {
constructor: Base,
_x: 'base'
};
Object.defineProperty(Base.prototype, x, { get: function() {
assertSame(this, derived);
return this._x;
}});
function Derived() {}
Derived.__proto__ = Base;
Derived.prototype = {
__proto__: Base.prototype,
constructor: Derived,
_x: 'derived',
testGetter() {
return super[x];
},
testGetterStrict() {
'use strict';
return super[x];
},
testGetterWithToString() {
var toStringCalled;
var o = {
toString: function() {
toStringCalled++;
return '42';
}
};
toStringCalled = 0;
assertEquals('derived', super[o]);
assertEquals(1, toStringCalled);
var eToThrow = new Error();
var oThrowsInToString = {
toString: function() {
throw eToThrow;
}
};
var ex = null;
try {
super[oThrowsInToString];
} catch(e) { ex = e }
assertEquals(eToThrow, ex);
var oReturnsNumericString = {
toString: function() {
return "42";
}
};
assertEquals('derived', super[oReturnsNumericString]);
assertEquals('derived', super[42]);
}
};
derived = new Derived();
assertEquals('derived', derived.testGetter());
derived = new Derived();
assertEquals('derived', derived.testGetterStrict());
derived = new Derived();
derived.testGetterWithToString();
}());
(function TestSetter() {
function Base() {}
Base.prototype = {
constructor: Base,
get x() {
return this._x;
},
set x(v) {
this._x = v;
},
_x: 'base'
};
function Derived() {}
Derived.__proto__ = Base;
Derived.prototype = {
__proto__: Base.prototype,
constructor: Derived,
_x: 'derived',
testSetter() {
assertEquals('foobar', super.x = 'foobar');
assertEquals('foobarabc', super.x += 'abc');
},
testSetterStrict() {
'use strict';
assertEquals('foobar', super.x = 'foobar');
assertEquals('foobarabc', super.x += 'abc');
}
};
var d = new Derived();
d.testSetter();
assertEquals('base', Base.prototype._x);
assertEquals('foobarabc', d._x);
d._x = '';
d.testSetterStrict();
assertEquals('base', Base.prototype._x);
assertEquals('foobarabc', d._x);
}());
(function TestSetterNumericKeyed() {
var x = 42;
function Base() {}
Base.prototype = {
constructor: Base,
_x: 'base'
};
Object.defineProperty(Base.prototype, x,
{ get: function() { return this._x; },
set: function(v) { this._x = v; }
});
function Derived() {}
Derived.__proto__ = Base;
Derived.prototype = {
__proto__: Base.prototype,
constructor: Derived,
_x: 'derived',
testSetter() {
assertEquals('foobar', super[x] = 'foobar');
assertEquals('foobarabc', super[x] += 'abc');
},
testSetterStrict() {
'use strict';
assertEquals('foobar', super[x] = 'foobar');
assertEquals('foobarabc', super[x] += 'abc');
},
testSetterWithToString() {
var toStringCalled;
var o = {
toString: function() {
toStringCalled++;
return x;
}
};
toStringCalled = 0;
super[o] = 'set';
assertEquals(1, toStringCalled);
assertEquals('set', this._x);
var eToThrow = new Error();
var oThrowsInToString = {
toString: function() {
throw eToThrow;
}
};
var ex = null;
try {
super[oThrowsInToString] = 'xyz';
} catch(e) { ex = e }
assertEquals(eToThrow, ex);
assertEquals('set', this._x);
}
};
var d = new Derived();
d.testSetter();
assertEquals('base', Base.prototype._x);
assertEquals('foobarabc', d._x);
d._x = '';
d.testSetterStrict();
assertEquals('base', Base.prototype._x);
assertEquals('foobarabc', d._x);
d = new Derived();
d.testSetterWithToString();
}());
(function TestSetterKeyed() {
var x = 'x';
function Base() {}
Base.prototype = {
constructor: Base,
get x() {
return this._x;
},
set x(v) {
this._x = v;
},
_x: 'base'
};
function Derived() {}
Derived.__proto__ = Base;
Derived.prototype = {
__proto__: Base.prototype,
constructor: Derived,
_x: 'derived',
testSetter() {
assertEquals('foobar', super[x] = 'foobar');
assertEquals('foobarabc', super[x] += 'abc');
},
testSetterStrict() {
'use strict';
assertEquals('foobar', super[x] = 'foobar');
assertEquals('foobarabc', super[x] += 'abc');
},
testSetterWithToString() {
var toStringCalled;
var o = {
toString: function() {
toStringCalled++;
return 'x';
}
};
toStringCalled = 0;
super[o] = 'set';
assertEquals(1, toStringCalled);
assertEquals('set', this._x);
var eToThrow = new Error();
var oThrowsInToString = {
toString: function() {
throw eToThrow;
}
};
var ex = null;
try {
super[oThrowsInToString] = 'xyz';
} catch(e) { ex = e }
assertEquals(eToThrow, ex);
assertEquals('set', this._x);
var oReturnsNumericString = {
toString: function() {
return "1";
}
};
assertEquals('abc', super[oReturnsNumericString] = 'abc');
assertEquals('set', this._x);
assertEquals(10, super[1] = 10);
}
};
var d = new Derived();
d.testSetter();
assertEquals('base', Base.prototype._x);
assertEquals('foobarabc', d._x);
d._x = '';
d.testSetterStrict();
assertEquals('base', Base.prototype._x);
assertEquals('foobarabc', d._x);
d = new Derived();
d.testSetterWithToString();
}());
(function TestSetterDataProperties() {
function Base() {}
Base.prototype = {
constructor: Base,
x: 'x from Base'
};
function Derived() {}
Derived.prototype = {
__proto__: Base.prototype,
constructor: Derived,
testSetter() {
assertEquals('x from Base', super.x);
super.x = 'data property';
assertEquals('x from Base', super.x);
assertEquals('data property', this.x);
}
};
new Derived().testSetter();
}());
(function TestKeyedSetterDataProperties() {
var x = 'x';
function Base() {}
Base.prototype = {
constructor: Base,
x: 'x from Base'
};
function Derived() {}
Derived.prototype = {
__proto__: Base.prototype,
constructor: Derived,
testSetter() {
assertEquals('x from Base', super[x]);
super[x] = 'data property';
assertEquals('x from Base', super[x]);
assertEquals('data property', this[x]);
}
};
new Derived().testSetter();
}());
(function TestKeyedNumericSetterDataProperties() {
var x = 42;
function Base() {}
Base.prototype = {
constructor: Base,
42: 'x from Base'
};
function Derived() {}
Derived.prototype = {
__proto__: Base.prototype,
constructor: Derived,
testSetter() {
assertEquals('x from Base', super[x]);
super[x] = 'data property';
assertEquals('x from Base', super[x]);
assertEquals('data property', this[x]);
}
};
new Derived().testSetter();
}());
(function TestAccessorsOnPrimitives() {
var getCalled = 0;
var setCalled = 0;
function Base() {}
Base.prototype = {
constructor: Base,
get x() {
getCalled++;
return 1;
},
set x(v) {
setCalled++;
return v;
},
};
function Derived() {}
Derived.prototype = {
__proto__: Base.prototype,
constructor: Derived,
testSetter() {
setCalled = 0;
getCalled = 0;
assertEquals('object', typeof this);
assertInstanceof(this, Number)
assertEquals(42, this.valueOf());
assertEquals(1, super.x);
assertEquals(1, getCalled);
assertEquals(0, setCalled);
assertEquals(5, super.x = 5);
assertEquals(1, getCalled);
assertEquals(1, setCalled);
assertEquals(6, super.x += 5);
assertEquals(2, getCalled);
assertEquals(2, setCalled);
super.newProperty = 15;
assertEquals(15, this.newProperty);
assertEquals(undefined, super.newProperty);
},
testSetterStrict() {
'use strict';
getCalled = 0;
setCalled = 0;
assertTrue(42 === this);
assertEquals(1, super.x);
assertEquals(1, getCalled);
assertEquals(0, setCalled);
assertEquals(5, super.x = 5);
assertEquals(1, getCalled);
assertEquals(1, setCalled);
assertEquals(6, super.x += 5);
assertEquals(2, getCalled);
assertEquals(2, setCalled);
var ex;
try {
super.newProperty = 15;
} catch (e) { ex = e; }
assertInstanceof(ex, TypeError);
}
}
Derived.prototype.testSetter.call(42);
Derived.prototype.testSetterStrict.call(42);
function DerivedFromString() {}
DerivedFromString.prototype = {
__proto__: String.prototype,
f() {
'use strict';
assertTrue(42 === this);
assertEquals(String.prototype.toString, super.toString);
var ex;
try {
super.toString();
} catch(e) { ex = e; }
assertInstanceof(ex, TypeError);
}
};
DerivedFromString.prototype.f.call(42);
}());
(function TestKeyedAccessorsOnPrimitives() {
var x = 'x';
var newProperty = 'newProperty';
var toString = 'toString';
var getCalled = 0;
var setCalled = 0;
function Base() {}
Base.prototype = {
constructor: Base,
get x() {
getCalled++;
return 1;
},
set x(v) {
setCalled++;
return v;
},
};
function Derived() {}
Derived.prototype = {
__proto__: Base.prototype,
constructor: Derived,
testSetter() {
setCalled = 0;
getCalled = 0;
assertEquals('object', typeof this);
assertInstanceof(this, Number)
assertEquals(42, this.valueOf());
assertEquals(1, super[x]);
assertEquals(1, getCalled);
assertEquals(0, setCalled);
assertEquals(5, super[x] = 5);
assertEquals(1, getCalled);
assertEquals(1, setCalled);
assertEquals(6, super[x] += 5);
assertEquals(2, getCalled);
assertEquals(2, setCalled);
super[newProperty] = 15;
assertEquals(15, this[newProperty]);
assertEquals(undefined, super[newProperty]);
},
testSetterStrict() {
'use strict';
getCalled = 0;
setCalled = 0;
assertTrue(42 === this);
assertEquals(1, super[x]);
assertEquals(1, getCalled);
assertEquals(0, setCalled);
assertEquals(5, super[x] = 5);
assertEquals(1, getCalled);
assertEquals(1, setCalled);
assertEquals(6, super[x] += 5);
assertEquals(2, getCalled);
assertEquals(2, setCalled);
var ex;
try {
super[newProperty] = 15;
} catch (e) { ex = e; }
assertInstanceof(ex,TypeError);
}
};
Derived.prototype.testSetter.call(42);
Derived.prototype.testSetterStrict.call(42);
function DerivedFromString() {}
DerivedFromString.prototype = {
__proto__: String.prototype,
f() {
'use strict';
assertTrue(42 === this);
assertEquals(String.prototype.toString, super[toString]);
var ex;
try {
super[toString]();
} catch(e) { ex = e; }
assertInstanceof(ex, TypeError);
}
};
DerivedFromString.prototype.f.call(42);
}());
(function TestNumericKeyedAccessorsOnPrimitives() {
var x = 42;
var newProperty = 43;
var getCalled = 0;
var setCalled = 0;
function Base() {}
Base.prototype = {
constructor: Base,
};
Object.defineProperty(Base.prototype, x, {
get: function() {
getCalled++;
return 1;
},
set: function(v) {
setCalled++;
return v;
}
});
function Derived() {}
Derived.prototype = {
__proto__: Base.prototype,
constructor: Derived,
testSetter() {
setCalled = 0;
getCalled = 0;
assertEquals('object', typeof this);
assertInstanceof(this, Number)
assertEquals(42, this.valueOf());
assertEquals(1, super[x]);
assertEquals(1, getCalled);
assertEquals(0, setCalled);
assertEquals(5, super[x] = 5);
assertEquals(1, getCalled);
assertEquals(1, setCalled);
assertEquals(6, super[x] += 5);
assertEquals(2, getCalled);
assertEquals(2, setCalled);
super[newProperty] = 15;
assertEquals(15, this[newProperty]);
assertEquals(undefined, super[newProperty]);
},
testSetterStrict() {
'use strict';
getCalled = 0;
setCalled = 0;
assertTrue(42 === this);
assertEquals(1, super[x]);
assertEquals(1, getCalled);
assertEquals(0, setCalled);
assertEquals(5, super[x] = 5);
assertEquals(1, getCalled);
assertEquals(1, setCalled);
assertEquals(6, super[x] += 5);
assertEquals(2, getCalled);
assertEquals(2, setCalled);
var ex;
try {
super[newProperty] = 15;
} catch (e) { ex = e; }
assertInstanceof(ex, TypeError);
}
};
Derived.prototype.testSetter.call(42);
Derived.prototype.testSetterStrict.call(42);
}());
(function TestKeyedNumericSetterOnExotics() {
function Base() {}
function Derived() {}
Derived.prototype = {
__proto__: Base.prototype,
callSetterOnArray() {
super[42] = 1;
},
callStrictSetterOnString() {
'use strict';
assertEquals('string', typeof this);
assertTrue('abcdef' === this);
var ex = null;
try {
super[5] = 'q';
} catch(e) { ex = e; }
assertInstanceof(ex, TypeError);
ex = null;
try {
super[1024] = 'q';
} catch(e) { ex = e; }
assertInstanceof(ex, TypeError);
}
};
var x = [];
assertEquals(0, x.length);
Derived.prototype.callSetterOnArray.call(x);
assertEquals(43, x.length);
assertEquals(1, x[42]);
var s = 'abcdef';
Derived.prototype.callStrictSetterOnString.call(s)
}());
(function TestSetterUndefinedProperties() {
function Base() {}
function Derived() {}
Derived.prototype = {
__proto__: Base.prototype,
mSloppy() {
assertEquals(undefined, super.x);
assertEquals(undefined, this.x);
super.x = 10;
assertEquals(10, this.x);
assertEquals(undefined, super.x);
},
mStrict() {
'use strict';
assertEquals(undefined, super.x);
assertEquals(undefined, this.x);
super.x = 10;
assertEquals(10, this.x);
assertEquals(undefined, super.x);
}
};
var d = new Derived();
d.mSloppy();
assertEquals(10, d.x);
var d1 = new Derived();
d1.mStrict();
assertEquals(10, d.x);
}());
(function TestKeyedSetterUndefinedProperties() {
var x = 'x';
function Base() {}
function Derived() {}
Derived.prototype = {
__proto__: Base.prototype,
mSloppy() {
assertEquals(undefined, super[x]);
assertEquals(undefined, this[x]);
super[x] = 10;
assertEquals(10, this[x]);
assertEquals(undefined, super[x]);
},
mStrict() {
'use strict';
assertEquals(undefined, super[x]);
assertEquals(undefined, this[x]);
super[x] = 10;
assertEquals(10, this[x]);
assertEquals(undefined, super[x]);
}
};
var d = new Derived();
d.mSloppy();
assertEquals(10, d.x);
var d1 = new Derived();
d1.mStrict();
assertEquals(10, d.x);
}());
(function TestKeyedNumericSetterUndefinedProperties() {
var x = 42;
function Base() {}
function Derived() {}
Derived.prototype = {
__proto__: Base.prototype,
mSloppy() {
assertEquals(undefined, super[x]);
assertEquals(undefined, this[x]);
super[x] = 10;
assertEquals(10, this[x]);
assertEquals(undefined, super[x]);
},
mStrict() {
'use strict';
assertEquals(undefined, super[x]);
assertEquals(undefined, this[x]);
super[x] = 10;
assertEquals(10, this[x]);
assertEquals(undefined, super[x]);
}
};
var d = new Derived();
d.mSloppy();
assertEquals(10, d[x]);
var d1 = new Derived();
d1.mStrict();
assertEquals(10, d[x]);
}());
(function TestSetterCreatingOwnPropertiesReconfigurable() {
function Base() {}
function Derived() {}
Derived.prototype = {
__proto__: Base.prototype,
mSloppy() {
assertEquals(42, this.ownReadOnly);
super.ownReadOnly = 55;
assertEquals(55, this.ownReadOnly);
var descr = Object.getOwnPropertyDescriptor(this, 'ownReadOnly');
assertEquals(55, descr.value);
assertTrue(descr.configurable);
assertFalse(descr.enumerable);
assertFalse(descr.writable);
assertFalse(Base.prototype.hasOwnProperty('ownReadOnly'));
assertEquals(15, this.ownReadonlyAccessor);
super.ownReadonlyAccessor = 25;
assertEquals(25, this.ownReadonlyAccessor);
var descr = Object.getOwnPropertyDescriptor(this, 'ownReadonlyAccessor');
assertEquals(25, descr.value);
assertTrue(descr.configurable);
assertFalse(descr.enumerable);
assertTrue(descr.writable);
assertFalse(Base.prototype.hasOwnProperty('ownReadonlyAccessor'));
super.ownSetter = 35;
assertEquals(35, this.ownSetter);
var descr = Object.getOwnPropertyDescriptor(this, 'ownSetter');
assertEquals(35, descr.value);
assertTrue(descr.configurable);
assertFalse(descr.enumerable);
assertTrue(descr.writable);
assertFalse(Base.prototype.hasOwnProperty('ownSetter'));
},
mStrict() {
'use strict';
assertEquals(42, this.ownReadOnly);
super.ownReadOnly = 55;
assertEquals(55, this.ownReadOnly);
var descr = Object.getOwnPropertyDescriptor(this, 'ownReadOnly');
assertEquals(55, descr.value);
assertTrue(descr.configurable);
assertFalse(descr.enumerable);
assertFalse(descr.writable);
assertFalse(Base.prototype.hasOwnProperty('ownReadOnly'));
assertEquals(15, this.ownReadonlyAccessor);
super.ownReadonlyAccessor = 25;
assertEquals(25, this.ownReadonlyAccessor);
var descr = Object.getOwnPropertyDescriptor(this, 'ownReadonlyAccessor');
assertEquals(25, descr.value);
assertTrue(descr.configurable);
assertFalse(descr.enumerable);
assertTrue(descr.writable);
assertFalse(Base.prototype.hasOwnProperty('ownReadonlyAccessor'));
super.ownSetter = 35;
assertEquals(35, this.ownSetter);
var descr = Object.getOwnPropertyDescriptor(this, 'ownSetter');
assertEquals(35, descr.value);
assertTrue(descr.configurable);
assertFalse(descr.enumerable);
assertTrue(descr.writable);
assertFalse(Base.prototype.hasOwnProperty('ownSetter'));
},
};
var d = new Derived();
Object.defineProperty(d, 'ownReadOnly', {
value: 42,
writable: false,
configurable: true
});
Object.defineProperty(d, 'ownSetter', {
set: function() { assertUnreachable(); },
configurable: true
});
Object.defineProperty(d, 'ownReadonlyAccessor', {
get: function() { return 15; },
configurable: true
});
d.mSloppy();
var d = new Derived();
Object.defineProperty(d, 'ownReadOnly', {
value: 42,
writable: false,
configurable: true
});
Object.defineProperty(d, 'ownSetter', {
set: function() { assertUnreachable(); },
configurable: true
});
Object.defineProperty(d, 'ownReadonlyAccessor', {
get: function() { return 15; },
configurable: true
});
d.mStrict();
}());
(function TestSetterCreatingOwnPropertiesNonConfigurable() {
function Base() {}
function Derived() {}
Derived.prototype = {
__proto__: Base.prototype,
mSloppy() {
assertEquals(42, this.ownReadOnly);
super.ownReadOnly = 55;
assertEquals(42, this.ownReadOnly);
var descr = Object.getOwnPropertyDescriptor(this, 'ownReadOnly');
assertEquals(42, descr.value);
assertFalse(descr.configurable);
assertFalse(descr.enumerable);
assertFalse(descr.writable);
assertFalse(Base.prototype.hasOwnProperty('ownReadOnly'));
assertEquals(15, this.ownReadonlyAccessor);
super.ownReadonlyAccessor = 25;
assertEquals(15, this.ownReadonlyAccessor);
var descr = Object.getOwnPropertyDescriptor(this, 'ownReadonlyAccessor');
assertFalse(descr.configurable);
assertFalse(descr.enumerable);
assertFalse(Base.prototype.hasOwnProperty('ownReadonlyAccessor'));
super.ownSetter = 35;
var descr = Object.getOwnPropertyDescriptor(this, 'ownSetter');
assertFalse(descr.configurable);
assertFalse(descr.enumerable);
assertFalse(Base.prototype.hasOwnProperty('ownSetter'));
},
mStrict() {
'use strict';
var ex;
assertEquals(42, this.ownReadOnly);
try {
super.ownReadOnly = 55;
} catch (e) {
ex = e;
}
assertInstanceof(ex, TypeError);
assertEquals(
"Cannot assign to read only property 'ownReadOnly' of #<Base>",
ex.message);
assertEquals(42, this.ownReadOnly);
ex = null;
assertEquals(15, this.ownReadonlyAccessor);
try {
super.ownReadonlyAccessor = 25;
} catch (e) {
ex = e;
}
assertInstanceof(ex, TypeError);
assertEquals('Cannot redefine property: ownReadonlyAccessor', ex.message);
assertEquals(15, this.ownReadonlyAccessor);
ex = null;
try {
super.ownSetter = 35;
} catch (e) {
ex = e;
}
assertInstanceof(ex, TypeError);
assertEquals('Cannot redefine property: ownSetter', ex.message);
}
};
var d = new Derived();
Object.defineProperty(d, 'ownReadOnly', { value : 42, writable : false });
Object.defineProperty(d, 'ownSetter',
{ set : function() { assertUnreachable(); } });
Object.defineProperty(d, 'ownReadonlyAccessor',
{ get : function() { return 15; }});
d.mSloppy();
d.mStrict();
}());
(function TestSetterInForIn() {
var setCalled = 0;
var getCalled = 0;
function Base() {}
Base.prototype = {
constructor: Base,
get x() {
getCalled++;
return 1;
},
set x(v) {
setCalled++;
this.x_.push(v);
},
};
function Derived() {
this.x_ = [];
}
Derived.prototype = {
__proto__: Base.prototype,
constructor: Derived,
testIter() {
setCalled = 0;
getCalled = 0;
for (super.x in [1,2,3]) {}
assertEquals(0, getCalled);
assertEquals(3, setCalled);
assertEquals(["0", "1", "2"], this.x_);
},
testIterKeyed() {
setCalled = 0;
getCalled = 0;
for (super[x] in [1,2,3]) {}
assertEquals(0, getCalled);
assertEquals(3, setCalled);
assertEquals(["0","1","2"], this.x_);
this.x_ = [];
setCalled = 0;
getCalled = 0;
var toStringCalled = 0;
var o = {toString: function () { toStringCalled++; return x }};
for (super[o] in [1,2,3]) {}
assertEquals(0, getCalled);
assertEquals(3, setCalled);
assertEquals(3, toStringCalled);
assertEquals(["0","1","2"], this.x_);
}
};
new Derived().testIter();
var x = 'x';
new Derived().testIterKeyed();
}());
function TestKeyedSetterCreatingOwnPropertiesReconfigurable(ownReadOnly,
ownReadonlyAccessor, ownSetter) {
function Base() {}
function Derived() {}
Derived.prototype = {
__proto__: Base.prototype,
mSloppy() {
assertEquals(42, this[ownReadOnly]);
super[ownReadOnly] = 55;
assertEquals(55, this[ownReadOnly]);
var descr = Object.getOwnPropertyDescriptor(this, ownReadOnly);
assertEquals(55, descr.value);
assertTrue(descr.configurable);
assertFalse(descr.enumerable);
assertFalse(descr.writable);
assertFalse(Base.prototype.hasOwnProperty(ownReadOnly));
assertEquals(15, this[ownReadonlyAccessor]);
super[ownReadonlyAccessor] = 25;
assertEquals(25, this[ownReadonlyAccessor]);
var descr = Object.getOwnPropertyDescriptor(this, ownReadonlyAccessor);
assertEquals(25, descr.value);
assertTrue(descr.configurable);
assertFalse(descr.enumerable);
assertTrue(descr.writable);
assertFalse(Base.prototype.hasOwnProperty(ownReadonlyAccessor));
super[ownSetter] = 35;
assertEquals(35, this[ownSetter]);
var descr = Object.getOwnPropertyDescriptor(this, ownSetter);
assertEquals(35, descr.value);
assertTrue(descr.configurable);
assertFalse(descr.enumerable);
assertTrue(descr.writable);
assertFalse(Base.prototype.hasOwnProperty(ownSetter));
},
mStrict() {
'use strict';
assertEquals(42, this[ownReadOnly]);
super[ownReadOnly] = 55;
assertEquals(55, this[ownReadOnly]);
var descr = Object.getOwnPropertyDescriptor(this, ownReadOnly);
assertEquals(55, descr.value);
assertTrue(descr.configurable);
assertFalse(descr.enumerable);
assertFalse(descr.writable);
assertFalse(Base.prototype.hasOwnProperty(ownReadOnly));
assertEquals(15, this[ownReadonlyAccessor]);
super[ownReadonlyAccessor] = 25;
assertEquals(25, this[ownReadonlyAccessor]);
var descr = Object.getOwnPropertyDescriptor(this, ownReadonlyAccessor);
assertEquals(25, descr.value);
assertTrue(descr.configurable);
assertFalse(descr.enumerable);
assertTrue(descr.writable);
assertFalse(Base.prototype.hasOwnProperty(ownReadonlyAccessor));
super[ownSetter] = 35;
assertEquals(35, this[ownSetter]);
var descr = Object.getOwnPropertyDescriptor(this, ownSetter);
assertEquals(35, descr.value);
assertTrue(descr.configurable);
assertFalse(descr.enumerable);
assertTrue(descr.writable);
assertFalse(Base.prototype.hasOwnProperty(ownSetter));
},
};
var d = new Derived();
Object.defineProperty(d, ownReadOnly, {
value: 42,
writable: false,
configurable: true
});
Object.defineProperty(d, ownSetter, {
set: function() { assertUnreachable(); },
configurable: true
});
Object.defineProperty(d, ownReadonlyAccessor, {
get: function() { return 15; },
configurable: true
});
d.mSloppy();
var d = new Derived();
Object.defineProperty(d, ownReadOnly, {
value: 42,
writable: false,
configurable: true
});
Object.defineProperty(d, ownSetter, {
set: function() { assertUnreachable(); },
configurable: true
});
Object.defineProperty(d, ownReadonlyAccessor, {
get: function() { return 15; },
configurable: true
});
d.mStrict();
}
TestKeyedSetterCreatingOwnPropertiesReconfigurable('ownReadOnly',
'ownReadonlyAccessor',
'ownSetter');
TestKeyedSetterCreatingOwnPropertiesReconfigurable(42, 43, 44);
function TestKeyedSetterCreatingOwnPropertiesNonConfigurable(
ownReadOnly, ownReadonlyAccessor, ownSetter) {
function Base() {}
function Derived() {}
Derived.prototype = {
__proto__: Base.prototype,
mSloppy() {
assertEquals(42, this[ownReadOnly]);
super[ownReadOnly] = 55;
assertEquals(42, this[ownReadOnly]);
var descr = Object.getOwnPropertyDescriptor(this, ownReadOnly);
assertEquals(42, descr.value);
assertFalse(descr.configurable);
assertFalse(descr.enumerable);
assertFalse(descr.writable);
assertFalse(Base.prototype.hasOwnProperty(ownReadOnly));
assertEquals(15, this[ownReadonlyAccessor]);
super[ownReadonlyAccessor] = 25;
assertEquals(15, this[ownReadonlyAccessor]);
var descr = Object.getOwnPropertyDescriptor(this, ownReadonlyAccessor);
assertFalse(descr.configurable);
assertFalse(descr.enumerable);
assertFalse(Base.prototype.hasOwnProperty(ownReadonlyAccessor));
super[ownSetter] = 35;
var descr = Object.getOwnPropertyDescriptor(this, ownSetter);
assertFalse(descr.configurable);
assertFalse(descr.enumerable);
assertFalse(Base.prototype.hasOwnProperty(ownSetter));
},
mStrict() {
'use strict';
var ex;
assertEquals(42, this[ownReadOnly]);
try {
super[ownReadOnly] = 55;
} catch (e) {
ex = e;
}
assertInstanceof(ex, TypeError);
assertEquals(
"Cannot assign to read only property '" + ownReadOnly +
"' of #<Base>",
ex.message);
assertEquals(42, this[ownReadOnly]);
ex = null;
assertEquals(15, this[ownReadonlyAccessor]);
try {
super[ownReadonlyAccessor] = 25;
} catch (e) {
ex = e;
}
assertInstanceof(ex, TypeError);
assertEquals('Cannot redefine property: ' + ownReadonlyAccessor,
ex.message);
assertEquals(15, this[ownReadonlyAccessor]);
ex = null;
try {
super[ownSetter] = 35;
} catch (e) {
ex = e;
}
assertInstanceof(ex, TypeError);
assertEquals('Cannot redefine property: ' + ownSetter, ex.message);
}
};
var d = new Derived();
Object.defineProperty(d, ownReadOnly, { value : 42, writable : false });
Object.defineProperty(d, ownSetter,
{ set : function() { assertUnreachable(); } });
Object.defineProperty(d, ownReadonlyAccessor,
{ get : function() { return 15; }});
d.mSloppy();
d.mStrict();
}
TestKeyedSetterCreatingOwnPropertiesNonConfigurable('ownReadOnly',
'ownReadonlyAccessor', 'ownSetter');
TestKeyedSetterCreatingOwnPropertiesNonConfigurable(42, 43, 44);
(function TestSetterNoProtoWalk() {
function Base() {}
function Derived() {}
var getCalled;
var setCalled;
Derived.prototype = {
__proto__: Base.prototype,
get x() { getCalled++; return 42; },
set x(v) { setCalled++; },
mSloppy() {
setCalled = 0;
getCalled = 0;
assertEquals(42, this.x);
assertEquals(1, getCalled);
assertEquals(0, setCalled);
getCalled = 0;
setCalled = 0;
this.x = 43;
assertEquals(0, getCalled);
assertEquals(1, setCalled);
getCalled = 0;
setCalled = 0;
super.x = 15;
assertEquals(0, setCalled);
assertEquals(0, getCalled);
assertEquals(15, this.x);
assertEquals(0, getCalled);
assertEquals(0, setCalled);
},
mStrict() {
'use strict';
setCalled = 0;
getCalled = 0;
assertEquals(42, this.x);
assertEquals(1, getCalled);
assertEquals(0, setCalled);
getCalled = 0;
setCalled = 0;
this.x = 43;
assertEquals(0, getCalled);
assertEquals(1, setCalled);
getCalled = 0;
setCalled = 0;
super.x = 15;
assertEquals(0, setCalled);
assertEquals(0, getCalled);
assertEquals(15, this.x);
assertEquals(0, getCalled);
assertEquals(0, setCalled);
}
};
new Derived().mSloppy();
new Derived().mStrict();
}());
(function TestKeyedSetterNoProtoWalk() {
var x = 'x';
function Base() {}
function Derived() {}
var getCalled;
var setCalled;
Derived.prototype = {
__proto__: Base.prototype,
get x() { getCalled++; return 42; },
set x(v) { setCalled++; },
mSloppy() {
setCalled = 0;
getCalled = 0;
assertEquals(42, this[x]);
assertEquals(1, getCalled);
assertEquals(0, setCalled);
getCalled = 0;
setCalled = 0;
this[x] = 43;
assertEquals(0, getCalled);
assertEquals(1, setCalled);
getCalled = 0;
setCalled = 0;
super[x] = 15;
assertEquals(0, setCalled);
assertEquals(0, getCalled);
assertEquals(15, this[x]);
assertEquals(0, getCalled);
assertEquals(0, setCalled);
},
mStrict() {
'use strict';
setCalled = 0;
getCalled = 0;
assertEquals(42, this[x]);
assertEquals(1, getCalled);
assertEquals(0, setCalled);
getCalled = 0;
setCalled = 0;
this[x] = 43;
assertEquals(0, getCalled);
assertEquals(1, setCalled);
getCalled = 0;
setCalled = 0;
super[x] = 15;
assertEquals(0, setCalled);
assertEquals(0, getCalled);
assertEquals(15, this[x]);
assertEquals(0, getCalled);
assertEquals(0, setCalled);
}
};
new Derived().mSloppy();
new Derived().mStrict();
}());
(function TestKeyedNumericSetterNoProtoWalk() {
var x = 42;
function Base() {}
function Derived() {}
var getCalled;
var setCalled;
Derived.prototype = {
__proto__: Base.prototype,
mSloppy() {
setCalled = 0;
getCalled = 0;
assertEquals(42, this[x]);
assertEquals(1, getCalled);
assertEquals(0, setCalled);
getCalled = 0;
setCalled = 0;
this[x] = 43;
assertEquals(0, getCalled);
assertEquals(1, setCalled);
getCalled = 0;
setCalled = 0;
super[x] = 15;
assertEquals(0, setCalled);
assertEquals(0, getCalled);
assertEquals(15, this[x]);
assertEquals(0, getCalled);
assertEquals(0, setCalled);
},
mStrict() {
'use strict';
setCalled = 0;
getCalled = 0;
assertEquals(42, this[x]);
assertEquals(1, getCalled);
assertEquals(0, setCalled);
getCalled = 0;
setCalled = 0;
this[x] = 43;
assertEquals(0, getCalled);
assertEquals(1, setCalled);
getCalled = 0;
setCalled = 0;
super[x] = 15;
assertEquals(0, setCalled);
assertEquals(0, getCalled);
assertEquals(15, this[x]);
assertEquals(0, getCalled);
assertEquals(0, setCalled);
}
};
Object.defineProperty(Derived.prototype, x, {
get: function() { getCalled++; return 42; },
set: function(v) { setCalled++; }
});
new Derived().mSloppy();
new Derived().mStrict();
}());
(function TestSetterDoesNotReconfigure() {
function Base() {}
function Derived() {}
Derived.prototype = {
__proto__: Derived.prototype,
mStrict(){
'use strict';
super.nonEnumConfig = 5;
var d1 = Object.getOwnPropertyDescriptor(this, 'nonEnumConfig');
assertEquals(5, d1.value);
assertTrue(d1.configurable);
assertFalse(d1.enumerable);
super.nonEnumNonConfig = 5;
var d1 = Object.getOwnPropertyDescriptor(this, 'nonEnumNonConfig');
assertEquals(5, d1.value);
assertFalse(d1.configurable);
assertFalse(d1.enumerable);
},
mSloppy(){
super.nonEnumConfig = 42;
var d1 = Object.getOwnPropertyDescriptor(this, 'nonEnumConfig');
assertEquals(42, d1.value);
assertTrue(d1.configurable);
assertFalse(d1.enumerable);
super.nonEnumNonConfig = 42;
var d1 = Object.getOwnPropertyDescriptor(this, 'nonEnumNonConfig');
assertEquals(42, d1.value);
assertFalse(d1.configurable);
assertFalse(d1.enumerable);
}
};
var d = new Derived();
Object.defineProperty(d, 'nonEnumConfig',
{ value : 0, enumerable : false, configurable : true, writable : true });
Object.defineProperty(d, 'nonEnumNonConfig',
{ value : 0, enumerable : false, configurable : false, writable : true });
d.mStrict();
d.mSloppy();
}());
(function TestKeyedSetterDoesNotReconfigure() {
var nonEnumConfig = 'nonEnumConfig';
var nonEnumNonConfig = 'nonEnumNonConfig';
function Base() {}
function Derived() {}
Derived.prototype = {
__proto__: Base.prototype,
mStrict(){
'use strict';
super[nonEnumConfig] = 5;
var d1 = Object.getOwnPropertyDescriptor(this, nonEnumConfig);
assertEquals(5, d1.value);
assertTrue(d1.configurable);
assertFalse(d1.enumerable);
super[nonEnumNonConfig] = 5;
var d1 = Object.getOwnPropertyDescriptor(this, nonEnumNonConfig);
assertEquals(5, d1.value);
assertFalse(d1.configurable);
assertFalse(d1.enumerable);
},
mSloppy(){
super[nonEnumConfig] = 42;
var d1 = Object.getOwnPropertyDescriptor(this, nonEnumConfig);
assertEquals(42, d1.value);
assertTrue(d1.configurable);
assertFalse(d1.enumerable);
super[nonEnumNonConfig] = 42;
var d1 = Object.getOwnPropertyDescriptor(this, nonEnumNonConfig);
assertEquals(42, d1.value);
assertFalse(d1.configurable);
assertFalse(d1.enumerable);
}
};
var d = new Derived();
Object.defineProperty(d, nonEnumConfig,
{ value : 0, enumerable : false, configurable : true, writable : true });
Object.defineProperty(d, nonEnumNonConfig,
{ value : 0, enumerable : false, configurable : false, writable : true });
d.mStrict();
d.mSloppy();
}());
(function TestKeyedNumericSetterDoesNotReconfigure() {
var nonEnumConfig = 42;
var nonEnumNonConfig = 43;
function Base() {}
function Derived() {}
Derived.prototype = {
__proto__: Base.prototype,
mStrict(){
'use strict';
super[nonEnumConfig] = 5;
var d1 = Object.getOwnPropertyDescriptor(this, nonEnumConfig);
assertEquals(5, d1.value);
assertTrue(d1.configurable);
assertFalse(d1.enumerable);
super[nonEnumNonConfig] = 5;
var d1 = Object.getOwnPropertyDescriptor(this, nonEnumNonConfig);
assertEquals(5, d1.value);
assertFalse(d1.configurable);
assertFalse(d1.enumerable);
},
mSloppy(){
super[nonEnumConfig] = 42;
var d1 = Object.getOwnPropertyDescriptor(this, nonEnumConfig);
assertEquals(42, d1.value);
assertTrue(d1.configurable);
assertFalse(d1.enumerable);
super[nonEnumNonConfig] = 42;
var d1 = Object.getOwnPropertyDescriptor(this, nonEnumNonConfig);
assertEquals(42, d1.value);
assertFalse(d1.configurable);
assertFalse(d1.enumerable);
}
};
var d = new Derived();
Object.defineProperty(d, nonEnumConfig,
{ value : 0, enumerable : false, configurable : true, writable : true });
Object.defineProperty(d, nonEnumNonConfig,
{ value : 0, enumerable : false, configurable : false, writable : true });
d.mStrict();
d.mSloppy();
}());
(function TestCountOperations() {
function Base() {}
Base.prototype = {
constructor: Base,
get x() {
return this._x;
},
set x(v) {
this._x = v;
},
_x: 1
};
function Derived() {}
Derived.__proto__ = Base;
Derived.prototype = {
__proto__: Base.prototype,
constructor: Derived,
_x: 2,
testCounts() {
assertEquals(2, this._x);
assertEquals(2, super.x);
super.x++;
assertEquals(3, super.x);
++super.x;
assertEquals(4, super.x);
assertEquals(4, super.x++);
assertEquals(5, super.x);
assertEquals(6, ++super.x);
assertEquals(6, super.x);
assertEquals(6, this._x);
super.x--;
assertEquals(5, super.x);
--super.x;
assertEquals(4, super.x);
assertEquals(4, super.x--);
assertEquals(3, super.x);
assertEquals(2, --super.x);
assertEquals(2, super.x);
assertEquals(2, this._x);
}
};
new Derived().testCounts();
}());
(function TestKeyedCountOperations() {
var x = 'x';
function Base() {}
Base.prototype = {
constructor: Base,
get x() {
return this._x;
},
set x(v) {
this._x = v;
},
_x: 1
};
function Derived() {}
Derived.__proto__ = Base;
Derived.prototype = {
__proto__: Base.prototype,
constructor: Derived,
_x: 2,
testCounts() {
assertEquals(2, this._x);
assertEquals(2, super[x]);
super[x]++;
assertEquals(3, super[x]);
++super[x];
assertEquals(4, super[x]);
assertEquals(4, super[x]++);
assertEquals(5, super[x]);
assertEquals(6, ++super[x]);
assertEquals(6, super[x]);
assertEquals(6, this._x);
super[x]--;
assertEquals(5, super[x]);
--super[x];
assertEquals(4, super[x]);
assertEquals(4, super[x]--);
assertEquals(3, super[x]);
assertEquals(2, --super[x]);
assertEquals(2, super[x]);
assertEquals(2, this._x);
}
};
new Derived().testCounts();
}());
(function TestKeyedNumericCountOperations() {
var x = 42;
function Base() {}
Base.prototype = {
constructor: Base,
_x: 1
};
Object.defineProperty(Base.prototype, x, {
get: function() { return this._x; },
set: function(v) { this._x = v;; }
});
function Derived() {}
Derived.__proto__ = Base;
Derived.prototype = {
__proto__: Base.prototype,
constructor: Derived,
_x: 2,
testCounts() {
assertEquals(2, this._x);
assertEquals(2, super[x]);
super[x]++;
assertEquals(3, super[x]);
++super[x];
assertEquals(4, super[x]);
assertEquals(4, super[x]++);
assertEquals(5, super[x]);
assertEquals(6, ++super[x]);
assertEquals(6, super[x]);
assertEquals(6, this._x);
super[x]--;
assertEquals(5, super[x]);
--super[x];
assertEquals(4, super[x]);
assertEquals(4, super[x]--);
assertEquals(3, super[x]);
assertEquals(2, --super[x]);
assertEquals(2, super[x]);
assertEquals(2, this._x);
}
};
new Derived().testCounts();
}());
(function TestSetterSuperNonWritable() {
function Base() {}
Object.defineProperty(Base.prototype, 'x', { value : 27, writable: false });
function Derived() {}
Derived.prototype = {
__proto__: Base.prototype,
constructor: Derived,
mSloppy() {
assertEquals(27, super.x);
assertEquals(27, this.x);
super.x = 10;
assertEquals(27, super.x);
assertEquals(27, this.x);
},
mStrict() {
'use strict';
assertEquals(27, super.x);
assertEquals(27, this.x);
var ex = null;
try { super.x = 10; } catch(e) { ex = e; }
assertInstanceof(ex, TypeError);
assertEquals(27, super.x);
assertEquals(27, this.x);
}
};
new Derived().mSloppy();
new Derived().mStrict();
}());
(function TestSetterKeyedSuperNonWritable() {
var x = 'xyz';
function Base() {}
Object.defineProperty(Base.prototype, x, { value : 27, writable: false });
function Derived() {}
Derived.prototype = {
__proto__: Base.prototype,
constructor: Derived,
mSloppy() {
assertEquals(27, super[x]);
assertEquals(27, this[x]);
super[x] = 10;
assertEquals(27, super[x]);
assertEquals(27, this[x]);
},
mStrict() {
'use strict';
assertEquals(27, super[x]);
assertEquals(27, this[x]);
var ex = null;
try { super[x] = 10; } catch(e) { ex = e; }
assertInstanceof(ex, TypeError);
assertEquals(27, super[x]);
assertEquals(27, this[x]);
}
};
new Derived().mSloppy();
new Derived().mStrict();
}());
(function TestSetterKeyedNumericSuperNonWritable() {
var x = 42;
function Base() {}
Object.defineProperty(Base.prototype, x, { value : 27, writable: false });
function Derived() {}
Derived.prototype = {
__proto__: Base.prototype,
constructor: Derived,
mSloppy() {
assertEquals(27, super[x]);
assertEquals(27, this[x]);
super[x] = 10;
assertEquals(27, super[x]);
assertEquals(27, this[x]);
},
mStrict() {
'use strict';
assertEquals(27, super[x]);
assertEquals(27, this[x]);
var ex = null;
try { super[x] = 10; } catch(e) { ex = e; }
assertInstanceof(ex, TypeError);
assertEquals(27, super[x]);
assertEquals(27, this[x]);
}
};
new Derived().mSloppy();
new Derived().mStrict();
}());
(function TestSuperCall() {
'use strict';
var baseCalled = 0;
var derivedCalled = 0;
var derivedDerivedCalled = 0;
class Base {
constructor() {
baseCalled++;
}
}
class Derived extends Base {
constructor() {
super();
derivedCalled++;
}
}
assertEquals(Base, Base.prototype.constructor);
assertEquals(Base.prototype, Derived.prototype.__proto__);
baseCalled = 0;
derivedCalled = 0;
new Derived();
assertEquals(1, baseCalled);
assertEquals(1, derivedCalled);
class DerivedDerived extends Derived {
constructor() {
super();
derivedDerivedCalled++;
}
}
baseCalled = 0;
derivedCalled = 0;
derivedDerivedCalled = 0;
new DerivedDerived();
assertEquals(1, baseCalled);
assertEquals(1, derivedCalled);
assertEquals(1, derivedDerivedCalled);
class Base2 {
constructor(v) {
this.fromBase = v;
}
}
class Derived2 extends Base2 {
constructor(v1, v2) {
super(v1);
this.fromDerived = v2;
}
}
var d = new Derived2("base", "derived");
assertEquals("base", d.fromBase);
assertEquals("derived", d.fromDerived);
var calls = 0;
class G {
constructor() {
calls++;
}
}
class F extends Object {
constructor() {
super();
}
}
F.__proto__ = G;
new F();
assertEquals(1, calls);
F.__proto__ = function() {};
new F();
assertEquals(1, calls);
}());
(function TestExtendsObject() {
'use strict';
class F extends Object { }
var f = new F(42);
// TODO(dslomov,arv): Fix this. BUG=v8:3886.
assertInstanceof(f, Number);
}());
(function TestSuperCallErrorCases() {
'use strict';
class T extends Object {
constructor() {
super();
}
}
T.__proto__ = null;
assertThrows(function() { new T(); }, TypeError);
}());
(function TestSuperPropertyInEval() {
'use strict';
let y = 3;
class Base {
m() { return 1; }
get x() { return 2; }
}
class Derived extends Base {
eval() {
assertSame(super.x, eval('super.x'));
assertSame(super.m(), eval('super.m()'));
// Global eval.
assertThrows('super.x', SyntaxError);
assertThrows('super.m()', SyntaxError);
return eval('super.m()');
}
}
let d = new Derived();
assertSame(1, d.eval());
})();
(function TestSuperPropertyInArrow() {
'use strict';
let y = 3;
class Base {
m() { return 1; }
get x() { return 2; }
}
class Derived extends Base {
arrow() {
assertSame(super.x, (() => super.x)());
assertSame(super.m(), (() => super.m())());
return (() => super.m())();
}
}
let d = new Derived();
assertSame(1, d.arrow());
})();
(function TestSuperCallInEval() {
'use strict';
class Base {
constructor(x) {
this.x = x;
}
}
class Derived extends Base {
constructor(x) {
eval('super(x)');
}
}
let d = new Derived(42);
assertSame(42, d.x);
})();
(function TestSuperCallInArrow() {
'use strict';
class Base {
constructor(x) {
this.x = x;
}
}
class Derived extends Base {
constructor(x) {
(() => super(x))();
}
}
let d = new Derived(42);
assertSame(42, d.x);
})();
(function TestSuperCallEscapes() {
'use strict';
class Base {
constructor(x) {
this.x = x;
}
}
let f;
class Derived extends Base {
constructor() {
f = () => super(2);
}
}
assertThrows(function() {
new Derived();
}, ReferenceError);
let o = f();
assertEquals(2, o.x);
assertInstanceof(o, Derived);
assertThrows(function() {
f();
}, ReferenceError);
})();
(function TestSuperCallSpreadInEval() {
'use strict';
class Base {
constructor(x) {
this.x = x;
}
}
class Derived extends Base {
constructor(x) {
eval('super(...[x])');
}
}
let d = new Derived(42);
assertSame(42, d.x);
})();
(function TestSuperCallSpreadInArrow() {
'use strict';
class Base {
constructor(x) {
this.x = x;
}
}
class Derived extends Base {
constructor(x) {
(() => super(...[x]))();
}
}
let d = new Derived(42);
assertSame(42, d.x);
})();