Repository: denoland/deno
Pull request: fix(unstable): wrong node with shorthand ObjectPattern + AssignPattern

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

Changed files:
filename: cli/tools/lint/ast_buffer/swc.rs
patch: @@ -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,
             )
           }

filename: tests/unit/__snapshots__/lint_plugin_test.ts.snap
patch: @@ -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: [

filename: tests/unit/lint_plugin_test.ts
patch: @@ -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) => {