mathiasbynens / luamin

A Lua minifier written in JavaScript
https://mths.be/luamin
MIT License
217 stars 54 forks source link

Brackets incorrectly removed from function calls #62

Closed Ayplow closed 5 years ago

Ayplow commented 5 years ago
luamin -c "return (func())"
# Outputs
return func()

This is incorrect, because

function func() return 1, 2 end
a, b = func()
c, d = (func())
print(a, b, c, d)
--> 1, 2, 1, nil

I just realised this is basically #51 , which already has code half the way to solving it. I'l throw together a pr that applies the fix to all functions

I also found the spec in the manual that specifies this

hsandt commented 4 years ago

The issue is still there, you can see EnclosedCallStatement test failing.

The reason is that we are passing the expression.base to formatBase which is really select in (select(1, ...)) and is has type "Identifier". Even if we managed to detect the parent expression to be a CallStatement and surround it with brackets, it would just output (select)(1, ...).

I could brute-fix that by adding

            result = '(' + result + ')';

in either formatStatement when detecting CallStatement or formatExpression when detecting CallExpression, but that would add brackets on every call, which may either be unneeded or even give the wrong result as in the OP's example. I don't know how to only keep brackets already added by the user, I'd need luaparse to give me that information.

Note that if you find a fix, you'll also want to apply the same to table calls and string calls, adding those tests:

            {
                'description': 'EnclosedCallStatement + StringCallExpression',
                'original': '(a"foo")',
                'minified': '(a"foo")'
            },
            {
                'description': 'EnclosedCallStatement + TableCallExpression',
                'original': '(a{})',
                'minified': '(a{})'
            },