I've been adding some features to UglifyJS - a rather nice JavaScript parser / compressor / beautifier that is itself written in JavaScript.
It implements a JavaScript 1.5 parser, and then has various routines to walk the AST doing things like renaming variables and collapsing selected expressions.
I've added the ability to safely replace selected global symbols with constant values (which can then allow the minifier to collapse entire sections, like #ifdef in C++) which has been pulled into the main tree, and the ability to spot and shortcut constant expressions involving &&, ||, and ?: (ie eliminate the RHS when a true constant value on the LHS means that the RHS will never be evaluated).
I've also added the ability to mangle selected object property names, which obviously needs some care, but is great for obfuscating internals and can shorten long method names etc. This change is only in my fork for now - https://github.com/schmerg/UglifyJS (see the mangleprops branch)
I also toyed with the idea of extending the parser to understand some features of later versions of javascript (eg the very useful let statement of 1.7) and have an option to compile them down to javascript 1.5, so that
It implements a JavaScript 1.5 parser, and then has various routines to walk the AST doing things like renaming variables and collapsing selected expressions.
I've added the ability to safely replace selected global symbols with constant values (which can then allow the minifier to collapse entire sections, like #ifdef in C++) which has been pulled into the main tree, and the ability to spot and shortcut constant expressions involving &&, ||, and ?: (ie eliminate the RHS when a true constant value on the LHS means that the RHS will never be evaluated).
I've also added the ability to mangle selected object property names, which obviously needs some care, but is great for obfuscating internals and can shorten long method names etc. This change is only in my fork for now - https://github.com/schmerg/UglifyJS (see the mangleprops branch)
I also toyed with the idea of extending the parser to understand some features of later versions of javascript (eg the very useful let statement of 1.7) and have an option to compile them down to javascript 1.5, so that
var x = 1, y =2;
if (something) {
let x = x+y;
console.log("X is now "+x+" and y is "+y);
}
console.log("X ends with value "+x);
would be re-written as
var x = 1, y =2;
if (something) {
(function(x) {
console.log("X is now "+x+" and y is "+y);
}(x+y);
}
console.log("X ends with value "+x);
Yeah, I know about things like coffee-script, but I don't want to be debugging something too far away from my original source, and I hope eventually javascript 1.7 will be supported in more browsers (in which case I can stop using this conversion)
And I'm also thinking about inlining selected methods - I know javascript engines do this internally, but there are sometimes big wins to be had from inlining trivial functions (which you've coded a such to avoid repeating the same expression endlessly). Again this is a bit like the pre-processor in C++, but because it would be done as part of the proper parse process (rather than limited text substitution) then I think it could be done much more safely.
Anyway - I'll post things to github as I go...