2018-09-05 21:27:33 +00:00
|
|
|
// Copyright 2018 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-class-fields
|
|
|
|
|
|
|
|
// Utility function for testing that the expected strings occur
|
|
|
|
// in the stack trace produced when running the given function.
|
|
|
|
function testTrace(name, fun, expected, unexpected) {
|
|
|
|
var threw = false;
|
|
|
|
try {
|
|
|
|
fun();
|
|
|
|
} catch (e) {
|
|
|
|
for (var i = 0; i < expected.length; i++) {
|
|
|
|
assertTrue(
|
|
|
|
e.stack.indexOf(expected[i]) != -1,
|
|
|
|
name + " doesn't contain expected[" + i + "] stack = " + e.stack
|
|
|
|
);
|
|
|
|
}
|
|
|
|
if (unexpected) {
|
|
|
|
for (var i = 0; i < unexpected.length; i++) {
|
|
|
|
assertEquals(
|
|
|
|
e.stack.indexOf(unexpected[i]),
|
|
|
|
-1,
|
|
|
|
name + " contains unexpected[" + i + "]"
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
threw = true;
|
|
|
|
}
|
|
|
|
assertTrue(threw, name + " didn't throw");
|
|
|
|
}
|
|
|
|
|
|
|
|
function thrower() {
|
|
|
|
FAIL;
|
|
|
|
}
|
|
|
|
|
|
|
|
function testClassConstruction() {
|
|
|
|
class X {
|
|
|
|
static x = thrower();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// ReferenceError: FAIL is not defined
|
|
|
|
// at thrower
|
2021-02-17 23:40:14 +00:00
|
|
|
// at <static_initializer>
|
2018-09-05 21:27:33 +00:00
|
|
|
// at testClassConstruction
|
|
|
|
// at testTrace
|
2018-09-07 18:00:58 +00:00
|
|
|
testTrace(
|
|
|
|
"during class construction",
|
|
|
|
testClassConstruction,
|
2021-02-17 23:40:14 +00:00
|
|
|
["thrower", "<static_initializer>"],
|
2018-09-07 18:00:58 +00:00
|
|
|
["anonymous"]
|
|
|
|
);
|
2018-09-05 21:27:33 +00:00
|
|
|
|
|
|
|
function testClassConstruction2() {
|
|
|
|
class X {
|
|
|
|
[thrower()];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// ReferenceError: FAIL is not defined
|
|
|
|
// at thrower
|
|
|
|
// at testClassConstruction2
|
|
|
|
// at testTrace
|
2018-09-07 18:00:58 +00:00
|
|
|
testTrace("during class construction2", testClassConstruction2, ["thrower"]);
|
2018-09-05 21:27:33 +00:00
|
|
|
|
|
|
|
function testClassInstantiation() {
|
|
|
|
class X {
|
|
|
|
x = thrower();
|
|
|
|
}
|
|
|
|
|
|
|
|
new X();
|
|
|
|
}
|
|
|
|
|
|
|
|
// ReferenceError: FAIL is not defined
|
|
|
|
// at thrower
|
2018-11-06 12:06:39 +00:00
|
|
|
// at X.<instance_members_initializer>
|
2018-09-05 21:27:33 +00:00
|
|
|
// at new X
|
|
|
|
// at testClassInstantiation
|
|
|
|
// at testTrace
|
2018-09-07 18:00:58 +00:00
|
|
|
testTrace(
|
|
|
|
"during class instantiation",
|
|
|
|
testClassInstantiation,
|
2018-11-06 12:06:39 +00:00
|
|
|
["thrower", "X.<instance_members_initializer>", "new X"],
|
2018-09-07 18:00:58 +00:00
|
|
|
["anonymous"]
|
|
|
|
);
|
2018-09-05 21:27:33 +00:00
|
|
|
|
|
|
|
function testClassInstantiationWithSuper() {
|
|
|
|
class Base {}
|
|
|
|
|
|
|
|
class X extends Base {
|
|
|
|
x = thrower();
|
|
|
|
}
|
|
|
|
|
|
|
|
new X();
|
|
|
|
}
|
|
|
|
|
|
|
|
// ReferenceError: FAIL is not defined
|
|
|
|
// at thrower
|
2018-11-06 12:06:39 +00:00
|
|
|
// at X.<instance_members_initializer>
|
2018-09-05 21:27:33 +00:00
|
|
|
// at new X
|
|
|
|
// at testClassInstantiation
|
|
|
|
// at testTrace
|
|
|
|
testTrace(
|
|
|
|
"during class instantiation with super",
|
|
|
|
testClassInstantiationWithSuper,
|
2018-11-06 12:06:39 +00:00
|
|
|
["thrower", "X.<instance_members_initializer>", "new X"],
|
2018-09-07 18:00:58 +00:00
|
|
|
["Base", "anonymous"]
|
2018-09-05 21:27:33 +00:00
|
|
|
);
|
|
|
|
|
|
|
|
function testClassInstantiationWithSuper2() {
|
|
|
|
class Base {}
|
|
|
|
|
|
|
|
class X extends Base {
|
|
|
|
constructor() {
|
|
|
|
super();
|
|
|
|
}
|
|
|
|
x = thrower();
|
|
|
|
}
|
|
|
|
|
|
|
|
new X();
|
|
|
|
}
|
|
|
|
|
|
|
|
// ReferenceError: FAIL is not defined
|
|
|
|
// at thrower
|
2018-11-06 12:06:39 +00:00
|
|
|
// at X.<instance_members_initializer>
|
2018-09-05 21:27:33 +00:00
|
|
|
// at new X
|
|
|
|
// at testClassInstantiation
|
|
|
|
// at testTrace
|
|
|
|
testTrace(
|
|
|
|
"during class instantiation with super2",
|
|
|
|
testClassInstantiationWithSuper2,
|
2018-11-06 12:06:39 +00:00
|
|
|
["thrower", "X.<instance_members_initializer>", "new X"],
|
2018-09-07 18:00:58 +00:00
|
|
|
["Base", "anonymous"]
|
2018-09-05 21:27:33 +00:00
|
|
|
);
|
|
|
|
|
|
|
|
function testClassInstantiationWithSuper3() {
|
|
|
|
class Base {
|
|
|
|
x = thrower();
|
|
|
|
}
|
|
|
|
|
|
|
|
class X extends Base {
|
|
|
|
constructor() {
|
|
|
|
super();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
new X();
|
|
|
|
}
|
|
|
|
|
|
|
|
// ReferenceError: FAIL is not defined
|
|
|
|
// at thrower
|
2018-11-06 12:06:39 +00:00
|
|
|
// at X.<instance_members_initializer>
|
2018-09-05 21:27:33 +00:00
|
|
|
// at new Base
|
|
|
|
// at new X
|
|
|
|
// at testClassInstantiationWithSuper3
|
|
|
|
// at testTrace
|
|
|
|
testTrace(
|
|
|
|
"during class instantiation with super3",
|
|
|
|
testClassInstantiationWithSuper3,
|
2018-11-06 12:06:39 +00:00
|
|
|
["thrower", "X.<instance_members_initializer>", "new Base", "new X"],
|
2018-09-07 18:00:58 +00:00
|
|
|
["anonymous"]
|
2018-09-05 21:27:33 +00:00
|
|
|
);
|
|
|
|
|
|
|
|
function testClassFieldCall() {
|
|
|
|
class X {
|
|
|
|
x = thrower;
|
|
|
|
}
|
|
|
|
|
|
|
|
let x = new X();
|
|
|
|
x.x();
|
|
|
|
}
|
|
|
|
|
|
|
|
// ReferenceError: FAIL is not defined
|
|
|
|
// at X.thrower [as x]
|
|
|
|
// at testClassFieldCall
|
|
|
|
// at testTrace
|
|
|
|
testTrace(
|
|
|
|
"during class field call",
|
|
|
|
testClassFieldCall,
|
|
|
|
["X.thrower"],
|
|
|
|
["anonymous"]
|
|
|
|
);
|
|
|
|
|
|
|
|
function testStaticClassFieldCall() {
|
|
|
|
class X {
|
|
|
|
static x = thrower;
|
|
|
|
}
|
|
|
|
|
|
|
|
X.x();
|
|
|
|
}
|
|
|
|
|
|
|
|
// ReferenceError: FAIL is not defined
|
|
|
|
// at Function.thrower [as x]
|
|
|
|
// at testStaticClassFieldCall
|
|
|
|
// at testTrace
|
|
|
|
testTrace(
|
|
|
|
"during static class field call",
|
|
|
|
testStaticClassFieldCall,
|
|
|
|
["Function.thrower"],
|
|
|
|
["anonymous"]
|
|
|
|
);
|
|
|
|
|
|
|
|
function testClassFieldCallWithFNI() {
|
|
|
|
class X {
|
|
|
|
x = function() {
|
|
|
|
FAIL;
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
let x = new X();
|
|
|
|
x.x();
|
|
|
|
}
|
|
|
|
|
|
|
|
// ReferenceError: FAIL is not defined
|
|
|
|
// at X.x
|
|
|
|
// at testClassFieldCallWithFNI
|
|
|
|
// at testTrace
|
|
|
|
testTrace(
|
|
|
|
"during class field call with FNI",
|
|
|
|
testClassFieldCallWithFNI,
|
|
|
|
["X.x"],
|
|
|
|
["anonymous"]
|
|
|
|
);
|
|
|
|
|
|
|
|
function testStaticClassFieldCallWithFNI() {
|
|
|
|
class X {
|
|
|
|
static x = function() {
|
|
|
|
FAIL;
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
X.x();
|
|
|
|
}
|
|
|
|
|
|
|
|
// ReferenceError: FAIL is not defined
|
|
|
|
// at Function.x
|
|
|
|
// at testStaticClassFieldCallWithFNI
|
|
|
|
// at testTrace
|
|
|
|
testTrace(
|
|
|
|
"during static class field call with FNI",
|
|
|
|
testStaticClassFieldCallWithFNI,
|
|
|
|
["Function.x"],
|
|
|
|
["anonymous"]
|
|
|
|
);
|