fix(unstable): wrong node with shorthand ObjectPattern + AssignPattern (#28402)

We did not serialize the `AssignmentPattern` node inside `ObjectPattern`
properties.

```ts
({ a = b } = {})
```

This is a bit different in SWC and looks like I got confused with the
different AST formats.

Fixes https://github.com/denoland/deno/issues/28399
This commit is contained in:
Marvin Hagemeister 2025-03-05 21:12:19 +01:00 committed by GitHub
parent 731a238d34
commit 7f7b51c414
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 145 additions and 32 deletions

View file

@ -1898,24 +1898,23 @@ fn serialize_pat(ctx: &mut TsEsTreeBuilder, pat: &Pat) -> NodeRef {
)
}
ObjectPatProp::Assign(assign_pat_prop) => {
let ident = serialize_binding_ident(ctx, &assign_pat_prop.key);
let key = serialize_binding_ident(ctx, &assign_pat_prop.key);
let mut value = serialize_binding_ident(ctx, &assign_pat_prop.key);
let shorthand = assign_pat_prop.value.is_none();
let value = assign_pat_prop.value.as_ref().map_or(
// SWC has value as optional with shorthand properties,
// but TSESTree expects the value to be a duplicate of
// the binding ident.
serialize_binding_ident(ctx, &assign_pat_prop.key),
|value| serialize_expr(ctx, value),
);
if let Some(assign) = &assign_pat_prop.value {
let expr = serialize_expr(ctx, assign);
value = ctx.write_assign_pat(&assign_pat_prop.span, value, expr);
}
ctx.write_property(
&assign_pat_prop.span,
&node.span,
shorthand,
false,
false,
PropertyKind::Init,
ident,
key,
value,
)
}

View file

@ -177,19 +177,36 @@ snapshot[`Plugin - FunctionDeclaration 3`] = `
kind: "init",
method: false,
range: [
22,
27,
20,
38,
],
shorthand: false,
type: "Property",
value: {
left: {
name: "a",
optional: false,
range: [
22,
23,
],
type: "Identifier",
typeAnnotation: undefined,
},
range: [
26,
22,
27,
],
raw: "2",
type: "Literal",
value: 2,
right: {
range: [
26,
27,
],
raw: "2",
type: "Literal",
value: 2,
},
type: "AssignmentPattern",
},
},
{
@ -207,8 +224,8 @@ snapshot[`Plugin - FunctionDeclaration 3`] = `
kind: "init",
method: false,
range: [
29,
30,
20,
38,
],
shorthand: true,
type: "Property",
@ -5451,8 +5468,8 @@ snapshot[`Plugin - ObjectPattern 1`] = `
kind: "init",
method: false,
range: [
8,
12,
6,
14,
],
shorthand: true,
type: "Property",
@ -5585,19 +5602,36 @@ snapshot[`Plugin - ObjectPattern 4`] = `
kind: "init",
method: false,
range: [
8,
16,
6,
18,
],
shorthand: false,
type: "Property",
value: {
left: {
name: "prop",
optional: false,
range: [
8,
12,
],
type: "Identifier",
typeAnnotation: undefined,
},
range: [
15,
8,
16,
],
raw: "2",
type: "Literal",
value: 2,
right: {
range: [
15,
16,
],
raw: "2",
type: "Literal",
value: 2,
},
type: "AssignmentPattern",
},
},
],
@ -5629,19 +5663,36 @@ snapshot[`Plugin - ObjectPattern 5`] = `
kind: "init",
method: false,
range: [
8,
16,
6,
24,
],
shorthand: false,
type: "Property",
value: {
left: {
name: "prop",
optional: false,
range: [
8,
12,
],
type: "Identifier",
typeAnnotation: undefined,
},
range: [
15,
8,
16,
],
raw: "2",
type: "Literal",
value: 2,
right: {
range: [
15,
16,
],
raw: "2",
type: "Literal",
value: 2,
},
type: "AssignmentPattern",
},
},
{
@ -5672,6 +5723,68 @@ snapshot[`Plugin - ObjectPattern 5`] = `
}
`;
snapshot[`Plugin - ObjectPattern 6`] = `
{
optional: false,
properties: [
{
computed: false,
key: {
name: "a",
optional: false,
range: [
3,
4,
],
type: "Identifier",
typeAnnotation: undefined,
},
kind: "init",
method: false,
range: [
1,
10,
],
shorthand: false,
type: "Property",
value: {
left: {
name: "a",
optional: false,
range: [
3,
4,
],
type: "Identifier",
typeAnnotation: undefined,
},
range: [
3,
8,
],
right: {
name: "b",
optional: false,
range: [
7,
8,
],
type: "Identifier",
typeAnnotation: undefined,
},
type: "AssignmentPattern",
},
},
],
range: [
1,
10,
],
type: "ObjectPattern",
typeAnnotation: undefined,
}
`;
snapshot[`Plugin - ArrayPattern 1`] = `
{
elements: [

View file

@ -855,6 +855,7 @@ Deno.test("Plugin - ObjectPattern", async (t) => {
await testSnapshot(t, "const { 'a.b': A } = {}", "ObjectPattern");
await testSnapshot(t, "const { prop = 2 } = {}", "ObjectPattern");
await testSnapshot(t, "const { prop = 2, ...c } = {}", "ObjectPattern");
await testSnapshot(t, "({ a = b } = {})", "ObjectPattern");
});
Deno.test("Plugin - ArrayPattern", async (t) => {