v8/test/mjsunit/es6/super.js
adamk 624bc966b3 Super property loads and stores should throw if [[Prototype]] is null
While fixing the bug, removed code duplication from super load/store
runtime calls, and inlined calls of Object::ReadAbsentProperty (left
over from strong mode).

BUG=v8:5335

Review-Url: https://codereview.chromium.org/2311413002
Cr-Commit-Position: refs/heads/master@{#39257}
2016-09-07 17:14:14 +00:00

2248 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: --allow-natives-syntax
(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 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;
assertSame(undefined, super.ownReadOnly);
assertEquals(42, this.ownReadOnly);
assertFalse(Base.prototype.hasOwnProperty('ownReadOnly'));
assertEquals(15, this.ownReadonlyAccessor);
super.ownReadonlyAccessor = 25;
assertSame(undefined, super.ownReadonlyAccessor);
assertEquals(15, this.ownReadonlyAccessor);
assertFalse(Base.prototype.hasOwnProperty('ownReadonlyAccessor'));
super.ownSetter = 35;
assertSame(undefined, super.ownSetter);
var descr = Object.getOwnPropertyDescriptor(this, 'ownSetter');
assertTrue('set' in descr);
assertFalse(Base.prototype.hasOwnProperty('ownSetter'));
},
mStrict() {
'use strict';
assertEquals(42, this.ownReadOnly);
assertThrows(() => {super.ownReadOnly = 55}, TypeError);
assertSame(undefined, super.ownReadOnly);
assertEquals(42, this.ownReadOnly);
assertFalse(Base.prototype.hasOwnProperty('ownReadOnly'));
assertEquals(15, this.ownReadonlyAccessor);
assertThrows(() => {super.ownReadonlyAccessor = 25}, TypeError);
assertSame(undefined, super.ownReadonlyAccessor);
assertEquals(15, this.ownReadonlyAccessor);
assertFalse(Base.prototype.hasOwnProperty('ownReadonlyAccessor'));
assertThrows(() => {super.ownSetter = 35}, TypeError);
assertSame(undefined, super.ownSetter);
var descr = Object.getOwnPropertyDescriptor(this, 'ownSetter');
assertTrue('set' in descr);
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;
assertSame(undefined, super.ownReadonlyAccessor);
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 object '#<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;
assertSame(undefined, super[ownReadOnly]);
assertEquals(42, this[ownReadOnly]);
assertFalse(Base.prototype.hasOwnProperty(ownReadOnly));
assertEquals(15, this[ownReadonlyAccessor]);
super[ownReadonlyAccessor] = 25;
assertSame(undefined, super[ownReadonlyAccessor]);
assertEquals(15, this[ownReadonlyAccessor]);
assertFalse(Base.prototype.hasOwnProperty(ownReadonlyAccessor));
super[ownSetter] = 35;
assertSame(undefined, super[ownSetter]);
var descr = Object.getOwnPropertyDescriptor(this, ownSetter);
assertTrue('set' in descr);
assertFalse(Base.prototype.hasOwnProperty(ownSetter));
},
mStrict() {
'use strict';
assertEquals(42, this[ownReadOnly]);
assertThrows(() => {super[ownReadOnly] = 55}, TypeError);
assertSame(undefined, super[ownReadOnly]);
assertEquals(42, this[ownReadOnly]);
assertFalse(Base.prototype.hasOwnProperty(ownReadOnly));
assertEquals(15, this[ownReadonlyAccessor]);
assertThrows(() => {super[ownReadonlyAccessor] = 25}, TypeError);
assertSame(undefined, super[ownReadonlyAccessor]);
assertEquals(15, this[ownReadonlyAccessor]);
assertFalse(Base.prototype.hasOwnProperty(ownReadonlyAccessor));
assertThrows(() => {super[ownSetter] = 35}, TypeError);
assertSame(undefined, super[ownSetter]);
var descr = Object.getOwnPropertyDescriptor(this, ownSetter);
assertTrue('set' in descr);
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;
assertSame(undefined, super[ownReadonlyAccessor]);
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 object '#<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() {
let r = super();
assertEquals(this, r);
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() {
let r = super();
assertEquals(this, r);
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) {
let r = super(v1);
assertEquals(this, r);
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);
assertInstanceof(f, F);
assertInstanceof(f, Object);
}());
(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 {
evalM() {
assertEquals(1, eval('super.m()'));
}
evalX() {
assertEquals(2, eval('super.x'));
}
globalEval1() {
assertThrows('super.x', SyntaxError);
assertThrows('super.m()', SyntaxError);
}
globalEval2() {
super.x;
assertThrows('super.x', SyntaxError);
assertThrows('super.m()', SyntaxError);
}
}
let d = new Derived();
d.globalEval1();
d.globalEval2();
d.evalM();
d.evalX();
})();
(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 TestSuperInOtherScopes() {
var p = {x: 99};
var o0 = {__proto__: p, f() { return eval("'use strict'; super.x") }};
assertEquals(p.x, o0.f());
var o1 = {__proto__: p, f() { with ({}) return super.x }};
assertEquals(p.x, o1.f());
var o2 = {__proto__: p, f({a}) { return super.x }};
assertEquals(p.x, o2.f({}));
var o3 = {__proto__: p, f(...a) { return super.x }};
assertEquals(p.x, o3.f());
var o4 = {__proto__: p, f() { 'use strict'; { let x; return super.x } }};
assertEquals(p.x, o4.f());
})();
(function TestSuperCallInOtherScopes() {
class C {constructor() { this.x = 99 }}
class D0 extends C {constructor() { eval("'use strict'; super()") }}
assertEquals(99, (new D0).x);
class D2 extends C {constructor({a}) { super() }}
assertEquals(99, (new D2({})).x);
class D3 extends C {constructor(...a) { super() }}
assertEquals(99, (new D3()).x);
class D4 extends C {constructor() { { let x; super() } }}
assertEquals(99, (new D4).x);
})();
(function TestSuperCallInEval() {
'use strict';
class Base {
constructor(x) {
this.x = x;
}
}
class Derived extends Base {
constructor(x) {
let r = eval('super(x)');
assertEquals(this, r);
}
}
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) {
let r = (() => super(x))();
assertEquals(this, r);
}
}
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 TestSuperCallInLoop() {
'use strict';
class Base {
constructor(x) {
this.x = x;
}
}
class Derived extends Base {
constructor(x, n) {
for (var i = 0; i < n; ++i) {
super(x);
}
}
}
let o = new Derived(23, 1);
assertEquals(23, o.x);
assertInstanceof(o, Derived);
assertThrows("new Derived(42, 0)", ReferenceError);
assertThrows("new Derived(65, 2)", ReferenceError);
})();
(function TestSuperCallReentrant() {
'use strict';
class Base {
constructor(fun) {
this.x = fun();
}
}
class Derived extends Base {
constructor(x) {
let f = () => super(() => x)
super(f);
}
}
assertThrows("new Derived(23)", ReferenceError);
})();
(function TestSuperCallSpreadInEval() {
'use strict';
class Base {
constructor(x) {
this.x = x;
}
}
class Derived extends Base {
constructor(x) {
let r = eval('super(...[x])');
assertEquals(this, r);
}
}
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) {
let r = (() => super(...[x]))();
assertEquals(this, r);
}
}
let d = new Derived(42);
assertSame(42, d.x);
})();
(function TestNullSuperPropertyLoad() {
var obj = {
__proto__: null,
named() { return super.x },
keyed() { return super[5] }
};
assertThrows(obj.named, TypeError);
assertThrows(obj.keyed, TypeError);
class C extends null {
named() { return super.x }
keyed() { return super[5] }
}
assertThrows(C.prototype.named, TypeError);
assertThrows(C.prototype.keyed, TypeError);
})();
(function TestNullSuperPropertyStore() {
var obj = {
__proto__: null,
named() { super.x = 42 },
keyed() { super[5] = 42 }
};
assertThrows(obj.named, TypeError);
assertThrows(obj.keyed, TypeError);
class C extends null {
named() { super.x = 42 }
keyed() { super[5] = 42 }
}
assertThrows(C.prototype.named, TypeError);
assertThrows(C.prototype.keyed, TypeError);
})();