From edfe46051f27399089fe8684f05808aa82a3c997 Mon Sep 17 00:00:00 2001 From: SUZUKI Sosuke Date: Mon, 9 Oct 2023 08:36:11 +0900 Subject: [PATCH] Support optional chaining assignment (#15488) --- src/language-js/parse/babel.js | 1 + .../__snapshots__/jsfmt.spec.js.snap | 35 ++ tests/format/js/babel-plugins/jsfmt.spec.js | 3 + .../optional-chaining-assignment.js | 1 + .../__snapshots__/jsfmt.spec.js.snap | 482 ++++++++++++++++++ .../invalid-destructuring-arr.js | 1 + .../invalid-destructuring-obj.js | 1 + .../invalid-fn-param-arrow.js | 1 + .../invalid-fn-param-assign.js | 1 + .../invalid-fn-param.js | 1 + .../invalid-for-await-of.js | 1 + .../invalid-for-in.js | 1 + .../invalid-for-of.js | 1 + .../invalid-inc-postfix.js | 1 + .../invalid-inc-prefix.js | 1 + .../jsfmt.spec.js | 37 ++ .../valid-complex-case.js | 2 + .../valid-lhs-eq.js | 1 + .../valid-lhs-plus-eq.js | 1 + .../valid-parenthesized.js | 1 + .../__snapshots__/jsfmt.spec.js.snap | 56 +- .../misc/errors/js/assignment/jsfmt.spec.js | 10 +- 22 files changed, 576 insertions(+), 64 deletions(-) create mode 100644 tests/format/js/babel-plugins/optional-chaining-assignment.js create mode 100644 tests/format/js/optional-chaining-assignment/__snapshots__/jsfmt.spec.js.snap create mode 100644 tests/format/js/optional-chaining-assignment/invalid-destructuring-arr.js create mode 100644 tests/format/js/optional-chaining-assignment/invalid-destructuring-obj.js create mode 100644 tests/format/js/optional-chaining-assignment/invalid-fn-param-arrow.js create mode 100644 tests/format/js/optional-chaining-assignment/invalid-fn-param-assign.js create mode 100644 tests/format/js/optional-chaining-assignment/invalid-fn-param.js create mode 100644 tests/format/js/optional-chaining-assignment/invalid-for-await-of.js create mode 100644 tests/format/js/optional-chaining-assignment/invalid-for-in.js create mode 100644 tests/format/js/optional-chaining-assignment/invalid-for-of.js create mode 100644 tests/format/js/optional-chaining-assignment/invalid-inc-postfix.js create mode 100644 tests/format/js/optional-chaining-assignment/invalid-inc-prefix.js create mode 100644 tests/format/js/optional-chaining-assignment/jsfmt.spec.js create mode 100644 tests/format/js/optional-chaining-assignment/valid-complex-case.js create mode 100644 tests/format/js/optional-chaining-assignment/valid-lhs-eq.js create mode 100644 tests/format/js/optional-chaining-assignment/valid-lhs-plus-eq.js create mode 100644 tests/format/js/optional-chaining-assignment/valid-parenthesized.js diff --git a/src/language-js/parse/babel.js b/src/language-js/parse/babel.js index 1907ae1ba..8e901e995 100644 --- a/src/language-js/parse/babel.js +++ b/src/language-js/parse/babel.js @@ -45,6 +45,7 @@ const parseOptions = { "importReflection", "explicitResourceManagement", ["importAttributes", { deprecatedAssertSyntax: true }], + ["optionalChainingAssign", { version: "2023-07" }], ], tokens: true, ranges: true, diff --git a/tests/format/js/babel-plugins/__snapshots__/jsfmt.spec.js.snap b/tests/format/js/babel-plugins/__snapshots__/jsfmt.spec.js.snap index 0c25e0db5..99ddbe419 100644 --- a/tests/format/js/babel-plugins/__snapshots__/jsfmt.spec.js.snap +++ b/tests/format/js/babel-plugins/__snapshots__/jsfmt.spec.js.snap @@ -1824,6 +1824,41 @@ const ret = delete obj?.foo?.bar?.baz; // true ================================================================================ `; +exports[`optional-chaining-assignment.js [acorn] format 1`] = ` +"Optional chaining cannot appear in left-hand side (1:1) +> 1 | maybeAnObj?.prop = theValue; + | ^ + 2 |" +`; + +exports[`optional-chaining-assignment.js [espree] format 1`] = ` +"Optional chaining cannot appear in left-hand side (1:1) +> 1 | maybeAnObj?.prop = theValue; + | ^ + 2 |" +`; + +exports[`optional-chaining-assignment.js [meriyah] format 1`] = ` +"Invalid left-hand side in assignment (1:18) +> 1 | maybeAnObj?.prop = theValue; + | ^ + 2 |" +`; + +exports[`optional-chaining-assignment.js format 1`] = ` +====================================options===================================== +parsers: ["babel", "babel-ts", "babel-flow"] +printWidth: 80 + | printWidth +=====================================input====================================== +maybeAnObj?.prop = theValue; + +=====================================output===================================== +maybeAnObj?.prop = theValue; + +================================================================================ +`; + exports[`partial-application.js [acorn] format 1`] = ` "Unexpected token (5:23) 3 | function add(x, y) { return x + y; } diff --git a/tests/format/js/babel-plugins/jsfmt.spec.js b/tests/format/js/babel-plugins/jsfmt.spec.js index b47c0f904..5aeacace8 100644 --- a/tests/format/js/babel-plugins/jsfmt.spec.js +++ b/tests/format/js/babel-plugins/jsfmt.spec.js @@ -31,6 +31,7 @@ run_spec(import.meta, ["babel", "babel-ts", "babel-flow"], { "import-reflection.js", "explicit-resource-management.js", "regexp-modifiers.js", + "optional-chaining-assignment.js", ], espree: [ "decimal.js", @@ -60,6 +61,7 @@ run_spec(import.meta, ["babel", "babel-ts", "babel-flow"], { "import-reflection.js", "explicit-resource-management.js", "regexp-modifiers.js", + "optional-chaining-assignment.js", ], meriyah: [ "decimal.js", @@ -91,6 +93,7 @@ run_spec(import.meta, ["babel", "babel-ts", "babel-flow"], { "import-reflection.js", "explicit-resource-management.js", "regexp-modifiers.js", + "optional-chaining-assignment.js", ], babel: ["flow.js", "typescript.js"], __babel_estree: ["flow.js", "typescript.js"], diff --git a/tests/format/js/babel-plugins/optional-chaining-assignment.js b/tests/format/js/babel-plugins/optional-chaining-assignment.js new file mode 100644 index 000000000..d15b0a213 --- /dev/null +++ b/tests/format/js/babel-plugins/optional-chaining-assignment.js @@ -0,0 +1 @@ +maybeAnObj?.prop = theValue; diff --git a/tests/format/js/optional-chaining-assignment/__snapshots__/jsfmt.spec.js.snap b/tests/format/js/optional-chaining-assignment/__snapshots__/jsfmt.spec.js.snap new file mode 100644 index 000000000..a805cf434 --- /dev/null +++ b/tests/format/js/optional-chaining-assignment/__snapshots__/jsfmt.spec.js.snap @@ -0,0 +1,482 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`invalid-destructuring-arr.js [__babel_estree] format 1`] = ` +"Invalid optional chaining in the left-hand side of array destructuring pattern. (1:2) +> 1 | [a?.b] = []; + | ^ + 2 |" +`; + +exports[`invalid-destructuring-arr.js [acorn] format 1`] = ` +"Optional chaining cannot appear in left-hand side (1:2) +> 1 | [a?.b] = []; + | ^ + 2 |" +`; + +exports[`invalid-destructuring-arr.js [babel] format 1`] = ` +"Invalid optional chaining in the left-hand side of array destructuring pattern. (1:2) +> 1 | [a?.b] = []; + | ^ + 2 |" +`; + +exports[`invalid-destructuring-arr.js [espree] format 1`] = ` +"Optional chaining cannot appear in left-hand side (1:2) +> 1 | [a?.b] = []; + | ^ + 2 |" +`; + +exports[`invalid-destructuring-arr.js [meriyah] format 1`] = ` +"Invalid left-hand side in assignment (1:10) +> 1 | [a?.b] = []; + | ^ + 2 |" +`; + +exports[`invalid-destructuring-obj.js [__babel_estree] format 1`] = ` +"Invalid optional chaining in the left-hand side of object destructuring pattern. (1:10) +> 1 | ({ prop: a?.b } = {}); + | ^ + 2 |" +`; + +exports[`invalid-destructuring-obj.js [acorn] format 1`] = ` +"Optional chaining cannot appear in left-hand side (1:10) +> 1 | ({ prop: a?.b } = {}); + | ^ + 2 |" +`; + +exports[`invalid-destructuring-obj.js [babel] format 1`] = ` +"Invalid optional chaining in the left-hand side of object destructuring pattern. (1:10) +> 1 | ({ prop: a?.b } = {}); + | ^ + 2 |" +`; + +exports[`invalid-destructuring-obj.js [espree] format 1`] = ` +"Optional chaining cannot appear in left-hand side (1:10) +> 1 | ({ prop: a?.b } = {}); + | ^ + 2 |" +`; + +exports[`invalid-destructuring-obj.js [meriyah] format 1`] = ` +"Invalid left-hand side in assignment (1:19) +> 1 | ({ prop: a?.b } = {}); + | ^ + 2 |" +`; + +exports[`invalid-fn-param.js [__babel_estree] format 1`] = ` +"Unexpected token, expected "," (1:13) +> 1 | function f(a?.b) {} + | ^ + 2 |" +`; + +exports[`invalid-fn-param.js [acorn] format 1`] = ` +"Unexpected token (1:13) +> 1 | function f(a?.b) {} + | ^ + 2 |" +`; + +exports[`invalid-fn-param.js [babel] format 1`] = ` +"Unexpected token, expected "," (1:13) +> 1 | function f(a?.b) {} + | ^ + 2 |" +`; + +exports[`invalid-fn-param.js [espree] format 1`] = ` +"Unexpected token ?. (1:13) +> 1 | function f(a?.b) {} + | ^ + 2 |" +`; + +exports[`invalid-fn-param.js [meriyah] format 1`] = ` +"Expected ')' (1:14) +> 1 | function f(a?.b) {} + | ^ + 2 |" +`; + +exports[`invalid-fn-param-arrow.js [__babel_estree] format 1`] = ` +"Invalid optional chaining in the left-hand side of function parameter list. (1:2) +> 1 | (a?.b) => {} + | ^ + 2 |" +`; + +exports[`invalid-fn-param-arrow.js [acorn] format 1`] = ` +"Optional chaining cannot appear in left-hand side (1:2) +> 1 | (a?.b) => {} + | ^ + 2 |" +`; + +exports[`invalid-fn-param-arrow.js [babel] format 1`] = ` +"Invalid optional chaining in the left-hand side of function parameter list. (1:2) +> 1 | (a?.b) => {} + | ^ + 2 |" +`; + +exports[`invalid-fn-param-arrow.js [espree] format 1`] = ` +"Optional chaining cannot appear in left-hand side (1:2) +> 1 | (a?.b) => {} + | ^ + 2 |" +`; + +exports[`invalid-fn-param-arrow.js [meriyah] format 1`] = ` +"The left-hand side of the arrow can only be destructed through assignment (1:9) +> 1 | (a?.b) => {} + | ^ + 2 |" +`; + +exports[`invalid-fn-param-assign.js [__babel_estree] format 1`] = ` +"Unexpected token, expected "," (1:13) +> 1 | function f(a?.b = c) {} + | ^ + 2 |" +`; + +exports[`invalid-fn-param-assign.js [acorn] format 1`] = ` +"Unexpected token (1:13) +> 1 | function f(a?.b = c) {} + | ^ + 2 |" +`; + +exports[`invalid-fn-param-assign.js [babel] format 1`] = ` +"Unexpected token, expected "," (1:13) +> 1 | function f(a?.b = c) {} + | ^ + 2 |" +`; + +exports[`invalid-fn-param-assign.js [espree] format 1`] = ` +"Unexpected token ?. (1:13) +> 1 | function f(a?.b = c) {} + | ^ + 2 |" +`; + +exports[`invalid-fn-param-assign.js [meriyah] format 1`] = ` +"Expected ')' (1:14) +> 1 | function f(a?.b = c) {} + | ^ + 2 |" +`; + +exports[`invalid-for-await-of.js [__babel_estree] format 1`] = ` +"Invalid optional chaining in the left-hand side of for-of statement. (1:6) +> 1 | for (a?.b of x); + | ^ + 2 |" +`; + +exports[`invalid-for-await-of.js [acorn] format 1`] = ` +"Optional chaining cannot appear in left-hand side (1:6) +> 1 | for (a?.b of x); + | ^ + 2 |" +`; + +exports[`invalid-for-await-of.js [babel] format 1`] = ` +"Invalid optional chaining in the left-hand side of for-of statement. (1:6) +> 1 | for (a?.b of x); + | ^ + 2 |" +`; + +exports[`invalid-for-await-of.js [espree] format 1`] = ` +"Optional chaining cannot appear in left-hand side (1:6) +> 1 | for (a?.b of x); + | ^ + 2 |" +`; + +exports[`invalid-for-await-of.js [meriyah] format 1`] = ` +"Invalid left-hand side in for-of (1:12) +> 1 | for (a?.b of x); + | ^ + 2 |" +`; + +exports[`invalid-for-in.js [__babel_estree] format 1`] = ` +"Invalid optional chaining in the left-hand side of for-in statement. (1:6) +> 1 | for (a?.b in x); + | ^ + 2 |" +`; + +exports[`invalid-for-in.js [acorn] format 1`] = ` +"Optional chaining cannot appear in left-hand side (1:6) +> 1 | for (a?.b in x); + | ^ + 2 |" +`; + +exports[`invalid-for-in.js [babel] format 1`] = ` +"Invalid optional chaining in the left-hand side of for-in statement. (1:6) +> 1 | for (a?.b in x); + | ^ + 2 |" +`; + +exports[`invalid-for-in.js [espree] format 1`] = ` +"Optional chaining cannot appear in left-hand side (1:6) +> 1 | for (a?.b in x); + | ^ + 2 |" +`; + +exports[`invalid-for-in.js [meriyah] format 1`] = ` +"Invalid left-hand side in for-in (1:12) +> 1 | for (a?.b in x); + | ^ + 2 |" +`; + +exports[`invalid-for-of.js [__babel_estree] format 1`] = ` +"Invalid optional chaining in the left-hand side of for-of statement. (1:6) +> 1 | for (a?.b of x); + | ^ + 2 |" +`; + +exports[`invalid-for-of.js [acorn] format 1`] = ` +"Optional chaining cannot appear in left-hand side (1:6) +> 1 | for (a?.b of x); + | ^ + 2 |" +`; + +exports[`invalid-for-of.js [babel] format 1`] = ` +"Invalid optional chaining in the left-hand side of for-of statement. (1:6) +> 1 | for (a?.b of x); + | ^ + 2 |" +`; + +exports[`invalid-for-of.js [espree] format 1`] = ` +"Optional chaining cannot appear in left-hand side (1:6) +> 1 | for (a?.b of x); + | ^ + 2 |" +`; + +exports[`invalid-for-of.js [meriyah] format 1`] = ` +"Invalid left-hand side in for-of (1:12) +> 1 | for (a?.b of x); + | ^ + 2 |" +`; + +exports[`invalid-inc-postfix.js [__babel_estree] format 1`] = ` +"Invalid optional chaining in the left-hand side of postfix operation. (1:1) +> 1 | a?.b++; + | ^ + 2 |" +`; + +exports[`invalid-inc-postfix.js [acorn] format 1`] = ` +"Optional chaining cannot appear in left-hand side (1:1) +> 1 | a?.b++; + | ^ + 2 |" +`; + +exports[`invalid-inc-postfix.js [babel] format 1`] = ` +"Invalid optional chaining in the left-hand side of postfix operation. (1:1) +> 1 | a?.b++; + | ^ + 2 |" +`; + +exports[`invalid-inc-postfix.js [espree] format 1`] = ` +"Optional chaining cannot appear in left-hand side (1:1) +> 1 | a?.b++; + | ^ + 2 |" +`; + +exports[`invalid-inc-postfix.js [meriyah] format 1`] = ` +"Invalid increment/decrement operand (1:6) +> 1 | a?.b++; + | ^ + 2 |" +`; + +exports[`invalid-inc-prefix.js [__babel_estree] format 1`] = ` +"Invalid optional chaining in the left-hand side of prefix operation. (1:3) +> 1 | ++a?.b; + | ^ + 2 |" +`; + +exports[`invalid-inc-prefix.js [acorn] format 1`] = ` +"Optional chaining cannot appear in left-hand side (1:3) +> 1 | ++a?.b; + | ^ + 2 |" +`; + +exports[`invalid-inc-prefix.js [babel] format 1`] = ` +"Invalid optional chaining in the left-hand side of prefix operation. (1:3) +> 1 | ++a?.b; + | ^ + 2 |" +`; + +exports[`invalid-inc-prefix.js [espree] format 1`] = ` +"Optional chaining cannot appear in left-hand side (1:3) +> 1 | ++a?.b; + | ^ + 2 |" +`; + +exports[`invalid-inc-prefix.js [meriyah] format 1`] = ` +"Invalid increment/decrement operand (1:7) +> 1 | ++a?.b; + | ^ + 2 |" +`; + +exports[`valid-complex-case.js [acorn] format 1`] = ` +"The keyword 'let' is reserved (1:1) +> 1 | let?.()[a] =1; + | ^ + 2 | let?.[a] = 1; + 3 |" +`; + +exports[`valid-complex-case.js [espree] format 1`] = ` +"The keyword 'let' is reserved (1:1) +> 1 | let?.()[a] =1; + | ^ + 2 | let?.[a] = 1; + 3 |" +`; + +exports[`valid-complex-case.js [meriyah] format 1`] = ` +"\`let\` declaration not allowed here and \`let\` cannot be a regular var name in strict mode (1:5) +> 1 | let?.()[a] =1; + | ^ + 2 | let?.[a] = 1; + 3 |" +`; + +exports[`valid-complex-case.js format 1`] = ` +====================================options===================================== +parsers: ["babel"] +printWidth: 80 + | printWidth +=====================================input====================================== +let?.()[a] =1; +let?.[a] = 1; + +=====================================output===================================== +let?.()[a] = 1; +let?.[a] = 1; + +================================================================================ +`; + +exports[`valid-lhs-eq.js [acorn] format 1`] = ` +"Optional chaining cannot appear in left-hand side (1:1) +> 1 | a?.b.c = d; + | ^ + 2 |" +`; + +exports[`valid-lhs-eq.js [espree] format 1`] = ` +"Optional chaining cannot appear in left-hand side (1:1) +> 1 | a?.b.c = d; + | ^ + 2 |" +`; + +exports[`valid-lhs-eq.js format 1`] = ` +====================================options===================================== +parsers: ["babel"] +printWidth: 80 + | printWidth +=====================================input====================================== +a?.b.c = d; + +=====================================output===================================== +a?.b.c = d; + +================================================================================ +`; + +exports[`valid-lhs-plus-eq.js [acorn] format 1`] = ` +"Optional chaining cannot appear in left-hand side (1:1) +> 1 | a?.b.c += d; + | ^ + 2 |" +`; + +exports[`valid-lhs-plus-eq.js [espree] format 1`] = ` +"Optional chaining cannot appear in left-hand side (1:1) +> 1 | a?.b.c += d; + | ^ + 2 |" +`; + +exports[`valid-lhs-plus-eq.js format 1`] = ` +====================================options===================================== +parsers: ["babel"] +printWidth: 80 + | printWidth +=====================================input====================================== +a?.b.c += d; + +=====================================output===================================== +a?.b.c += d; + +================================================================================ +`; + +exports[`valid-parenthesized.js [acorn] format 1`] = ` +"Optional chaining cannot appear in left-hand side (1:2) +> 1 | (a?.b) = c; + | ^ + 2 |" +`; + +exports[`valid-parenthesized.js [espree] format 1`] = ` +"Optional chaining cannot appear in left-hand side (1:2) +> 1 | (a?.b) = c; + | ^ + 2 |" +`; + +exports[`valid-parenthesized.js [meriyah] format 1`] = ` +"Invalid left-hand side in assignment (1:8) +> 1 | (a?.b) = c; + | ^ + 2 |" +`; + +exports[`valid-parenthesized.js format 1`] = ` +====================================options===================================== +parsers: ["babel"] +printWidth: 80 + | printWidth +=====================================input====================================== +(a?.b) = c; + +=====================================output===================================== +a?.b = c; + +================================================================================ +`; diff --git a/tests/format/js/optional-chaining-assignment/invalid-destructuring-arr.js b/tests/format/js/optional-chaining-assignment/invalid-destructuring-arr.js new file mode 100644 index 000000000..d2d56ccd9 --- /dev/null +++ b/tests/format/js/optional-chaining-assignment/invalid-destructuring-arr.js @@ -0,0 +1 @@ +[a?.b] = []; diff --git a/tests/format/js/optional-chaining-assignment/invalid-destructuring-obj.js b/tests/format/js/optional-chaining-assignment/invalid-destructuring-obj.js new file mode 100644 index 000000000..818ba60fe --- /dev/null +++ b/tests/format/js/optional-chaining-assignment/invalid-destructuring-obj.js @@ -0,0 +1 @@ +({ prop: a?.b } = {}); diff --git a/tests/format/js/optional-chaining-assignment/invalid-fn-param-arrow.js b/tests/format/js/optional-chaining-assignment/invalid-fn-param-arrow.js new file mode 100644 index 000000000..21cf5338f --- /dev/null +++ b/tests/format/js/optional-chaining-assignment/invalid-fn-param-arrow.js @@ -0,0 +1 @@ +(a?.b) => {} diff --git a/tests/format/js/optional-chaining-assignment/invalid-fn-param-assign.js b/tests/format/js/optional-chaining-assignment/invalid-fn-param-assign.js new file mode 100644 index 000000000..c8085ff71 --- /dev/null +++ b/tests/format/js/optional-chaining-assignment/invalid-fn-param-assign.js @@ -0,0 +1 @@ +function f(a?.b = c) {} diff --git a/tests/format/js/optional-chaining-assignment/invalid-fn-param.js b/tests/format/js/optional-chaining-assignment/invalid-fn-param.js new file mode 100644 index 000000000..1db702ecf --- /dev/null +++ b/tests/format/js/optional-chaining-assignment/invalid-fn-param.js @@ -0,0 +1 @@ +function f(a?.b) {} diff --git a/tests/format/js/optional-chaining-assignment/invalid-for-await-of.js b/tests/format/js/optional-chaining-assignment/invalid-for-await-of.js new file mode 100644 index 000000000..ba964a0ed --- /dev/null +++ b/tests/format/js/optional-chaining-assignment/invalid-for-await-of.js @@ -0,0 +1 @@ +for (a?.b of x); diff --git a/tests/format/js/optional-chaining-assignment/invalid-for-in.js b/tests/format/js/optional-chaining-assignment/invalid-for-in.js new file mode 100644 index 000000000..57cc56518 --- /dev/null +++ b/tests/format/js/optional-chaining-assignment/invalid-for-in.js @@ -0,0 +1 @@ +for (a?.b in x); diff --git a/tests/format/js/optional-chaining-assignment/invalid-for-of.js b/tests/format/js/optional-chaining-assignment/invalid-for-of.js new file mode 100644 index 000000000..ba964a0ed --- /dev/null +++ b/tests/format/js/optional-chaining-assignment/invalid-for-of.js @@ -0,0 +1 @@ +for (a?.b of x); diff --git a/tests/format/js/optional-chaining-assignment/invalid-inc-postfix.js b/tests/format/js/optional-chaining-assignment/invalid-inc-postfix.js new file mode 100644 index 000000000..9bbcb40bf --- /dev/null +++ b/tests/format/js/optional-chaining-assignment/invalid-inc-postfix.js @@ -0,0 +1 @@ +a?.b++; diff --git a/tests/format/js/optional-chaining-assignment/invalid-inc-prefix.js b/tests/format/js/optional-chaining-assignment/invalid-inc-prefix.js new file mode 100644 index 000000000..72c17bb98 --- /dev/null +++ b/tests/format/js/optional-chaining-assignment/invalid-inc-prefix.js @@ -0,0 +1 @@ +++a?.b; diff --git a/tests/format/js/optional-chaining-assignment/jsfmt.spec.js b/tests/format/js/optional-chaining-assignment/jsfmt.spec.js new file mode 100644 index 000000000..58b58d18c --- /dev/null +++ b/tests/format/js/optional-chaining-assignment/jsfmt.spec.js @@ -0,0 +1,37 @@ +const invalidSyntaxTests = [ + "invalid-destructuring-arr.js", + "invalid-destructuring-obj.js", + "invalid-fn-param-arrow.js", + "invalid-fn-param.js", + "invalid-fn-param-assign.js", + "invalid-for-await-of.js", + "invalid-for-in.js", + "invalid-for-of.js", + "invalid-inc-postfix.js", + "invalid-inc-prefix.js", +]; + +const optionalChainingAssignTests = [ + "valid-lhs-eq.js", + "valid-lhs-plus-eq.js", + "valid-parenthesized.js", + "valid-complex-case.js", +]; + +// meriyah can parse these files +const meriyahCanParse = new Set(["valid-lhs-eq.js", "valid-lhs-plus-eq.js"]); + +run_spec(import.meta, ["babel"], { + errors: { + acorn: [...optionalChainingAssignTests, ...invalidSyntaxTests], + espree: [...optionalChainingAssignTests, ...invalidSyntaxTests], + meriyah: [ + ...optionalChainingAssignTests.filter( + (test) => !meriyahCanParse.has(test), + ), + ...invalidSyntaxTests, + ], + babel: invalidSyntaxTests, + __babel_estree: invalidSyntaxTests, + }, +}); diff --git a/tests/format/js/optional-chaining-assignment/valid-complex-case.js b/tests/format/js/optional-chaining-assignment/valid-complex-case.js new file mode 100644 index 000000000..602f18c52 --- /dev/null +++ b/tests/format/js/optional-chaining-assignment/valid-complex-case.js @@ -0,0 +1,2 @@ +let?.()[a] =1; +let?.[a] = 1; diff --git a/tests/format/js/optional-chaining-assignment/valid-lhs-eq.js b/tests/format/js/optional-chaining-assignment/valid-lhs-eq.js new file mode 100644 index 000000000..b709b1cd6 --- /dev/null +++ b/tests/format/js/optional-chaining-assignment/valid-lhs-eq.js @@ -0,0 +1 @@ +a?.b.c = d; diff --git a/tests/format/js/optional-chaining-assignment/valid-lhs-plus-eq.js b/tests/format/js/optional-chaining-assignment/valid-lhs-plus-eq.js new file mode 100644 index 000000000..decb2e9d6 --- /dev/null +++ b/tests/format/js/optional-chaining-assignment/valid-lhs-plus-eq.js @@ -0,0 +1 @@ +a?.b.c += d; diff --git a/tests/format/js/optional-chaining-assignment/valid-parenthesized.js b/tests/format/js/optional-chaining-assignment/valid-parenthesized.js new file mode 100644 index 000000000..5d060e412 --- /dev/null +++ b/tests/format/js/optional-chaining-assignment/valid-parenthesized.js @@ -0,0 +1 @@ +(a?.b) = c; diff --git a/tests/format/misc/errors/js/assignment/__snapshots__/jsfmt.spec.js.snap b/tests/format/misc/errors/js/assignment/__snapshots__/jsfmt.spec.js.snap index 1c7025ad8..542a8b53f 100644 --- a/tests/format/misc/errors/js/assignment/__snapshots__/jsfmt.spec.js.snap +++ b/tests/format/misc/errors/js/assignment/__snapshots__/jsfmt.spec.js.snap @@ -7,12 +7,6 @@ exports[`snippet: #0 [acorn] format 1`] = ` `; exports[`snippet: #0 [acorn] format 2`] = ` -"The keyword 'let' is reserved (1:1) -> 1 | let?.()[a] =1 - | ^" -`; - -exports[`snippet: #0 [acorn] format 3`] = ` "The keyword 'let' is reserved (1:21) > 1 | class Foo extends ((let)[0] = 1) {} | ^" @@ -24,24 +18,12 @@ exports[`snippet: #0 [babel] format 1`] = ` | ^" `; -exports[`snippet: #0 [babel] format 2`] = ` -"This experimental syntax requires enabling the parser plugin: "optionalChainingAssign". (1:1) -> 1 | let?.()[a] =1 - | ^" -`; - exports[`snippet: #0 [babel-ts] format 1`] = ` "Invalid parenthesized assignment pattern. (1:1) > 1 | ({}) = x; | ^" `; -exports[`snippet: #0 [babel-ts] format 2`] = ` -"This experimental syntax requires enabling the parser plugin: "optionalChainingAssign". (1:1) -> 1 | let?.()[a] =1 - | ^" -`; - exports[`snippet: #0 [espree] format 1`] = ` "Assigning to rvalue (1:1) > 1 | ({}) = x; @@ -49,18 +31,12 @@ exports[`snippet: #0 [espree] format 1`] = ` `; exports[`snippet: #0 [espree] format 2`] = ` -"The keyword 'let' is reserved (1:1) -> 1 | let?.()[a] =1 - | ^" -`; - -exports[`snippet: #0 [espree] format 3`] = ` "The keyword 'let' is reserved (1:21) > 1 | class Foo extends ((let)[0] = 1) {} | ^" `; -exports[`snippet: #0 [espree] format 4`] = ` +exports[`snippet: #0 [espree] format 3`] = ` "The keyword 'let' is reserved (1:18) > 1 | export default ((let)[0] = 1); | ^" @@ -83,33 +59,3 @@ exports[`snippet: #0 [meriyah] format 3`] = ` > 1 | export default ((let)[0] = 1); | ^" `; - -exports[`snippet: #1 [acorn] format 1`] = ` -"The keyword 'let' is reserved (1:1) -> 1 | let?.[a] = 1 - | ^" -`; - -exports[`snippet: #1 [babel] format 1`] = ` -"This experimental syntax requires enabling the parser plugin: "optionalChainingAssign". (1:1) -> 1 | let?.[a] = 1 - | ^" -`; - -exports[`snippet: #1 [babel-ts] format 1`] = ` -"This experimental syntax requires enabling the parser plugin: "optionalChainingAssign". (1:1) -> 1 | let?.[a] = 1 - | ^" -`; - -exports[`snippet: #1 [espree] format 1`] = ` -"The keyword 'let' is reserved (1:1) -> 1 | let?.[a] = 1 - | ^" -`; - -exports[`snippet: #1 [meriyah] format 1`] = ` -"\`let\` declaration not allowed here and \`let\` cannot be a regular var name in strict mode (1:5) -> 1 | let?.[a] = 1 - | ^" -`; diff --git a/tests/format/misc/errors/js/assignment/jsfmt.spec.js b/tests/format/misc/errors/js/assignment/jsfmt.spec.js index 81a9246bf..64c097296 100644 --- a/tests/format/misc/errors/js/assignment/jsfmt.spec.js +++ b/tests/format/misc/errors/js/assignment/jsfmt.spec.js @@ -1,19 +1,11 @@ run_spec( { importMeta: import.meta, - snippets: ["({}) = x;", "let?.[a] = 1"], + snippets: ["({}) = x;"], }, ["babel", "babel-ts", "acorn", "espree", "meriyah"], ); -run_spec( - { - importMeta: import.meta, - snippets: ["let?.()[a] =1"], - }, - ["babel", "babel-ts", "acorn", "espree"], -); - run_spec( { importMeta: import.meta,