blob: a731a35548fb587d22eb19d9f556ec793fa23b4b [file] [log] [blame]
// 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: --allow-natives-syntax
"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);
}