diff --git a/test/language/statements/class/privatefieldget-success-1.js b/test/language/statements/class/privatefieldget-success-1.js new file mode 100644 index 0000000000000000000000000000000000000000..73836bd040cb2dba7e67563aeff58adf4809511e --- /dev/null +++ b/test/language/statements/class/privatefieldget-success-1.js @@ -0,0 +1,46 @@ +// Copyright (C) 2017 Valerie Young. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +description: Successfully access private field +esid: sec-getvalue +info: | + GetValue ( V ) + ... + 5. If IsPropertyReference(V), then + ... + b. If IsPrivateReference(V), then + i. Let env be the running execution context's PrivateNameEnvironment. + ii. Let field be ? ResolveBinding(GetReferencedName(V), env). + iii. Assert: field is a Private Name. + iv. Return ? PrivateFieldGet(field, base). + + PrivateFieldGet (P, O ) + 1. Assert: P is a Private Name value. + 2. If O is not an object, throw a TypeError exception. + 3. Let entry be PrivateFieldFind(P, O). + 4. If entry is empty, throw a TypeError exception. + 5. Return entry.[[PrivateFieldValue]]. + +features: [class-fields] +---*/ + +class Outer { + #x = 42; + + innerclass() { + var self = this; + + return class extends Outer { + f() { + return self.#x; + } + } + } +} + +var Inner = new Outer().innerclass(); +var i = new Inner(); +var value = i.f(); + +assert.sameValue(value, 42) diff --git a/test/language/statements/class/privatefieldget-success-2.js b/test/language/statements/class/privatefieldget-success-2.js new file mode 100644 index 0000000000000000000000000000000000000000..adc4e9a10fb678e3b01f7e574ee86b7fdb07ad76 --- /dev/null +++ b/test/language/statements/class/privatefieldget-success-2.js @@ -0,0 +1,44 @@ +// Copyright (C) 2017 Valerie Young. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +description: Successfully access private field +esid: sec-getvalue +info: | + GetValue ( V ) + ... + 5. If IsPropertyReference(V), then + ... + b. If IsPrivateReference(V), then + i. Let env be the running execution context's PrivateNameEnvironment. + ii. Let field be ? ResolveBinding(GetReferencedName(V), env). + iii. Assert: field is a Private Name. + iv. Return ? PrivateFieldGet(field, base). + + PrivateFieldGet (P, O ) + 1. Assert: P is a Private Name value. + 2. If O is not an object, throw a TypeError exception. + 3. Let entry be PrivateFieldFind(P, O). + 4. If entry is empty, throw a TypeError exception. + 5. Return entry.[[PrivateFieldValue]]. + +features: [class-fields] +---*/ + + +class A { + #x = 'Avalue'; + x() { + return this.#x; + } +} +class B extends A { + #x = 'Bvalue'; + x() { + return this.#x; + } +} + +var b = new B(); + +assert.sameValue(b.x(), 'Bvalue') diff --git a/test/language/statements/class/privatefieldget-success-3.js b/test/language/statements/class/privatefieldget-success-3.js new file mode 100644 index 0000000000000000000000000000000000000000..d9722f5639fb7d6a74e31ed3eec20b9a5ccf102f --- /dev/null +++ b/test/language/statements/class/privatefieldget-success-3.js @@ -0,0 +1,41 @@ +// Copyright (C) 2017 Valerie Young. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +description: Successfully access private field +esid: sec-getvalue +info: | + GetValue ( V ) + ... + 5. If IsPropertyReference(V), then + ... + b. If IsPrivateReference(V), then + i. Let env be the running execution context's PrivateNameEnvironment. + ii. Let field be ? ResolveBinding(GetReferencedName(V), env). + iii. Assert: field is a Private Name. + iv. Return ? PrivateFieldGet(field, base). + + PrivateFieldGet (P, O ) + 1. Assert: P is a Private Name value. + 2. If O is not an object, throw a TypeError exception. + 3. Let entry be PrivateFieldFind(P, O). + 4. If entry is empty, throw a TypeError exception. + 5. Return entry.[[PrivateFieldValue]]. + +features: [class-fields] +---*/ + + +class A { + #x = 'Avalue'; + x() { + return this.#x; + } +} +class B extends A { + #x = 'Bvalue'; +} + +var b = new B(); + +assert.sameValue(b.x(), 'Avalue') diff --git a/test/language/statements/class/privatefieldget-success-4.js b/test/language/statements/class/privatefieldget-success-4.js new file mode 100644 index 0000000000000000000000000000000000000000..7253d32f1cea0df443e4163b15bc77928101e2a5 --- /dev/null +++ b/test/language/statements/class/privatefieldget-success-4.js @@ -0,0 +1,40 @@ +// Copyright (C) 2017 Valerie Young. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +description: Successfully access private field +esid: sec-getvalue +info: | + GetValue ( V ) + ... + 5. If IsPropertyReference(V), then + ... + b. If IsPrivateReference(V), then + i. Let env be the running execution context's PrivateNameEnvironment. + ii. Let field be ? ResolveBinding(GetReferencedName(V), env). + iii. Assert: field is a Private Name. + iv. Return ? PrivateFieldGet(field, base). + + PrivateFieldGet (P, O ) + 1. Assert: P is a Private Name value. + 2. If O is not an object, throw a TypeError exception. + 3. Let entry be PrivateFieldFind(P, O). + 4. If entry is empty, throw a TypeError exception. + 5. Return entry.[[PrivateFieldValue]]. + +features: [class-fields] +---*/ + + +class A { + #x = 'Avalue'; + x() { + return this.#x; + } +} +class B extends A { +} + +var b = new B(); + +assert.sameValue(b.x(), 'Avalue') diff --git a/test/language/statements/class/privatefieldget-success-5.js b/test/language/statements/class/privatefieldget-success-5.js new file mode 100644 index 0000000000000000000000000000000000000000..9bf09e9ea464995ed259c87df271c037a9218d48 --- /dev/null +++ b/test/language/statements/class/privatefieldget-success-5.js @@ -0,0 +1,40 @@ +// Copyright (C) 2017 Valerie Young. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +description: Successfully access private field +esid: sec-getvalue +info: | + GetValue ( V ) + ... + 5. If IsPropertyReference(V), then + ... + b. If IsPrivateReference(V), then + i. Let env be the running execution context's PrivateNameEnvironment. + ii. Let field be ? ResolveBinding(GetReferencedName(V), env). + iii. Assert: field is a Private Name. + iv. Return ? PrivateFieldGet(field, base). + + PrivateFieldGet (P, O ) + 1. Assert: P is a Private Name value. + 2. If O is not an object, throw a TypeError exception. + 3. Let entry be PrivateFieldFind(P, O). + 4. If entry is empty, throw a TypeError exception. + 5. Return entry.[[PrivateFieldValue]]. + +features: [class-fields] +---*/ + + +class C { + #x = 42; + f() { + return this.#x; + } +} + +var c1 = new C(); +var c2 = new C(); +var value = c2.f.call(c1); + +assert.sameValue(value, 'Avalue'); diff --git a/test/language/statements/class/privatefieldget-typeerror-1.js b/test/language/statements/class/privatefieldget-typeerror-1.js new file mode 100644 index 0000000000000000000000000000000000000000..1f1f20144921ee7e7067fe3e98f1f57840802f71 --- /dev/null +++ b/test/language/statements/class/privatefieldget-typeerror-1.js @@ -0,0 +1,39 @@ +// Copyright (C) 2017 Valerie Young. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +description: Cannot access private field before the entry was added to [[PrivateFieldValues]] +esid: sec-getvalue +info: | + GetValue ( V ) + ... + 5. If IsPropertyReference(V), then + ... + b. If IsPrivateReference(V), then + i. Let env be the running execution context's PrivateNameEnvironment. + ii. Let field be ? ResolveBinding(GetReferencedName(V), env). + iii. Assert: field is a Private Name. + iv. Return ? PrivateFieldGet(field, base). + + PrivateFieldGet (P, O ) + 1. Assert: P is a Private Name value. + 2. If O is not an object, throw a TypeError exception. + 3. Let entry be PrivateFieldFind(P, O). + 4. If entry is empty, throw a TypeError exception. + + PrivateFieldFind (P, O) + 1. Assert: P is a Private Name value. + 2. Assert: O is an object with a [[PrivateFieldValues]] internal slot. + 3. For each element entry in O.[[PrivateFieldValues]], + a. If entry.[[PrivateName]] is P, return entry. + 4. Return empty. + +features: [class-fields] +---*/ + +class C { + y = this.#x; + #x; +} + +assert.throws(TypeError, function() { new C(); }) diff --git a/test/language/statements/class/privatefieldget-typeerror-2.js b/test/language/statements/class/privatefieldget-typeerror-2.js new file mode 100644 index 0000000000000000000000000000000000000000..4a5f6be65674eb2de22e0079cef1a5c3cf4fd707 --- /dev/null +++ b/test/language/statements/class/privatefieldget-typeerror-2.js @@ -0,0 +1,55 @@ +// Copyright (C) 2017 Valerie Young. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +description: TypeError when referenced private field cannot be found in `this`'s [[PrivateFieldValues]] +esid: sec-getvalue +info: | + GetValue ( V ) + ... + 5. If IsPropertyReference(V), then + ... + b. If IsPrivateReference(V), then + i. Let env be the running execution context's PrivateNameEnvironment. + ii. Let field be ? ResolveBinding(GetReferencedName(V), env). + iii. Assert: field is a Private Name. + iv. Return ? PrivateFieldGet(field, base). + + PrivateFieldGet (P, O ) + 1. Assert: P is a Private Name value. + 2. If O is not an object, throw a TypeError exception. + 3. Let entry be PrivateFieldFind(P, O). + 4. If entry is empty, throw a TypeError exception. + + PrivateFieldFind (P, O) + 1. Assert: P is a Private Name value. + 2. Assert: O is an object with a [[PrivateFieldValues]] internal slot. + 3. For each element entry in O.[[PrivateFieldValues]], + a. If entry.[[PrivateName]] is P, return entry. + 4. Return empty. + +features: [class-fields] +---*/ + +class Outer { + #x = 42; + + innerclass() { + + // create class within in Outerclass -- the PrivateNameEnvironment binding for + // private field `#x` is resolvable. + return class { + f() { + return this.#x; + } + } + } +} + +var Inner = new Outer().innerclass(); +var i = new Inner(); + +assert.throws(TypeError, function() { + // when f() is called, the private field will not be found in Inner's `this` + i.f(); +}) diff --git a/test/language/statements/class/privatefieldget-typeerror-3.js b/test/language/statements/class/privatefieldget-typeerror-3.js new file mode 100644 index 0000000000000000000000000000000000000000..8c1ef2748b115ba417859a95fcf10dc2541e7046 --- /dev/null +++ b/test/language/statements/class/privatefieldget-typeerror-3.js @@ -0,0 +1,55 @@ +// Copyright (C) 2017 Valerie Young. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +description: TypeError when referenced private field cannot be found in `this`'s [[PrivateFieldValues]] +esid: sec-getvalue +info: | + GetValue ( V ) + ... + 5. If IsPropertyReference(V), then + ... + b. If IsPrivateReference(V), then + i. Let env be the running execution context's PrivateNameEnvironment. + ii. Let field be ? ResolveBinding(GetReferencedName(V), env). + iii. Assert: field is a Private Name. + iv. Return ? PrivateFieldGet(field, base). + + PrivateFieldGet (P, O ) + 1. Assert: P is a Private Name value. + 2. If O is not an object, throw a TypeError exception. + 3. Let entry be PrivateFieldFind(P, O). + 4. If entry is empty, throw a TypeError exception. + + PrivateFieldFind (P, O) + 1. Assert: P is a Private Name value. + 2. Assert: O is an object with a [[PrivateFieldValues]] internal slot. + 3. For each element entry in O.[[PrivateFieldValues]], + a. If entry.[[PrivateName]] is P, return entry. + 4. Return empty. + +features: [class-fields] +---*/ + +class Outer { + #x = 42; + + innerclass() { + + // create class within in Outerclass -- the PrivateNameEnvironment binding for + // private field `#x` is resolvable. + return class extends Outer { + f() { + return this.#x; + } + } + } +} + +var Inner = new Outer().innerclass(); +var i = new Inner(); + +assert.throws(TypeError, function() { + // when f() is called, the private field will not be found in Inner's `this` + i.f(); +}) diff --git a/test/language/statements/class/privatefieldget-typeerror-4.js b/test/language/statements/class/privatefieldget-typeerror-4.js new file mode 100644 index 0000000000000000000000000000000000000000..61f2d3a78dedcdcbc046278643658a792f7e39da --- /dev/null +++ b/test/language/statements/class/privatefieldget-typeerror-4.js @@ -0,0 +1,53 @@ +// Copyright (C) 2017 Valerie Young. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +description: TypeError when referenced private field cannot be found in `this`'s [[PrivateFieldValues]] +esid: sec-getvalue +info: | + GetValue ( V ) + ... + 5. If IsPropertyReference(V), then + ... + b. If IsPrivateReference(V), then + i. Let env be the running execution context's PrivateNameEnvironment. + ii. Let field be ? ResolveBinding(GetReferencedName(V), env). + iii. Assert: field is a Private Name. + iv. Return ? PrivateFieldGet(field, base). + + PrivateFieldGet (P, O ) + 1. Assert: P is a Private Name value. + 2. If O is not an object, throw a TypeError exception. + 3. Let entry be PrivateFieldFind(P, O). + 4. If entry is empty, throw a TypeError exception. + + PrivateFieldFind (P, O) + 1. Assert: P is a Private Name value. + 2. Assert: O is an object with a [[PrivateFieldValues]] internal slot. + 3. For each element entry in O.[[PrivateFieldValues]], + a. If entry.[[PrivateName]] is P, return entry. + 4. Return empty. + +features: [class-fields] +---*/ + +function classfactory() { + return class { + #x; + f() { + this.#x; + } + } +} + +var C1 = classfactory(); +var C2 = classfactory(); + +c1 = new C1(); +c2 = new C2(); + +assert.throws(TypeError, function() { + // when f() is called in class C1, the Private Name binding for #x in C1 will + // not found in C2's [[PrivateNameValues]] + c1.f.call(c2); +}) diff --git a/test/language/statements/class/privatefieldget-typeerror-5.js b/test/language/statements/class/privatefieldget-typeerror-5.js new file mode 100644 index 0000000000000000000000000000000000000000..ff1f3737c15d6b2774bfb625a452fb8481bf2f17 --- /dev/null +++ b/test/language/statements/class/privatefieldget-typeerror-5.js @@ -0,0 +1,58 @@ +// Copyright (C) 2017 Valerie Young. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +description: TypeError when referenced private field cannot be found in `this`'s [[PrivateFieldValues]] +esid: sec-getvalue +info: | + GetValue ( V ) + ... + 5. If IsPropertyReference(V), then + ... + b. If IsPrivateReference(V), then + i. Let env be the running execution context's PrivateNameEnvironment. + ii. Let field be ? ResolveBinding(GetReferencedName(V), env). + iii. Assert: field is a Private Name. + iv. Return ? PrivateFieldGet(field, base). + + PrivateFieldGet (P, O ) + 1. Assert: P is a Private Name value. + 2. If O is not an object, throw a TypeError exception. + 3. Let entry be PrivateFieldFind(P, O). + 4. If entry is empty, throw a TypeError exception. + + PrivateFieldFind (P, O) + 1. Assert: P is a Private Name value. + 2. Assert: O is an object with a [[PrivateFieldValues]] internal slot. + 3. For each element entry in O.[[PrivateFieldValues]], + a. If entry.[[PrivateName]] is P, return entry. + 4. Return empty. + +features: [class-fields] +---*/ + +class Outer { + #x = 42; + + innerclass() { + var self = this; + + return class extends Outer { + #x = 'not42'; + f() { + return self.#x; + } + } + } +} + +var Inner = new Outer().innerclass(); +var i = new Inner(); + +assert.throws(TypeError, function() { + // when f() is called, the entry in the PrivateNameEnironment's environment + // record for '#x' will contain the Inner class's Private Name for '#x'. + // When this Private Name is used for lookup on the `self` object, it + // will not be found (as the `self` object has the Outer's Private Name for #x) + i.f(); +}) diff --git a/test/language/statements/class/privatefieldset-typeerror-1.js b/test/language/statements/class/privatefieldset-typeerror-1.js new file mode 100644 index 0000000000000000000000000000000000000000..ddd1a3f1999f73732b8e7b2ba50e0bdb13582ffb --- /dev/null +++ b/test/language/statements/class/privatefieldset-typeerror-1.js @@ -0,0 +1,39 @@ +// Copyright (C) 2017 Valerie Young. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +description: TypeError when setting private field before the entry was added to [[PrivateFieldValues]] +esid: sec-putvalue +info: | + PutValue ( V, W ) + ... + 5. Else if IsPropertyReference(V), then + ... + b. If IsPrivateReference(V), then + i. Let env be the running execution context's PrivateNameEnvironment. + ii. Let field be ? ResolveBinding(GetReferencedName(V), env). + iii. Assert: field is a Private Name. + iv. Perform ? PrivateFieldSet(field, base, W). + + PrivateFieldSet (P, O, value ) + 1. Assert: P is a Private Name value. + 2. If O is not an object, throw a TypeError exception. + 3. Let entry be PrivateFieldFind(P, O). + 4. If entry is empty, throw a TypeError exception. + + PrivateFieldFind (P, O) + 1. Assert: P is a Private Name value. + 2. Assert: O is an object with a [[PrivateFieldValues]] internal slot. + 3. For each element entry in O.[[PrivateFieldValues]], + a. If entry.[[PrivateName]] is P, return entry. + 4. Return empty. + +features: [class-fields] +---*/ + +class C { + y = this.#x = 1; + #x; +} + +assert.throws(TypeError, function() { new C(); }) diff --git a/test/language/statements/class/privatefieldset-typeerror-2.js b/test/language/statements/class/privatefieldset-typeerror-2.js new file mode 100644 index 0000000000000000000000000000000000000000..8f83e513ea79d0f5fb5464c70ae3cf9ecf0ff2c2 --- /dev/null +++ b/test/language/statements/class/privatefieldset-typeerror-2.js @@ -0,0 +1,55 @@ +// Copyright (C) 2017 Valerie Young. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +description: TypeError when setting private field not in `this`'s [[PrivateFieldValues]] +esid: sec-putvalue +info: | + PutValue ( V, W ) + ... + 5. Else if IsPropertyReference(V), then + ... + b. If IsPrivateReference(V), then + i. Let env be the running execution context's PrivateNameEnvironment. + ii. Let field be ? ResolveBinding(GetReferencedName(V), env). + iii. Assert: field is a Private Name. + iv. Perform ? PrivateFieldSet(field, base, W). + + PrivateFieldSet (P, O, value ) + 1. Assert: P is a Private Name value. + 2. If O is not an object, throw a TypeError exception. + 3. Let entry be PrivateFieldFind(P, O). + 4. If entry is empty, throw a TypeError exception. + + PrivateFieldFind (P, O) + 1. Assert: P is a Private Name value. + 2. Assert: O is an object with a [[PrivateFieldValues]] internal slot. + 3. For each element entry in O.[[PrivateFieldValues]], + a. If entry.[[PrivateName]] is P, return entry. + 4. Return empty. + +features: [class-fields] +---*/ + +class Outer { + #x = 42; + + innerclass() { + + // create class within in Outerclass -- the PrivateNameEnvironment binding for + // private field `#x` is resolvable. + return class { + f() { + this.#x = 1; + } + } + } +} + +var Inner = new Outer().innerclass(); +var i = new Inner(); + +assert.throws(TypeError, function() { + // when f() is called, the private field will not be found in Inner's `this` + i.f(); +}) diff --git a/test/language/statements/class/privatefieldset-typeerror-3.js b/test/language/statements/class/privatefieldset-typeerror-3.js new file mode 100644 index 0000000000000000000000000000000000000000..4a0bfabd9069ca3ddb4d5997b190ed01a8517980 --- /dev/null +++ b/test/language/statements/class/privatefieldset-typeerror-3.js @@ -0,0 +1,55 @@ +// Copyright (C) 2017 Valerie Young. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +description: TypeError when setting private field not in `this`'s [[PrivateFieldValues]] +esid: sec-putvalue +info: | + PutValue ( V, W ) + ... + 5. Else if IsPropertyReference(V), then + ... + b. If IsPrivateReference(V), then + i. Let env be the running execution context's PrivateNameEnvironment. + ii. Let field be ? ResolveBinding(GetReferencedName(V), env). + iii. Assert: field is a Private Name. + iv. Perform ? PrivateFieldSet(field, base, W). + + PrivateFieldSet (P, O, value ) + 1. Assert: P is a Private Name value. + 2. If O is not an object, throw a TypeError exception. + 3. Let entry be PrivateFieldFind(P, O). + 4. If entry is empty, throw a TypeError exception. + + PrivateFieldFind (P, O) + 1. Assert: P is a Private Name value. + 2. Assert: O is an object with a [[PrivateFieldValues]] internal slot. + 3. For each element entry in O.[[PrivateFieldValues]], + a. If entry.[[PrivateName]] is P, return entry. + 4. Return empty. + +features: [class-fields] +---*/ + +class Outer { + #x = 42; + + innerclass() { + + // create class within in Outerclass -- the PrivateNameEnvironment binding for + // private field `#x` is resolvable. + return class extends Outer { + f() { + this.#x = 1; + } + } + } +} + +var Inner = new Outer().innerclass(); +var i = new Inner(); + +assert.throws(TypeError, function() { + // when f() is called, the private field will not be found in Inner's `this` + i.f(); +}) diff --git a/test/language/statements/class/privatefieldset-typeerror-4.js b/test/language/statements/class/privatefieldset-typeerror-4.js new file mode 100644 index 0000000000000000000000000000000000000000..d3dc0ab966920b5ea6779155b52cda00db54c1f1 --- /dev/null +++ b/test/language/statements/class/privatefieldset-typeerror-4.js @@ -0,0 +1,53 @@ +// Copyright (C) 2017 Valerie Young. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +description: TypeError when setting private field not in `this`'s [[PrivateFieldValues]] +esid: sec-putvalue +info: | + PutValue ( V, W ) + ... + 5. Else if IsPropertyReference(V), then + ... + b. If IsPrivateReference(V), then + i. Let env be the running execution context's PrivateNameEnvironment. + ii. Let field be ? ResolveBinding(GetReferencedName(V), env). + iii. Assert: field is a Private Name. + iv. Perform ? PrivateFieldSet(field, base, W). + + PrivateFieldSet (P, O, value ) + 1. Assert: P is a Private Name value. + 2. If O is not an object, throw a TypeError exception. + 3. Let entry be PrivateFieldFind(P, O). + 4. If entry is empty, throw a TypeError exception. + + PrivateFieldFind (P, O) + 1. Assert: P is a Private Name value. + 2. Assert: O is an object with a [[PrivateFieldValues]] internal slot. + 3. For each element entry in O.[[PrivateFieldValues]], + a. If entry.[[PrivateName]] is P, return entry. + 4. Return empty. + +features: [class-fields] +---*/ + +function classfactory() { + return class { + #x; + f() { + this.#x = 1; + } + } +} + +var C1 = classfactory(); +var C2 = classfactory(); + +c1 = new C1(); +c2 = new C2(); + +assert.throws(TypeError, function() { + // when f() is called in class C1, the Private Name binding for #x in C1 will + // not found in C2's [[PrivateNameValues]] + c1.f.call(c2); +}) diff --git a/test/language/statements/class/privatefieldset-typeerror-5.js b/test/language/statements/class/privatefieldset-typeerror-5.js new file mode 100644 index 0000000000000000000000000000000000000000..7ccdc75e858cec38cf9ab4631f7078acf5e220e6 --- /dev/null +++ b/test/language/statements/class/privatefieldset-typeerror-5.js @@ -0,0 +1,59 @@ +// Copyright (C) 2017 Valerie Young. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +description: TypeError when setting private field not in `this`'s [[PrivateFieldValues]] +esid: sec-putvalue +info: | + PutValue ( V, W ) + ... + 5. Else if IsPropertyReference(V), then + ... + b. If IsPrivateReference(V), then + i. Let env be the running execution context's PrivateNameEnvironment. + ii. Let field be ? ResolveBinding(GetReferencedName(V), env). + iii. Assert: field is a Private Name. + iv. Perform ? PrivateFieldSet(field, base, W). + + PrivateFieldSet (P, O, value ) + 1. Assert: P is a Private Name value. + 2. If O is not an object, throw a TypeError exception. + 3. Let entry be PrivateFieldFind(P, O). + 4. If entry is empty, throw a TypeError exception. + + PrivateFieldFind (P, O) + 1. Assert: P is a Private Name value. + 2. Assert: O is an object with a [[PrivateFieldValues]] internal slot. + 3. For each element entry in O.[[PrivateFieldValues]], + a. If entry.[[PrivateName]] is P, return entry. + 4. Return empty. + +features: [class-fields] +---*/ + + +class Outer { + #x = 42; + + innerclass() { + var self = this; + + return class extends Outer { + #x = 'not42'; + f() { + self.#x = 1; + } + } + } +} + +var Inner = new Outer().innerclass(); +var i = new Inner(); + +assert.throws(TypeError, function() { + // when f() is called, the entry in the PrivateNameEnironment's environment + // record for '#x' will contain the Inner class's Private Name for '#x'. + // When this Private Name is used for lookup on the `self` object, it + // will not be found (as the `self` object has the Outer's Private Name for #x) + i.f(); +})