fix(js-parser): handle default values with destructuring in arrow expression
MODIFY
internal/js-parser/parser/expression.ts
internal/js-parser/parser/expression.ts
@@ -1924,6 +1924,7 @@ export function parseParenAndDistinguishExpression(
const innerStart = parser.getPosition();
const exprList: ToReferencedItem[] = [];
+ const bindingList: AnyJSBindingPattern[] = [];
const refShorthandDefaultPos: IndexTracker = createIndexTracker();
const refNeedsArrowPos: IndexTracker = createIndexTracker();
let first = true;
@@ -1967,16 +1968,39 @@ export function parseParenAndDistinguishExpression(
eat(parser, tt.comma);
}
} else {
- exprList.push(
- parseMaybeAssign<ReturnType<typeof parseParenItem>>(
+ const branches = createBranch<
+ ReturnType<typeof parseParenItem> | JSBindingObjectPattern
+ >(parser);
+
+ // Try parsing normally
+ branches.add(
+ () => {
+ return parseMaybeAssign<ReturnType<typeof parseParenItem>>(
parser,
context,
false,
refShorthandDefaultPos,
parseParenItem,
refNeedsArrowPos,
- ),
);
+ },
+ {
+ diagnosticsPriority: 1,
+ },
+ );
+
+ // Try parsing as JSBindingObjectPattern
+ branches.add(() => {
+ return parseObjectPattern(parser, refShorthandDefaultPos);
+ });
+
+ const node = branches.pick();
+
+ if (node.type === "JSBindingObjectPattern") {
+ bindingList.push(node);
+ } else {
+ exprList.push(node);
+ }
}
}
@@ -2010,6 +2034,7 @@ export function parseParenAndDistinguishExpression(
parser,
startPos,
{
+ bindingList,
assignmentList: exprList,
},
);
@@ -2156,6 +2181,7 @@ export function parseArrowHead(
}
}
+// TODO: remove flow?
// Parse a possible function param or call argument
export function parseParenItem(
parser: JSParser,
@@ -3181,10 +3207,6 @@ export function parseArrowExpression(
let params: AnyJSBindingPattern[] = [];
let rest: undefined | AnyJSTargetBindingPattern = opts.rest;
- if (opts.bindingList !== undefined) {
- params = opts.bindingList;
- }
-
if (opts.assignmentList !== undefined) {
({params, rest} = toFunctionParamsBindingList(
parser,
@@ -3193,6 +3215,10 @@ export function parseArrowExpression(
));
}
+ if (opts.bindingList !== undefined) {
+ params.push(...opts.bindingList);
+ }
+
let head = parser.finishNodeAt(
start,
headEnd,

ADD
internal/js-parser/test-fixtures/es2015/arrow-functions/destructuring-rename/input.js
+({ bar: foo = "foobar" }) => foo

ADD
internal/js-parser/test-fixtures/es2015/arrow-functions/destructuring-rename/input.test.md
+# `index.test.ts`
+
+**DO NOT MODIFY**. This file has been autogenerated. Run `rome test internal/js-parser/index.test.ts --update-snapshots` to update.
+
+## `es2015 > arrow-functions > destructuring-rename`
+
+### `ast`
+
+```javascript
+JSRoot {
+ body: [
+ JSExpressionStatement {
+ expression: JSArrowFunctionExpression {
+ body: JSReferenceIdentifier {
+ name: "foo"
+ loc: SourceLocation es2015/arrow-functions/destructuring-rename/input.js 1:29-1:32 (foo)
+ }
+ head: JSFunctionHead {
+ async: false
+ hasHoistedVars: false
+ params: [
+ JSBindingObjectPattern {
+ properties: [
+ JSBindingObjectPatternProperty {
+ key: JSStaticPropertyKey {
+ value: JSIdentifier {
+ name: "bar"
+ loc: SourceLocation es2015/arrow-functions/destructuring-rename/input.js 1:3-1:6 (bar)
+ }
+ loc: SourceLocation es2015/arrow-functions/destructuring-rename/input.js 1:3-1:6
+ }
+ value: JSBindingAssignmentPattern {
+ operator: "="
+ left: JSBindingIdentifier {
+ name: "foo"
+ loc: SourceLocation es2015/arrow-functions/destructuring-rename/input.js 1:8-1:11 (foo)
+ }
+ right: JSStringLiteral {
+ value: "foobar"
+ loc: SourceLocation es2015/arrow-functions/destructuring-rename/input.js 1:14-1:22
+ }
+ loc: SourceLocation es2015/arrow-functions/destructuring-rename/input.js 1:8-1:22
+ }
+ loc: SourceLocation es2015/arrow-functions/destructuring-rename/input.js 1:3-1:22
+ }
+ ]
+ loc: SourceLocation es2015/arrow-functions/destructuring-rename/input.js 1:1-1:24
+ }
+ ]
+ loc: SourceLocation es2015/arrow-functions/destructuring-rename/input.js 1:0-1:28
+ }
+ loc: SourceLocation es2015/arrow-functions/destructuring-rename/input.js 1:0-1:32
+ }
+ loc: SourceLocation es2015/arrow-functions/destructuring-rename/input.js 1:0-1:32
+ }
+ ]
+ comments: []
+ corrupt: false
+ diagnostics: []
+ directives: []
+ hasHoistedVars: false
+ sourceType: "script"
+ syntax: []
+ path: UIDPath<es2015/arrow-functions/destructuring-rename/input.js>
+ loc: SourceLocation es2015/arrow-functions/destructuring-rename/input.js 1:0-2:0
+}
+```
+
+### `diagnostics`
+
+```
+
+```

ADD
internal/js-parser/test-fixtures/es2015/arrow-functions/destructuring/input.js
+({ bar = "foobar" }) => bar

ADD
internal/js-parser/test-fixtures/es2015/arrow-functions/destructuring/input.test.md
+# `index.test.ts`
+
+**DO NOT MODIFY**. This file has been autogenerated. Run `rome test internal/js-parser/index.test.ts --update-snapshots` to update.
+
+## `es2015 > arrow-functions > destructuring`
+
+### `ast`
+
+```javascript
+JSRoot {
+ body: [
+ JSExpressionStatement {
+ expression: JSArrowFunctionExpression {
+ body: JSReferenceIdentifier {
+ name: "bar"
+ loc: SourceLocation es2015/arrow-functions/destructuring/input.js 1:24-1:27 (bar)
+ }
+ head: JSFunctionHead {
+ async: false
+ hasHoistedVars: false
+ params: [
+ JSBindingObjectPattern {
+ properties: [
+ JSBindingObjectPatternProperty {
+ key: JSStaticPropertyKey {
+ value: JSIdentifier {
+ name: "bar"
+ loc: SourceLocation es2015/arrow-functions/destructuring/input.js 1:3-1:6 (bar)
+ }
+ loc: SourceLocation es2015/arrow-functions/destructuring/input.js 1:3-1:6
+ }
+ value: JSBindingAssignmentPattern {
+ left: JSBindingIdentifier {
+ name: "bar"
+ loc: SourceLocation es2015/arrow-functions/destructuring/input.js 1:3-1:6 (bar)
+ }
+ right: JSStringLiteral {
+ value: "foobar"
+ loc: SourceLocation es2015/arrow-functions/destructuring/input.js 1:9-1:17
+ }
+ loc: SourceLocation es2015/arrow-functions/destructuring/input.js 1:3-1:17
+ }
+ loc: SourceLocation es2015/arrow-functions/destructuring/input.js 1:3-1:17
+ }
+ ]
+ loc: SourceLocation es2015/arrow-functions/destructuring/input.js 1:1-1:19
+ }
+ ]
+ loc: SourceLocation es2015/arrow-functions/destructuring/input.js 1:0-1:23
+ }
+ loc: SourceLocation es2015/arrow-functions/destructuring/input.js 1:0-1:27
+ }
+ loc: SourceLocation es2015/arrow-functions/destructuring/input.js 1:0-1:27
+ }
+ ]
+ comments: []
+ corrupt: false
+ diagnostics: []
+ directives: []
+ hasHoistedVars: false
+ sourceType: "script"
+ syntax: []
+ path: UIDPath<es2015/arrow-functions/destructuring/input.js>
+ loc: SourceLocation es2015/arrow-functions/destructuring/input.js 1:0-2:0
+}
+```
+
+### `diagnostics`
+
+```
+
+```

fix(js-parser): handle default values with destructuring in arrow expression (#1651)