Merge pull request #1335 from bocoup/classfields-alg

classfields: Tests for modified algorithms and Private Names
This commit is contained in:
Leo Balter 2017-11-06 10:11:24 -05:00 committed by GitHub
commit c4e3d12597
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
21 changed files with 1020 additions and 0 deletions

View File

@ -0,0 +1,42 @@
// Copyright (C) 2017 Valerie Young. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
description: Class definition should error if evaluation of ClassElementName errors
esid: runtime-semantics-class-definition-evaluation
info: |
Runtime Semantics: ClassDefinitionEvaluation
...
27. For each ClassElement e in order from elements
a. If IsStatic of e is false, then
i. Let fields be the result of performing ClassElementEvaluation for e with arguments proto and false.
b. Else,
i. Let fields be the result of performing ClassElementEvaluation for e with arguments F and false.
c. If fields is an abrupt completion, then
i. Set the running execution context's LexicalEnvironment to lex.
ii. Set the running execution context's PrivateNameEnvironment to outerPrivateEnvironment.
iii. Return Completion(status).
Runtime Semantics: ClassElementEvaluation
...
ClassElement : FieldDefinition ;
1. Return ClassFieldDefinitionEvaluation of FieldDefinition with parameter false and object.
Runtime Semantics: ClassFieldDefinitionEvaluation
With parameters isStatic and homeObject.
FieldDefinition : ClassElementNameInitializer
1. Let fieldName be the result of evaluating ClassElementName.
2. ReturnIfAbrupt(fieldName).
features: [class-fields]
---*/
function f() {
throw new Test262Error();
}
assert.throws(Test262Error, function() {
class C {
[f()]
}
});

View File

@ -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: Class construction should error if evaluation of field initializer errors
esid: sec-ecmascript-function-objects-construct-argumentslist-newtarget
info: |
[[Construct]] ( argumentsList, newTarget)
...
8. If kind is "base", then
a. Perform OrdinaryCallBindThis(F, calleeContext, thisArgument).
b. Let result be InitializeInstanceFields(thisArgument, F).
c. If result is an abrupt completion, then
i. Remove calleeContext from execution context stack and restore callerContext as the running execution context.
ii. Return Completion(result).
InitializeInstanceFields ( O, constructor )
1. Assert: Type ( O ) is Object.
2. Assert: Assert constructor is an ECMAScript function object.
3. Let fieldRecords be the value of constructor's [[Fields]] internal slot.
4. For each item fieldRecord in order from fieldRecords,
a. If fieldRecord.[[static]] is false, then
i. Perform ? DefineField(O, fieldRecord).
DefineField(receiver, fieldRecord)
1. Assert: Type(receiver) is Object.
2. Assert: fieldRecord is a Record as created by ClassFieldDefinitionEvaluation.
3. Let fieldName be fieldRecord.[[Name]].
4. Let initializer be fieldRecord.[[Initializer]].
5. If initializer is not empty, then
a.Let initValue be ? Call(initializer, receiver).
features: [class-fields]
---*/
function f() {
throw new Test262Error();
}
class C {
x = f();
}
assert.throws(Test262Error, function() {
new C();
})

View File

@ -0,0 +1,60 @@
// Copyright (C) 2017 Valerie Young. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
description: Class construction should error if attempting to add private field twice
esid: sec-ecmascript-function-objects-construct-argumentslist-newtarget
info: |
[[Construct]] ( argumentsList, newTarget)
...
8. If kind is "base", then
a. Perform OrdinaryCallBindThis(F, calleeContext, thisArgument).
b. Let result be InitializeInstanceFields(thisArgument, F).
c. If result is an abrupt completion, then
i. Remove calleeContext from execution context stack and restore callerContext as the running execution context.
ii. Return Completion(result).
InitializeInstanceFields ( O, constructor )
1. Assert: Type ( O ) is Object.
2. Assert: Assert constructor is an ECMAScript function object.
3. Let fieldRecords be the value of constructor's [[Fields]] internal slot.
4. For each item fieldRecord in order from fieldRecords,
a. If fieldRecord.[[static]] is false, then
i. Perform ? DefineField(O, fieldRecord).
DefineField(receiver, fieldRecord)
...
8. If fieldName is a Private Name,
a. Perform ? PrivateFieldAdd(fieldName, receiver, initValue).
PrivateFieldAdd (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 not empty, throw a TypeError exception.
features: [class-fields]
---*/
class A {
constructor(arg) {
return arg;
}
}
class C extends A {
#x;
constructor(arg) {
super(arg);
}
}
var containsprivatex = new C();
assert.throws(TypeError, function() {
// After the super call in C's constructor, the `this` value in C will
// already have "#x" in it's [[PrivateFieldValues]]
new C(containsprivatex);
})

View File

@ -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)

View File

@ -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')

View File

@ -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')

View File

@ -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')

View File

@ -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');

View File

@ -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(); })

View File

@ -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();
})

View File

@ -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();
})

View File

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

View File

@ -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();
})

View File

@ -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(); })

View File

@ -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();
})

View File

@ -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();
})

View File

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

View File

@ -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();
})

View File

@ -0,0 +1,42 @@
// Copyright (C) 2017 Valerie Young. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
description: Class definition should error if evaluation of static ClassElementName errors
esid: runtime-semantics-class-definition-evaluation
info: |
Runtime Semantics: ClassDefinitionEvaluation
...
27. For each ClassElement e in order from elements
a. If IsStatic of e is false, then
i. Let fields be the result of performing ClassElementEvaluation for e with arguments proto and false.
b. Else,
i. Let fields be the result of performing ClassElementEvaluation for e with arguments F and false.
c. If fields is an abrupt completion, then
i. Set the running execution context's LexicalEnvironment to lex.
ii. Set the running execution context's PrivateNameEnvironment to outerPrivateEnvironment.
iii. Return Completion(status).
Runtime Semantics: ClassElementEvaluation
...
ClassElement : static FieldDefinition ;
1. Return ClassFieldDefinitionEvaluation of FieldDefinition with parameter true and object.
Runtime Semantics: ClassFieldDefinitionEvaluation
With parameters isStatic and homeObject.
FieldDefinition : ClassElementNameInitializer
1. Let fieldName be the result of evaluating ClassElementName.
2. ReturnIfAbrupt(fieldName).
features: [class-fields]
---*/
function f() {
throw new Test262Error();
}
assert.throws(Test262Error, function() {
class C {
static [f()]
}
});

View File

@ -0,0 +1,42 @@
// Copyright (C) 2017 Valerie Young. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
description: Class construction should error if evaluation of static field initializer errors
esid: runtime-semantics-class-definition-evaluation
info: |
Runtime Semantics: ClassDefinitionEvaluation
...
33. Let result be InitializeStaticFields(F).
34. If result is an abrupt completion, then
a. Set the running execution context's LexicalEnvironment to lex.
b. Return Completion(result).
InitializeStaticFields(F)
1. Assert: Type(F) is Object.
2. Assert: F is an ECMAScript function object.
3. Let fieldRecords be the value of F's [[Fields]] internal slot.
4. For each item fieldRecord in order from fieldRecords,
a. If fieldRecord.[[static]] is true, then
i. Perform ? DefineField(F, fieldRecord).
DefineField(receiver, fieldRecord)
1. Assert: Type(receiver) is Object.
2. Assert: fieldRecord is a Record as created by ClassFieldDefinitionEvaluation.
3. Let fieldName be fieldRecord.[[Name]].
4. Let initializer be fieldRecord.[[Initializer]].
5. If initializer is not empty, then
a. Let initValue be ? Call(initializer, receiver).
features: [class-fields]
---*/
function f() {
throw new Test262Error();
}
assert.throws(Test262Error, function() {
class C {
static x = f();
}
})

View File

@ -0,0 +1,56 @@
// Copyright (C) 2017 Valerie Young. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
description: Class construction should error if evaluation of field initializer in super errors
esid: sec-super-keyword-runtime-semantics-evaluation
info: |
Runtime Semantics: Evaluation
SuperCall : superArguments
1. Let newTarget be GetNewTarget().
2. If newTarget is undefined, throw a ReferenceError exception.
3. Let func be ? GetSuperConstructor().
4. Let argList be ArgumentListEvaluation of Arguments.
5. ReturnIfAbrupt(argList).
6. Let result be ? Construct(func, argList, newTarget).
7. Let thisER be GetThisEnvironment( ).
8. Let F be thisER.[[FunctionObject]].
9. Assert: F is an ECMAScript function object.
10. Perform ? InitializeInstanceFields(result, F).
InitializeInstanceFields ( O, constructor )
1. Assert: Type ( O ) is Object.
2. Assert: Assert constructor is an ECMAScript function object.
3. Let fieldRecords be the value of constructor's [[Fields]] internal slot.
4. For each item fieldRecord in order from fieldRecords,
a. If fieldRecord.[[static]] is false, then
i. Perform ? DefineField(O, fieldRecord).
DefineField(receiver, fieldRecord)
1. Assert: Type(receiver) is Object.
2. Assert: fieldRecord is a Record as created by ClassFieldDefinitionEvaluation.
3. Let fieldName be fieldRecord.[[Name]].
4. Let initializer be fieldRecord.[[Initializer]].
5. If initializer is not empty, then
a.Let initValue be ? Call(initializer, receiver).
features: [class-fields]
---*/
function f() {
throw new Test262Error();
}
class A {
x = f();
}
class C extends A {
constructor() {
super();
}
}
assert.throws(Test262Error, function() {
new C();
})