From 763bd36b604c80ecbf7387bac97cb366e54aaa1f Mon Sep 17 00:00:00 2001 From: Jordan Harband Date: Sat, 11 Apr 2015 15:35:18 -0700 Subject: [PATCH 01/18] Test on latest `node` and `io.js` Per https://github.com/mishoo/UglifyJS2/commit/0262b4244c13b3ef148bf096874847aea84b93e5 - 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. --- .travis.yml | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 82460de5..4e046b8f 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,5 +1,10 @@ language: node_js before_install: "npm install -g npm" node_js: - - "0.10" + - "iojs" + - "0.12" - "0.11" + - "0.10" +matrix: + fast_finish: true +sudo: false From efea52a4f495ec921cb05d4ce09693520b657257 Mon Sep 17 00:00:00 2001 From: XhmikosR Date: Tue, 14 Apr 2015 18:29:14 +0300 Subject: [PATCH 02/18] Normalize package.json. * Specify the files to install in package.json * Add missing properties * Follow `npm init`'s scheme --- .gitignore | 3 +- .npmignore | 2 -- package.json | 80 ++++++++++++++++++++++++++++++---------------------- 3 files changed, 49 insertions(+), 36 deletions(-) delete mode 100644 .npmignore diff --git a/.gitignore b/.gitignore index 94fceeb2..6000c6c3 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ +/node_modules/ +/npm-debug.log tmp/ -node_modules/ diff --git a/.npmignore b/.npmignore deleted file mode 100644 index efab07fb..00000000 --- a/.npmignore +++ /dev/null @@ -1,2 +0,0 @@ -test -.travis.yml diff --git a/package.json b/package.json index aaa4359d..64e37c41 100644 --- a/package.json +++ b/package.json @@ -1,37 +1,51 @@ { "name": "uglify-js", "description": "JavaScript parser, mangler/compressor and beautifier toolkit", - "homepage": "http://lisperator.net/uglifyjs", - "main": "tools/node.js", - "version": "2.4.20", - "engines": { "node" : ">=0.4.0" }, - "maintainers": [{ - "name": "Mihai Bazon", - "email": "mihai.bazon@gmail.com", - "web": "http://lisperator.net/" - }], - "repository": { - "type": "git", - "url": "https://github.com/mishoo/UglifyJS2.git" - }, - "dependencies": { - "async" : "~0.2.6", - "source-map" : "0.1.34", - "yargs": "~3.5.4", - "uglify-to-browserify": "~1.0.0" - }, - "devDependencies": { - "acorn": "~0.6.0", - "escodegen": "~1.3.3", - "esfuzz": "~0.3.1", - "estraverse": "~1.5.1" - }, - "browserify": { - "transform": [ "uglify-to-browserify" ] - }, - "bin": { - "uglifyjs" : "bin/uglifyjs" - }, - "license": "BSD", - "scripts": {"test": "node test/run-tests.js"} + "homepage": "http://lisperator.net/uglifyjs", + "author": "Mihai Bazon (http://lisperator.net/)", + "license": "BSD", + "version": "2.4.20", + "engines": { + "node": ">=0.4.0" + }, + "maintainers": [ + "Mihai Bazon (http://lisperator.net/)" + ], + "repository": { + "type": "git", + "url": "https://github.com/mishoo/UglifyJS2.git" + }, + "bugs": { + "url": "https://github.com/mishoo/UglifyJS2/issues" + }, + "main": "tools/node.js", + "bin": { + "uglifyjs": "bin/uglifyjs" + }, + "files": [ + "bin", + "lib", + "tools", + "LICENSE" + ], + "dependencies": { + "async": "~0.2.6", + "source-map": "0.1.34", + "uglify-to-browserify": "~1.0.0", + "yargs": "~3.5.4" + }, + "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" + } } From de58b0289d8858b60f5f9aa6e5548fae39109d06 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?F=C3=A1bio=20Santos?= Date: Sun, 12 Apr 2015 14:51:26 +0100 Subject: [PATCH 03/18] 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. --- test/run-tests.js | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/test/run-tests.js b/test/run-tests.js index 94bf6ad9..215f6af8 100755 --- a/test/run-tests.js +++ b/test/run-tests.js @@ -84,7 +84,12 @@ function run_compress_tests() { warnings: false }); 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_code = make_code(test.input); var output = input.transform(cmp); @@ -150,7 +155,7 @@ function parse_test(file) { } if (node instanceof U.AST_LabeledStatement) { 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}]", { name: node.label.name, line: node.label.start.line, @@ -162,7 +167,16 @@ function parse_test(file) { if (stat.body.length == 1) stat = stat.body[0]; 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; } }); From 274e1b3dc75ff72c85f803f642e3bb51a0d15953 Mon Sep 17 00:00:00 2001 From: Mihai Bazon Date: Fri, 17 Apr 2015 11:25:19 +0300 Subject: [PATCH 04/18] Drop NaN -> 0/0 transformation. Fix #687 --- lib/compress.js | 8 -------- 1 file changed, 8 deletions(-) diff --git a/lib/compress.js b/lib/compress.js index fa89c322..7d20a4ea 100644 --- a/lib/compress.js +++ b/lib/compress.js @@ -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){ if (compressor.option("unsafe")) { var scope = compressor.find_parent(AST_Scope); From 3b14582d6b8a93e6f459d71f630a67b489e47dd0 Mon Sep 17 00:00:00 2001 From: Mihai Bazon Date: Fri, 17 Apr 2015 11:28:59 +0300 Subject: [PATCH 05/18] Fix tests --- test/compress/issue-597.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/compress/issue-597.js b/test/compress/issue-597.js index 3c651a4c..f243223a 100644 --- a/test/compress/issue-597.js +++ b/test/compress/issue-597.js @@ -6,7 +6,7 @@ NaN_and_Infinity_must_have_parens: { } expect: { (1/0).toString(); - (0/0).toString(); + NaN.toString(); // transformation to 0/0 dropped } } From 7b22f2031fdbb778dac1968449b950290f6d9216 Mon Sep 17 00:00:00 2001 From: Mihai Bazon Date: Wed, 22 Apr 2015 17:34:49 +0300 Subject: [PATCH 06/18] If name_cache is specified, do rename cached properties (even if --mangle-props is not there) --- bin/uglifyjs | 7 ++++--- lib/propmangle.js | 6 +++++- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/bin/uglifyjs b/bin/uglifyjs index df7b7832..67db2979 100755 --- a/bin/uglifyjs +++ b/bin/uglifyjs @@ -372,12 +372,13 @@ async.eachLimit(files, 1, function (file, cb) { 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 cache = readNameCache("props"); TOPLEVEL = UglifyJS.mangle_properties(TOPLEVEL, { - reserved: reserved, - cache: cache + reserved : reserved, + cache : cache, + only_cache : !ARGS.mangle_props }); writeNameCache("props", cache); })(); diff --git a/lib/propmangle.js b/lib/propmangle.js index 46fb7521..8f291d64 100644 --- a/lib/propmangle.js +++ b/lib/propmangle.js @@ -63,7 +63,8 @@ function find_builtins() { function mangle_properties(ast, options) { options = defaults(options, { reserved : null, - cache : null + cache : null, + only_cache : false }); var reserved = options.reserved; @@ -139,6 +140,9 @@ function mangle_properties(ast, options) { // only function declarations after this line function can_mangle(name) { + if (options.only_cache) { + return cache.props.has(name); + } if (reserved.indexOf(name) >= 0) return false; if (/^[0-9.]+$/.test(name)) return false; return true; From 92e4340732ba9b182e339896ffda0e13ef98e40a Mon Sep 17 00:00:00 2001 From: Mihai Bazon Date: Thu, 23 Apr 2015 12:08:19 +0300 Subject: [PATCH 07/18] Fix parsing strings with literal DOS newlines (should not set newline_before) Fix #693 --- lib/parse.js | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/lib/parse.js b/lib/parse.js index 95a9f776..53aaabd6 100644 --- a/lib/parse.js +++ b/lib/parse.js @@ -354,8 +354,13 @@ function tokenizer($TEXT, filename, html5_comments) { case 120 : return String.fromCharCode(hex_bytes(2)); // \x case 117 : return String.fromCharCode(hex_bytes(4)); // \u 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) { @@ -372,7 +377,7 @@ function tokenizer($TEXT, filename, html5_comments) { var read_string = with_eof_error("Unterminated string constant", function(quote_char){ var quote = next(), ret = ""; for (;;) { - var ch = next(true); + var ch = next(true, true); if (ch == "\\") { // read OctalEscapeSequence (XXX: deprecated if "strict mode") // https://github.com/mishoo/UglifyJS/issues/178 From c3a10c135eac6fff360ad109f30245459b0b7e13 Mon Sep 17 00:00:00 2001 From: Mihai Bazon Date: Mon, 4 May 2015 14:49:17 +0300 Subject: [PATCH 08/18] Avoid spurious brackets when dropping unused vars Fix #702 --- lib/compress.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/compress.js b/lib/compress.js index 7d20a4ea..944db1d2 100644 --- a/lib/compress.js +++ b/lib/compress.js @@ -1168,12 +1168,12 @@ merge(Compressor.prototype, { return make_node(AST_EmptyStatement, node); } if (def.length == 0) { - return side_effects; + return in_list ? MAP.splice(side_effects.body) : side_effects; } node.definitions = def; if (side_effects) { side_effects.body.unshift(node); - node = side_effects; + return in_list ? MAP.splice(side_effects.body) : side_effects; } return node; } From d2dda34b2a8de310f26a26e58ed28275ba5ecc7f Mon Sep 17 00:00:00 2001 From: Mihai Bazon Date: Mon, 4 May 2015 15:07:16 +0300 Subject: [PATCH 09/18] Remove deprecated calls to utils.print/utils.error Close #542, #641, #647 --- bin/uglifyjs | 52 +++++++++++++++++++++++++++++---------------------- tools/node.js | 6 ++---- 2 files changed, 32 insertions(+), 26 deletions(-) diff --git a/bin/uglifyjs b/bin/uglifyjs index 67db2979..8851660f 100755 --- a/bin/uglifyjs +++ b/bin/uglifyjs @@ -132,24 +132,24 @@ normalize(ARGS); if (ARGS.noerr) { UglifyJS.DefaultsError.croak = function(msg, defs) { - sys.error("WARN: " + msg); + print_error("WARN: " + msg); }; } if (ARGS.version || ARGS.V) { var json = require("../package.json"); - sys.puts(json.name + ' ' + json.version); + print(json.name + ' ' + json.version); process.exit(0); } if (ARGS.ast_help) { 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); } if (ARGS.h || ARGS.help) { - sys.puts(yargs.help()); + print(yargs.help()); process.exit(0); } @@ -221,7 +221,7 @@ if (ARGS.comments != null) { try { OUTPUT_OPTIONS.comments = new RegExp(ARGS.comments.substr(1, regex_pos - 1), ARGS.comments.substr(regex_pos + 1)); } catch (e) { - sys.error("ERROR: Invalid --comments: " + e.message); + print_error("ERROR: Invalid --comments: " + e.message); } } else if (ARGS.comments == "all") { OUTPUT_OPTIONS.comments = true; @@ -241,7 +241,7 @@ var files = ARGS._.slice(); if (ARGS.self) { 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; if (!ARGS.wrap) ARGS.wrap = "UglifyJS"; @@ -253,7 +253,7 @@ var ORIG_MAP = ARGS.in_source_map; if (ORIG_MAP) { ORIG_MAP = JSON.parse(fs.readFileSync(ORIG_MAP)); 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 ]; } if (ARGS.source_map_root == null) { @@ -266,12 +266,12 @@ if (files.length == 0) { } 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); } 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); } @@ -294,9 +294,9 @@ try { var compressor = COMPRESS && UglifyJS.Compressor(COMPRESS); } catch(ex) { if (ex instanceof UglifyJS.DefaultsError) { - sys.error(ex.msg); - sys.error("Supported options:"); - sys.error(sys.inspect(ex.defs)); + print_error(ex.msg); + print_error("Supported options:"); + print_error(sys.inspect(ex.defs)); process.exit(1); } } @@ -304,7 +304,7 @@ try { async.eachLimit(files, 1, function (file, cb) { read_whole_file(file, function (err, code) { if (err) { - sys.error("ERROR: can't read file: " + file); + print_error("ERROR: can't read file: " + file); process.exit(1); } if (ARGS.p != null) { @@ -341,9 +341,9 @@ async.eachLimit(files, 1, function (file, cb) { }); } catch(ex) { if (ex instanceof UglifyJS.JS_Parse_Error) { - sys.error("Parse error at " + file + ":" + ex.line + "," + ex.col); - sys.error(ex.message); - sys.error(ex.stack); + print_error("Parse error at " + file + ":" + ex.line + "," + ex.col); + print_error(ex.message); + print_error(ex.stack); process.exit(1); } throw ex; @@ -444,15 +444,15 @@ async.eachLimit(files, 1, function (file, cb) { if (OUTPUT_FILE) { fs.writeFileSync(OUTPUT_FILE, output, "utf8"); } else { - sys.print(output); + print(output); } 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 })); 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, time: (STATS[i] / 1000).toFixed(3) })); @@ -479,7 +479,7 @@ function getOptions(x, constants) { ast = UglifyJS.parse(x, { expression: true }); } catch(ex) { if (ex instanceof UglifyJS.JS_Parse_Error) { - sys.error("Error parsing arguments in: " + x); + print_error("Error parsing arguments in: " + x); process.exit(1); } } @@ -498,8 +498,8 @@ function getOptions(x, constants) { ret[name] = true; return true; // no descend } - sys.error(node.TYPE) - sys.error("Error parsing arguments in: " + x); + print_error(node.TYPE) + print_error("Error parsing arguments in: " + x); process.exit(1); })); } @@ -531,3 +531,11 @@ function time_it(name, cont) { } return ret; } + +function print_error(msg) { + console.error("%s", msg); +} + +function print(txt) { + console.log("%s", txt); +} diff --git a/tools/node.js b/tools/node.js index 054a05c0..cbe49e39 100644 --- a/tools/node.js +++ b/tools/node.js @@ -1,10 +1,8 @@ var path = require("path"); var fs = require("fs"); var vm = require("vm"); -var sys = require("util"); var UglifyJS = vm.createContext({ - sys : sys, console : console, process : process, Buffer : Buffer, @@ -19,7 +17,7 @@ function load_global(file) { } catch(ex) { // XXX: in case of a syntax error, the message is kinda // useless. (no location information). - sys.debug("ERROR in file: " + file + " / " + ex); + console.log("ERROR in file: " + file + " / " + ex); process.exit(1); } }; @@ -42,7 +40,7 @@ var FILES = exports.FILES = [ FILES.forEach(load_global); 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. From 4aed0830e5c1e5dabf05c0db4366c965fe952ced Mon Sep 17 00:00:00 2001 From: Mihai Bazon Date: Mon, 4 May 2015 17:55:42 +0300 Subject: [PATCH 10/18] 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. --- lib/output.js | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/output.js b/lib/output.js index 135636b9..1d67b1b9 100644 --- a/lib/output.js +++ b/lib/output.js @@ -176,7 +176,6 @@ function OutputStream(options) { might_need_space = false; } might_need_semicolon = false; - maybe_newline(); } if (!options.beautify && options.preserve_line && stack[stack.length - 1]) { From d558abbdb76a69d99d3ebde6c8903e47639b3f68 Mon Sep 17 00:00:00 2001 From: Mihai Bazon Date: Mon, 4 May 2015 19:14:42 +0300 Subject: [PATCH 11/18] v2.4.21 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 64e37c41..d9340b9a 100644 --- a/package.json +++ b/package.json @@ -4,7 +4,7 @@ "homepage": "http://lisperator.net/uglifyjs", "author": "Mihai Bazon (http://lisperator.net/)", "license": "BSD", - "version": "2.4.20", + "version": "2.4.21", "engines": { "node": ">=0.4.0" }, From e637bdaf4e95ce65c1021f7dda7d198054e99e83 Mon Sep 17 00:00:00 2001 From: Mihai Bazon Date: Tue, 5 May 2015 10:11:38 +0300 Subject: [PATCH 12/18] Only drop the BOM when it's the first character. Close #704 --- lib/parse.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/parse.js b/lib/parse.js index 53aaabd6..3cc2da51 100644 --- a/lib/parse.js +++ b/lib/parse.js @@ -213,7 +213,7 @@ var EX_EOF = {}; function tokenizer($TEXT, filename, html5_comments) { var S = { - text : $TEXT.replace(/\uFEFF/g, ''), + text : $TEXT.replace(/^\uFEFF/g, ''), filename : filename, pos : 0, tokpos : 0, From e48db3a8b6ce8bf06448224dbb3f6339f834ed98 Mon Sep 17 00:00:00 2001 From: Mihai Bazon Date: Thu, 7 May 2015 15:01:16 +0300 Subject: [PATCH 13/18] Make reserved names take priority over the name cache --- lib/propmangle.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/propmangle.js b/lib/propmangle.js index 8f291d64..d3e582d6 100644 --- a/lib/propmangle.js +++ b/lib/propmangle.js @@ -140,10 +140,10 @@ function mangle_properties(ast, options) { // only function declarations after this line function can_mangle(name) { + if (reserved.indexOf(name) >= 0) return false; if (options.only_cache) { return cache.props.has(name); } - if (reserved.indexOf(name) >= 0) return false; if (/^[0-9.]+$/.test(name)) return false; return true; } From 44fd6694ebf1def9974915b163cfc79114eb8e80 Mon Sep 17 00:00:00 2001 From: Mihai Bazon Date: Wed, 13 May 2015 22:03:00 +0300 Subject: [PATCH 14/18] fix again reserved props --- lib/propmangle.js | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/propmangle.js b/lib/propmangle.js index d3e582d6..0890eaa7 100644 --- a/lib/propmangle.js +++ b/lib/propmangle.js @@ -149,6 +149,7 @@ function mangle_properties(ast, options) { } function should_mangle(name) { + if (reserved.indexOf(name) >= 0) return false; return cache.props.has(name) || names_to_mangle.indexOf(name) >= 0; } From a5b60217cede3f214153e62087d32274aa0859e5 Mon Sep 17 00:00:00 2001 From: Mihai Bazon Date: Mon, 18 May 2015 13:56:04 +0300 Subject: [PATCH 15/18] Fix compressing conditionals Only transform foo() ? EXP(x) : EXP(y) into EXP(foo() ? x : y) if EXP has no side effects. Fix #710 --- lib/compress.js | 1 + test/compress/conditionals.js | 10 ++++++++-- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/lib/compress.js b/lib/compress.js index 944db1d2..530e7c2f 100644 --- a/lib/compress.js +++ b/lib/compress.js @@ -2356,6 +2356,7 @@ merge(Compressor.prototype, { if (consequent instanceof AST_Call && alternative.TYPE === consequent.TYPE && consequent.args.length == alternative.args.length + && !consequent.expression.has_side_effects(compressor) && consequent.expression.equivalent_to(alternative.expression)) { if (consequent.args.length == 0) { return make_node(AST_Seq, self, { diff --git a/test/compress/conditionals.js b/test/compress/conditionals.js index 299097be..1b961812 100644 --- a/test/compress/conditionals.js +++ b/test/compress/conditionals.js @@ -153,6 +153,7 @@ cond_1: { conditionals: true }; input: { + var do_something; // if undeclared it's assumed to have side-effects if (some_condition()) { do_something(x); } else { @@ -160,6 +161,7 @@ cond_1: { } } expect: { + var do_something; do_something(some_condition() ? x : y); } } @@ -169,7 +171,7 @@ cond_2: { conditionals: true }; input: { - var x; + var x, FooBar; if (some_condition()) { x = new FooBar(1); } else { @@ -177,7 +179,7 @@ cond_2: { } } expect: { - var x; + var x, FooBar; x = new FooBar(some_condition() ? 1 : 2); } } @@ -187,6 +189,7 @@ cond_3: { conditionals: true }; input: { + var FooBar; if (some_condition()) { new FooBar(1); } else { @@ -194,6 +197,7 @@ cond_3: { } } expect: { + var FooBar; some_condition() ? new FooBar(1) : FooBar(2); } } @@ -203,6 +207,7 @@ cond_4: { conditionals: true }; input: { + var do_something; if (some_condition()) { do_something(); } else { @@ -210,6 +215,7 @@ cond_4: { } } expect: { + var do_something; some_condition(), do_something(); } } From 96ad94ab419ede17a5c931a1dc86416ea0c9d2a8 Mon Sep 17 00:00:00 2001 From: Mihai Bazon Date: Mon, 18 May 2015 13:58:25 +0300 Subject: [PATCH 16/18] v2.4.22 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index d9340b9a..db960f3f 100644 --- a/package.json +++ b/package.json @@ -4,7 +4,7 @@ "homepage": "http://lisperator.net/uglifyjs", "author": "Mihai Bazon (http://lisperator.net/)", "license": "BSD", - "version": "2.4.21", + "version": "2.4.22", "engines": { "node": ">=0.4.0" }, From bce4307e9e1c22bcc00c83f9b51bb0bdb2f432b0 Mon Sep 17 00:00:00 2001 From: Mihai Bazon Date: Wed, 20 May 2015 16:17:46 +0300 Subject: [PATCH 17/18] Treat \uFEFF as whitespace. Fix #714 --- lib/parse.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/parse.js b/lib/parse.js index 3cc2da51..e65c4faa 100644 --- a/lib/parse.js +++ b/lib/parse.js @@ -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("[{(,.;:")); @@ -213,7 +213,7 @@ var EX_EOF = {}; function tokenizer($TEXT, filename, html5_comments) { var S = { - text : $TEXT.replace(/^\uFEFF/g, ''), + text : $TEXT, filename : filename, pos : 0, tokpos : 0, From c6fa2915715f0a1a2b1527c23388bd7de56284c4 Mon Sep 17 00:00:00 2001 From: Mihai Bazon Date: Wed, 20 May 2015 17:48:30 +0300 Subject: [PATCH 18/18] v2.4.23 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index db960f3f..27f8c857 100644 --- a/package.json +++ b/package.json @@ -4,7 +4,7 @@ "homepage": "http://lisperator.net/uglifyjs", "author": "Mihai Bazon (http://lisperator.net/)", "license": "BSD", - "version": "2.4.22", + "version": "2.4.23", "engines": { "node": ">=0.4.0" },