mathiasbynens / luamin

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

Fix multiple cases of bracket and semicolon mishandling #89

Open 9382 opened 2 months ago

9382 commented 2 months ago

Fix prefix expressions not being bracketed when required

Now code like (nil)() or ("")"" will stop producing invalid syntax

Not sure why the test cases were configured to see 1() or true() as valid, as calling a literal like this is invalid syntax

Based on prefixexp ::= var | functioncall | `(´ exp `)´ (lua 5.1 docs)

Fixes #87 Fixes #48

Fix truncation via parenthesis being removed when it shouldn't be

Fix (f()) being shortened to f(), even though these aren't actually the same (In lua, if a call expression is surrounded by brackets, its result will always be truncated to one value, which can be an important difference)

Solves the first issue of #88

Fix semicolons not being written in potential ambiguous syntax cases

Fixes the case where a = b; ({})(c) (and similar statement combinations) would be written without the semicolon when minified, causing it to become one large statement

The only way to start a statement with anything other than an alphanumeric (+ underscore) character is a call statement that has its base wrapped in brackets (see stat ::= BNF), so if we see this occur we make sure the end of our first statement couldn't be construed as a prefixexp (which I've just considered might encompass every possible ending to a statement)

Not perfect in terms of minification since it just considers what the last character is instead of its context (e.g. do end;({})() is the same with or without the semicolon), but we only pass the resultant string, not the statements involved, so I don't think this can be easily improved

Fully fixes #88

cohler commented 2 months ago

Wow. That looks great. I will try it out your new commits and let you know how it goes.

I have luamin installed using node, fyi, and I invoke it from the command line in various build scripts that I use which then minify large numbers of files. Because of all the file opening, writing, and closing, the process it is quite slow and occupies 90% or more of my entire project build time.

Is there any way to improve that invocation speed?

9382 commented 2 months ago

I could certainly have a look to see if I could figure out any performance improvements, but I don't often mess with javascript or nodejs, so I can't guarantee I'll be able to improve anything I will note that, from some minor testing on the existing luamin testcases, it appears the majority of execution time (>85%) might be getting consumed by luaparse instead of luamin. Upgrading luaparse to 0.3.1 would improve that greatly (~40-50% faster), but unfortunately that can't happen without changes in luaparse to bring back an inParens equivilant

cohler commented 2 months ago

Thanks. I tried out your version with the latest fixes and the ; and () problems seem to be fixed!! In the coming days, I'll test it on a big codebase and let you know if there are any problems. Thank you for your work on this!