coderaiser / putout

🐊 Pluggable and configurable JavaScript Linter, code transformer and formatter, drop-in ESLint superpower replacement 💪 with built-in support for js, jsx, typescript, flow, markdown, yaml and json. Write declarative codemods in a simplest possible way 😏
https://putout.cloudcmd.io/
MIT License
712 stars 40 forks source link

Incorrect order of initialization of variables #197

Closed sirenkovladd closed 11 months ago

sirenkovladd commented 11 months ago
import {
    parse,
    transform,
} from 'putout';
import {print} from '@putout/printer';
import {rules} from '@putout/plugin-minify';
const js = `function c(n) {const a=s=>s.b*n;return a.bind()}
function v(o) {o.e=c(2)}
function s(n) {
  var o = n.q;
  o && "pre" === o.n.toLowerCase() && v(o);
  var s = {e:o.e,b:o.w};
  return s.e(s);
}
console.log(s({q:{n:'pre',e:c(1),w:2}}))`;

const ast = parse(js, {
    printer: 'putout',
});
transform(ast, js, {plugins: [
    ['minify', {rules: {mv: rules['merge-variables']}}],
]});
const min = print(ast);

console.log(min);
eval(js);
eval(min);

result

❯ node m.js
function c(n) {
    const a = (s) => s.b * n;
    return a.bind();
}

function v(o) {
    o.e = c(2);
}

function s(n) {
    var o = n.q, s = {
            e: o.e,
            b: o.w,
        };
    o && 'pre' === o.n.toLowerCase() && v(o);

    return s.e(s);
}

console.log(s({
    q: {
        n: 'pre',
        e: c(1),
        w: 2,
    },
}));

4
2

You can see the difference between the original code and the minification (result 2 and 4) The problem is plugin-minify -> merge-variables

in function s() variable s init before calling v(o) should be the opposite

coderaiser commented 11 months ago

Could you please simplify example, too deep nesting and not looks like code you keep in your repository.

You can also apply needed modifications to https://github.com/coderaiser/putout/blob/v34.8.1/packages/plugin-minify/lib/merge-variables/index.js.

coderaiser commented 11 months ago

If you keep state in variable on move it here in there you should do one of next:

🐊Putout cannot support all cases that is possible to write, only real human readable code.

Feel free to reopen if you have something to add.

sirenkovladd commented 10 months ago

Unfortunately, this is the code I got from esbuild, so I can't change it in fact, the original code works on the DOM, so as a result it is quite complex (I tried to simplify it so that it could be called without using other packages) the main problem is that the order initialization of the variable s has changed its position in the function s(n)

coderaiser commented 10 months ago

Maybe you can provide original code? Or simplify it?