2019-01-08 23:54:30 +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.
|
|
|
|
|
2019-04-30 18:47:05 +00:00
|
|
|
// Flags: --allow-natives-syntax
|
2019-01-08 23:54:30 +00:00
|
|
|
|
|
|
|
|
|
|
|
"use strict";
|
|
|
|
|
|
|
|
{
|
|
|
|
class C {
|
|
|
|
static #a;
|
|
|
|
static getA() { return this.#a; }
|
|
|
|
}
|
|
|
|
|
|
|
|
assertEquals(undefined, C.a);
|
|
|
|
assertEquals(undefined, C.getA());
|
|
|
|
|
|
|
|
let c = new C;
|
|
|
|
assertEquals(undefined, c.a);
|
|
|
|
}
|
|
|
|
|
|
|
|
{
|
|
|
|
class C {
|
|
|
|
static #a = 1;
|
|
|
|
static getA() { return this.#a; }
|
|
|
|
}
|
|
|
|
|
|
|
|
assertEquals(undefined, C.a);
|
|
|
|
assertEquals(1, C.getA());
|
|
|
|
|
|
|
|
let c = new C;
|
|
|
|
assertEquals(undefined, c.a);
|
|
|
|
}
|
|
|
|
|
|
|
|
{
|
|
|
|
class C {
|
|
|
|
static #a = 1;
|
|
|
|
static #b = this.#a;
|
|
|
|
static getB() { return this.#b; }
|
|
|
|
}
|
|
|
|
|
|
|
|
assertEquals(1, C.getB());
|
|
|
|
|
|
|
|
let c = new C;
|
|
|
|
assertEquals(undefined, c.getB);
|
|
|
|
}
|
|
|
|
|
|
|
|
{
|
|
|
|
class C {
|
|
|
|
static #a = 1;
|
|
|
|
static getA() { return this.#a; }
|
|
|
|
constructor() {
|
|
|
|
assertThrows(() => this.#a, TypeError);
|
|
|
|
C.#a = 2;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
assertEquals(1, C.getA());
|
|
|
|
|
|
|
|
let c = new C;
|
|
|
|
assertThrows(() => C.prototype.getA.call(c));
|
|
|
|
assertEquals(2, C.getA());
|
|
|
|
}
|
|
|
|
|
|
|
|
{
|
|
|
|
class C {
|
|
|
|
static #a = this;
|
|
|
|
static #b = () => this;
|
|
|
|
static getA() { return this.#a; }
|
|
|
|
static getB() { return this.#b; }
|
|
|
|
}
|
|
|
|
|
|
|
|
assertSame(C, C.getA());
|
|
|
|
assertSame(C, C.getB()());
|
|
|
|
}
|
|
|
|
|
|
|
|
{
|
|
|
|
class C {
|
|
|
|
static #a = this;
|
|
|
|
static #b = function() { return this; };
|
|
|
|
static getA() { return this.#a; }
|
|
|
|
static getB() { return this.#b; }
|
|
|
|
}
|
|
|
|
|
|
|
|
assertSame(C, C.getA());
|
|
|
|
assertSame(C, C.getB().call(C));
|
|
|
|
assertSame(undefined, C.getB()());
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
{
|
|
|
|
class C {
|
|
|
|
static #a = function() { return 1 };
|
|
|
|
static getA() {return this.#a;}
|
|
|
|
}
|
|
|
|
|
|
|
|
assertEquals('#a', C.getA().name);
|
|
|
|
}
|
|
|
|
|
|
|
|
{
|
|
|
|
let d = function() { return new.target; }
|
|
|
|
class C {
|
|
|
|
static #c = d;
|
|
|
|
static getC() { return this.#c; }
|
|
|
|
}
|
|
|
|
|
|
|
|
assertEquals(undefined, C.getC()());
|
|
|
|
assertSame(new d, new (C.getC()));
|
|
|
|
}
|
|
|
|
|
|
|
|
{
|
|
|
|
class C {
|
|
|
|
static #a = 1;
|
|
|
|
static getA(instance) { return instance.#a; }
|
|
|
|
}
|
|
|
|
|
|
|
|
class B { }
|
|
|
|
|
|
|
|
assertEquals(undefined, C.a);
|
|
|
|
assertEquals(1, C.getA(C));
|
|
|
|
assertThrows(() => C.getA(B), TypeError);
|
|
|
|
}
|
|
|
|
|
|
|
|
{
|
|
|
|
class A {
|
|
|
|
static #a = 1;
|
|
|
|
static getA() { return this.#a; }
|
|
|
|
}
|
|
|
|
|
|
|
|
class B extends A {}
|
|
|
|
assertThrows(() => B.getA(), TypeError);
|
|
|
|
}
|
|
|
|
|
|
|
|
{
|
|
|
|
class A {
|
|
|
|
static #a = 1;
|
|
|
|
static getA() { return A.#a; }
|
|
|
|
}
|
|
|
|
|
|
|
|
class B extends A {}
|
|
|
|
assertSame(1, B.getA());
|
|
|
|
}
|
|
|
|
|
|
|
|
{
|
|
|
|
let prototypeLookup = false;
|
|
|
|
class A {
|
|
|
|
static set a(val) {
|
|
|
|
prototypeLookup = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
static get a() { return undefined; }
|
|
|
|
}
|
|
|
|
|
|
|
|
class C extends A {
|
|
|
|
static #a = 1;
|
|
|
|
static getA() { return this.#a; }
|
|
|
|
}
|
|
|
|
|
|
|
|
assertEquals(1, C.getA());
|
|
|
|
assertEquals(false, prototypeLookup);
|
|
|
|
}
|
|
|
|
|
|
|
|
{
|
|
|
|
class A {
|
|
|
|
static a = 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
class B extends A {
|
|
|
|
static #b = this.a;
|
|
|
|
static getB() { return this.#b; }
|
|
|
|
}
|
|
|
|
|
|
|
|
assertEquals(1, B.getB());
|
|
|
|
}
|
|
|
|
|
|
|
|
{
|
|
|
|
class A {
|
|
|
|
static #a = 1;
|
|
|
|
static getA() { return this.#a; }
|
|
|
|
}
|
|
|
|
|
|
|
|
class B extends A {
|
|
|
|
static getA() { return super.getA(); }
|
|
|
|
}
|
|
|
|
|
|
|
|
assertThrows(() => B.getA(), TypeError);
|
|
|
|
}
|
|
|
|
|
|
|
|
{
|
|
|
|
class A {
|
|
|
|
static #a = 1;
|
|
|
|
static getA() { return this.#a;}
|
|
|
|
}
|
|
|
|
|
|
|
|
class B extends A {
|
|
|
|
static #a = 2;
|
|
|
|
static get_A() { return this.#a;}
|
|
|
|
}
|
|
|
|
|
|
|
|
assertEquals(1, A.getA());
|
|
|
|
assertThrows(() => B.getA(), TypeError);
|
|
|
|
assertEquals(2, B.get_A());
|
|
|
|
}
|
|
|
|
|
|
|
|
{
|
|
|
|
let foo = undefined;
|
|
|
|
class A {
|
|
|
|
static #a = (function() { foo = 1; })();
|
|
|
|
}
|
|
|
|
|
|
|
|
assertEquals(1, foo);
|
|
|
|
}
|
|
|
|
|
|
|
|
{
|
|
|
|
let foo = undefined;
|
|
|
|
class A extends class {} {
|
|
|
|
static #a = (function() { foo = 1; })();
|
|
|
|
}
|
|
|
|
|
|
|
|
assertEquals(1, foo);
|
|
|
|
}
|
|
|
|
|
|
|
|
{
|
|
|
|
function makeClass() {
|
|
|
|
return class {
|
|
|
|
static #a;
|
|
|
|
static setA(val) { this.#a = val; }
|
|
|
|
static getA() { return this.#a; }
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
let classA = makeClass();
|
|
|
|
let classB = makeClass();
|
|
|
|
|
|
|
|
assertEquals(undefined, classA.getA());
|
|
|
|
assertEquals(undefined, classB.getA());
|
|
|
|
|
|
|
|
classA.setA(3);
|
|
|
|
assertEquals(3, classA.getA());
|
|
|
|
assertEquals(undefined, classB.getA());
|
|
|
|
|
|
|
|
classB.setA(5);
|
|
|
|
assertEquals(3, classA.getA());
|
|
|
|
assertEquals(5, classB.getA());
|
|
|
|
|
|
|
|
assertThrows(() => classA.getA.call(classB), TypeError);
|
|
|
|
assertThrows(() => classB.getA.call(classA), TypeError);
|
|
|
|
}
|
|
|
|
|
|
|
|
{
|
|
|
|
let value = undefined;
|
|
|
|
|
|
|
|
new class {
|
|
|
|
static #a = 1;
|
|
|
|
static getA() { return this.#a; }
|
|
|
|
|
|
|
|
constructor() {
|
|
|
|
new class C {
|
|
|
|
static #a = 2;
|
|
|
|
constructor() {
|
|
|
|
value = C.#a;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
assertEquals(2, value);
|
|
|
|
}
|
|
|
|
|
|
|
|
{
|
|
|
|
class A {
|
|
|
|
static #a = 1;
|
|
|
|
static b = class {
|
|
|
|
static getA() { return this.#a; }
|
|
|
|
static get_A(val) { return val.#a; }
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
assertEquals(1, A.b.getA.call(A));
|
|
|
|
assertEquals(1, A.b.get_A(A));
|
|
|
|
}
|
|
|
|
|
|
|
|
{
|
|
|
|
assertThrows(() => class { static b = this.#a; static #a = 1 }, TypeError);
|
|
|
|
}
|
|
|
|
|
|
|
|
{
|
|
|
|
let symbol = Symbol();
|
|
|
|
|
|
|
|
class C {
|
|
|
|
static #a = 1;
|
|
|
|
static [symbol] = 1;
|
|
|
|
static getA() { return this.#a; }
|
|
|
|
static setA(val) { this.#a = val; }
|
|
|
|
}
|
|
|
|
|
|
|
|
var p = new Proxy(C, {
|
|
|
|
get: function(target, name) {
|
|
|
|
if (typeof(arg) === 'symbol') {
|
|
|
|
assertFalse(%SymbolIsPrivate(name));
|
|
|
|
}
|
|
|
|
return target[name];
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
assertThrows(() => p.getA(), TypeError);
|
|
|
|
assertThrows(() => p.setA(1), TypeError);
|
|
|
|
assertEquals(1, p[symbol]);
|
|
|
|
}
|
|
|
|
|
|
|
|
{
|
|
|
|
class C {
|
|
|
|
static #b = Object.freeze(this);
|
|
|
|
static getA() { return this.#a; }
|
|
|
|
static #a = 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
assertEquals(1, C.getA());
|
|
|
|
}
|
|
|
|
|
|
|
|
{
|
|
|
|
class C {
|
|
|
|
static #a = 1;
|
|
|
|
static getA() { return eval('this.#a'); }
|
|
|
|
}
|
|
|
|
|
|
|
|
assertEquals(1, C.getA());
|
|
|
|
}
|
|
|
|
|
|
|
|
{
|
|
|
|
var C;
|
|
|
|
eval('C = class { static #a = 1; static getA() { return eval(\'this.#a\'); }}');
|
|
|
|
|
|
|
|
assertEquals(1, C.getA());
|
|
|
|
}
|
|
|
|
|
|
|
|
{
|
|
|
|
class C {
|
|
|
|
static #a = 1;
|
|
|
|
static getA() { return this.#a; }
|
|
|
|
static setA() { eval('this.#a = 4'); }
|
|
|
|
}
|
|
|
|
|
|
|
|
assertEquals(1, C.getA());
|
|
|
|
C.setA();
|
|
|
|
assertEquals(4, C.getA());
|
|
|
|
}
|
|
|
|
|
|
|
|
{
|
|
|
|
class C {
|
|
|
|
static getA() { return eval('this.#a'); }
|
|
|
|
}
|
|
|
|
|
|
|
|
assertThrows(() => C.getA(), SyntaxError);
|
|
|
|
}
|