Skip to content
Permalink
Browse files

Update the UglifyJS code.

  • Loading branch information...
jeresig committed May 2, 2011
1 parent c0d9939 commit f4b5d3fc51cfb2b62f182e88b85386b4456c080d
Showing with 222 additions and 90 deletions.
  1. +18 −22 build/lib/parse-js.js
  2. +73 −23 build/lib/process.js
  3. +131 −45 build/uglify.js
@@ -751,14 +751,17 @@ function parse($TEXT, exigent_mode, embed_tokens) {
return str instanceof NodeWithToken ? str : new NodeWithToken(str, start, end);
};

var statement = embed_tokens ? function() {
var start = S.token;
var ast = $statement.apply(this, arguments);
ast[0] = add_tokens(ast[0], start, prev());
return ast;
} : $statement;

function $statement() {
function maybe_embed_tokens(parser) {
if (embed_tokens) return function() {
var start = S.token;
var ast = parser.apply(this, arguments);
ast[0] = add_tokens(ast[0], start, prev());
return ast;
};
else return parser;
};

var statement = maybe_embed_tokens(function() {
if (is("operator", "/")) {
S.peeked = null;
S.token = S.input(true); // force regexp
@@ -852,7 +855,7 @@ function parse($TEXT, exigent_mode, embed_tokens) {
unexpected();
}
}
};
});

function labeled_statement(label) {
S.labels.push(label);
@@ -910,14 +913,7 @@ function parse($TEXT, exigent_mode, embed_tokens) {
return as("for-in", init, lhs, obj, in_loop(statement));
};

var function_ = embed_tokens ? function() {
var start = prev();
var ast = $function_.apply(this, arguments);
ast[0] = add_tokens(ast[0], start, prev());
return ast;
} : $function_;

function $function_(in_statement) {
var function_ = maybe_embed_tokens(function(in_statement) {
var name = is("name") ? prog1(S.token.value, next) : null;
if (in_statement && !name)
unexpected();
@@ -945,7 +941,7 @@ function parse($TEXT, exigent_mode, embed_tokens) {
S.in_loop = loop;
return a;
})());
};
});

function if_() {
var cond = parenthesised(), body = statement(), belse;
@@ -1053,7 +1049,7 @@ function parse($TEXT, exigent_mode, embed_tokens) {
return subscripts(as("new", newexp, args), true);
};

function expr_atom(allow_calls) {
var expr_atom = maybe_embed_tokens(function(allow_calls) {
if (is("operator", "new")) {
next();
return new_();
@@ -1088,7 +1084,7 @@ function parse($TEXT, exigent_mode, embed_tokens) {
return subscripts(prog1(atom, next), allow_calls);
}
unexpected();
};
});

function expr_list(closing, allow_trailing_comma, allow_empty) {
var first = true, a = [];
@@ -1228,7 +1224,7 @@ function parse($TEXT, exigent_mode, embed_tokens) {
return left;
};

function expression(commas, no_in) {
var expression = maybe_embed_tokens(function(commas, no_in) {
if (arguments.length == 0)
commas = true;
var expr = maybe_assign(no_in);
@@ -1237,7 +1233,7 @@ function parse($TEXT, exigent_mode, embed_tokens) {
return as("seq", expr, expression(true, no_in));
}
return expr;
};
});

function in_loop(cont) {
try {
@@ -75,6 +75,12 @@ function ast_walker(ast) {
return a;
}) ];
};
function _block(statements) {
var out = [ this[0] ];
if (statements != null)
out.push(MAP(statements, walk));
return out;
};
var walkers = {
"string": function(str) {
return [ this[0], str ];
@@ -88,12 +94,8 @@ function ast_walker(ast) {
"toplevel": function(statements) {
return [ this[0], MAP(statements, walk) ];
},
"block": function(statements) {
var out = [ this[0] ];
if (statements != null)
out.push(MAP(statements, walk));
return out;
},
"block": _block,
"splice": _block,
"var": _vardefs,
"const": _vardefs,
"try": function(t, c, f) {
@@ -377,7 +379,9 @@ function ast_add_scope(ast) {
};

function _lambda(name, args, body) {
return [ this[0], this[0] == "defun" ? define(name) : name, args, with_new_scope(function(){
var is_defun = this[0] == "defun";
return [ this[0], is_defun ? define(name) : name, args, with_new_scope(function(){
if (!is_defun) define(name);
MAP(args, define);
return MAP(body, walk);
})];
@@ -463,9 +467,22 @@ function ast_mangle(ast, options) {
return scope.get_mangled(name, newMangle);
};

function get_define(name) {
// we always lookup a defined symbol for the current scope FIRST, so declared
// vars trump a DEFINE symbol, but if no such var is found, then match a DEFINE value
if (!scope.has(name)) {
if (HOP(options.defines, name)) {
return options.defines[name];
}
}
return null;
};

function _lambda(name, args, body) {
if (name) name = get_mangled(name);
var is_defun = this[0] == "defun";
if (is_defun && name) name = get_mangled(name);
body = with_scope(body.scope, function(){
if (!is_defun && name) name = get_mangled(name);
args = MAP(args, function(name){ return get_mangled(name) });
return MAP(body, walk);
});
@@ -507,7 +524,7 @@ function ast_mangle(ast, options) {
"var": _vardefs,
"const": _vardefs,
"name": function(name) {
return [ this[0], get_mangled(name) ];
return get_define(name) || [ this[0], get_mangled(name) ];
},
"try": function(t, c, f) {
return [ this[0],
@@ -583,11 +600,18 @@ function boolean_expr(expr) {
};

function make_conditional(c, t, e) {
var make_real_conditional = function() {
if (c[0] == "unary-prefix" && c[1] == "!") {
return e ? [ "conditional", c[2], e, t ] : [ "binary", "||", c[2], t ];
return e ? [ "conditional", c[2], e, t ] : [ "binary", "||", c[2], t ];
} else {
return e ? [ "conditional", c, t, e ] : [ "binary", "&&", c, t ];
return e ? [ "conditional", c, t, e ] : [ "binary", "&&", c, t ];
}
};
// shortcut the conditional if the expression has a constant value
return when_constant(c, function(ast, val){
warn_unreachable(val ? e : t);
return (val ? t : e);
}, make_real_conditional);
};

function empty(b) {
@@ -676,6 +700,18 @@ var when_constant = (function(){
|| (boolean_expr(expr[2]) && boolean_expr(expr[3])))) {
expr[1] = expr[1].substr(0, 2);
}
else if (no && expr[0] == "binary"
&& (expr[1] == "||" || expr[1] == "&&")) {
// the whole expression is not constant but the lval may be...
try {
var lval = evaluate(expr[2]);
expr = ((expr[1] == "&&" && (lval ? expr[3] : lval)) ||
(expr[1] == "||" && (lval ? lval : expr[3])) ||
expr);
} catch(ex2) {
// IGNORE... lval is not constant
}
}
return no ? no.call(expr, expr) : null;
}
else throw ex;
@@ -751,9 +787,14 @@ function ast_squeeze(ast, options) {
};

function _lambda(name, args, body) {
return [ this[0], name, args, with_scope(body.scope, function(){
return tighten(MAP(body, walk), "lambda");
}) ];
var is_defun = this[0] == "defun";
body = with_scope(body.scope, function(){
var ret = tighten(MAP(body, walk), "lambda");
if (!is_defun && name && !HOP(scope.refs, name))
name = null;
return ret;
});
return [ this[0], name, args, body ];
};

// we get here for blocks that have been already transformed.
@@ -959,13 +1000,7 @@ function ast_squeeze(ast, options) {
return [ branch[0] ? walk(branch[0]) : null, block ];
}) ];
},
"function": function() {
var ret = _lambda.apply(this, arguments);
if (ret[1] && !HOP(scope.refs, ret[1])) {
ret[1] = null;
}
return ret;
},
"function": _lambda,
"defun": _lambda,
"block": function(body) {
if (body) return rmblock([ "block", tighten(MAP(body, walk)) ]);
@@ -1067,6 +1102,8 @@ function to_ascii(str) {
});
};

var SPLICE_NEEDS_BRACKETS = jsp.array_to_hash([ "if", "while", "do", "for", "for-in", "with" ]);

function gen_code(ast, options) {
options = defaults(options, {
indent_start : 0,
@@ -1197,6 +1234,19 @@ function gen_code(ast, options) {
return make_block_statements(statements)
.join(newline + newline);
},
"splice": function(statements) {
var parent = $stack[$stack.length - 2][0];
if (HOP(SPLICE_NEEDS_BRACKETS, parent)) {
// we need block brackets in this case
return make_block.apply(this, arguments);
} else {
return MAP(make_block_statements(statements, true),
function(line, i) {
// the first line is already indented
return i > 0 ? indent(line) : line;
}).join(newline);
}
},
"block": make_block,
"var": function(defs) {
return "var " + add_commas(MAP(defs, make_1vardef)) + ";";
@@ -1437,7 +1487,7 @@ function gen_code(ast, options) {
return add_spaces([ out, make_block(body) ]);
};

function make_block_statements(statements) {
function make_block_statements(statements, noindent) {
for (var a = [], last = statements.length - 1, i = 0; i <= last; ++i) {
var stat = statements[i];
var code = make(stat);
@@ -1455,7 +1505,7 @@ function gen_code(ast, options) {
a.push(code);
}
}
return MAP(a, indent);
return noindent ? a : MAP(a, indent);
};

function make_switch_block(body) {

0 comments on commit f4b5d3f

Please sign in to comment.
You can’t perform that action at this time.