Compare commits

...

18 Commits

Author SHA1 Message Date
Mihai Bazon
c6fa291571 v2.4.23 2015-05-20 17:48:30 +03:00
Mihai Bazon
bce4307e9e Treat \uFEFF as whitespace.
Fix #714
2015-05-20 16:17:46 +03:00
Mihai Bazon
96ad94ab41 v2.4.22 2015-05-18 13:58:25 +03:00
Mihai Bazon
a5b60217ce Fix compressing conditionals
Only transform foo() ? EXP(x) : EXP(y) into EXP(foo() ? x : y) if EXP has no
side effects.

Fix #710
2015-05-18 13:56:04 +03:00
Mihai Bazon
44fd6694eb fix again reserved props 2015-05-13 22:03:00 +03:00
Mihai Bazon
e48db3a8b6 Make reserved names take priority over the name cache 2015-05-07 15:01:16 +03:00
Mihai Bazon
e637bdaf4e Only drop the BOM when it's the first character.
Close #704
2015-05-05 10:11:38 +03:00
Mihai Bazon
d558abbdb7 v2.4.21 2015-05-04 19:14:42 +03:00
Mihai Bazon
4aed0830e5 Fix blank lines in the output.
The issue was more obvious when max_line_len has a small value, rather than
the default 32K characters.  A blank line showed up after most statements.
2015-05-04 17:55:42 +03:00
Mihai Bazon
d2dda34b2a Remove deprecated calls to utils.print/utils.error
Close #542, #641, #647
2015-05-04 15:07:16 +03:00
Mihai Bazon
c3a10c135e Avoid spurious brackets when dropping unused vars
Fix #702
2015-05-04 14:49:17 +03:00
Mihai Bazon
92e4340732 Fix parsing strings with literal DOS newlines
(should not set newline_before)

Fix #693
2015-04-23 12:08:19 +03:00
Mihai Bazon
7b22f2031f If name_cache is specified, do rename cached properties
(even if --mangle-props is not there)
2015-04-22 17:34:49 +03:00
Mihai Bazon
3b14582d6b Fix tests 2015-04-17 11:28:59 +03:00
Mihai Bazon
274e1b3dc7 Drop NaN -> 0/0 transformation.
Fix #687
2015-04-17 11:26:36 +03:00
Fábio Santos
de58b0289d Added expect_exact for testing the OutputStream
This works almost exactly like `expect`, except that you pass a literal string
of which the result is compared with the generated output.
2015-04-14 20:26:47 +02:00
XhmikosR
efea52a4f4 Normalize package.json.
* Specify the files to install in package.json
* Add missing properties
* Follow `npm init`'s scheme
2015-04-14 20:17:03 +02:00
Jordan Harband
763bd36b60 Test on latest node and io.js
Per 0262b4244c - if you're going to stop testing on 0.8, you should be testing on 0.12.

Also allow failures on unstable nodes and "older than two latest" `io.js` versions, and enable "sudo: false" which makes tests run faster.
2015-04-14 20:06:09 +02:00
13 changed files with 135 additions and 88 deletions

3
.gitignore vendored
View File

@@ -1,2 +1,3 @@
/node_modules/
/npm-debug.log
tmp/ tmp/
node_modules/

View File

@@ -1,2 +0,0 @@
test
.travis.yml

View File

@@ -1,5 +1,10 @@
language: node_js language: node_js
before_install: "npm install -g npm" before_install: "npm install -g npm"
node_js: node_js:
- "0.10" - "iojs"
- "0.12"
- "0.11" - "0.11"
- "0.10"
matrix:
fast_finish: true
sudo: false

View File

@@ -132,24 +132,24 @@ normalize(ARGS);
if (ARGS.noerr) { if (ARGS.noerr) {
UglifyJS.DefaultsError.croak = function(msg, defs) { UglifyJS.DefaultsError.croak = function(msg, defs) {
sys.error("WARN: " + msg); print_error("WARN: " + msg);
}; };
} }
if (ARGS.version || ARGS.V) { if (ARGS.version || ARGS.V) {
var json = require("../package.json"); var json = require("../package.json");
sys.puts(json.name + ' ' + json.version); print(json.name + ' ' + json.version);
process.exit(0); process.exit(0);
} }
if (ARGS.ast_help) { if (ARGS.ast_help) {
var desc = UglifyJS.describe_ast(); var desc = UglifyJS.describe_ast();
sys.puts(typeof desc == "string" ? desc : JSON.stringify(desc, null, 2)); print(typeof desc == "string" ? desc : JSON.stringify(desc, null, 2));
process.exit(0); process.exit(0);
} }
if (ARGS.h || ARGS.help) { if (ARGS.h || ARGS.help) {
sys.puts(yargs.help()); print(yargs.help());
process.exit(0); process.exit(0);
} }
@@ -221,7 +221,7 @@ if (ARGS.comments != null) {
try { try {
OUTPUT_OPTIONS.comments = new RegExp(ARGS.comments.substr(1, regex_pos - 1), ARGS.comments.substr(regex_pos + 1)); OUTPUT_OPTIONS.comments = new RegExp(ARGS.comments.substr(1, regex_pos - 1), ARGS.comments.substr(regex_pos + 1));
} catch (e) { } catch (e) {
sys.error("ERROR: Invalid --comments: " + e.message); print_error("ERROR: Invalid --comments: " + e.message);
} }
} else if (ARGS.comments == "all") { } else if (ARGS.comments == "all") {
OUTPUT_OPTIONS.comments = true; OUTPUT_OPTIONS.comments = true;
@@ -241,7 +241,7 @@ var files = ARGS._.slice();
if (ARGS.self) { if (ARGS.self) {
if (files.length > 0) { if (files.length > 0) {
sys.error("WARN: Ignoring input files since --self was passed"); print_error("WARN: Ignoring input files since --self was passed");
} }
files = UglifyJS.FILES; files = UglifyJS.FILES;
if (!ARGS.wrap) ARGS.wrap = "UglifyJS"; if (!ARGS.wrap) ARGS.wrap = "UglifyJS";
@@ -253,7 +253,7 @@ var ORIG_MAP = ARGS.in_source_map;
if (ORIG_MAP) { if (ORIG_MAP) {
ORIG_MAP = JSON.parse(fs.readFileSync(ORIG_MAP)); ORIG_MAP = JSON.parse(fs.readFileSync(ORIG_MAP));
if (files.length == 0) { if (files.length == 0) {
sys.error("INFO: Using file from the input source map: " + ORIG_MAP.file); print_error("INFO: Using file from the input source map: " + ORIG_MAP.file);
files = [ ORIG_MAP.file ]; files = [ ORIG_MAP.file ];
} }
if (ARGS.source_map_root == null) { if (ARGS.source_map_root == null) {
@@ -266,12 +266,12 @@ if (files.length == 0) {
} }
if (files.indexOf("-") >= 0 && ARGS.source_map) { if (files.indexOf("-") >= 0 && ARGS.source_map) {
sys.error("ERROR: Source map doesn't work with input from STDIN"); print_error("ERROR: Source map doesn't work with input from STDIN");
process.exit(1); process.exit(1);
} }
if (files.filter(function(el){ return el == "-" }).length > 1) { if (files.filter(function(el){ return el == "-" }).length > 1) {
sys.error("ERROR: Can read a single file from STDIN (two or more dashes specified)"); print_error("ERROR: Can read a single file from STDIN (two or more dashes specified)");
process.exit(1); process.exit(1);
} }
@@ -294,9 +294,9 @@ try {
var compressor = COMPRESS && UglifyJS.Compressor(COMPRESS); var compressor = COMPRESS && UglifyJS.Compressor(COMPRESS);
} catch(ex) { } catch(ex) {
if (ex instanceof UglifyJS.DefaultsError) { if (ex instanceof UglifyJS.DefaultsError) {
sys.error(ex.msg); print_error(ex.msg);
sys.error("Supported options:"); print_error("Supported options:");
sys.error(sys.inspect(ex.defs)); print_error(sys.inspect(ex.defs));
process.exit(1); process.exit(1);
} }
} }
@@ -304,7 +304,7 @@ try {
async.eachLimit(files, 1, function (file, cb) { async.eachLimit(files, 1, function (file, cb) {
read_whole_file(file, function (err, code) { read_whole_file(file, function (err, code) {
if (err) { if (err) {
sys.error("ERROR: can't read file: " + file); print_error("ERROR: can't read file: " + file);
process.exit(1); process.exit(1);
} }
if (ARGS.p != null) { if (ARGS.p != null) {
@@ -341,9 +341,9 @@ async.eachLimit(files, 1, function (file, cb) {
}); });
} catch(ex) { } catch(ex) {
if (ex instanceof UglifyJS.JS_Parse_Error) { if (ex instanceof UglifyJS.JS_Parse_Error) {
sys.error("Parse error at " + file + ":" + ex.line + "," + ex.col); print_error("Parse error at " + file + ":" + ex.line + "," + ex.col);
sys.error(ex.message); print_error(ex.message);
sys.error(ex.stack); print_error(ex.stack);
process.exit(1); process.exit(1);
} }
throw ex; throw ex;
@@ -372,12 +372,13 @@ async.eachLimit(files, 1, function (file, cb) {
TOPLEVEL = TOPLEVEL.wrap_enclose(arg_parameter_list); TOPLEVEL = TOPLEVEL.wrap_enclose(arg_parameter_list);
} }
if (ARGS.mangle_props) (function(){ if (ARGS.mangle_props || ARGS.name_cache) (function(){
var reserved = RESERVED ? RESERVED.props : null; var reserved = RESERVED ? RESERVED.props : null;
var cache = readNameCache("props"); var cache = readNameCache("props");
TOPLEVEL = UglifyJS.mangle_properties(TOPLEVEL, { TOPLEVEL = UglifyJS.mangle_properties(TOPLEVEL, {
reserved: reserved, reserved : reserved,
cache: cache cache : cache,
only_cache : !ARGS.mangle_props
}); });
writeNameCache("props", cache); writeNameCache("props", cache);
})(); })();
@@ -443,15 +444,15 @@ async.eachLimit(files, 1, function (file, cb) {
if (OUTPUT_FILE) { if (OUTPUT_FILE) {
fs.writeFileSync(OUTPUT_FILE, output, "utf8"); fs.writeFileSync(OUTPUT_FILE, output, "utf8");
} else { } else {
sys.print(output); print(output);
} }
if (ARGS.stats) { if (ARGS.stats) {
sys.error(UglifyJS.string_template("Timing information (compressed {count} files):", { print_error(UglifyJS.string_template("Timing information (compressed {count} files):", {
count: files.length count: files.length
})); }));
for (var i in STATS) if (STATS.hasOwnProperty(i)) { for (var i in STATS) if (STATS.hasOwnProperty(i)) {
sys.error(UglifyJS.string_template("- {name}: {time}s", { print_error(UglifyJS.string_template("- {name}: {time}s", {
name: i, name: i,
time: (STATS[i] / 1000).toFixed(3) time: (STATS[i] / 1000).toFixed(3)
})); }));
@@ -478,7 +479,7 @@ function getOptions(x, constants) {
ast = UglifyJS.parse(x, { expression: true }); ast = UglifyJS.parse(x, { expression: true });
} catch(ex) { } catch(ex) {
if (ex instanceof UglifyJS.JS_Parse_Error) { if (ex instanceof UglifyJS.JS_Parse_Error) {
sys.error("Error parsing arguments in: " + x); print_error("Error parsing arguments in: " + x);
process.exit(1); process.exit(1);
} }
} }
@@ -497,8 +498,8 @@ function getOptions(x, constants) {
ret[name] = true; ret[name] = true;
return true; // no descend return true; // no descend
} }
sys.error(node.TYPE) print_error(node.TYPE)
sys.error("Error parsing arguments in: " + x); print_error("Error parsing arguments in: " + x);
process.exit(1); process.exit(1);
})); }));
} }
@@ -530,3 +531,11 @@ function time_it(name, cont) {
} }
return ret; return ret;
} }
function print_error(msg) {
console.error("%s", msg);
}
function print(txt) {
console.log("%s", txt);
}

View File

@@ -1168,12 +1168,12 @@ merge(Compressor.prototype, {
return make_node(AST_EmptyStatement, node); return make_node(AST_EmptyStatement, node);
} }
if (def.length == 0) { if (def.length == 0) {
return side_effects; return in_list ? MAP.splice(side_effects.body) : side_effects;
} }
node.definitions = def; node.definitions = def;
if (side_effects) { if (side_effects) {
side_effects.body.unshift(node); side_effects.body.unshift(node);
node = side_effects; return in_list ? MAP.splice(side_effects.body) : side_effects;
} }
return node; return node;
} }
@@ -2272,14 +2272,6 @@ merge(Compressor.prototype, {
}); });
}); });
OPT(AST_NaN, function (self, compressor) {
return make_node(AST_Binary, self, {
operator : '/',
left : make_node(AST_Number, self, {value: 0}),
right : make_node(AST_Number, self, {value: 0})
});
});
OPT(AST_Undefined, function(self, compressor){ OPT(AST_Undefined, function(self, compressor){
if (compressor.option("unsafe")) { if (compressor.option("unsafe")) {
var scope = compressor.find_parent(AST_Scope); var scope = compressor.find_parent(AST_Scope);
@@ -2364,6 +2356,7 @@ merge(Compressor.prototype, {
if (consequent instanceof AST_Call if (consequent instanceof AST_Call
&& alternative.TYPE === consequent.TYPE && alternative.TYPE === consequent.TYPE
&& consequent.args.length == alternative.args.length && consequent.args.length == alternative.args.length
&& !consequent.expression.has_side_effects(compressor)
&& consequent.expression.equivalent_to(alternative.expression)) { && consequent.expression.equivalent_to(alternative.expression)) {
if (consequent.args.length == 0) { if (consequent.args.length == 0) {
return make_node(AST_Seq, self, { return make_node(AST_Seq, self, {

View File

@@ -176,7 +176,6 @@ function OutputStream(options) {
might_need_space = false; might_need_space = false;
} }
might_need_semicolon = false; might_need_semicolon = false;
maybe_newline();
} }
if (!options.beautify && options.preserve_line && stack[stack.length - 1]) { if (!options.beautify && options.preserve_line && stack[stack.length - 1]) {

View File

@@ -108,7 +108,7 @@ var OPERATORS = makePredicate([
"||" "||"
]); ]);
var WHITESPACE_CHARS = makePredicate(characters(" \u00a0\n\r\t\f\u000b\u200b\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000")); var WHITESPACE_CHARS = makePredicate(characters(" \u00a0\n\r\t\f\u000b\u200b\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000\uFEFF"));
var PUNC_BEFORE_EXPRESSION = makePredicate(characters("[{(,.;:")); var PUNC_BEFORE_EXPRESSION = makePredicate(characters("[{(,.;:"));
@@ -213,7 +213,7 @@ var EX_EOF = {};
function tokenizer($TEXT, filename, html5_comments) { function tokenizer($TEXT, filename, html5_comments) {
var S = { var S = {
text : $TEXT.replace(/\uFEFF/g, ''), text : $TEXT,
filename : filename, filename : filename,
pos : 0, pos : 0,
tokpos : 0, tokpos : 0,
@@ -354,8 +354,13 @@ function tokenizer($TEXT, filename, html5_comments) {
case 120 : return String.fromCharCode(hex_bytes(2)); // \x case 120 : return String.fromCharCode(hex_bytes(2)); // \x
case 117 : return String.fromCharCode(hex_bytes(4)); // \u case 117 : return String.fromCharCode(hex_bytes(4)); // \u
case 10 : return ""; // newline case 10 : return ""; // newline
default : return ch; case 13 : // \r
if (peek() == "\n") { // DOS newline
next(true, in_string);
return "";
}
} }
return ch;
}; };
function hex_bytes(n) { function hex_bytes(n) {
@@ -372,7 +377,7 @@ function tokenizer($TEXT, filename, html5_comments) {
var read_string = with_eof_error("Unterminated string constant", function(quote_char){ var read_string = with_eof_error("Unterminated string constant", function(quote_char){
var quote = next(), ret = ""; var quote = next(), ret = "";
for (;;) { for (;;) {
var ch = next(true); var ch = next(true, true);
if (ch == "\\") { if (ch == "\\") {
// read OctalEscapeSequence (XXX: deprecated if "strict mode") // read OctalEscapeSequence (XXX: deprecated if "strict mode")
// https://github.com/mishoo/UglifyJS/issues/178 // https://github.com/mishoo/UglifyJS/issues/178

View File

@@ -63,7 +63,8 @@ function find_builtins() {
function mangle_properties(ast, options) { function mangle_properties(ast, options) {
options = defaults(options, { options = defaults(options, {
reserved : null, reserved : null,
cache : null cache : null,
only_cache : false
}); });
var reserved = options.reserved; var reserved = options.reserved;
@@ -140,11 +141,15 @@ function mangle_properties(ast, options) {
function can_mangle(name) { function can_mangle(name) {
if (reserved.indexOf(name) >= 0) return false; if (reserved.indexOf(name) >= 0) return false;
if (options.only_cache) {
return cache.props.has(name);
}
if (/^[0-9.]+$/.test(name)) return false; if (/^[0-9.]+$/.test(name)) return false;
return true; return true;
} }
function should_mangle(name) { function should_mangle(name) {
if (reserved.indexOf(name) >= 0) return false;
return cache.props.has(name) return cache.props.has(name)
|| names_to_mangle.indexOf(name) >= 0; || names_to_mangle.indexOf(name) >= 0;
} }

View File

@@ -1,37 +1,51 @@
{ {
"name": "uglify-js", "name": "uglify-js",
"description": "JavaScript parser, mangler/compressor and beautifier toolkit", "description": "JavaScript parser, mangler/compressor and beautifier toolkit",
"homepage": "http://lisperator.net/uglifyjs", "homepage": "http://lisperator.net/uglifyjs",
"main": "tools/node.js", "author": "Mihai Bazon <mihai.bazon@gmail.com> (http://lisperator.net/)",
"version": "2.4.20", "license": "BSD",
"engines": { "node" : ">=0.4.0" }, "version": "2.4.23",
"maintainers": [{ "engines": {
"name": "Mihai Bazon", "node": ">=0.4.0"
"email": "mihai.bazon@gmail.com", },
"web": "http://lisperator.net/" "maintainers": [
}], "Mihai Bazon <mihai.bazon@gmail.com> (http://lisperator.net/)"
"repository": { ],
"type": "git", "repository": {
"url": "https://github.com/mishoo/UglifyJS2.git" "type": "git",
}, "url": "https://github.com/mishoo/UglifyJS2.git"
"dependencies": { },
"async" : "~0.2.6", "bugs": {
"source-map" : "0.1.34", "url": "https://github.com/mishoo/UglifyJS2/issues"
"yargs": "~3.5.4", },
"uglify-to-browserify": "~1.0.0" "main": "tools/node.js",
}, "bin": {
"devDependencies": { "uglifyjs": "bin/uglifyjs"
"acorn": "~0.6.0", },
"escodegen": "~1.3.3", "files": [
"esfuzz": "~0.3.1", "bin",
"estraverse": "~1.5.1" "lib",
}, "tools",
"browserify": { "LICENSE"
"transform": [ "uglify-to-browserify" ] ],
}, "dependencies": {
"bin": { "async": "~0.2.6",
"uglifyjs" : "bin/uglifyjs" "source-map": "0.1.34",
}, "uglify-to-browserify": "~1.0.0",
"license": "BSD", "yargs": "~3.5.4"
"scripts": {"test": "node test/run-tests.js"} },
"devDependencies": {
"acorn": "~0.6.0",
"escodegen": "~1.3.3",
"esfuzz": "~0.3.1",
"estraverse": "~1.5.1"
},
"browserify": {
"transform": [
"uglify-to-browserify"
]
},
"scripts": {
"test": "node test/run-tests.js"
}
} }

View File

@@ -153,6 +153,7 @@ cond_1: {
conditionals: true conditionals: true
}; };
input: { input: {
var do_something; // if undeclared it's assumed to have side-effects
if (some_condition()) { if (some_condition()) {
do_something(x); do_something(x);
} else { } else {
@@ -160,6 +161,7 @@ cond_1: {
} }
} }
expect: { expect: {
var do_something;
do_something(some_condition() ? x : y); do_something(some_condition() ? x : y);
} }
} }
@@ -169,7 +171,7 @@ cond_2: {
conditionals: true conditionals: true
}; };
input: { input: {
var x; var x, FooBar;
if (some_condition()) { if (some_condition()) {
x = new FooBar(1); x = new FooBar(1);
} else { } else {
@@ -177,7 +179,7 @@ cond_2: {
} }
} }
expect: { expect: {
var x; var x, FooBar;
x = new FooBar(some_condition() ? 1 : 2); x = new FooBar(some_condition() ? 1 : 2);
} }
} }
@@ -187,6 +189,7 @@ cond_3: {
conditionals: true conditionals: true
}; };
input: { input: {
var FooBar;
if (some_condition()) { if (some_condition()) {
new FooBar(1); new FooBar(1);
} else { } else {
@@ -194,6 +197,7 @@ cond_3: {
} }
} }
expect: { expect: {
var FooBar;
some_condition() ? new FooBar(1) : FooBar(2); some_condition() ? new FooBar(1) : FooBar(2);
} }
} }
@@ -203,6 +207,7 @@ cond_4: {
conditionals: true conditionals: true
}; };
input: { input: {
var do_something;
if (some_condition()) { if (some_condition()) {
do_something(); do_something();
} else { } else {
@@ -210,6 +215,7 @@ cond_4: {
} }
} }
expect: { expect: {
var do_something;
some_condition(), do_something(); some_condition(), do_something();
} }
} }

View File

@@ -6,7 +6,7 @@ NaN_and_Infinity_must_have_parens: {
} }
expect: { expect: {
(1/0).toString(); (1/0).toString();
(0/0).toString(); NaN.toString(); // transformation to 0/0 dropped
} }
} }

View File

@@ -84,7 +84,12 @@ function run_compress_tests() {
warnings: false warnings: false
}); });
var cmp = new U.Compressor(options, true); var cmp = new U.Compressor(options, true);
var expect = make_code(as_toplevel(test.expect), false); var expect;
if (test.expect) {
expect = make_code(as_toplevel(test.expect), false);
} else {
expect = test.expect_exact;
}
var input = as_toplevel(test.input); var input = as_toplevel(test.input);
var input_code = make_code(test.input); var input_code = make_code(test.input);
var output = input.transform(cmp); var output = input.transform(cmp);
@@ -150,7 +155,7 @@ function parse_test(file) {
} }
if (node instanceof U.AST_LabeledStatement) { if (node instanceof U.AST_LabeledStatement) {
assert.ok( assert.ok(
node.label.name == "input" || node.label.name == "expect", node.label.name == "input" || node.label.name == "expect" || node.label.name == "expect_exact",
tmpl("Unsupported label {name} [{line},{col}]", { tmpl("Unsupported label {name} [{line},{col}]", {
name: node.label.name, name: node.label.name,
line: node.label.start.line, line: node.label.start.line,
@@ -162,7 +167,16 @@ function parse_test(file) {
if (stat.body.length == 1) stat = stat.body[0]; if (stat.body.length == 1) stat = stat.body[0];
else if (stat.body.length == 0) stat = new U.AST_EmptyStatement(); else if (stat.body.length == 0) stat = new U.AST_EmptyStatement();
} }
test[node.label.name] = stat; if (node.label.name === "expect_exact") {
if (!(stat.TYPE === "SimpleStatement" && stat.body.TYPE === "String")) {
throw new Error(
"The value of the expect_exact clause should be a string, " +
"like `expect_exact: \"some.exact.javascript;\"`");
}
test[node.label.name] = stat.body.start.value
} else {
test[node.label.name] = stat;
}
return true; return true;
} }
}); });

View File

@@ -1,10 +1,8 @@
var path = require("path"); var path = require("path");
var fs = require("fs"); var fs = require("fs");
var vm = require("vm"); var vm = require("vm");
var sys = require("util");
var UglifyJS = vm.createContext({ var UglifyJS = vm.createContext({
sys : sys,
console : console, console : console,
process : process, process : process,
Buffer : Buffer, Buffer : Buffer,
@@ -19,7 +17,7 @@ function load_global(file) {
} catch(ex) { } catch(ex) {
// XXX: in case of a syntax error, the message is kinda // XXX: in case of a syntax error, the message is kinda
// useless. (no location information). // useless. (no location information).
sys.debug("ERROR in file: " + file + " / " + ex); console.log("ERROR in file: " + file + " / " + ex);
process.exit(1); process.exit(1);
} }
}; };
@@ -42,7 +40,7 @@ var FILES = exports.FILES = [
FILES.forEach(load_global); FILES.forEach(load_global);
UglifyJS.AST_Node.warn_function = function(txt) { UglifyJS.AST_Node.warn_function = function(txt) {
sys.error("WARN: " + txt); console.error("WARN: %s", txt);
}; };
// XXX: perhaps we shouldn't export everything but heck, I'm lazy. // XXX: perhaps we shouldn't export everything but heck, I'm lazy.