coderaiser/putout

Incorrect order of initialization of variables

sirenkovladd opened this issue · 4 comments

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

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.

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

  • rewrite your code to not be so much dependent on position;
  • disable current rule;

🐊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.

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)

Maybe you can provide original code? Or simplify it?