Issue #1658 - Part 8: Update tests

This commit is contained in:
FranklinDM 2022-05-04 02:16:05 +08:00 committed by roytam1
commit f2cd5760ba
79 changed files with 2988 additions and 0 deletions

View file

@ -0,0 +1,5 @@
// |jit-test| skip-if: !('oomTest' in this)
var code = `
(\`\${key}: \${(args[1]?.toString)?.()}\`)
`;
oomTest(function() { return parseModule(code); });

View file

@ -0,0 +1,5 @@
// |jit-test| skip-if: !('oomTest' in this)
var code = `
(\`\${key}: \${args[1]?.toString()}\`)
`;
oomTest(function() { return parseModule(code); });

View file

@ -0,0 +1,34 @@
// Tests for JSOp::CallIgnoresRv in optional chains.
// Note:: IgnoresReturnValueNative is supported for Array.prototype.splice.
// Test for optional call.
function testOptionalCall() {
for (var i = 0; i < 100; ++i) {
var x = [1, 2, 3];
x.splice?.(0);
}
}
for (var i = 0; i < 5; ++i) { testOptionalCall(); }
// Test for optional prop directly followed by call.
function testOptionalProp() {
for (var i = 0; i < 100; ++i) {
var x = [1, 2, 3];
x?.splice(0);
}
}
for (var i = 0; i < 5; ++i) { testOptionalProp(); }
// Test for call in optional chain expression.
function testOptionalChain() {
for (var i = 0; i < 100; ++i) {
var x = [1, 2, 3];
var o = {x};
o?.x.splice(0);
}
}
for (var i = 0; i < 5; ++i) { testOptionalChain(); }

View file

@ -0,0 +1,60 @@
// Tests for JSOp::FunCall and JSOp::FunApply in optional calls.
function f1() {
return 0;
}
function f2(a) {
return a * 2;
}
function funCall(fn) {
// Without arguments.
for (var i = 0; i < 100; ++i) {
assertEq(f1?.call(), 0);
}
// Only this-arg.
for (var i = 0; i < 100; ++i) {
assertEq(f1?.call(null), 0);
}
// With one arg.
for (var i = 0; i < 100; ++i) {
assertEq(f1?.call(null, 1), 0);
assertEq(f2?.call(null, 5), 10);
}
// With multiple args.
for (var i = 0; i < 100; ++i) {
assertEq(f1?.call(null, 1, 2, 3), 0);
assertEq(f2?.call(null, 4, 5, 6), 8);
}
}
for (var i = 0; i < 5; ++i) { funCall(); }
function funApply(fn) {
// Without arguments.
for (var i = 0; i < 100; ++i) {
assertEq(f1?.apply(), 0);
}
// Only this-arg.
for (var i = 0; i < 100; ++i) {
assertEq(f1?.apply(null), 0);
}
// With one arg.
for (var i = 0; i < 100; ++i) {
assertEq(f1?.apply(null, [1]), 0);
assertEq(f2?.apply(null, [5]), 10);
}
// With multiple args.
for (var i = 0; i < 100; ++i) {
assertEq(f1?.apply(null, [1, 2, 3]), 0);
assertEq(f2?.apply(null, [4, 5, 6]), 8);
}
}
for (var i = 0; i < 5; ++i) { funApply(); }

View file

@ -0,0 +1,10 @@
// Optional expression can be part of a class heritage expression.
var a = {b: null};
class C extends a?.b {}
assertEq(Object.getPrototypeOf(C.prototype), null);
if (typeof reportCompare === "function")
reportCompare(true, true);

View file

@ -0,0 +1,92 @@
// Verify bytecode emitter accepts all valid optional chain first expressions.
const expressions = [
// https://tc39.es/ecma262/#sec-primary-expression
"this",
"ident",
"null",
"true",
"false",
"123",
"123n",
"'str'",
"[]",
"{}",
"function(){}",
"class{}",
"function*(){}",
"async function(){}",
"async function*(){}",
"/a/",
"`str`",
"(a + b)",
// https://tc39.es/ecma262/#sec-left-hand-side-expressions
"a[b]",
"a.b",
"a``",
"super[a]",
"super.a",
"new.target",
"import.meta",
"new C()",
"new C",
"f()",
"super()",
"a?.b",
"a?.[b]",
"a?.()",
"a?.``",
];
function tryParse(s, f = Function) {
try { f(s); } catch {}
}
function tryRun(s, f = Function) {
try { f(s)(); } catch {}
}
for (let expr of expressions) {
// Evaluate in an expression context.
tryRun(`void (${expr}?.());`);
tryRun(`void (${expr}?.p());`);
// Also try parenthesized.
tryRun(`void ((${expr})?.());`);
tryRun(`void ((${expr})?.p());`);
}
function inClassConstructor(s) {
return `class C { constructor() { ${s} } }`;
}
for (let expr of ["super[a]", "super.a", "super()"]) {
// Evaluate in an expression context.
tryRun(inClassConstructor(`void (${expr}?.());`));
tryRun(inClassConstructor(`void (${expr}?.p());`));
// Also try parenthesized.
tryRun(inClassConstructor(`void ((${expr})?.());`));
tryRun(inClassConstructor(`void ((${expr})?.p());`));
}
if (typeof parseModule === "function") {
const expressions = [
"import.meta",
"import('')",
];
for (let expr of expressions) {
// Evaluate in an expression context.
tryParse(`void (${expr}?.());`, parseModule);
tryParse(`void (${expr}?.p());`, parseModule);
// Also try parenthesized.
tryParse(`void ((${expr})?.());`, parseModule);
tryParse(`void ((${expr})?.p());`, parseModule);
}
}
if (typeof reportCompare === "function")
reportCompare(true, true);

View file

@ -0,0 +1,12 @@
// Don't assert.
var obj = {
m() {
super[0]?.a
}
};
obj.m();
if (typeof reportCompare === "function")
reportCompare(true, true);

View file

@ -0,0 +1,28 @@
// Test TDZ for optional chaining.
// TDZ for lexical |let| bindings with optional chaining.
{
assertThrowsInstanceOf(() => {
const Null = null;
Null?.[b];
b = 0;
let b;
}, ReferenceError);
assertThrowsInstanceOf(() => {
const Null = null;
Null?.[b]();
b = 0;
let b;
}, ReferenceError);
assertThrowsInstanceOf(() => {
const Null = null;
delete Null?.[b];
b = 0;
let b;
}, ReferenceError);
}
if (typeof reportCompare === "function")
reportCompare(true, true);

View file

@ -0,0 +1,223 @@
var BUGNUMBER = 1566143;
var summary = "Implement the Optional Chain operator (?.) proposal";
print(BUGNUMBER + ": " + summary);
// These tests are originally from webkit.
// webkit specifics have been removed and error messages have been updated.
function shouldBe(actual, expected) {
if (actual !== expected)
throw new Error(`expected ${expected} but got ${actual}`);
}
function shouldThrowSyntaxError(script) {
let error;
try {
eval(script);
} catch (e) {
error = e;
}
if (!(error instanceof SyntaxError))
throw new Error('Expected SyntaxError!');
}
function shouldNotThrowSyntaxError(script) {
let error;
try {
eval(script);
} catch (e) {
error = e;
}
if ((error instanceof SyntaxError))
throw new Error('Unxpected SyntaxError!');
}
function shouldThrowTypeError(func, messagePrefix) {
let error;
try {
func();
} catch (e) {
error = e;
}
if (!(error instanceof TypeError))
throw new Error('Expected TypeError!');
}
function testBasicSuccessCases() {
shouldBe(undefined?.valueOf(), undefined);
shouldBe(null?.valueOf(), undefined);
shouldBe(true?.valueOf(), true);
shouldBe(false?.valueOf(), false);
shouldBe(0?.valueOf(), 0);
shouldBe(1?.valueOf(), 1);
shouldBe(''?.valueOf(), '');
shouldBe('hi'?.valueOf(), 'hi');
shouldBe(({})?.constructor, Object);
shouldBe(({ x: 'hi' })?.x, 'hi');
shouldBe([]?.length, 0);
shouldBe(['hi']?.length, 1);
shouldBe(undefined?.['valueOf'](), undefined);
shouldBe(null?.['valueOf'](), undefined);
shouldBe(true?.['valueOf'](), true);
shouldBe(false?.['valueOf'](), false);
shouldBe(0?.['valueOf'](), 0);
shouldBe(1?.['valueOf'](), 1);
shouldBe(''?.['valueOf'](), '');
shouldBe('hi'?.['valueOf'](), 'hi');
shouldBe(({})?.['constructor'], Object);
shouldBe(({ x: 'hi' })?.['x'], 'hi');
shouldBe([]?.['length'], 0);
shouldBe(['hi']?.[0], 'hi');
shouldBe(undefined?.(), undefined);
shouldBe(null?.(), undefined);
shouldBe((() => 3)?.(), 3);
}
function testBasicFailureCases() {
shouldThrowTypeError(() => true?.(), 'true is not a function');
shouldThrowTypeError(() => false?.(), 'false is not a function');
shouldThrowTypeError(() => 0?.(), '0 is not a function');
shouldThrowTypeError(() => 1?.(), '1 is not a function');
shouldThrowTypeError(() => ''?.(), '"" is not a function');
shouldThrowTypeError(() => 'hi'?.(), '"hi" is not a function');
shouldThrowTypeError(() => ({})?.(), '({}) is not a function');
shouldThrowTypeError(() => ({ x: 'hi' })?.(), '({x:"hi"}) is not a function');
shouldThrowTypeError(() => []?.(), '[] is not a function');
shouldThrowTypeError(() => ['hi']?.(), '[...] is not a function');
}
testBasicSuccessCases();
testBasicFailureCases();
shouldThrowTypeError(() => ({})?.i(), '(intermediate value).i is not a function');
shouldBe(({}).i?.(), undefined);
shouldBe(({})?.i?.(), undefined);
shouldThrowTypeError(() => ({})?.['i'](), '(intermediate value)["i"] is not a function');
shouldBe(({})['i']?.(), undefined);
shouldBe(({})?.['i']?.(), undefined);
shouldThrowTypeError(() => ({})?.a['b'], 'can\'t access property "b", (intermediate value).a is undefined');
shouldBe(({})?.a?.['b'], undefined);
shouldBe(null?.a['b']().c, undefined);
shouldThrowTypeError(() => ({})?.['a'].b, 'can\'t access property "b", (intermediate value)["a"] is undefined');
shouldBe(({})?.['a']?.b, undefined);
shouldBe(null?.['a'].b()['c'], undefined);
shouldBe(null?.()().a['b'], undefined);
const o0 = { a: { b() { return this._b.bind(this); }, _b() { return this.__b; }, __b: { c: 42 } } };
shouldBe(o0?.a?.['b']?.()?.()?.c, 42);
shouldBe(o0?.i?.['j']?.()?.()?.k, undefined);
shouldBe((o0.a?._b)?.().c, 42);
shouldBe((o0.a?._b)().c, 42);
shouldBe((o0.a?.b?.())?.().c, 42);
shouldBe((o0.a?.['b']?.())?.().c, 42);
shouldBe(({ undefined: 3 })?.[null?.a], 3);
shouldBe((() => 3)?.(null?.a), 3);
const o1 = { count: 0, get x() { this.count++; return () => {}; } };
o1.x?.y;
shouldBe(o1.count, 1);
o1.x?.['y'];
shouldBe(o1.count, 2);
o1.x?.();
shouldBe(o1.count, 3);
null?.(o1.x);
shouldBe(o1.count, 3);
shouldBe(delete undefined?.foo, true);
shouldBe(delete null?.foo, true);
shouldBe(delete undefined?.['foo'], true);
shouldBe(delete null?.['foo'], true);
shouldBe(delete undefined?.(), true);
shouldBe(delete null?.(), true);
shouldBe(delete ({}).a?.b?.b, true);
shouldBe(delete ({a : {b: undefined}}).a?.b?.b, true);
shouldBe(delete ({a : {b: undefined}}).a?.["b"]?.["b"], true);
const o2 = { x: 0, y: 0, z() {} };
shouldBe(delete o2?.x, true);
shouldBe(o2.x, undefined);
shouldBe(o2.y, 0);
shouldBe(delete o2?.x, true);
shouldBe(delete o2?.['y'], true);
shouldBe(o2.y, undefined);
shouldBe(delete o2?.['y'], true);
shouldBe(delete o2.z?.(), true);
function greet(name) { return `hey, ${name}${this.suffix ?? '.'}`; }
shouldBe(eval?.('greet("world")'), 'hey, world.');
shouldBe(greet?.call({ suffix: '!' }, 'world'), 'hey, world!');
shouldBe(greet.call?.({ suffix: '!' }, 'world'), 'hey, world!');
shouldBe(null?.call({ suffix: '!' }, 'world'), undefined);
shouldBe(({}).call?.({ suffix: '!' }, 'world'), undefined);
shouldBe(greet?.apply({ suffix: '?' }, ['world']), 'hey, world?');
shouldBe(greet.apply?.({ suffix: '?' }, ['world']), 'hey, world?');
shouldBe(null?.apply({ suffix: '?' }, ['world']), undefined);
shouldBe(({}).apply?.({ suffix: '?' }, ['world']), undefined);
shouldThrowSyntaxError('class C {} class D extends C { foo() { return super?.bar; } }');
shouldThrowSyntaxError('class C {} class D extends C { foo() { return super?.["bar"]; } }');
shouldThrowSyntaxError('class C {} class D extends C { constructor() { super?.(); } }');
shouldThrowSyntaxError('const o = { C: class {} }; new o?.C();')
shouldThrowSyntaxError('const o = { C: class {} }; new o?.["C"]();')
shouldThrowSyntaxError('class C {} new C?.();')
shouldThrowSyntaxError('function foo() { new?.target; }');
shouldThrowSyntaxError('function tag() {} tag?.``;');
shouldThrowSyntaxError('const o = { tag() {} }; o?.tag``;');
// NOT an optional chain
shouldBe(false?.4:5, 5);
function testSideEffectCountFunction() {
let count = 0;
let a = {
b: {
c: {
d: () => {
count++;
return a;
}
}
}
}
a.b.c.d?.()?.b?.c?.d
shouldBe(count, 1);
}
function testSideEffectCountGetters() {
let count = 0;
let a = {
get b() {
count++;
return { c: {} };
}
}
a.b?.c?.d;
shouldBe(count, 1);
a.b?.c?.d;
shouldBe(count, 2);
}
testSideEffectCountFunction();
testSideEffectCountGetters();
// stress test SM
shouldBe(({a : {b: undefined}}).a.b?.()()(), undefined);
shouldBe(({a : {b: undefined}}).a.b?.()?.()(), undefined);
shouldBe(({a : {b: () => undefined}}).a.b?.()?.(), undefined);
shouldThrowTypeError(() => delete ({a : {b: undefined}}).a?.b.b.c, 'can\'t access property "b", (intermediate value).a.b is undefined');
shouldBe(delete ({a : {b: undefined}}).a?.["b"]?.["b"], true);
shouldThrowTypeError(() => (({a : {b: () => undefined}}).a.b?.())(), 'undefined is not a function');
if (typeof reportCompare === "function")
reportCompare(true, true);
print("Tests complete");

View file

View file

View file

@ -0,0 +1,57 @@
// |reftest| error:SyntaxError
// This file was procedurally generated from the following sources:
// - src/dstr-assignment/array-elem-nested-memberexpr-optchain-prop-ref-init.case
// - src/dstr-assignment/syntax/assignment-expr.template
/*---
description: It is a Syntax Error if LeftHandSideExpression of an DestructuringAssignmentTarget is neither an ObjectLiteral nor an ArrayLiteral and AssignmentTargetType(LeftHandSideExpression) is not simple Using Object (MemberExpression OptionalChain .IdentifierName Initializer) (AssignmentExpression)
esid: sec-variable-statement-runtime-semantics-evaluation
features: [optional-chaining, destructuring-binding]
flags: [generated]
negative:
phase: parse
type: SyntaxError
info: |
VariableDeclaration : BindingPattern Initializer
1. Let rhs be the result of evaluating Initializer.
2. Let rval be GetValue(rhs).
3. ReturnIfAbrupt(rval).
4. Return the result of performing BindingInitialization for
BindingPattern passing rval and undefined as arguments.
Syntax
AssignmentElement : DestructuringAssignmentTarget Initializer_opt
DestructuringAssignmentTarget : LeftHandSideExpression
Static Semantics: Early Errors
OptionalExpression:
MemberExpression OptionalChain
CallExpression OptionalChain
OptionalExpression OptionalChain
OptionalChain:
?. [ Expression ]
?. IdentifierName
?. Arguments
?. TemplateLiteral
OptionalChain [ Expression ]
OptionalChain .IdentifierName
OptionalChain Arguments
OptionalChain TemplateLiteral
DestructuringAssignmentTarget : LeftHandSideExpression
- It is a Syntax Error if LeftHandSideExpression is neither an ObjectLiteral nor an ArrayLiteral and IsValidSimpleAssignmentTarget(LeftHandSideExpression) is not true.
Static Semantics: IsValidSimpleAssignmentTarget
LeftHandSideExpression : OptionalExpression
1. Return false.
---*/
$DONOTEVALUATE();
var x = {};
0, [x?.y = 42] = [23];

View file

@ -0,0 +1,60 @@
// |reftest| error:SyntaxError
// This file was procedurally generated from the following sources:
// - src/dstr-assignment/array-elem-put-obj-literal-optchain-prop-ref-init.case
// - src/dstr-assignment/syntax/assignment-expr.template
/*---
description: It is a Syntax Error if LeftHandSideExpression of an DestructuringAssignmentTarget is neither an ObjectLiteral nor an ArrayLiteral and AssignmentTargetType(LeftHandSideExpression) is not simple Using Object (AssignmentExpression)
esid: sec-variable-statement-runtime-semantics-evaluation
features: [optional-chaining, destructuring-binding]
flags: [generated]
negative:
phase: parse
type: SyntaxError
info: |
VariableDeclaration : BindingPattern Initializer
1. Let rhs be the result of evaluating Initializer.
2. Let rval be GetValue(rhs).
3. ReturnIfAbrupt(rval).
4. Return the result of performing BindingInitialization for
BindingPattern passing rval and undefined as arguments.
Syntax
AssignmentElement : DestructuringAssignmentTarget Initializer_opt
DestructuringAssignmentTarget : LeftHandSideExpression
Static Semantics: Early Errors
OptionalExpression:
MemberExpression OptionalChain
CallExpression OptionalChain
OptionalExpression OptionalChain
OptionalChain:
?. [ Expression ]
?. IdentifierName
?. Arguments
?. TemplateLiteral
OptionalChain [ Expression ]
OptionalChain .IdentifierName
OptionalChain Arguments
OptionalChain TemplateLiteral
DestructuringAssignmentTarget : LeftHandSideExpression
- It is a Syntax Error if LeftHandSideExpression is neither an ObjectLiteral nor an ArrayLiteral and IsValidSimpleAssignmentTarget(LeftHandSideExpression) is not true.
Static Semantics: IsValidSimpleAssignmentTarget
LeftHandSideExpression : OptionalExpression
1. Return false.
---*/
$DONOTEVALUATE();
0, [{
set y(val) {
throw new Test262Error('The property should not be accessed.');
}
}?.y = 42] = [23];

View file

@ -0,0 +1,57 @@
// |reftest| error:SyntaxError
// This file was procedurally generated from the following sources:
// - src/dstr-assignment/obj-prop-elem-target-memberexpr-optchain-prop-ref-init.case
// - src/dstr-assignment/syntax/assignment-expr.template
/*---
description: It is a Syntax Error if LeftHandSideExpression of an DestructuringAssignmentTarget is neither an ObjectLiteral nor an ArrayLiteral and AssignmentTargetType(LeftHandSideExpression) is not simple Using Object (MemberExpression OptionalChain .IdentifierName Initializer) (AssignmentExpression)
esid: sec-variable-statement-runtime-semantics-evaluation
features: [optional-chaining, destructuring-binding]
flags: [generated]
negative:
phase: parse
type: SyntaxError
info: |
VariableDeclaration : BindingPattern Initializer
1. Let rhs be the result of evaluating Initializer.
2. Let rval be GetValue(rhs).
3. ReturnIfAbrupt(rval).
4. Return the result of performing BindingInitialization for
BindingPattern passing rval and undefined as arguments.
Syntax
AssignmentElement : DestructuringAssignmentTarget Initializer_opt
DestructuringAssignmentTarget : LeftHandSideExpression
Static Semantics: Early Errors
OptionalExpression:
MemberExpression OptionalChain
CallExpression OptionalChain
OptionalExpression OptionalChain
OptionalChain:
?. [ Expression ]
?. IdentifierName
?. Arguments
?. TemplateLiteral
OptionalChain [ Expression ]
OptionalChain .IdentifierName
OptionalChain Arguments
OptionalChain TemplateLiteral
DestructuringAssignmentTarget : LeftHandSideExpression
- It is a Syntax Error if LeftHandSideExpression is neither an ObjectLiteral nor an ArrayLiteral and IsValidSimpleAssignmentTarget(LeftHandSideExpression) is not true.
Static Semantics: IsValidSimpleAssignmentTarget
LeftHandSideExpression : OptionalExpression
1. Return false.
---*/
$DONOTEVALUATE();
var y = {};
0, { x: y?.z = 42 } = { x: 23 };

View file

@ -0,0 +1,60 @@
// |reftest| error:SyntaxError
// This file was procedurally generated from the following sources:
// - src/dstr-assignment/obj-prop-elem-target-obj-literal-optchain-prop-ref-init.case
// - src/dstr-assignment/syntax/assignment-expr.template
/*---
description: It is a Syntax Error if LeftHandSideExpression of an DestructuringAssignmentTarget is neither an ObjectLiteral nor an ArrayLiteral and AssignmentTargetType(LeftHandSideExpression) is not simple Using Object (AssignmentExpression)
esid: sec-variable-statement-runtime-semantics-evaluation
features: [optional-chaining, destructuring-binding]
flags: [generated]
negative:
phase: parse
type: SyntaxError
info: |
VariableDeclaration : BindingPattern Initializer
1. Let rhs be the result of evaluating Initializer.
2. Let rval be GetValue(rhs).
3. ReturnIfAbrupt(rval).
4. Return the result of performing BindingInitialization for
BindingPattern passing rval and undefined as arguments.
Syntax
AssignmentElement : DestructuringAssignmentTarget Initializer_opt
DestructuringAssignmentTarget : LeftHandSideExpression
Static Semantics: Early Errors
OptionalExpression:
MemberExpression OptionalChain
CallExpression OptionalChain
OptionalExpression OptionalChain
OptionalChain:
?. [ Expression ]
?. IdentifierName
?. Arguments
?. TemplateLiteral
OptionalChain [ Expression ]
OptionalChain .IdentifierName
OptionalChain Arguments
OptionalChain TemplateLiteral
DestructuringAssignmentTarget : LeftHandSideExpression
- It is a Syntax Error if LeftHandSideExpression is neither an ObjectLiteral nor an ArrayLiteral and IsValidSimpleAssignmentTarget(LeftHandSideExpression) is not true.
Static Semantics: IsValidSimpleAssignmentTarget
LeftHandSideExpression : OptionalExpression
1. Return false.
---*/
$DONOTEVALUATE();
0, { x: {
set y(val) {
throw new Test262Error('The property should not be accessed.');
}
}?.y = 42} = {x: 42};

View file

@ -0,0 +1,16 @@
// GENERATED, DO NOT EDIT
// file: tcoHelper.js
// Copyright (C) 2016 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
description: |
This defines the number of consecutive recursive function calls that must be
made in order to prove that stack frames are properly destroyed according to
ES2015 tail call optimization semantics.
defines: [$MAX_ITERATIONS]
---*/
var $MAX_ITERATIONS = 100000;

View file

@ -0,0 +1,24 @@
// |reftest| error:SyntaxError
// Copyright 2019 Google, Inc. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: prod-OptionalExpression
description: >
should not suppress error if super called on class with no base
info: |
Left-Hand-Side Expressions
OptionalExpression:
SuperCall OptionalChain
features: [optional-chaining]
negative:
phase: parse
type: SyntaxError
---*/
$DONOTEVALUATE();
class C {
constructor () {
super()?.a;
}
}

View file

@ -0,0 +1,77 @@
// Copyright 2019 Google, Inc. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: prod-OptionalExpression
description: >
optional chain on call expression
info: |
Left-Hand-Side Expressions
OptionalExpression:
CallExpression OptionalChain
features: [optional-chaining]
---*/
// CallExpression CoverCallExpressionAndAsyncArrowHead
function fn () {
return {a: 33};
};
const obj = {
fn () {
return 44;
}
}
assert.sameValue(33, fn()?.a);
assert.sameValue(undefined, fn()?.b);
assert.sameValue(44, obj?.fn());
// CallExpression SuperCall
class A {}
class B extends A {
constructor () {
assert.sameValue(undefined, super()?.a);
}
}
new B();
// CallExpression Arguments
function fn2 () {
return () => {
return {a: 66};
};
}
function fn3 () {
return () => {
return null;
};
}
assert.sameValue(66, fn2()()?.a);
assert.sameValue(undefined, fn3()()?.a);
// CallExpression [Expression]
function fn4 () {
return [{a: 77}];
}
function fn5 () {
return [];
}
assert.sameValue(77, fn4()[0]?.a);
assert.sameValue(undefined, fn5()[0]?.a);
// CallExpression .IdentifierName
function fn6 () {
return {
a: {
b: 88
}
};
}
assert.sameValue(88, fn6().a?.b);
assert.sameValue(undefined, fn6().b?.c);
// CallExpression TemplateLiteral
function fn7 () {
return () => {};
}
assert.sameValue(undefined, fn7()`hello`?.a);
reportCompare(0, 0);

View file

@ -0,0 +1,26 @@
// |reftest| error:SyntaxError
// Copyright 2020 Salesforce.com, Inc. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: prod-OptionalExpression
description: >
template string passed to tail position of optional chain
info: |
Static Semantics: Early Errors
OptionalChain:
?.TemplateLiteral
OptionalChain TemplateLiteral
It is a Syntax Error if any code matches this production.
features: [optional-chaining]
negative:
phase: parse
type: SyntaxError
---*/
$DONOTEVALUATE();
// This production exists in order to prevent automatic semicolon
// insertion rules.
null?.
`hello`

View file

@ -0,0 +1,23 @@
// |reftest| error:SyntaxError
// Copyright 2020 Salesforce.com, Inc. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: prod-OptionalExpression
description: >
template string passed to tail position of optional chain
info: |
Static Semantics: Early Errors
OptionalChain:
?.TemplateLiteral
OptionalChain TemplateLiteral
It is a Syntax Error if any code matches this production.
features: [optional-chaining]
negative:
phase: parse
type: SyntaxError
---*/
$DONOTEVALUATE();
null?.`hello`;

View file

@ -0,0 +1,26 @@
// |reftest| error:SyntaxError
// Copyright 2020 Salesforce.com, Inc. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: prod-OptionalExpression
description: >
template string passed to tail position of optional chain
info: |
Static Semantics: Early Errors
OptionalChain:
?.TemplateLiteral
OptionalChain TemplateLiteral
It is a Syntax Error if any code matches this production.
features: [optional-chaining]
negative:
phase: parse
type: SyntaxError
---*/
$DONOTEVALUATE();
// This production exists in order to prevent automatic semicolon
// insertion rules.
null?.fn
`hello`

View file

@ -0,0 +1,23 @@
// |reftest| error:SyntaxError
// Copyright 2020 Salesforce.com, Inc. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: prod-OptionalExpression
description: >
template string passed to tail position of optional chain
info: |
Static Semantics: Early Errors
OptionalChain:
?.TemplateLiteral
OptionalChain TemplateLiteral
It is a Syntax Error if any code matches this production.
features: [optional-chaining]
negative:
phase: parse
type: SyntaxError
---*/
$DONOTEVALUATE();
null?.fn`hello`;

View file

@ -0,0 +1,28 @@
// |reftest| error:SyntaxError
// Copyright 2020 Salesforce.com, Inc. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: prod-OptionalExpression
description: >
template string passed to tail position of optional chain
info: |
Static Semantics: Early Errors
OptionalChain:
?.TemplateLiteral
OptionalChain TemplateLiteral
It is a Syntax Error if any code matches this production.
features: [optional-chaining]
negative:
phase: parse
type: SyntaxError
---*/
$DONOTEVALUATE();
const a = function() {};
// This production exists in order to prevent automatic semicolon
// insertion rules.
a?.
`hello`

View file

@ -0,0 +1,25 @@
// |reftest| error:SyntaxError
// Copyright 2020 Salesforce.com, Inc. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: prod-OptionalExpression
description: >
template string passed to tail position of optional chain
info: |
Static Semantics: Early Errors
OptionalChain:
?.TemplateLiteral
OptionalChain TemplateLiteral
It is a Syntax Error if any code matches this production.
features: [optional-chaining]
negative:
phase: parse
type: SyntaxError
---*/
$DONOTEVALUATE();
const a = function() {};
a?.`hello`;

View file

@ -0,0 +1,28 @@
// |reftest| error:SyntaxError
// Copyright 2019 Google, Inc. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: prod-OptionalExpression
description: >
template string passed to tail position of optional chain
info: |
Static Semantics: Early Errors
OptionalChain:
?.TemplateLiteral
OptionalChain TemplateLiteral
It is a Syntax Error if any code matches this production.
features: [optional-chaining]
negative:
phase: parse
type: SyntaxError
---*/
$DONOTEVALUATE();
const a = {fn() {}};
// This production exists in order to prevent automatic semicolon
// insertion rules.
a?.fn
`hello`

View file

@ -0,0 +1,25 @@
// |reftest| error:SyntaxError
// Copyright 2019 Google, Inc. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: prod-OptionalExpression
description: >
template string passed to tail position of optional chain
info: |
Static Semantics: Early Errors
OptionalChain:
?.TemplateLiteral
OptionalChain TemplateLiteral
It is a Syntax Error if any code matches this production.
features: [optional-chaining]
negative:
phase: parse
type: SyntaxError
---*/
$DONOTEVALUATE();
const a = {fn() {}};
a?.fn`hello`;

View file

@ -0,0 +1,41 @@
// Copyright 2020 Toru Nagashima. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-optional-chaining-chain-evaluation
description: optional call invoked on eval function should be indirect eval.
info: |
Runtime Semantics: ChainEvaluation
OptionalChain: ?. Arguments
1. Let thisChain be this OptionalChain.
2. Let tailCall be IsInTailPosition(thisChain).
3. Return ? EvaluateCall(baseValue, baseReference, Arguments, tailCall).
Runtime Semantics: EvaluateCall ( func, ref, arguments, tailPosition )
...
7. Let result be Call(func, thisValue, argList).
...
eval ( x )
...
4. Return ? PerformEval(x, callerRealm, false, false).
Runtime Semantics: PerformEval ( x, callerRealm, strictCaller, direct )
features: [optional-chaining]
---*/
const a = 'global';
function fn() {
const a = 'local';
return eval?.('a');
}
assert.sameValue(fn(), 'global', 'fn() returns "global" value from indirect eval');
const b = (a => eval?.('a'))('local');
assert.sameValue(b, 'global', 'b is "global", from indirect eval not observing parameter');
reportCompare(0, 0);

View file

@ -0,0 +1,20 @@
// Copyright 2019 Google, LLC. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: prod-OptionalExpression
description: >
optional chain in test portion of do while statement
info: |
IterationStatement
do Statement while (OptionalExpression)
features: [optional-chaining]
---*/
let count = 0;
const obj = {a: true};
do {
count++;
break;
} while (obj?.a);
assert.sameValue(1, count);
reportCompare(0, 0);

View file

@ -0,0 +1,36 @@
// |reftest| async
// Copyright 2019 Google, LLC. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: prod-OptionalExpression
description: >
optional chain RHS of for await statement
info: |
IterationStatement
for await (LeftHandSideExpression of AssignmentExpression) Statement
features: [optional-chaining]
flags: [async]
---*/
const obj = {
iterable: {
[Symbol.asyncIterator]() {
return {
i: 0,
next() {
if (this.i < 3) {
return Promise.resolve({ value: this.i++, done: false });
}
return Promise.resolve({ done: true });
}
};
}
}
};
async function checkAssertions() {
let count = 0;
for await (const num of obj?.iterable) {
count += num;
}
assert.sameValue(3, count);
}
checkAssertions().then($DONE, $DONE);

View file

@ -0,0 +1,24 @@
// Copyright 2019 Google, LLC. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: prod-OptionalExpression
description: >
optional chain in test portion of do while statement
info: |
IterationStatement
for (LeftHandSideExpression in Expression) Statement
features: [optional-chaining]
---*/
const obj = {
inner: {
a: 1,
b: 2
}
};
let str = '';
for (const key in obj?.inner) {
str += key;
}
assert.sameValue('ab', str);
reportCompare(0, 0);

View file

@ -0,0 +1,30 @@
// Copyright 2019 Google, LLC. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: prod-OptionalExpression
description: >
optional chain returning undefined in RHS of for of statement
info: |
IterationStatement
for (LeftHandSideExpression of Expression) Statement
features: [optional-chaining]
---*/
assert.throws(TypeError, function() {
for (const key of {}?.a) ;
});
assert.throws(TypeError, function() {
for (const key of {}?.a) {}
});
const obj = undefined;
assert.throws(TypeError, function() {
for (const key of obj?.a) {}
});
assert.throws(TypeError, function() {
for (const key of obj?.a);
});
reportCompare(0, 0);

View file

@ -0,0 +1,45 @@
// Copyright 2019 Google, LLC. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: prod-OptionalExpression
description: >
optional chain in init/test/update of for statement
info: |
IterationStatement
for (Expression; Expression; Expression) Statement
features: [optional-chaining]
---*/
// OptionalExpression in test.
let count;
const obj = {a: true};
for (count = 0; obj?.a; count++) {
if (count > 0) break;
}
assert.sameValue(count, 1);
// OptionalExpression in init/test/update.
let count2 = 0;
const obj2 = undefined;
for (obj?.a; obj2?.a; obj?.a) { count2++; }
assert.sameValue(count2, 0);
for (obj?.a; undefined?.a; obj?.a) { count2++; }
assert.sameValue(count2, 0);
// Short-circuiting
let touched = 0;
const obj3 = {
get a() {
count++;
return undefined; // explicit for clarity
}
};
for (count = 0; true; obj3?.a?.[touched++]) {
if (count > 0) { break; }
}
assert.sameValue(count, 1);
assert.sameValue(touched, 0);
reportCompare(0, 0);

View file

@ -0,0 +1,20 @@
// Copyright 2019 Google, LLC. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: prod-OptionalExpression
description: >
optional chain in test portion of while statement
info: |
IterationStatement
while (Expression) Statement
features: [optional-chaining]
---*/
let count = 0;
const obj = {a: true};
while (obj?.a) {
count++;
break;
}
assert.sameValue(1, count);
reportCompare(0, 0);

View file

@ -0,0 +1,33 @@
// |reftest| async
// Copyright 2019 Google, Inc. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: prod-OptionalExpression
description: >
optional chain on member expression in async context
info: |
Left-Hand-Side Expressions
OptionalExpression
MemberExpression [PrimaryExpression identifier] OptionalChain
features: [optional-chaining]
flags: [async]
---*/
const a = undefined;
const c = {d: Promise.resolve(11)};
async function checkAssertions() {
assert.sameValue(await a?.b, undefined);
assert.sameValue(await c?.d, 11);
Promise.prototype.x = 42;
var res = await Promise.resolve(undefined)?.x;
assert.sameValue(res, 42, 'await unwraps the evaluation of the whole optional chaining expression #1');
Promise.prototype.y = 43;
var res = await Promise.reject(undefined)?.y;
assert.sameValue(res, 43, 'await unwraps the evaluation of the whole optional chaining expression #2');
c.e = Promise.resolve(39);
assert.sameValue(await c?.e, 39, 'await unwraps the promise given after the evaluation of the OCE');
}
checkAssertions().then($DONE, $DONE);

View file

@ -0,0 +1,20 @@
// |reftest| async
// Copyright 2019 Google, Inc. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: prod-OptionalExpression
description: >
optional chain on member expression in async context
info: |
Left-Hand-Side Expressions
OptionalExpression:
MemberExpression [PrimaryExpression literal] OptionalChain
features: [optional-chaining]
flags: [async]
---*/
async function checkAssertions() {
assert.sameValue(await "hello"?.[0], 'h');
assert.sameValue(await null?.a, undefined);
}
checkAssertions().then($DONE, $DONE);

View file

@ -0,0 +1,21 @@
// |reftest| async
// Copyright 2019 Google, Inc. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: prod-OptionalExpression
description: >
optional chain on member expression in async context
info: |
Left-Hand-Side Expressions
OptionalExpression:
MemberExpression [PrimaryExpression this] OptionalChain
features: [optional-chaining]
flags: [async]
---*/
async function thisFn() {
return await this?.a
}
thisFn.call({a: Promise.resolve(33)}).then(function(arg) {
assert.sameValue(33, arg);
}).then($DONE, $DONE);

View file

@ -0,0 +1,106 @@
// Copyright 2019 Google, Inc. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: prod-OptionalExpression
description: >
optional chain on member expression
info: |
Left-Hand-Side Expressions
OptionalExpression:
MemberExpression OptionalChain
features: [optional-chaining]
---*/
// PrimaryExpression
// IdentifierReference
const a = {b: 22};
assert.sameValue(22, a?.b);
// this
function fn () {
return this?.a
}
assert.sameValue(33, fn.call({a: 33}));
// Literal
assert.sameValue(undefined, "hello"?.a);
assert.sameValue(undefined, null?.a);
// ArrayLiteral
assert.sameValue(2, [1, 2]?.[1]);
// ObjectLiteral
assert.sameValue(44, {a: 44}?.a);
// FunctionExpression
assert.sameValue('a', (function a () {}?.name));
// ClassExpression
assert.sameValue('Foo', (class Foo {}?.name));
// GeneratorFunction
assert.sameValue('a', (function * a () {}?.name));
// AsyncFunctionExpression
assert.sameValue('a', (async function a () {}?.name));
// AsyncGeneratorExpression
assert.sameValue('a', (async function * a () {}?.name));
// RegularExpressionLiteral
assert.sameValue(true, /[a-z]/?.test('a'));
// TemplateLiteral
assert.sameValue('h', `hello`?.[0]);
// CoverParenthesizedExpressionAndArrowParameterList
assert.sameValue(undefined, ({a: 33}, null)?.a);
assert.sameValue(33, (undefined, {a: 33})?.a);
// MemberExpression [ Expression ]
const arr = [{a: 33}];
assert.sameValue(33, arr[0]?.a);
assert.sameValue(undefined, arr[1]?.a);
// MemberExpression .IdentifierName
const obj = {a: {b: 44}};
assert.sameValue(44, obj.a?.b);
assert.sameValue(undefined, obj.c?.b);
// MemberExpression TemplateLiteral
function f2 () {
return {a: 33};
}
function f3 () {}
assert.sameValue(33, f2`hello world`?.a);
assert.sameValue(undefined, f3`hello world`?.a);
// MemberExpression SuperProperty
class A {
a () {}
undf () {
return super.a?.c;
}
}
class B extends A {
dot () {
return super.a?.name;
}
expr () {
return super['a']?.name;
}
undf2 () {
return super.b?.c;
}
}
const subcls = new B();
assert.sameValue('a', subcls.dot());
assert.sameValue('a', subcls.expr());
assert.sameValue(undefined, subcls.undf2());
assert.sameValue(undefined, (new A()).undf());
// MemberExpression MetaProperty
class C {
constructor () {
assert.sameValue(undefined, new.target?.a);
}
}
new C();
// new MemberExpression Arguments
class D {
constructor (val) {
this.a = val;
}
}
assert.sameValue(99, new D(99)?.a);
reportCompare(0, 0);

View file

@ -0,0 +1,32 @@
// Copyright 2019 Google, LLC. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: prod-OptionalExpression
description: >
optional call invoked on new.target should be equivalent to call
info: |
OptionalExpression
MemberExpression OptionalChain
NewTarget OptionalChain
features: [optional-chaining]
---*/
const newTargetContext = (function() { return this; })();
let called = false;
// should be set to 'undefined' or global context, depending on whether
// mode is strict or sloppy.
let context = null;
function Base() {
called = true;
context = this;
}
function Foo(blerg) {
new.target?.();
}
Reflect.construct(Foo, [], Base);
assert(context === newTargetContext);
assert.sameValue(called, true);
reportCompare(0, 0);

View file

@ -0,0 +1,29 @@
// Copyright (C) 2019 Sony Interactive Entertainment Inc. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-optional-chaining-chain-evaluation
description: >
optional call must preserve this context, as with a non-optional call
info: |
OptionalChain : ?. Arguments
1. Let thisChain be this OptionalChain.
2. Let tailCall be IsInTailPosition(thisChain).
3. Return ? EvaluateCall(baseValue, baseReference, Arguments, tailCall).
features: [optional-chaining]
---*/
const a = {
b() { return this._b; },
_b: { c: 42 }
};
assert.sameValue(a?.b().c, 42);
assert.sameValue((a?.b)().c, 42);
assert.sameValue(a.b?.().c, 42);
assert.sameValue((a.b)?.().c, 42);
assert.sameValue(a?.b?.().c, 42);
assert.sameValue((a?.b)?.().c, 42);
reportCompare(0, 0);

View file

@ -0,0 +1,29 @@
// |reftest| async
// Copyright 2019 Google, Inc. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: prod-OptionalExpression
description: >
optional chain expansions in an async context
info: |
Left-Hand-Side Expressions
OptionalExpression
MemberExpression [PrimaryExpression Identifier] OptionalChain
OptionalChain OptionalChain ?.[Expression]
features: [optional-chaining]
flags: [async]
---*/
async function checkAssertions() {
assert.sameValue(await {a: [11]}?.a[0], 11);
const b = {c: [22, 33]};
assert.sameValue(b?.c[await Promise.resolve(1)], 33);
function e(val) {
return val;
}
assert.sameValue({d: e}?.d(await Promise.resolve([44, 55]))[1], 55);
assert.sameValue(undefined?.arr[
await Promise.reject(new Error('unreachable'))
], undefined);
}
checkAssertions().then($DONE, $DONE);

View file

@ -0,0 +1,25 @@
// |reftest| async
// Copyright 2019 Google, Inc. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: prod-OptionalExpression
description: >
optional chain expansions in an async context
info: |
Left-Hand-Side Expressions
OptionalExpression
MemberExpression [PrimaryExpression Identifier] OptionalChain
OptionalChain ?.[Expression]
features: [optional-chaining]
flags: [async]
---*/
async function checkAssertions() {
assert.sameValue(await [11]?.[0], 11);
assert.sameValue([22, 33]?.[await Promise.resolve(1)], 33);
assert.sameValue([44, await Promise.resolve(55)]?.[1], 55);
assert.sameValue(undefined?.[
await Promise.reject(new Error('unreachable'))
], undefined);
}
checkAssertions().then($DONE, $DONE);

View file

@ -0,0 +1,22 @@
// Copyright 2019 Google, Inc. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: prod-OptionalExpression
description: >
optional chain bracket notation containing optional expresion
info: |
OptionalChain:
?. [OptionalExpression]
features: [optional-chaining]
---*/
const a = undefined;
const b = {e: 0};
const c = {};
c[undefined] = 11;
const d = [22];
assert.sameValue(undefined, a?.[a?.b]);
assert.sameValue(11, c?.[a?.b]);
assert.sameValue(22, d?.[b?.e]);
reportCompare(0, 0);

View file

@ -0,0 +1,21 @@
// Copyright 2020 Salesforce.com, Inc. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: prod-OptionalExpression
description: >
Productions for ?. Arguments
info: |
OptionalChain[Yield, Await]:
?. Arguments
features: [optional-chaining]
---*/
function fn(arg1, arg2, arg3 = 0) {
return arg1 + arg2 + arg3;
}
assert.sameValue(fn?.(10, 20), 30, 'regular');
assert.sameValue(String?.(42), '42', 'built-in');
assert.sameValue(fn ?. (...[10, 20, 40]), 70, 'spread');
reportCompare(0, 0);

View file

@ -0,0 +1,44 @@
// Copyright 2020 Salesforce.com, Inc. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: prod-OptionalExpression
description: >
Productions for ?. [Expression]
info: |
OptionalChain:
?.[ Expression ]
features: [optional-chaining]
---*/
const $ = 'x';
const arr = [39, 42];
arr.true = 'prop';
arr[1.1] = 'other prop';
const obj = {
a: 'hello',
undefined: 40,
$: 0,
NaN: 41,
null: 42,
x: 43,
true: 44
};
assert.sameValue(arr?.[0], 39, '[0]');
assert.sameValue(arr?.[0, 1], 42, '[0, 1]');
assert.sameValue(arr?.[1], 42, '[1]');
assert.sameValue(arr?.[1, 0], 39, '[1, 0]');
assert.sameValue(arr?.[{}, NaN, undefined, 2, 0, 10 / 10], 42, '[{}, NaN, undefined, 2, 0, 10 / 10]');
assert.sameValue(arr?.[true], 'prop', '[true]');
assert.sameValue(arr?.[1.1], 'other prop', '[1.1]');
assert.sameValue(obj?.[undefined], 40, '[undefined]');
assert.sameValue(obj?.[NaN], 41, '[NaN]');
assert.sameValue(obj?.[null], 42, '[null]');
assert.sameValue(obj?.['$'], 0, '["$"]');
assert.sameValue(obj?.[$], 43, '[$]');
assert.sameValue(obj?.[true], 44, '[true]');
reportCompare(0, 0);

View file

@ -0,0 +1,40 @@
// Copyright 2020 Salesforce.com, Inc. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: prod-OptionalExpression
description: >
Productions for ?. IdentifierName
info: |
OptionalChain[Yield, Await]:
?. IdentifierName
features: [optional-chaining]
---*/
const arr = [10, 11];
const obj = {
a: 'hello'
};
assert.sameValue(obj?.a, 'hello');
assert.sameValue(obj?.\u0061, 'hello');
assert.sameValue(obj?.\u{0061}, 'hello');
assert.sameValue(obj?.\u0062, undefined);
assert.sameValue(obj?.\u{0062}, undefined);
assert.sameValue(arr ?. length, 2);
assert.sameValue(arr ?. l\u0065ngth, 2);
assert.sameValue(arr ?. l\u{0065}ngth, 2);
assert.sameValue(obj?.$, undefined);
obj.$ = 42;
assert.sameValue(obj?.$, 42);
assert.sameValue(obj?._, undefined);
obj._ = 39;
assert.sameValue(obj?._, 39);
reportCompare(0, 0);

View file

@ -0,0 +1,52 @@
// Copyright 2019 Google, Inc. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: prod-OptionalExpression
description: >
various optional chain expansions
info: |
OptionalChain[Yield, Await]:
?.[Expression]
?.IdentifierName
?.Arguments
?.TemplateLiteral
OptionalChain [Expression]
OptionalChain .IdentifierName
OptionalChain Arguments[?Yield, ?Await]
OptionalChain TemplateLiteral
features: [optional-chaining]
---*/
const arr = [10, 11];
const obj = {
a: 'hello',
b: {val: 13},
c(arg1) {
return arg1 * 2;
},
arr: [11, 12]
};
const i = 0;
// OptionalChain: ?.[Expression]
assert.sameValue(11, arr?.[i + 1]);
// OptionalChain: ?.IdentifierName
assert.sameValue('hello', obj?.a);
// OptionalChain: ?.Arguments
const fn = (arg1, arg2) => {
return arg1 + arg2;
}
assert.sameValue(30, fn?.(10, 20));
// OptionalChain: OptionalChain [Expression]
assert.sameValue(12, obj?.arr[i + 1]);
// OptionalChain: OptionalChain .IdentifierName
assert.sameValue(13, obj?.b.val);
// OptionalChain: OptionalChain Arguments
assert.sameValue(20, obj?.c(10));
reportCompare(0, 0);

View file

@ -0,0 +1,29 @@
// Copyright 2019 Google, Inc. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: prod-OptionalExpression
description: >
optional chain on recursive optional expression
info: |
Left-Hand-Side Expressions
OptionalExpression:
OptionalExpression OptionalChain
features: [optional-chaining]
---*/
const obj = {
a: {
b: 22
}
};
function fn () {
return {};
}
// OptionalExpression (MemberExpression OptionalChain) OptionalChain
assert.sameValue(22, obj?.a?.b);
// OptionalExpression (CallExpression OptionalChain) OptionalChain
assert.sameValue(undefined, fn()?.a?.b);
reportCompare(0, 0);

View file

@ -0,0 +1,17 @@
// Copyright 2019 Google, Inc. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: prod-OptionalExpression
description: >
ternary operation with decimal does not evaluate as optional chain
info: |
Punctuators
OptionalChainingPunctuator::
?.[lookahead DecimalDigit]
features: [optional-chaining]
---*/
const value = true ?.30 : false;
assert.sameValue(.30, value);
reportCompare(0, 0);

View file

@ -0,0 +1,20 @@
// Copyright 2019 Google, Inc. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: prod-OptionalExpression
description: >
accessing optional value on undefined or null returns undefined.
info: |
If baseValue is undefined or null, then
Return undefined.
features: [optional-chaining]
---*/
const nul = null;
const undf = undefined;
assert.sameValue(undefined, nul?.a);
assert.sameValue(undefined, undf?.b);
assert.sameValue(undefined, null?.a);
assert.sameValue(undefined, undefined?.b);
reportCompare(0, 0);

View file

@ -0,0 +1,24 @@
// Copyright 2019 Google, Inc. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: prod-OptionalExpression
description: >
demonstrate syntax-based short-circuiting.
info: |
If the expression on the LHS of ?. evaluates to null/undefined, the RHS is
not evaluated
features: [optional-chaining]
---*/
const a = undefined;
let x = 1;
a?.[++x] // short-circuiting.
a?.b.c(++x).d; // long short-circuiting.
undefined?.[++x] // short-circuiting.
undefined?.b.c(++x).d; // long short-circuiting.
assert.sameValue(1, x);
reportCompare(0, 0);

View file

@ -0,0 +1,24 @@
// |reftest| error:SyntaxError
// Copyright 2019 Google, Inc. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: prod-OptionalExpression
description: >
an optional expression cannot be target of assignment
info: |
Static Semantics: IsValidSimpleAssignmentTarget
LeftHandSideExpression:
OptionalExpression
Return false.
features: [optional-chaining]
negative:
phase: parse
type: SyntaxError
---*/
$DONOTEVALUATE();
const obj = {};
obj?.a = 33;

View file

@ -0,0 +1,32 @@
// Copyright 2019 Google, LLC. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: prod-OptionalExpression
description: >
optional call invoked on super method should be equivalent to call
info: |
OptionalExpression
MemberExpression OptionalChain
SuperProperty OptionalChain
features: [optional-chaining]
---*/
let called = false;
let context;
class Base {
method() {
called = true;
context = this;
}
}
class Foo extends Base {
method() {
super.method?.();
}
}
const foo = new Foo();
foo.method();
assert(foo === context);
assert.sameValue(called, true);
reportCompare(0, 0);

View file

@ -0,0 +1,24 @@
// |reftest| error:SyntaxError
// Copyright 2019 Google, Inc. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: prod-OptionalExpression
description: >
optional chaining is forbidden in write contexts
info: |
UpdateExpression[Yield, Await]:
LeftHandSideExpression++
LeftHandSideExpression--
++UnaryExpression
--UnaryExpression
features: [optional-chaining]
negative:
phase: parse
type: SyntaxError
---*/
$DONOTEVALUATE();
// LeftHandSideExpression ++
const a = {};
a?.b++;

View file

@ -0,0 +1,24 @@
// |reftest| error:SyntaxError
// Copyright 2019 Google, Inc. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: prod-OptionalExpression
description: >
optional chaining is forbidden in write contexts
info: |
UpdateExpression[Yield, Await]:
LeftHandSideExpression++
LeftHandSideExpression--
++UnaryExpression
--UnaryExpression
features: [optional-chaining]
negative:
phase: parse
type: SyntaxError
---*/
$DONOTEVALUATE();
// --UnaryExpression
const a = {};
--a?.b;

View file

@ -0,0 +1,66 @@
// |reftest| error:SyntaxError
// This file was procedurally generated from the following sources:
// - src/dstr-assignment/array-elem-nested-memberexpr-optchain-prop-ref-init.case
// - src/dstr-assignment/syntax/for-in.template
/*---
description: It is a Syntax Error if LeftHandSideExpression of an DestructuringAssignmentTarget is neither an ObjectLiteral nor an ArrayLiteral and AssignmentTargetType(LeftHandSideExpression) is not simple Using Object (MemberExpression OptionalChain .IdentifierName Initializer) (For..in statement)
esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
features: [optional-chaining, destructuring-binding]
flags: [generated]
negative:
phase: parse
type: SyntaxError
info: |
IterationStatement :
for ( LeftHandSideExpression of AssignmentExpression ) Statement
1. Let keyResult be the result of performing ? ForIn/OfHeadEvaluation(« »,
AssignmentExpression, iterate).
2. Return ? ForIn/OfBodyEvaluation(LeftHandSideExpression, Statement,
keyResult, assignment, labelSet).
13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
[...]
4. If destructuring is true and if lhsKind is assignment, then
a. Assert: lhs is a LeftHandSideExpression.
b. Let assignmentPattern be the parse of the source text corresponding to
lhs using AssignmentPattern as the goal symbol.
[...]
Syntax
AssignmentElement : DestructuringAssignmentTarget Initializer_opt
DestructuringAssignmentTarget : LeftHandSideExpression
Static Semantics: Early Errors
OptionalExpression:
MemberExpression OptionalChain
CallExpression OptionalChain
OptionalExpression OptionalChain
OptionalChain:
?. [ Expression ]
?. IdentifierName
?. Arguments
?. TemplateLiteral
OptionalChain [ Expression ]
OptionalChain .IdentifierName
OptionalChain Arguments
OptionalChain TemplateLiteral
DestructuringAssignmentTarget : LeftHandSideExpression
- It is a Syntax Error if LeftHandSideExpression is neither an ObjectLiteral nor an ArrayLiteral and IsValidSimpleAssignmentTarget(LeftHandSideExpression) is not true.
Static Semantics: IsValidSimpleAssignmentTarget
LeftHandSideExpression : OptionalExpression
1. Return false.
---*/
$DONOTEVALUATE();
var x = {};
for ([x?.y = 42] in [[23]]) ;

View file

@ -0,0 +1,66 @@
// |reftest| error:SyntaxError
// This file was procedurally generated from the following sources:
// - src/dstr-assignment/array-elem-nested-memberexpr-optchain-prop-ref.case
// - src/dstr-assignment/syntax/for-in.template
/*---
description: It is a Syntax Error if LeftHandSideExpression of an DestructuringAssignmentTarget is neither an ObjectLiteral nor an ArrayLiteral and AssignmentTargetType(LeftHandSideExpression) is not simple Using Object (MemberExpression OptionalChain .IdentifierName) (For..in statement)
esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
features: [optional-chaining, destructuring-binding]
flags: [generated]
negative:
phase: parse
type: SyntaxError
info: |
IterationStatement :
for ( LeftHandSideExpression of AssignmentExpression ) Statement
1. Let keyResult be the result of performing ? ForIn/OfHeadEvaluation(« »,
AssignmentExpression, iterate).
2. Return ? ForIn/OfBodyEvaluation(LeftHandSideExpression, Statement,
keyResult, assignment, labelSet).
13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
[...]
4. If destructuring is true and if lhsKind is assignment, then
a. Assert: lhs is a LeftHandSideExpression.
b. Let assignmentPattern be the parse of the source text corresponding to
lhs using AssignmentPattern as the goal symbol.
[...]
Syntax
AssignmentElement : DestructuringAssignmentTarget Initializer_opt
DestructuringAssignmentTarget : LeftHandSideExpression
Static Semantics: Early Errors
OptionalExpression:
MemberExpression OptionalChain
CallExpression OptionalChain
OptionalExpression OptionalChain
OptionalChain:
?. [ Expression ]
?. IdentifierName
?. Arguments
?. TemplateLiteral
OptionalChain [ Expression ]
OptionalChain .IdentifierName
OptionalChain Arguments
OptionalChain TemplateLiteral
DestructuringAssignmentTarget : LeftHandSideExpression
- It is a Syntax Error if LeftHandSideExpression is neither an ObjectLiteral nor an ArrayLiteral and IsValidSimpleAssignmentTarget(LeftHandSideExpression) is not true.
Static Semantics: IsValidSimpleAssignmentTarget
LeftHandSideExpression : OptionalExpression
1. Return false.
---*/
$DONOTEVALUATE();
var x = {};
for ([x?.y] in [[23]]) ;

View file

@ -0,0 +1,69 @@
// |reftest| error:SyntaxError
// This file was procedurally generated from the following sources:
// - src/dstr-assignment/array-elem-put-obj-literal-optchain-prop-ref-init.case
// - src/dstr-assignment/syntax/for-in.template
/*---
description: It is a Syntax Error if LeftHandSideExpression of an DestructuringAssignmentTarget is neither an ObjectLiteral nor an ArrayLiteral and AssignmentTargetType(LeftHandSideExpression) is not simple Using Object (For..in statement)
esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
features: [optional-chaining, destructuring-binding]
flags: [generated]
negative:
phase: parse
type: SyntaxError
info: |
IterationStatement :
for ( LeftHandSideExpression of AssignmentExpression ) Statement
1. Let keyResult be the result of performing ? ForIn/OfHeadEvaluation(« »,
AssignmentExpression, iterate).
2. Return ? ForIn/OfBodyEvaluation(LeftHandSideExpression, Statement,
keyResult, assignment, labelSet).
13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
[...]
4. If destructuring is true and if lhsKind is assignment, then
a. Assert: lhs is a LeftHandSideExpression.
b. Let assignmentPattern be the parse of the source text corresponding to
lhs using AssignmentPattern as the goal symbol.
[...]
Syntax
AssignmentElement : DestructuringAssignmentTarget Initializer_opt
DestructuringAssignmentTarget : LeftHandSideExpression
Static Semantics: Early Errors
OptionalExpression:
MemberExpression OptionalChain
CallExpression OptionalChain
OptionalExpression OptionalChain
OptionalChain:
?. [ Expression ]
?. IdentifierName
?. Arguments
?. TemplateLiteral
OptionalChain [ Expression ]
OptionalChain .IdentifierName
OptionalChain Arguments
OptionalChain TemplateLiteral
DestructuringAssignmentTarget : LeftHandSideExpression
- It is a Syntax Error if LeftHandSideExpression is neither an ObjectLiteral nor an ArrayLiteral and IsValidSimpleAssignmentTarget(LeftHandSideExpression) is not true.
Static Semantics: IsValidSimpleAssignmentTarget
LeftHandSideExpression : OptionalExpression
1. Return false.
---*/
$DONOTEVALUATE();
for ([{
set y(val) {
throw new Test262Error('The property should not be accessed.');
}
}?.y = 42] in [[23]]) ;

View file

@ -0,0 +1,69 @@
// |reftest| error:SyntaxError
// This file was procedurally generated from the following sources:
// - src/dstr-assignment/array-elem-put-obj-literal-optchain-prop-ref.case
// - src/dstr-assignment/syntax/for-in.template
/*---
description: It is a Syntax Error if LeftHandSideExpression of an DestructuringAssignmentTarget is neither an ObjectLiteral nor an ArrayLiteral and AssignmentTargetType(LeftHandSideExpression) is not simple Using Object (For..in statement)
esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
features: [optional-chaining, destructuring-binding]
flags: [generated]
negative:
phase: parse
type: SyntaxError
info: |
IterationStatement :
for ( LeftHandSideExpression of AssignmentExpression ) Statement
1. Let keyResult be the result of performing ? ForIn/OfHeadEvaluation(« »,
AssignmentExpression, iterate).
2. Return ? ForIn/OfBodyEvaluation(LeftHandSideExpression, Statement,
keyResult, assignment, labelSet).
13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
[...]
4. If destructuring is true and if lhsKind is assignment, then
a. Assert: lhs is a LeftHandSideExpression.
b. Let assignmentPattern be the parse of the source text corresponding to
lhs using AssignmentPattern as the goal symbol.
[...]
Syntax
AssignmentElement : DestructuringAssignmentTarget Initializer_opt
DestructuringAssignmentTarget : LeftHandSideExpression
Static Semantics: Early Errors
OptionalExpression:
MemberExpression OptionalChain
CallExpression OptionalChain
OptionalExpression OptionalChain
OptionalChain:
?. [ Expression ]
?. IdentifierName
?. Arguments
?. TemplateLiteral
OptionalChain [ Expression ]
OptionalChain .IdentifierName
OptionalChain Arguments
OptionalChain TemplateLiteral
DestructuringAssignmentTarget : LeftHandSideExpression
- It is a Syntax Error if LeftHandSideExpression is neither an ObjectLiteral nor an ArrayLiteral and IsValidSimpleAssignmentTarget(LeftHandSideExpression) is not true.
Static Semantics: IsValidSimpleAssignmentTarget
LeftHandSideExpression : OptionalExpression
1. Return false.
---*/
$DONOTEVALUATE();
for ([{
set y(val) {
throw new Test262Error('The property should not be accessed.');
}
}?.y] in [[23]]) ;

View file

@ -0,0 +1,66 @@
// |reftest| error:SyntaxError
// This file was procedurally generated from the following sources:
// - src/dstr-assignment/obj-prop-elem-target-memberexpr-optchain-prop-ref-init.case
// - src/dstr-assignment/syntax/for-in.template
/*---
description: It is a Syntax Error if LeftHandSideExpression of an DestructuringAssignmentTarget is neither an ObjectLiteral nor an ArrayLiteral and AssignmentTargetType(LeftHandSideExpression) is not simple Using Object (MemberExpression OptionalChain .IdentifierName Initializer) (For..in statement)
esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
features: [optional-chaining, destructuring-binding]
flags: [generated]
negative:
phase: parse
type: SyntaxError
info: |
IterationStatement :
for ( LeftHandSideExpression of AssignmentExpression ) Statement
1. Let keyResult be the result of performing ? ForIn/OfHeadEvaluation(« »,
AssignmentExpression, iterate).
2. Return ? ForIn/OfBodyEvaluation(LeftHandSideExpression, Statement,
keyResult, assignment, labelSet).
13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
[...]
4. If destructuring is true and if lhsKind is assignment, then
a. Assert: lhs is a LeftHandSideExpression.
b. Let assignmentPattern be the parse of the source text corresponding to
lhs using AssignmentPattern as the goal symbol.
[...]
Syntax
AssignmentElement : DestructuringAssignmentTarget Initializer_opt
DestructuringAssignmentTarget : LeftHandSideExpression
Static Semantics: Early Errors
OptionalExpression:
MemberExpression OptionalChain
CallExpression OptionalChain
OptionalExpression OptionalChain
OptionalChain:
?. [ Expression ]
?. IdentifierName
?. Arguments
?. TemplateLiteral
OptionalChain [ Expression ]
OptionalChain .IdentifierName
OptionalChain Arguments
OptionalChain TemplateLiteral
DestructuringAssignmentTarget : LeftHandSideExpression
- It is a Syntax Error if LeftHandSideExpression is neither an ObjectLiteral nor an ArrayLiteral and IsValidSimpleAssignmentTarget(LeftHandSideExpression) is not true.
Static Semantics: IsValidSimpleAssignmentTarget
LeftHandSideExpression : OptionalExpression
1. Return false.
---*/
$DONOTEVALUATE();
var y = {};
for ({ x: y?.z = 42 } in [{ x: 23 }]) ;

View file

@ -0,0 +1,66 @@
// |reftest| error:SyntaxError
// This file was procedurally generated from the following sources:
// - src/dstr-assignment/obj-prop-elem-target-memberexpr-optchain-prop-ref.case
// - src/dstr-assignment/syntax/for-in.template
/*---
description: It is a Syntax Error if LeftHandSideExpression of an DestructuringAssignmentTarget is neither an ObjectLiteral nor an ArrayLiteral and AssignmentTargetType(LeftHandSideExpression) is not simple Using Object (MemberExpression OptionalChain .IdentifierName) (For..in statement)
esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
features: [optional-chaining, destructuring-binding]
flags: [generated]
negative:
phase: parse
type: SyntaxError
info: |
IterationStatement :
for ( LeftHandSideExpression of AssignmentExpression ) Statement
1. Let keyResult be the result of performing ? ForIn/OfHeadEvaluation(« »,
AssignmentExpression, iterate).
2. Return ? ForIn/OfBodyEvaluation(LeftHandSideExpression, Statement,
keyResult, assignment, labelSet).
13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
[...]
4. If destructuring is true and if lhsKind is assignment, then
a. Assert: lhs is a LeftHandSideExpression.
b. Let assignmentPattern be the parse of the source text corresponding to
lhs using AssignmentPattern as the goal symbol.
[...]
Syntax
AssignmentElement : DestructuringAssignmentTarget Initializer_opt
DestructuringAssignmentTarget : LeftHandSideExpression
Static Semantics: Early Errors
OptionalExpression:
MemberExpression OptionalChain
CallExpression OptionalChain
OptionalExpression OptionalChain
OptionalChain:
?. [ Expression ]
?. IdentifierName
?. Arguments
?. TemplateLiteral
OptionalChain [ Expression ]
OptionalChain .IdentifierName
OptionalChain Arguments
OptionalChain TemplateLiteral
DestructuringAssignmentTarget : LeftHandSideExpression
- It is a Syntax Error if LeftHandSideExpression is neither an ObjectLiteral nor an ArrayLiteral and IsValidSimpleAssignmentTarget(LeftHandSideExpression) is not true.
Static Semantics: IsValidSimpleAssignmentTarget
LeftHandSideExpression : OptionalExpression
1. Return false.
---*/
$DONOTEVALUATE();
var y = {};
for ({ x: y?.z } in [{ x: 23 }]) ;

View file

@ -0,0 +1,69 @@
// |reftest| error:SyntaxError
// This file was procedurally generated from the following sources:
// - src/dstr-assignment/obj-prop-elem-target-obj-literal-optchain-prop-ref-init.case
// - src/dstr-assignment/syntax/for-in.template
/*---
description: It is a Syntax Error if LeftHandSideExpression of an DestructuringAssignmentTarget is neither an ObjectLiteral nor an ArrayLiteral and AssignmentTargetType(LeftHandSideExpression) is not simple Using Object (For..in statement)
esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
features: [optional-chaining, destructuring-binding]
flags: [generated]
negative:
phase: parse
type: SyntaxError
info: |
IterationStatement :
for ( LeftHandSideExpression of AssignmentExpression ) Statement
1. Let keyResult be the result of performing ? ForIn/OfHeadEvaluation(« »,
AssignmentExpression, iterate).
2. Return ? ForIn/OfBodyEvaluation(LeftHandSideExpression, Statement,
keyResult, assignment, labelSet).
13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
[...]
4. If destructuring is true and if lhsKind is assignment, then
a. Assert: lhs is a LeftHandSideExpression.
b. Let assignmentPattern be the parse of the source text corresponding to
lhs using AssignmentPattern as the goal symbol.
[...]
Syntax
AssignmentElement : DestructuringAssignmentTarget Initializer_opt
DestructuringAssignmentTarget : LeftHandSideExpression
Static Semantics: Early Errors
OptionalExpression:
MemberExpression OptionalChain
CallExpression OptionalChain
OptionalExpression OptionalChain
OptionalChain:
?. [ Expression ]
?. IdentifierName
?. Arguments
?. TemplateLiteral
OptionalChain [ Expression ]
OptionalChain .IdentifierName
OptionalChain Arguments
OptionalChain TemplateLiteral
DestructuringAssignmentTarget : LeftHandSideExpression
- It is a Syntax Error if LeftHandSideExpression is neither an ObjectLiteral nor an ArrayLiteral and IsValidSimpleAssignmentTarget(LeftHandSideExpression) is not true.
Static Semantics: IsValidSimpleAssignmentTarget
LeftHandSideExpression : OptionalExpression
1. Return false.
---*/
$DONOTEVALUATE();
for ({ x: {
set y(val) {
throw new Test262Error('The property should not be accessed.');
}
}?.y = 42} in [{x: 42}]) ;

View file

@ -0,0 +1,69 @@
// |reftest| error:SyntaxError
// This file was procedurally generated from the following sources:
// - src/dstr-assignment/obj-prop-elem-target-obj-literal-optchain-prop-ref.case
// - src/dstr-assignment/syntax/for-in.template
/*---
description: It is a Syntax Error if LeftHandSideExpression of an DestructuringAssignmentTarget is neither an ObjectLiteral nor an ArrayLiteral and AssignmentTargetType(LeftHandSideExpression) is not simple Using Object (For..in statement)
esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
features: [optional-chaining, destructuring-binding]
flags: [generated]
negative:
phase: parse
type: SyntaxError
info: |
IterationStatement :
for ( LeftHandSideExpression of AssignmentExpression ) Statement
1. Let keyResult be the result of performing ? ForIn/OfHeadEvaluation(« »,
AssignmentExpression, iterate).
2. Return ? ForIn/OfBodyEvaluation(LeftHandSideExpression, Statement,
keyResult, assignment, labelSet).
13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
[...]
4. If destructuring is true and if lhsKind is assignment, then
a. Assert: lhs is a LeftHandSideExpression.
b. Let assignmentPattern be the parse of the source text corresponding to
lhs using AssignmentPattern as the goal symbol.
[...]
Syntax
AssignmentElement : DestructuringAssignmentTarget Initializer_opt
DestructuringAssignmentTarget : LeftHandSideExpression
Static Semantics: Early Errors
OptionalExpression:
MemberExpression OptionalChain
CallExpression OptionalChain
OptionalExpression OptionalChain
OptionalChain:
?. [ Expression ]
?. IdentifierName
?. Arguments
?. TemplateLiteral
OptionalChain [ Expression ]
OptionalChain .IdentifierName
OptionalChain Arguments
OptionalChain TemplateLiteral
DestructuringAssignmentTarget : LeftHandSideExpression
- It is a Syntax Error if LeftHandSideExpression is neither an ObjectLiteral nor an ArrayLiteral and IsValidSimpleAssignmentTarget(LeftHandSideExpression) is not true.
Static Semantics: IsValidSimpleAssignmentTarget
LeftHandSideExpression : OptionalExpression
1. Return false.
---*/
$DONOTEVALUATE();
for ({ x: {
set y(val) {
throw new Test262Error('The property should not be accessed.');
}
}?.y} in [{x: 42}]) ;

View file

@ -0,0 +1,66 @@
// |reftest| error:SyntaxError
// This file was procedurally generated from the following sources:
// - src/dstr-assignment/array-elem-nested-memberexpr-optchain-prop-ref-init.case
// - src/dstr-assignment/syntax/for-of.template
/*---
description: It is a Syntax Error if LeftHandSideExpression of an DestructuringAssignmentTarget is neither an ObjectLiteral nor an ArrayLiteral and AssignmentTargetType(LeftHandSideExpression) is not simple Using Object (MemberExpression OptionalChain .IdentifierName Initializer) (For..of statement)
esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
features: [optional-chaining, destructuring-binding]
flags: [generated]
negative:
phase: parse
type: SyntaxError
info: |
IterationStatement :
for ( LeftHandSideExpression of AssignmentExpression ) Statement
1. Let keyResult be the result of performing ? ForIn/OfHeadEvaluation(« »,
AssignmentExpression, iterate).
2. Return ? ForIn/OfBodyEvaluation(LeftHandSideExpression, Statement,
keyResult, assignment, labelSet).
13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
[...]
4. If destructuring is true and if lhsKind is assignment, then
a. Assert: lhs is a LeftHandSideExpression.
b. Let assignmentPattern be the parse of the source text corresponding to
lhs using AssignmentPattern as the goal symbol.
[...]
Syntax
AssignmentElement : DestructuringAssignmentTarget Initializer_opt
DestructuringAssignmentTarget : LeftHandSideExpression
Static Semantics: Early Errors
OptionalExpression:
MemberExpression OptionalChain
CallExpression OptionalChain
OptionalExpression OptionalChain
OptionalChain:
?. [ Expression ]
?. IdentifierName
?. Arguments
?. TemplateLiteral
OptionalChain [ Expression ]
OptionalChain .IdentifierName
OptionalChain Arguments
OptionalChain TemplateLiteral
DestructuringAssignmentTarget : LeftHandSideExpression
- It is a Syntax Error if LeftHandSideExpression is neither an ObjectLiteral nor an ArrayLiteral and IsValidSimpleAssignmentTarget(LeftHandSideExpression) is not true.
Static Semantics: IsValidSimpleAssignmentTarget
LeftHandSideExpression : OptionalExpression
1. Return false.
---*/
$DONOTEVALUATE();
var x = {};
for ([x?.y = 42] of [[23]]) ;

View file

@ -0,0 +1,66 @@
// |reftest| error:SyntaxError
// This file was procedurally generated from the following sources:
// - src/dstr-assignment/array-elem-nested-memberexpr-optchain-prop-ref.case
// - src/dstr-assignment/syntax/for-of.template
/*---
description: It is a Syntax Error if LeftHandSideExpression of an DestructuringAssignmentTarget is neither an ObjectLiteral nor an ArrayLiteral and AssignmentTargetType(LeftHandSideExpression) is not simple Using Object (MemberExpression OptionalChain .IdentifierName) (For..of statement)
esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
features: [optional-chaining, destructuring-binding]
flags: [generated]
negative:
phase: parse
type: SyntaxError
info: |
IterationStatement :
for ( LeftHandSideExpression of AssignmentExpression ) Statement
1. Let keyResult be the result of performing ? ForIn/OfHeadEvaluation(« »,
AssignmentExpression, iterate).
2. Return ? ForIn/OfBodyEvaluation(LeftHandSideExpression, Statement,
keyResult, assignment, labelSet).
13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
[...]
4. If destructuring is true and if lhsKind is assignment, then
a. Assert: lhs is a LeftHandSideExpression.
b. Let assignmentPattern be the parse of the source text corresponding to
lhs using AssignmentPattern as the goal symbol.
[...]
Syntax
AssignmentElement : DestructuringAssignmentTarget Initializer_opt
DestructuringAssignmentTarget : LeftHandSideExpression
Static Semantics: Early Errors
OptionalExpression:
MemberExpression OptionalChain
CallExpression OptionalChain
OptionalExpression OptionalChain
OptionalChain:
?. [ Expression ]
?. IdentifierName
?. Arguments
?. TemplateLiteral
OptionalChain [ Expression ]
OptionalChain .IdentifierName
OptionalChain Arguments
OptionalChain TemplateLiteral
DestructuringAssignmentTarget : LeftHandSideExpression
- It is a Syntax Error if LeftHandSideExpression is neither an ObjectLiteral nor an ArrayLiteral and IsValidSimpleAssignmentTarget(LeftHandSideExpression) is not true.
Static Semantics: IsValidSimpleAssignmentTarget
LeftHandSideExpression : OptionalExpression
1. Return false.
---*/
$DONOTEVALUATE();
var x = {};
for ([x?.y] of [[23]]) ;

View file

@ -0,0 +1,69 @@
// |reftest| error:SyntaxError
// This file was procedurally generated from the following sources:
// - src/dstr-assignment/array-elem-put-obj-literal-optchain-prop-ref-init.case
// - src/dstr-assignment/syntax/for-of.template
/*---
description: It is a Syntax Error if LeftHandSideExpression of an DestructuringAssignmentTarget is neither an ObjectLiteral nor an ArrayLiteral and AssignmentTargetType(LeftHandSideExpression) is not simple Using Object (For..of statement)
esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
features: [optional-chaining, destructuring-binding]
flags: [generated]
negative:
phase: parse
type: SyntaxError
info: |
IterationStatement :
for ( LeftHandSideExpression of AssignmentExpression ) Statement
1. Let keyResult be the result of performing ? ForIn/OfHeadEvaluation(« »,
AssignmentExpression, iterate).
2. Return ? ForIn/OfBodyEvaluation(LeftHandSideExpression, Statement,
keyResult, assignment, labelSet).
13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
[...]
4. If destructuring is true and if lhsKind is assignment, then
a. Assert: lhs is a LeftHandSideExpression.
b. Let assignmentPattern be the parse of the source text corresponding to
lhs using AssignmentPattern as the goal symbol.
[...]
Syntax
AssignmentElement : DestructuringAssignmentTarget Initializer_opt
DestructuringAssignmentTarget : LeftHandSideExpression
Static Semantics: Early Errors
OptionalExpression:
MemberExpression OptionalChain
CallExpression OptionalChain
OptionalExpression OptionalChain
OptionalChain:
?. [ Expression ]
?. IdentifierName
?. Arguments
?. TemplateLiteral
OptionalChain [ Expression ]
OptionalChain .IdentifierName
OptionalChain Arguments
OptionalChain TemplateLiteral
DestructuringAssignmentTarget : LeftHandSideExpression
- It is a Syntax Error if LeftHandSideExpression is neither an ObjectLiteral nor an ArrayLiteral and IsValidSimpleAssignmentTarget(LeftHandSideExpression) is not true.
Static Semantics: IsValidSimpleAssignmentTarget
LeftHandSideExpression : OptionalExpression
1. Return false.
---*/
$DONOTEVALUATE();
for ([{
set y(val) {
throw new Test262Error('The property should not be accessed.');
}
}?.y = 42] of [[23]]) ;

View file

@ -0,0 +1,69 @@
// |reftest| error:SyntaxError
// This file was procedurally generated from the following sources:
// - src/dstr-assignment/array-elem-put-obj-literal-optchain-prop-ref.case
// - src/dstr-assignment/syntax/for-of.template
/*---
description: It is a Syntax Error if LeftHandSideExpression of an DestructuringAssignmentTarget is neither an ObjectLiteral nor an ArrayLiteral and AssignmentTargetType(LeftHandSideExpression) is not simple Using Object (For..of statement)
esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
features: [optional-chaining, destructuring-binding]
flags: [generated]
negative:
phase: parse
type: SyntaxError
info: |
IterationStatement :
for ( LeftHandSideExpression of AssignmentExpression ) Statement
1. Let keyResult be the result of performing ? ForIn/OfHeadEvaluation(« »,
AssignmentExpression, iterate).
2. Return ? ForIn/OfBodyEvaluation(LeftHandSideExpression, Statement,
keyResult, assignment, labelSet).
13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
[...]
4. If destructuring is true and if lhsKind is assignment, then
a. Assert: lhs is a LeftHandSideExpression.
b. Let assignmentPattern be the parse of the source text corresponding to
lhs using AssignmentPattern as the goal symbol.
[...]
Syntax
AssignmentElement : DestructuringAssignmentTarget Initializer_opt
DestructuringAssignmentTarget : LeftHandSideExpression
Static Semantics: Early Errors
OptionalExpression:
MemberExpression OptionalChain
CallExpression OptionalChain
OptionalExpression OptionalChain
OptionalChain:
?. [ Expression ]
?. IdentifierName
?. Arguments
?. TemplateLiteral
OptionalChain [ Expression ]
OptionalChain .IdentifierName
OptionalChain Arguments
OptionalChain TemplateLiteral
DestructuringAssignmentTarget : LeftHandSideExpression
- It is a Syntax Error if LeftHandSideExpression is neither an ObjectLiteral nor an ArrayLiteral and IsValidSimpleAssignmentTarget(LeftHandSideExpression) is not true.
Static Semantics: IsValidSimpleAssignmentTarget
LeftHandSideExpression : OptionalExpression
1. Return false.
---*/
$DONOTEVALUATE();
for ([{
set y(val) {
throw new Test262Error('The property should not be accessed.');
}
}?.y] of [[23]]) ;

View file

@ -0,0 +1,66 @@
// |reftest| error:SyntaxError
// This file was procedurally generated from the following sources:
// - src/dstr-assignment/obj-prop-elem-target-memberexpr-optchain-prop-ref-init.case
// - src/dstr-assignment/syntax/for-of.template
/*---
description: It is a Syntax Error if LeftHandSideExpression of an DestructuringAssignmentTarget is neither an ObjectLiteral nor an ArrayLiteral and AssignmentTargetType(LeftHandSideExpression) is not simple Using Object (MemberExpression OptionalChain .IdentifierName Initializer) (For..of statement)
esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
features: [optional-chaining, destructuring-binding]
flags: [generated]
negative:
phase: parse
type: SyntaxError
info: |
IterationStatement :
for ( LeftHandSideExpression of AssignmentExpression ) Statement
1. Let keyResult be the result of performing ? ForIn/OfHeadEvaluation(« »,
AssignmentExpression, iterate).
2. Return ? ForIn/OfBodyEvaluation(LeftHandSideExpression, Statement,
keyResult, assignment, labelSet).
13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
[...]
4. If destructuring is true and if lhsKind is assignment, then
a. Assert: lhs is a LeftHandSideExpression.
b. Let assignmentPattern be the parse of the source text corresponding to
lhs using AssignmentPattern as the goal symbol.
[...]
Syntax
AssignmentElement : DestructuringAssignmentTarget Initializer_opt
DestructuringAssignmentTarget : LeftHandSideExpression
Static Semantics: Early Errors
OptionalExpression:
MemberExpression OptionalChain
CallExpression OptionalChain
OptionalExpression OptionalChain
OptionalChain:
?. [ Expression ]
?. IdentifierName
?. Arguments
?. TemplateLiteral
OptionalChain [ Expression ]
OptionalChain .IdentifierName
OptionalChain Arguments
OptionalChain TemplateLiteral
DestructuringAssignmentTarget : LeftHandSideExpression
- It is a Syntax Error if LeftHandSideExpression is neither an ObjectLiteral nor an ArrayLiteral and IsValidSimpleAssignmentTarget(LeftHandSideExpression) is not true.
Static Semantics: IsValidSimpleAssignmentTarget
LeftHandSideExpression : OptionalExpression
1. Return false.
---*/
$DONOTEVALUATE();
var y = {};
for ({ x: y?.z = 42 } of [{ x: 23 }]) ;

View file

@ -0,0 +1,66 @@
// |reftest| error:SyntaxError
// This file was procedurally generated from the following sources:
// - src/dstr-assignment/obj-prop-elem-target-memberexpr-optchain-prop-ref.case
// - src/dstr-assignment/syntax/for-of.template
/*---
description: It is a Syntax Error if LeftHandSideExpression of an DestructuringAssignmentTarget is neither an ObjectLiteral nor an ArrayLiteral and AssignmentTargetType(LeftHandSideExpression) is not simple Using Object (MemberExpression OptionalChain .IdentifierName) (For..of statement)
esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
features: [optional-chaining, destructuring-binding]
flags: [generated]
negative:
phase: parse
type: SyntaxError
info: |
IterationStatement :
for ( LeftHandSideExpression of AssignmentExpression ) Statement
1. Let keyResult be the result of performing ? ForIn/OfHeadEvaluation(« »,
AssignmentExpression, iterate).
2. Return ? ForIn/OfBodyEvaluation(LeftHandSideExpression, Statement,
keyResult, assignment, labelSet).
13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
[...]
4. If destructuring is true and if lhsKind is assignment, then
a. Assert: lhs is a LeftHandSideExpression.
b. Let assignmentPattern be the parse of the source text corresponding to
lhs using AssignmentPattern as the goal symbol.
[...]
Syntax
AssignmentElement : DestructuringAssignmentTarget Initializer_opt
DestructuringAssignmentTarget : LeftHandSideExpression
Static Semantics: Early Errors
OptionalExpression:
MemberExpression OptionalChain
CallExpression OptionalChain
OptionalExpression OptionalChain
OptionalChain:
?. [ Expression ]
?. IdentifierName
?. Arguments
?. TemplateLiteral
OptionalChain [ Expression ]
OptionalChain .IdentifierName
OptionalChain Arguments
OptionalChain TemplateLiteral
DestructuringAssignmentTarget : LeftHandSideExpression
- It is a Syntax Error if LeftHandSideExpression is neither an ObjectLiteral nor an ArrayLiteral and IsValidSimpleAssignmentTarget(LeftHandSideExpression) is not true.
Static Semantics: IsValidSimpleAssignmentTarget
LeftHandSideExpression : OptionalExpression
1. Return false.
---*/
$DONOTEVALUATE();
var y = {};
for ({ x: y?.z } of [{ x: 23 }]) ;

View file

@ -0,0 +1,69 @@
// |reftest| error:SyntaxError
// This file was procedurally generated from the following sources:
// - src/dstr-assignment/obj-prop-elem-target-obj-literal-optchain-prop-ref-init.case
// - src/dstr-assignment/syntax/for-of.template
/*---
description: It is a Syntax Error if LeftHandSideExpression of an DestructuringAssignmentTarget is neither an ObjectLiteral nor an ArrayLiteral and AssignmentTargetType(LeftHandSideExpression) is not simple Using Object (For..of statement)
esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
features: [optional-chaining, destructuring-binding]
flags: [generated]
negative:
phase: parse
type: SyntaxError
info: |
IterationStatement :
for ( LeftHandSideExpression of AssignmentExpression ) Statement
1. Let keyResult be the result of performing ? ForIn/OfHeadEvaluation(« »,
AssignmentExpression, iterate).
2. Return ? ForIn/OfBodyEvaluation(LeftHandSideExpression, Statement,
keyResult, assignment, labelSet).
13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
[...]
4. If destructuring is true and if lhsKind is assignment, then
a. Assert: lhs is a LeftHandSideExpression.
b. Let assignmentPattern be the parse of the source text corresponding to
lhs using AssignmentPattern as the goal symbol.
[...]
Syntax
AssignmentElement : DestructuringAssignmentTarget Initializer_opt
DestructuringAssignmentTarget : LeftHandSideExpression
Static Semantics: Early Errors
OptionalExpression:
MemberExpression OptionalChain
CallExpression OptionalChain
OptionalExpression OptionalChain
OptionalChain:
?. [ Expression ]
?. IdentifierName
?. Arguments
?. TemplateLiteral
OptionalChain [ Expression ]
OptionalChain .IdentifierName
OptionalChain Arguments
OptionalChain TemplateLiteral
DestructuringAssignmentTarget : LeftHandSideExpression
- It is a Syntax Error if LeftHandSideExpression is neither an ObjectLiteral nor an ArrayLiteral and IsValidSimpleAssignmentTarget(LeftHandSideExpression) is not true.
Static Semantics: IsValidSimpleAssignmentTarget
LeftHandSideExpression : OptionalExpression
1. Return false.
---*/
$DONOTEVALUATE();
for ({ x: {
set y(val) {
throw new Test262Error('The property should not be accessed.');
}
}?.y = 42} of [{x: 42}]) ;

View file

@ -0,0 +1,69 @@
// |reftest| error:SyntaxError
// This file was procedurally generated from the following sources:
// - src/dstr-assignment/obj-prop-elem-target-obj-literal-optchain-prop-ref.case
// - src/dstr-assignment/syntax/for-of.template
/*---
description: It is a Syntax Error if LeftHandSideExpression of an DestructuringAssignmentTarget is neither an ObjectLiteral nor an ArrayLiteral and AssignmentTargetType(LeftHandSideExpression) is not simple Using Object (For..of statement)
esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
features: [optional-chaining, destructuring-binding]
flags: [generated]
negative:
phase: parse
type: SyntaxError
info: |
IterationStatement :
for ( LeftHandSideExpression of AssignmentExpression ) Statement
1. Let keyResult be the result of performing ? ForIn/OfHeadEvaluation(« »,
AssignmentExpression, iterate).
2. Return ? ForIn/OfBodyEvaluation(LeftHandSideExpression, Statement,
keyResult, assignment, labelSet).
13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
[...]
4. If destructuring is true and if lhsKind is assignment, then
a. Assert: lhs is a LeftHandSideExpression.
b. Let assignmentPattern be the parse of the source text corresponding to
lhs using AssignmentPattern as the goal symbol.
[...]
Syntax
AssignmentElement : DestructuringAssignmentTarget Initializer_opt
DestructuringAssignmentTarget : LeftHandSideExpression
Static Semantics: Early Errors
OptionalExpression:
MemberExpression OptionalChain
CallExpression OptionalChain
OptionalExpression OptionalChain
OptionalChain:
?. [ Expression ]
?. IdentifierName
?. Arguments
?. TemplateLiteral
OptionalChain [ Expression ]
OptionalChain .IdentifierName
OptionalChain Arguments
OptionalChain TemplateLiteral
DestructuringAssignmentTarget : LeftHandSideExpression
- It is a Syntax Error if LeftHandSideExpression is neither an ObjectLiteral nor an ArrayLiteral and IsValidSimpleAssignmentTarget(LeftHandSideExpression) is not true.
Static Semantics: IsValidSimpleAssignmentTarget
LeftHandSideExpression : OptionalExpression
1. Return false.
---*/
$DONOTEVALUATE();
for ({ x: {
set y(val) {
throw new Test262Error('The property should not be accessed.');
}
}?.y} of [{x: 42}]) ;