| // 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); |
| } |