5f0ef667c7
Bug: v8:5367, v8:5368 Change-Id: I86f25f9f658e21a05604f3014e6ebf74f1a8a1f7 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1590164 Reviewed-by: Mathias Bynens <mathias@chromium.org> Commit-Queue: Sathya Gunasekaran <gsathya@chromium.org> Cr-Commit-Position: refs/heads/master@{#61139}
716 lines
10 KiB
JavaScript
716 lines
10 KiB
JavaScript
// Copyright 2017 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.
|
|
|
|
"use strict";
|
|
|
|
{
|
|
class C {
|
|
a;
|
|
}
|
|
|
|
assertEquals(undefined, C.a);
|
|
|
|
let c = new C;
|
|
let descriptor = Object.getOwnPropertyDescriptor(c, 'a');
|
|
assertTrue(c.hasOwnProperty('a'));
|
|
assertTrue(descriptor.writable);
|
|
assertTrue(descriptor.enumerable);
|
|
assertTrue(descriptor.configurable);
|
|
assertEquals(undefined, c.a);
|
|
}
|
|
|
|
{
|
|
class C {
|
|
x = 1;
|
|
constructor() {}
|
|
}
|
|
|
|
let c = new C;
|
|
assertEquals(1, c.x);
|
|
}
|
|
|
|
{
|
|
function t() {
|
|
class X {
|
|
x = 1;
|
|
constructor() {}
|
|
}
|
|
|
|
var x = new X;
|
|
return x.x;
|
|
}
|
|
|
|
assertEquals(1, t());
|
|
}
|
|
|
|
{
|
|
let x = 'a';
|
|
class C {
|
|
a;
|
|
b = x;
|
|
c = 1;
|
|
hasOwnProperty() { return 1;}
|
|
}
|
|
|
|
let c = new C;
|
|
assertEquals(undefined, c.a);
|
|
assertEquals('a', c.b);
|
|
assertEquals(1, c.c);
|
|
assertEquals(undefined, c.d);
|
|
assertEquals(1, c.hasOwnProperty());
|
|
}
|
|
|
|
{
|
|
class C {
|
|
x = Object.freeze(this);
|
|
c = 42;
|
|
}
|
|
assertThrows(() => { new C; }, TypeError);
|
|
}
|
|
|
|
{
|
|
class C {
|
|
c = this;
|
|
d = () => this;
|
|
}
|
|
|
|
let c = new C;
|
|
assertEquals(c, c.c);
|
|
assertEquals(c, c.d());
|
|
|
|
assertEquals(undefined, C.c);
|
|
assertEquals(undefined, C.d);
|
|
}
|
|
|
|
{
|
|
class C {
|
|
c = 1;
|
|
d = this.c;
|
|
}
|
|
|
|
let c = new C;
|
|
assertEquals(1, c.c);
|
|
assertEquals(1, c.d);
|
|
|
|
assertEquals(undefined, C.c);
|
|
assertEquals(undefined, C.d);
|
|
}
|
|
|
|
{
|
|
class C {
|
|
b = 1;
|
|
c = () => this.b;
|
|
}
|
|
|
|
let c = new C;
|
|
assertEquals(1, c.b);
|
|
assertEquals(1, c.c());
|
|
|
|
assertEquals(undefined, C.c);
|
|
assertEquals(undefined, C.b);
|
|
}
|
|
|
|
{
|
|
let x = 'a';
|
|
class C {
|
|
b = 1;
|
|
c = () => this.b;
|
|
e = () => x;
|
|
}
|
|
|
|
let c = new C;
|
|
assertEquals(1, c.b);
|
|
assertEquals('a', c.e());
|
|
|
|
let a = {b : 2 };
|
|
assertEquals(1, c.c.call(a));
|
|
|
|
assertEquals(undefined, C.b);
|
|
assertEquals(undefined, C.c);
|
|
}
|
|
|
|
{
|
|
let x = 'a';
|
|
class C {
|
|
c = 1;
|
|
d = function() { return this.c; };
|
|
e = function() { return x; };
|
|
}
|
|
|
|
let c = new C;
|
|
assertEquals(1, c.c);
|
|
assertEquals(1, c.d());
|
|
assertEquals('a', c.e());
|
|
|
|
c.c = 2;
|
|
assertEquals(2, c.d());
|
|
|
|
let a = {c : 3 };
|
|
assertEquals(3, c.d.call(a));
|
|
|
|
assertThrows(c.d.bind(undefined));
|
|
|
|
assertEquals(undefined, C.c);
|
|
assertEquals(undefined, C.d);
|
|
assertEquals(undefined, C.e);
|
|
}
|
|
|
|
{
|
|
class C {
|
|
c = function() { return 1 };
|
|
}
|
|
|
|
let c = new C;
|
|
assertEquals('c', c.c.name);
|
|
}
|
|
|
|
{
|
|
let d = function() { return new.target; }
|
|
class C {
|
|
c = d;
|
|
}
|
|
|
|
let c = new C;
|
|
assertEquals(undefined, c.c());
|
|
assertEquals(new d, new c.c());
|
|
}
|
|
|
|
{
|
|
class C {
|
|
c = () => new.target;
|
|
}
|
|
|
|
let c = new C;
|
|
assertEquals(undefined, c.c());
|
|
}
|
|
|
|
{
|
|
let run = false;
|
|
class C {
|
|
c = () => {
|
|
let b;
|
|
class A {
|
|
constructor() {
|
|
b = new.target;
|
|
}
|
|
};
|
|
new A;
|
|
run = true;
|
|
assertEquals(A, b);
|
|
}
|
|
}
|
|
|
|
let c = new C;
|
|
c.c();
|
|
assertTrue(run);
|
|
}
|
|
|
|
{
|
|
class C {
|
|
c = new.target;
|
|
}
|
|
|
|
let c = new C;
|
|
assertEquals(undefined, c.c);
|
|
}
|
|
|
|
{
|
|
class B {
|
|
c = 1;
|
|
}
|
|
|
|
class C extends B {}
|
|
|
|
let c = new C;
|
|
assertEquals(1, c.c);
|
|
}
|
|
|
|
{
|
|
assertThrows(() => {
|
|
class C {
|
|
c = new C;
|
|
}
|
|
let c = new C;
|
|
});
|
|
}
|
|
|
|
(function test() {
|
|
function makeC() {
|
|
var x = 1;
|
|
|
|
return class {
|
|
a = () => () => x;
|
|
}
|
|
}
|
|
|
|
let C = makeC();
|
|
let c = new C;
|
|
let f = c.a();
|
|
assertEquals(1, f());
|
|
})()
|
|
|
|
{
|
|
let c1 = "c";
|
|
class C {
|
|
["a"] = 1;
|
|
["b"];
|
|
[c1];
|
|
}
|
|
|
|
let c = new C;
|
|
assertEquals(1, c.a);
|
|
assertEquals(undefined, c.b);
|
|
assertEquals(undefined, c[c1]);
|
|
}
|
|
|
|
{
|
|
let log = [];
|
|
function run(i) {
|
|
log.push(i);
|
|
return i;
|
|
}
|
|
|
|
class C {
|
|
[run(1)] = run(6);
|
|
[run(2)] = run(7);
|
|
[run(3)]() { run(9);}
|
|
[run(4)] = run(8);
|
|
[run(5)]() { throw new Error('should not execute');};
|
|
}
|
|
|
|
let c = new C;
|
|
c[3]();
|
|
assertEquals([1, 2, 3, 4, 5, 6, 7, 8, 9], log);
|
|
}
|
|
|
|
function x() {
|
|
// This tests lazy parsing.
|
|
return function() {
|
|
let log = [];
|
|
function run(i) {
|
|
log.push(i);
|
|
return i;
|
|
}
|
|
|
|
class C {
|
|
[run(1)] = run(6);
|
|
[run(2)] = run(7);
|
|
[run(3)]() { run(9);}
|
|
[run(4)] = run(8);
|
|
[run(5)]() { throw new Error('should not execute');};
|
|
}
|
|
|
|
let c = new C;
|
|
c[3]();
|
|
assertEquals([1, 2, 3, 4, 5, 6, 7, 8, 9], log);
|
|
}
|
|
}
|
|
x()();
|
|
|
|
{
|
|
class C {}
|
|
class D {
|
|
[C];
|
|
}
|
|
|
|
let d = new D;
|
|
assertThrows(() => { class X { [X] } let x = new X;});
|
|
assertEquals(undefined, d[C]);
|
|
}
|
|
|
|
{
|
|
class B {
|
|
a = 1;
|
|
}
|
|
|
|
class C extends B {
|
|
b = 2;
|
|
constructor() {
|
|
super();
|
|
}
|
|
}
|
|
|
|
let c = new C;
|
|
assertEquals(1, c.a);
|
|
assertEquals(2, c.b);
|
|
}
|
|
|
|
{
|
|
var log = [];
|
|
function addToLog(item) { log.push(item); }
|
|
|
|
class B {
|
|
a = 1;
|
|
constructor() {
|
|
addToLog("base constructor");
|
|
}
|
|
}
|
|
|
|
function initF() {
|
|
addToLog("init f");
|
|
return 1;
|
|
}
|
|
|
|
class C extends B {
|
|
f = initF();
|
|
|
|
constructor() {
|
|
addToLog("derived constructor");
|
|
var t = () => {
|
|
addToLog("t");
|
|
if (1==-1) {
|
|
super();
|
|
} else {
|
|
super();
|
|
}
|
|
}
|
|
(() => {
|
|
addToLog("anon");
|
|
t();
|
|
})();
|
|
}
|
|
}
|
|
|
|
let c = new C;
|
|
assertEquals(1, c.f);
|
|
assertEquals(1, c.a);
|
|
assertEquals(["derived constructor","anon","t","base constructor","init f"],
|
|
log);
|
|
}
|
|
|
|
{
|
|
class B {
|
|
a = 1;
|
|
returnA = () => this.a;
|
|
}
|
|
|
|
class C extends B {
|
|
c = this.a;
|
|
d = 2;
|
|
returnC = () => this.c;
|
|
returnD = () => this.d;
|
|
}
|
|
|
|
let c = new C;
|
|
assertEquals(1, c.a);
|
|
assertEquals(1, c.returnA());
|
|
assertEquals(1, c.c);
|
|
assertEquals(1, c.returnA());
|
|
assertEquals(1, c.returnC());
|
|
assertEquals(2, c.d);
|
|
assertEquals(2, c.returnD());
|
|
|
|
let c2 = new C;
|
|
assertNotEquals(c2.returnA, c.returnA);
|
|
assertNotEquals(c2.returnC, c.returnC);
|
|
assertNotEquals(c2.returnD, c.returnD);
|
|
}
|
|
|
|
{
|
|
let foo = undefined;
|
|
class B {
|
|
set d(x) {
|
|
foo = x;
|
|
}
|
|
}
|
|
|
|
class C extends B {
|
|
d = 2;
|
|
}
|
|
|
|
let c = new C;
|
|
assertEquals(undefined, foo);
|
|
assertEquals(2, c.d);
|
|
}
|
|
|
|
{
|
|
class B {}
|
|
class C extends B {
|
|
constructor() {
|
|
super();
|
|
}
|
|
|
|
c = 1;
|
|
}
|
|
|
|
let c = new C;
|
|
assertEquals(1, c.c);
|
|
}
|
|
|
|
{
|
|
class B {}
|
|
class C extends B {
|
|
constructor() {
|
|
let t = () => {
|
|
super();
|
|
}
|
|
t();
|
|
}
|
|
|
|
c = 1;
|
|
}
|
|
|
|
let c = new C;
|
|
assertEquals(1, c.c);
|
|
}
|
|
|
|
{
|
|
let log = [];
|
|
|
|
class B {}
|
|
|
|
class C extends B {
|
|
|
|
x = (log.push(1), 1);
|
|
|
|
constructor() {
|
|
let t = () => {
|
|
class D extends B {
|
|
|
|
x = (log.push(2), 2);
|
|
|
|
constructor() {
|
|
let p = () => {
|
|
super();
|
|
}
|
|
|
|
p();
|
|
}
|
|
}
|
|
|
|
let d = new D();
|
|
assertEquals(2, d.x);
|
|
super();
|
|
}
|
|
|
|
t();
|
|
}
|
|
}
|
|
|
|
|
|
let c = new C;
|
|
assertEquals(1, c.x);
|
|
assertEquals([2, 1], log);
|
|
}
|
|
|
|
{
|
|
let log = [];
|
|
class C1 extends class {} {
|
|
x = log.push(1);
|
|
constructor() {
|
|
var t = () => super();
|
|
super();
|
|
t();
|
|
}
|
|
}
|
|
|
|
assertThrows(() => new C1, ReferenceError);
|
|
assertEquals([1], log);
|
|
|
|
log = [];
|
|
class C2 extends class {} {
|
|
x = log.push(1);
|
|
constructor() {
|
|
var t = () => super();
|
|
t();
|
|
super();
|
|
}
|
|
}
|
|
|
|
assertThrows(() => new C2, ReferenceError);
|
|
assertEquals([1], log);
|
|
}
|
|
|
|
{
|
|
class C1 extends class {} {
|
|
x = 1
|
|
constructor() {
|
|
eval("super()");
|
|
}
|
|
}
|
|
|
|
let c = new C1;
|
|
assertEquals(1, c.x);
|
|
|
|
class C2 extends class {} {
|
|
x = 1
|
|
constructor() {
|
|
var t = () => {
|
|
eval("super()");
|
|
}
|
|
t();
|
|
}
|
|
}
|
|
|
|
c = new C2;
|
|
assertEquals(1, c.x);
|
|
}
|
|
|
|
{
|
|
class C {
|
|
['x'] = 1;
|
|
['y'] = 2;
|
|
}
|
|
|
|
class C1 extends C {
|
|
['x'] = 3;
|
|
['z'] = 4;
|
|
}
|
|
|
|
let c = new C1;
|
|
assertEquals(3, c.x);
|
|
assertEquals(2, c.y);
|
|
assertEquals(4, c.z);
|
|
}
|
|
|
|
{
|
|
class X extends class {} {
|
|
c = 1;
|
|
|
|
constructor() {
|
|
let t = () => {
|
|
|
|
class P extends class {} {
|
|
constructor() {
|
|
let t = () => { super(); };
|
|
t();
|
|
}
|
|
}
|
|
|
|
let p = new P;
|
|
assertEquals(undefined, p.c);
|
|
super();
|
|
}
|
|
|
|
t();
|
|
}
|
|
}
|
|
|
|
let x = new X;
|
|
assertEquals(1, x.c);
|
|
}
|
|
|
|
{
|
|
class A {
|
|
a() { return 1; }
|
|
}
|
|
|
|
class C extends A {
|
|
b = super.a();
|
|
c = () => super.a;
|
|
d = () => super.a();
|
|
e = super.a;
|
|
f = super.b;
|
|
}
|
|
|
|
let c = new C;
|
|
assertEquals(1, c.a());
|
|
assertEquals(1, c.b);
|
|
assertEquals(1, c.c()());
|
|
assertEquals(1, c.d());
|
|
assertEquals(1, c.e());
|
|
assertFalse(Object.hasOwnProperty(c, 'a'));
|
|
assertEquals(c.a, c.e);
|
|
assertEquals(undefined, c.f);
|
|
}
|
|
|
|
{
|
|
function t() {
|
|
return class {
|
|
['x'] = 1;
|
|
}
|
|
}
|
|
|
|
let klass = t();
|
|
let obj = new klass;
|
|
assertEquals(1, obj.x);
|
|
}
|
|
|
|
{
|
|
new class {
|
|
t = 1;
|
|
constructor(t = this.t) {
|
|
assertEquals(1, t);
|
|
}
|
|
}
|
|
|
|
new class extends class {} {
|
|
t = 1;
|
|
constructor(t = (super(), this.t)) {
|
|
assertEquals(1, t);
|
|
}
|
|
}
|
|
|
|
assertThrows(() => {
|
|
new class extends class {} {
|
|
t = 1;
|
|
constructor(t = this.t) {
|
|
super();
|
|
}
|
|
}
|
|
}, ReferenceError);
|
|
}
|
|
|
|
{
|
|
class X {
|
|
p = function() { return arguments[0]; }
|
|
}
|
|
|
|
let x = new X;
|
|
assertEquals(1, x.p(1));
|
|
}
|
|
|
|
{
|
|
class X {
|
|
t = () => {
|
|
function p() { return arguments[0]; };
|
|
return p;
|
|
}
|
|
}
|
|
|
|
let x = new X;
|
|
let p = x.t();
|
|
assertEquals(1, p(1));
|
|
}
|
|
|
|
{
|
|
class X {
|
|
t = () => {
|
|
function p() { return eval("arguments[0]"); };
|
|
return p;
|
|
}
|
|
}
|
|
|
|
let x = new X;
|
|
let p = x.t();
|
|
assertEquals(1, p(1));
|
|
}
|
|
|
|
{
|
|
class X {
|
|
p = eval("(function() { return arguments[0]; })(1)");
|
|
}
|
|
|
|
let x = new X;
|
|
assertEquals(1, x.p);
|
|
}
|
|
|
|
{
|
|
let thisInInitializer, thisInConstructor, thisFromArrowFn, arrowFn;
|
|
let C = class extends class {} {
|
|
field = (thisInInitializer = this, thisFromArrowFn = arrowFn());
|
|
constructor() {
|
|
arrowFn = () => this;
|
|
super();
|
|
thisInConstructor = this;
|
|
}
|
|
};
|
|
|
|
let c = new C();
|
|
|
|
assertSame(thisInInitializer, c);
|
|
assertSame(thisFromArrowFn, c);
|
|
assertSame(thisInConstructor, c);
|
|
}
|