summaryrefslogtreecommitdiff
path: root/js/src/tests/non262/expressions/optional-chain-first-expression.js
diff options
context:
space:
mode:
Diffstat (limited to 'js/src/tests/non262/expressions/optional-chain-first-expression.js')
-rw-r--r--js/src/tests/non262/expressions/optional-chain-first-expression.js92
1 files changed, 92 insertions, 0 deletions
diff --git a/js/src/tests/non262/expressions/optional-chain-first-expression.js b/js/src/tests/non262/expressions/optional-chain-first-expression.js
new file mode 100644
index 000000000..89912aec4
--- /dev/null
+++ b/js/src/tests/non262/expressions/optional-chain-first-expression.js
@@ -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);