Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Parens are dropped, changing program semantics / introducing syntax error #985

Open
NickHeiner opened this issue Sep 8, 2021 · 1 comment

Comments

@NickHeiner
Copy link
Contributor

I'm using Babel and Recast in conjunction to transform my AST. When I use Babel alone, the output is fine (although not formatted correctly.) When I introduce Recast, it drops parens, changing the program semantics (or introducing a syntax error).

Input code:

jest.mock('./my-module', () => () => ({
  mockedFn: jest.fn()
}));

Babel plugin:

const plugin = ({ types: t }) => ({
  visitor: {
    ArrowFunctionExpression(astPath) {
      const getWrappedValue = (originalValue) =>
        t.callExpression(t.identifier("wrapped"), [
          originalValue
        ]);

      const bodyPath = astPath.get("body");
      bodyPath.replaceWith(getWrappedValue(bodyPath.node));
      astPath.skip();
    }
  }
});

Transformed results:

// Babel result
jest.mock('./my-module', () => wrapped(() => ({
  mockedFn: jest.fn()
})));

// Recast result
jest.mock('./my-module', () => wrapped(() => {
  mockedFn: jest.fn()
}));

Full runnable repro.

We can see that the () around the arrow function return expression are dropped. When there are multiple members of the object, this results in a syntax error:

() => ({a: true, b: false})

// Syntax error
() => {a: true, b: false}

Possibly related: #914, #327, #533, #81
Versions:

  • recast@0.20.5
  • @babel/core@7.15.5
@gnprice
Copy link
Contributor

gnprice commented Jun 12, 2022

This issue no longer reproduces 🎉

With recast@0.21.1, I get:

Babel result
jest.mock('./my-module', () => wrapped(() => ({
  mockedFn: jest.fn()
})));
Recast result
jest.mock('./my-module', () => wrapped(() => ({
  mockedFn: jest.fn()
})));

i.e., the Recast result has that necessary pair of parens, just like the Babel result.

The issue does still reproduce if I go back to Recast 0.21.0. So most likely it was fixed by #1068, which was a parenthesization fix that happened between those versions.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants