benjamn / recast

JavaScript syntax tree transformer, nondestructive pretty-printer, and automatic source map generator
MIT License
4.99k stars 350 forks source link

Recast is adding extra newlines in ObjectExpressions #242

Open kumarharsh opened 8 years ago

kumarharsh commented 8 years ago

Refer to the following fiddle: http://astexplorer.net/#/27xKOBJJGN

When I have an object with a structure such as this:

const styles = {
  base: {
    height: '100%',
  },
  ribbon: {
    backgroundColor: 'black',
  },
};

and I do anything with the body of the ObjectExpression like this:

export default function(file, api) {
  const j = api.jscodeshift;
  window.j = j;
  const { statement, statements } = j.template;
  return j(file.source)
    .find(j.VariableDeclarator)
    .replaceWith(p => {
        p.node.init = j.objectExpression(p.node.init.properties);
        return p.node;
    })
    .toSource();
};

then the following output is gotten:

const styles = {
  base: {
    height: '100%',
  },

  ribbon: {
    backgroundColor: 'black',
  }
};

see that extra newline after base and before ribbon. These lines are added after every property, which is adding unnecessary changes to my codebase. Is there a way to suppress that? or is that a bug?

kumarharsh commented 8 years ago

Thinking about this a little, I'm inclined to believe that this is also related to #240. Essentially, the printer is forcefully adding one extra newline after each property in an objectExpression. So, if there is none, then there will be one. If there's one, then there will be two. But if there's two or more, then nothing happens.

kumarharsh commented 8 years ago

This comes from https://github.com/benjamn/recast/blob/827ae9ff9317179c9bf6bd21b6355601448bb9fd/lib/printer.js#L624-L627

From what I've seen, the practice of writing code as I've given in the first code snippet above is quite common and, at risk of sounding too narrow-minded, no one writes an extra newline in their code separating the properties of an objectExpression, not even Facebook.

petrfelzmann commented 7 years ago

353

pksjce commented 7 years ago

+1 I faced the same issue! My PR linked above is not an informed fix but it fixes this particular issue while not breaking any test cases. I also wrote a failing test case for this and made it oss as per of that PR

nickretallack commented 4 years ago

I found a ton of examples of cases where this happens. I originally filed a bug here: https://github.com/zxbodya/flowts/issues/11

It seems any property that spans multiple lines causes extra newlines, even if it's just because it has a comment.

danielo515 commented 3 years ago

It is happening something similar to me. This code, for example:

  const shortProperty = (j, identifier) => {
    return { ...j.objectProperty(identifier, identifier), shorthand: true };
  };

export default function (file, api) {
  const j = api.jscodeshift;

  const call = j.variableDeclaration("const", [
      j.variableDeclarator(
        j.objectPattern([shortProperty(j,j.identifier("__"))]),
        j.callExpression(j.identifier("usePulyglot"), [
          j.identifier("phrases")
        ])
      )
    ])

    return j(call).toSource();
}

Produces this output:

const {
  __
} = usePulyglot(phrases); = 99

But I expected this instead:

const { __ } = usePulyglot(phrases); = 99

Here is a playground:

https://astexplorer.net/#/gist/eeee224efd6c389deb8a82a338e4fbe7/latest

villesau commented 1 year ago

Made a fix for this: https://github.com/benjamn/recast/pull/1262

yhancsx commented 1 year ago

I have similar problem

image

https://astexplorer.net/#/gist/eeee224efd6c389deb8a82a338e4fbe7/af669315e6eead72e30a403b05298edd685fd864