From 572b97b0bb48285497ffbffed9420468e1700956 Mon Sep 17 00:00:00 2001 From: Richard van Velzen Date: Sun, 3 Jul 2016 21:46:14 +0200 Subject: [PATCH 01/21] v2.7.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 3ac7b52b..cc0917ed 100644 --- a/package.json +++ b/package.json @@ -4,7 +4,7 @@ "homepage": "http://lisperator.net/uglifyjs", "author": "Mihai Bazon (http://lisperator.net/)", "license": "BSD-2-Clause", - "version": "2.6.4", + "version": "2.7.0", "engines": { "node": ">=0.8.0" }, From 2650182f47883aaaeddd731fffa0c4940d94cc36 Mon Sep 17 00:00:00 2001 From: Anthony Van de Gejuchte Date: Mon, 4 Jul 2016 00:51:09 +0200 Subject: [PATCH 02/21] Backport mocha with test from harmony --- test/mocha/with.js | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/test/mocha/with.js b/test/mocha/with.js index 2e758d1e..734e1e13 100644 --- a/test/mocha/with.js +++ b/test/mocha/with.js @@ -2,7 +2,7 @@ var assert = require("assert"); var uglify = require("../../"); describe("With", function() { - it ("Should throw syntaxError when using with statement in strict mode", function() { + it("Should throw syntaxError when using with statement in strict mode", function() { var code = '"use strict";\nthrow NotEarlyError;\nwith ({}) { }'; var test = function() { uglify.parse(code); @@ -13,4 +13,11 @@ describe("With", function() { } assert.throws(test, error); }); -}); \ No newline at end of file + it("Should set uses_with for scopes involving With statements", function() { + var ast = uglify.parse("with(e) {f(1, 2)}"); + ast.figure_out_scope(); + assert.equal(ast.uses_with, true); + assert.equal(ast.body[0].expression.scope.uses_with, true); + assert.equal(ast.body[0].body.body[0].body.expression.scope.uses_with, true); + }); +}); From 2d8af8947e3bf2daa51bdc199c504122563375d1 Mon Sep 17 00:00:00 2001 From: Anthony Van de Gejuchte Date: Mon, 4 Jul 2016 02:51:20 +0200 Subject: [PATCH 03/21] Fix error style for regex errors --- lib/parse.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/parse.js b/lib/parse.js index bfbd14d5..bd6f95f6 100644 --- a/lib/parse.js +++ b/lib/parse.js @@ -495,7 +495,7 @@ function tokenizer($TEXT, filename, html5_comments, shebang) { try { return token("regexp", new RegExp(regexp, mods)); } catch(e) { - parse_error(e.message); + parse_error("SyntaxError: " + e.message); } }); From eb63fece2f48be2be5ee1090d7bb94889a12fd80 Mon Sep 17 00:00:00 2001 From: kzc Date: Wed, 13 Jul 2016 11:44:28 -0400 Subject: [PATCH 04/21] Fix mangle with option keep_fnames=true for Safari. Fixes: #1202 --- lib/scope.js | 6 ++++- test/compress/issue-1202.js | 52 +++++++++++++++++++++++++++++++++++++ 2 files changed, 57 insertions(+), 1 deletion(-) create mode 100644 test/compress/issue-1202.js diff --git a/lib/scope.js b/lib/scope.js index 7ae87072..606a5a2f 100644 --- a/lib/scope.js +++ b/lib/scope.js @@ -314,9 +314,13 @@ AST_Function.DEFMETHOD("next_mangled", function(options, def){ // a function expression's argument cannot shadow the function expression's name var tricky_def = def.orig[0] instanceof AST_SymbolFunarg && this.name && this.name.definition(); + + // the function's mangled_name is null when keep_fnames is true + var tricky_name = tricky_def ? tricky_def.mangled_name || tricky_def.name : null; + while (true) { var name = AST_Lambda.prototype.next_mangled.call(this, options, def); - if (!(tricky_def && tricky_def.mangled_name == name)) + if (!tricky_name || tricky_name != name) return name; } }); diff --git a/test/compress/issue-1202.js b/test/compress/issue-1202.js new file mode 100644 index 00000000..136515fd --- /dev/null +++ b/test/compress/issue-1202.js @@ -0,0 +1,52 @@ +mangle_keep_fnames_false: { + options = { + keep_fnames : true, + keep_fargs : true, + } + mangle = { + keep_fnames : false, + } + input: { + "use strict"; + function total() { + return function n(a, b, c) { + return a + b + c; + }; + } + } + expect: { + "use strict"; + function total() { + return function t(n, r, u) { + return n + r + u; + }; + } + } +} + +mangle_keep_fnames_true: { + options = { + keep_fnames : true, + keep_fargs : true, + } + mangle = { + keep_fnames : true, + } + input: { + "use strict"; + function total() { + return function n(a, b, c) { + return a + b + c; + }; + } + } + expect: { + "use strict"; + function total() { + return function n(t, r, u) { + return t + r + u; + }; + } + } +} + From 7eb52d2837c9d77a389457ae84bfddd28f86cf27 Mon Sep 17 00:00:00 2001 From: Anthony Van de Gejuchte Date: Thu, 14 Jul 2016 18:43:50 +0200 Subject: [PATCH 05/21] Keep const in own scope while compressing - Fixes #1205 - Fix provided by @kzc --- lib/compress.js | 2 +- test/compress/loops.js | 44 +++++++++++++++++++++++++++++++++++++++++- 2 files changed, 44 insertions(+), 2 deletions(-) diff --git a/lib/compress.js b/lib/compress.js index f0f3d09b..fd839fa1 100644 --- a/lib/compress.js +++ b/lib/compress.js @@ -810,7 +810,7 @@ merge(Compressor.prototype, { CHANGED = true; } else if (stat instanceof AST_For - && prev instanceof AST_Definitions + && prev instanceof AST_Var && (!stat.init || stat.init.TYPE == prev.TYPE)) { CHANGED = true; a.pop(); diff --git a/test/compress/loops.js b/test/compress/loops.js index 91aa1c5f..78f618aa 100644 --- a/test/compress/loops.js +++ b/test/compress/loops.js @@ -144,4 +144,46 @@ parse_do_while_without_semicolon: { expect: { do x(); while (false);y(); } -} \ No newline at end of file +} + + +keep_collapse_const_in_own_block_scope: { + options = { + join_vars: true, + loops: true + } + input: { + var i=2; + const c=5; + while(i--) + console.log(i); + console.log(c); + } + expect: { + var i=2; + const c=5; + for(;i--;) + console.log(i); + console.log(c); + } +} + +keep_collapse_const_in_own_block_scope_2: { + options = { + join_vars: true, + loops: true + } + input: { + const c=5; + var i=2; // Moves to loop, while it did not in previous test + while(i--) + console.log(i); + console.log(c); + } + expect: { + const c=5; + for(var i=2;i--;) + console.log(i); + console.log(c); + } +} From 41a9329409ca0f1273b6ccdcc9770713f44ec55a Mon Sep 17 00:00:00 2001 From: Lauri Pokka Date: Tue, 5 Jul 2016 02:06:14 +0900 Subject: [PATCH 06/21] lib/sourcemap.js: Copy sourceContent from old souce-map to the new source-map. Should fix #882 --- lib/sourcemap.js | 10 ++++++++ test/mocha/input-sourcemaps.js | 43 ++++++++++++++++++++++++++++++++++ 2 files changed, 53 insertions(+) create mode 100644 test/mocha/input-sourcemaps.js diff --git a/lib/sourcemap.js b/lib/sourcemap.js index e5d7df60..3714027e 100644 --- a/lib/sourcemap.js +++ b/lib/sourcemap.js @@ -58,6 +58,16 @@ function SourceMap(options) { sourceRoot : options.root }); var orig_map = options.orig && new MOZ_SourceMap.SourceMapConsumer(options.orig); + + if (orig_map && Array.isArray(options.orig.sources)) { + options.orig.sources.forEach(function(source) { + var sourceContent = orig_map.sourceContentFor(source, true); + if (sourceContent) { + generator.setSourceContent(source, sourceContent); + } + }); + } + function add(source, gen_line, gen_col, orig_line, orig_col, name) { if (orig_map) { var info = orig_map.originalPositionFor({ diff --git a/test/mocha/input-sourcemaps.js b/test/mocha/input-sourcemaps.js new file mode 100644 index 00000000..30ee5b92 --- /dev/null +++ b/test/mocha/input-sourcemaps.js @@ -0,0 +1,43 @@ +var Uglify = require('../../'); +var assert = require("assert"); +var SourceMapConsumer = require("source-map").SourceMapConsumer; + +describe("input sourcemaps", function() { + var transpiled = '"use strict";\n\n' + + 'var foo = function foo(x) {\n return "foo " + x;\n};\n' + + 'console.log(foo("bar"));\n\n' + + '//# sourceMappingURL=bundle.js.map'; + + var transpilemap = { + "version": 3, + "sources": ["index.js"], + "names": [], + "mappings": ";;AAAA,IAAI,MAAM,SAAN,GAAM;AAAA,SAAK,SAAS,CAAd;AAAA,CAAV;AACA,QAAQ,GAAR,CAAY,IAAI,KAAJ,CAAZ", + "file": "bundle.js", + "sourcesContent": ["let foo = x => \"foo \" + x;\nconsole.log(foo(\"bar\"));"] + }; + + var result = Uglify.minify(transpiled, { + fromString: true, + inSourceMap: transpilemap, + outSourceMap: true + }); + var map = new SourceMapConsumer(result.map); + + it("Should copy over original sourcesContent", function() { + assert.equal(map.sourceContentFor("index.js"), transpilemap.sourcesContent[0]); + }); + + it("Final sourcemap should not have invalid mappings from inputSourceMap (issue #882) ", function() { + // The original source has only 2 lines, check that mappings don't have more lines + + var msg = "Mapping should not have higher line number than the original file had"; + map.eachMapping(function(mapping) { + assert.ok(mapping.originalLine <= 2, msg) + }); + + map.allGeneratedPositionsFor({source: "index.js", line: 1, column: 1}).forEach(function(pos) { + assert.ok(pos.line <= 2, msg); + }) + }); +}); From af37ecafe1c24e9fb06a371357d10a04446ff71e Mon Sep 17 00:00:00 2001 From: Yotam Spenser Date: Wed, 6 Jul 2016 13:02:07 +0300 Subject: [PATCH 07/21] Source map URL override from programmatic API --- README.md | 19 +++++++++++++++++++ tools/node.js | 6 ++++-- 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 3245d404..04b0799e 100644 --- a/README.md +++ b/README.md @@ -628,6 +628,14 @@ console.log(result.code); // minified output console.log(result.map); ``` +To generate a source map with the fromString option, you can also use an object: +```javascript +var result = UglifyJS.minify({"file1.js": "var a = function () {};"}, { + outSourceMap: "out.js.map", + fromString: true +}); +``` + Note that the source map is not saved in a file, it's just returned in `result.map`. The value passed for `outSourceMap` is only used to set the `file` attribute in the source map (see [the spec][sm-spec]). @@ -663,6 +671,17 @@ var result = UglifyJS.minify("compiled.js", { The `inSourceMap` is only used if you also request `outSourceMap` (it makes no sense otherwise). +To set the source map url, use the `sourceMapUrl` option. +If you're using the X-SourceMap header instead, you can just set the `sourceMapUrl` option to false. +Defaults to outSourceMap: + +```javascript +var result = UglifyJS.minify([ "file1.js" ], { + outSourceMap: "out.js.map", + sourceMapUrl: "localhost/out.js.map" +}); +``` + Other options: - `warnings` (default `false`) — pass `true` to display compressor warnings. diff --git a/tools/node.js b/tools/node.js index 2ee7df21..20ecb473 100644 --- a/tools/node.js +++ b/tools/node.js @@ -43,6 +43,7 @@ exports.minify = function(files, options) { outSourceMap : null, sourceRoot : null, inSourceMap : null, + sourceMapUrl : null, fromString : false, warnings : false, mangle : {}, @@ -136,8 +137,9 @@ exports.minify = function(files, options) { var stream = UglifyJS.OutputStream(output); toplevel.print(stream); - if (options.outSourceMap && "string" === typeof options.outSourceMap) { - stream += "\n//# sourceMappingURL=" + options.outSourceMap; + var mappingUrlPrefix = "\n//# sourceMappingURL="; + if (options.outSourceMap && typeof options.outSourceMap === "string" && options.sourceMapUrl !== false) { + stream += mappingUrlPrefix + (typeof options.sourceMapUrl === "string" ? options.sourceMapUrl : options.outSourceMap); } var source_map = output.source_map; From 9edbe93df5633bd13b1c001d066887e011ce767c Mon Sep 17 00:00:00 2001 From: homuler Date: Sat, 16 Jul 2016 22:03:36 +0900 Subject: [PATCH 08/21] Fix the document of keep_fnames option --- README.md | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 04b0799e..61a6000e 100644 --- a/README.md +++ b/README.md @@ -135,11 +135,11 @@ The available options are: --reserved-file File containing reserved names --reserve-domprops Make (most?) DOM properties reserved for --mangle-props - --mangle-props Mangle property names (default `0`). Set to + --mangle-props Mangle property names (default `0`). Set to `true` or `1` to mangle all property names. Set - to `unquoted` or `2` to only mangle unquoted + to `unquoted` or `2` to only mangle unquoted property names. Mode `2` also enables the - `keep_quoted_props` beautifier option to + `keep_quoted_props` beautifier option to preserve the quotes around property names and disables the `properties` compressor option to prevent rewriting quoted properties with dot @@ -378,8 +378,8 @@ to set `true`; it's effectively a shortcut for `foo=true`). for code which relies on `Function.length`. - `keep_fnames` -- default `false`. Pass `true` to prevent the - compressor from mangling/discarding function names. Useful for code relying on - `Function.prototype.name`. + compressor from discarding function names. Useful for code relying on + `Function.prototype.name`. See also: the `keep_fnames` [mangle option](#mangle). - `passes` -- default `1`. Number of times to run compress. Use an integer argument larger than 1 to further reduce code size in some cases. @@ -712,9 +712,13 @@ Other options: - `toplevel` — mangle names declared in the toplevel scope (disabled by default). - - `eval` — mangle names visible in scopes where eval or with are used + - `eval` — mangle names visible in scopes where eval or with are used (disabled by default). + - `keep_fnames` -- default `false`. Pass `true` to not mangle + function names. Useful for code relying on `Function.prototype.name`. + See also: the `keep_fnames` [compress option](#compressor-options). + Examples: ```javascript From e8b23c779816442a1d4e06453f06ab5a187ac98e Mon Sep 17 00:00:00 2001 From: Richard van Velzen Date: Sun, 17 Jul 2016 18:17:33 +0200 Subject: [PATCH 09/21] Build with AppVeyor on windows --- appveyor.yml | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 appveyor.yml diff --git a/appveyor.yml b/appveyor.yml new file mode 100644 index 00000000..4d8c2e2b --- /dev/null +++ b/appveyor.yml @@ -0,0 +1,24 @@ +environment: + matrix: + - nodejs_version: "0.10" + - nodejs_version: "0.12" + - nodejs_version: "4.0" + - nodejs_version: "6.0" + +matrix: + fast_finish: true + +platform: + - x86 + - x64 + +install: + - ps: Install-Product node $env:nodejs_version $env:platform + - npm install + +test_script: + - node --version + - npm --version + - npm test + +build: off From 642273c29002e7676719f489d7fcf552974118f4 Mon Sep 17 00:00:00 2001 From: Anthony Van de Gejuchte Date: Thu, 21 Jul 2016 03:19:24 +0200 Subject: [PATCH 10/21] Legacy octal integer strict mode fixes --- lib/parse.js | 5 ++++- test/mocha/number-literal.js | 24 ++++++++++++++++++++++++ test/mocha/string-literal.js | 2 +- 3 files changed, 29 insertions(+), 2 deletions(-) create mode 100644 test/mocha/number-literal.js diff --git a/lib/parse.js b/lib/parse.js index bd6f95f6..ec82d47d 100644 --- a/lib/parse.js +++ b/lib/parse.js @@ -349,6 +349,9 @@ function tokenizer($TEXT, filename, html5_comments, shebang) { return is_alphanumeric_char(code); }); if (prefix) num = prefix + num; + if (RE_OCT_NUMBER.test(num) && next_token.has_directive("use strict")) { + parse_error("SyntaxError: Legacy octal literals are not allowed in strict mode"); + } var valid = parse_js_number(num); if (!isNaN(valid)) { return token("num", valid); @@ -392,7 +395,7 @@ function tokenizer($TEXT, filename, html5_comments, shebang) { // Parse if (ch === "0") return "\0"; if (ch.length > 0 && next_token.has_directive("use strict")) - parse_error("SyntaxError: Octal literals are not allowed in strict mode"); + parse_error("SyntaxError: Legacy octal escape sequences are not allowed in strict mode"); return String.fromCharCode(parseInt(ch, 8)); } diff --git a/test/mocha/number-literal.js b/test/mocha/number-literal.js new file mode 100644 index 00000000..8e05574a --- /dev/null +++ b/test/mocha/number-literal.js @@ -0,0 +1,24 @@ +var assert = require("assert"); +var uglify = require("../../"); + +describe("Number literals", function () { + it("Should not allow legacy octal literals in strict mode", function() { + var inputs = [ + '"use strict";00;', + '"use strict"; var foo = 00;' + ]; + + var test = function(input) { + return function() { + uglify.parse(input); + } + } + var error = function(e) { + return e instanceof uglify.JS_Parse_Error && + e.message === "SyntaxError: Legacy octal literals are not allowed in strict mode"; + } + for (var i = 0; i < inputs.length; i++) { + assert.throws(test(inputs[i]), error, inputs[i]); + } + }); +}); \ No newline at end of file diff --git a/test/mocha/string-literal.js b/test/mocha/string-literal.js index fc4c4277..eb9e6f1c 100644 --- a/test/mocha/string-literal.js +++ b/test/mocha/string-literal.js @@ -49,7 +49,7 @@ describe("String literals", function() { var error = function(e) { return e instanceof UglifyJS.JS_Parse_Error && - e.message === "SyntaxError: Octal literals are not allowed in strict mode"; + e.message === "SyntaxError: Legacy octal escape sequences are not allowed in strict mode"; } for (var input in inputs) { From 67cca43358cfcf7ff2e7c9e5532bc975fb2591d0 Mon Sep 17 00:00:00 2001 From: kzc Date: Fri, 22 Jul 2016 10:44:29 -0400 Subject: [PATCH 11/21] Test reparsing test/compress/*.js output --- test/run-tests.js | 42 ++++++++++++++++++++++++++++-------------- 1 file changed, 28 insertions(+), 14 deletions(-) diff --git a/test/run-tests.js b/test/run-tests.js index 0fdee6f1..4063870a 100755 --- a/test/run-tests.js +++ b/test/run-tests.js @@ -132,25 +132,39 @@ function run_compress_tests() { failures++; failed_files[file] = 1; } - else if (test.expect_warnings) { - U.AST_Node.warn_function = original_warn_function; - var expected_warnings = make_code(test.expect_warnings, { - beautify: false, - quote_style: 2, // force double quote to match JSON - }); - warnings_emitted = warnings_emitted.map(function(input) { - return input.split(process.cwd() + path.sep).join("").split(path.sep).join("/"); - }); - var actual_warnings = JSON.stringify(warnings_emitted); - if (expected_warnings != actual_warnings) { - log("!!! failed\n---INPUT---\n{input}\n---EXPECTED WARNINGS---\n{expected_warnings}\n---ACTUAL WARNINGS---\n{actual_warnings}\n\n", { + else { + // expect == output + try { + var reparsed_ast = U.parse(output); + } catch (ex) { + log("!!! Test matched expected result but cannot parse output\n---INPUT---\n{input}\n---OUTPUT---\n{output}\n--REPARSE ERROR--\n{error}\n\n", { input: input_code, - expected_warnings: expected_warnings, - actual_warnings: actual_warnings, + output: output, + error: ex.toString(), }); failures++; failed_files[file] = 1; } + if (test.expect_warnings) { + U.AST_Node.warn_function = original_warn_function; + var expected_warnings = make_code(test.expect_warnings, { + beautify: false, + quote_style: 2, // force double quote to match JSON + }); + warnings_emitted = warnings_emitted.map(function(input) { + return input.split(process.cwd() + path.sep).join("").split(path.sep).join("/"); + }); + var actual_warnings = JSON.stringify(warnings_emitted); + if (expected_warnings != actual_warnings) { + log("!!! failed\n---INPUT---\n{input}\n---EXPECTED WARNINGS---\n{expected_warnings}\n---ACTUAL WARNINGS---\n{actual_warnings}\n\n", { + input: input_code, + expected_warnings: expected_warnings, + actual_warnings: actual_warnings, + }); + failures++; + failed_files[file] = 1; + } + } } } var tests = parse_test(path.resolve(dir, file)); From fb049d3a81b744a5facf1f032b8b2815c410f178 Mon Sep 17 00:00:00 2001 From: kzc Date: Sat, 23 Jul 2016 11:50:44 -0400 Subject: [PATCH 12/21] Fix unneeded parens around unary args in new expression. --- lib/output.js | 2 +- test/compress/new.js | 25 +++++++++++++++++++++++++ 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/lib/output.js b/lib/output.js index 324f96ed..801f7516 100644 --- a/lib/output.js +++ b/lib/output.js @@ -533,7 +533,7 @@ function OutputStream(options) { PARENS([ AST_Unary, AST_Undefined ], function(output){ var p = output.parent(); return p instanceof AST_PropAccess && p.expression === this - || p instanceof AST_New; + || p instanceof AST_Call && p.expression === this; }); PARENS(AST_Seq, function(output){ diff --git a/test/compress/new.js b/test/compress/new.js index 78a1026e..bdf22b0c 100644 --- a/test/compress/new.js +++ b/test/compress/new.js @@ -50,3 +50,28 @@ new_with_many_parameters: { } expect_exact: 'new foo.bar("baz");new x(/123/,456);' } + +new_constructor_with_unary_arguments: { + input: { + new x(); + new x(-1); + new x(-1, -2); + new x(void 1, +2, -3, ~4, !5, --a, ++b, c--, d++, typeof e, delete f); + new (-1); // should parse despite being invalid at runtime. + new (-1)(); // should parse despite being invalid at runtime. + new (-1)(-2); // should parse despite being invalid at runtime. + } + expect_exact: "new x;new x(-1);new x(-1,-2);new x(void 1,+2,-3,~4,!5,--a,++b,c--,d++,typeof e,delete f);new(-1);new(-1);new(-1)(-2);" +} + +call_with_unary_arguments: { + input: { + x(); + x(-1); + x(-1, -2); + x(void 1, +2, -3, ~4, !5, --a, ++b, c--, d++, typeof e, delete f); + (-1)(); // should parse despite being invalid at runtime. + (-1)(-2); // should parse despite being invalid at runtime. + } + expect_exact: "x();x(-1);x(-1,-2);x(void 1,+2,-3,~4,!5,--a,++b,c--,d++,typeof e,delete f);(-1)();(-1)(-2);" +} From 307b88d6ccecf3de4150450ac651594db1b8ba56 Mon Sep 17 00:00:00 2001 From: Lucas Wiener Date: Tue, 26 Jul 2016 09:54:02 +0200 Subject: [PATCH 13/21] Fixed sourceMapIncludeSources and inSourceMap = string combination of the UglifyJS.minify function. --- tools/node.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/node.js b/tools/node.js index 20ecb473..179c69db 100644 --- a/tools/node.js +++ b/tools/node.js @@ -114,7 +114,7 @@ exports.minify = function(files, options) { var inMap = options.inSourceMap; var output = {}; if (typeof options.inSourceMap == "string") { - inMap = fs.readFileSync(options.inSourceMap, "utf8"); + inMap = JSON.parse(fs.readFileSync(options.inSourceMap, "utf8")); } if (options.outSourceMap) { output.source_map = UglifyJS.SourceMap({ From 85a09fc3b69cd4ea4b01151e235815b0796373f3 Mon Sep 17 00:00:00 2001 From: Lucas Wiener Date: Wed, 27 Jul 2016 16:02:33 +0200 Subject: [PATCH 14/21] Added test for #1236 --- test/mocha/input/issue-1236/simple.js | 8 ++++++++ test/mocha/input/issue-1236/simple.js.map | 8 ++++++++ test/mocha/minify.js | 16 ++++++++++++++++ 3 files changed, 32 insertions(+) create mode 100644 test/mocha/input/issue-1236/simple.js create mode 100644 test/mocha/input/issue-1236/simple.js.map diff --git a/test/mocha/input/issue-1236/simple.js b/test/mocha/input/issue-1236/simple.js new file mode 100644 index 00000000..8bdd7f26 --- /dev/null +++ b/test/mocha/input/issue-1236/simple.js @@ -0,0 +1,8 @@ +"use strict"; + +var foo = function foo(x) { + return "foo " + x; +}; +console.log(foo("bar")); + +//# sourceMappingURL=simple.js.map diff --git a/test/mocha/input/issue-1236/simple.js.map b/test/mocha/input/issue-1236/simple.js.map new file mode 100644 index 00000000..28989e0f --- /dev/null +++ b/test/mocha/input/issue-1236/simple.js.map @@ -0,0 +1,8 @@ +{ + "version": 3, + "sources": ["index.js"], + "names": [], + "mappings": ";;AAAA,IAAI,MAAM,SAAN,GAAM;AAAA,SAAK,SAAS,CAAd;AAAA,CAAV;AACA,QAAQ,GAAR,CAAY,IAAI,KAAJ,CAAZ", + "file": "simple.js", + "sourcesContent": ["let foo = x => \"foo \" + x;\nconsole.log(foo(\"bar\"));"] +} diff --git a/test/mocha/minify.js b/test/mocha/minify.js index 02d31558..b6e7a23f 100644 --- a/test/mocha/minify.js +++ b/test/mocha/minify.js @@ -59,4 +59,20 @@ describe("minify", function() { 'a["foo"]="bar",a.a="red",x={"bar":10};'); }); }); + + describe("inSourceMap", function() { + it("Should read the given string filename correctly when sourceMapIncludeSources is enabled (#1236)", function() { + var result = Uglify.minify('./test/mocha/input/issue-1236/simple.js', { + outSourceMap: "simple.js.min.map", + inSourceMap: "./test/mocha/input/issue-1236/simple.js.map", + sourceMapIncludeSources: true + }); + + var map = JSON.parse(result.map); + + assert.equal(map.sourcesContent.length, 1); + assert.equal(map.sourcesContent[0], + 'let foo = x => "foo " + x;\nconsole.log(foo("bar"));'); + }); + }); }); From 38756b1f269fec9fc7f13b82d014478662d00c4d Mon Sep 17 00:00:00 2001 From: Lucas Wiener Date: Thu, 28 Jul 2016 09:30:12 +0200 Subject: [PATCH 15/21] Moved test input files to test/input. --- test/{mocha => }/input/issue-1236/simple.js | 0 test/{mocha => }/input/issue-1236/simple.js.map | 0 test/mocha/minify.js | 4 ++-- 3 files changed, 2 insertions(+), 2 deletions(-) rename test/{mocha => }/input/issue-1236/simple.js (100%) rename test/{mocha => }/input/issue-1236/simple.js.map (100%) diff --git a/test/mocha/input/issue-1236/simple.js b/test/input/issue-1236/simple.js similarity index 100% rename from test/mocha/input/issue-1236/simple.js rename to test/input/issue-1236/simple.js diff --git a/test/mocha/input/issue-1236/simple.js.map b/test/input/issue-1236/simple.js.map similarity index 100% rename from test/mocha/input/issue-1236/simple.js.map rename to test/input/issue-1236/simple.js.map diff --git a/test/mocha/minify.js b/test/mocha/minify.js index b6e7a23f..2adbadcb 100644 --- a/test/mocha/minify.js +++ b/test/mocha/minify.js @@ -62,9 +62,9 @@ describe("minify", function() { describe("inSourceMap", function() { it("Should read the given string filename correctly when sourceMapIncludeSources is enabled (#1236)", function() { - var result = Uglify.minify('./test/mocha/input/issue-1236/simple.js', { + var result = Uglify.minify('./test/input/issue-1236/simple.js', { outSourceMap: "simple.js.min.map", - inSourceMap: "./test/mocha/input/issue-1236/simple.js.map", + inSourceMap: "./test/input/issue-1236/simple.js.map", sourceMapIncludeSources: true }); From 72306b9885dffcc206b6637a9c22e54fa54a168d Mon Sep 17 00:00:00 2001 From: kzc Date: Fri, 29 Jul 2016 16:18:56 -0400 Subject: [PATCH 16/21] Add simple file globbing to bin/uglifyjs for Windows --- bin/uglifyjs | 3 +++ tools/node.js | 44 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 47 insertions(+) diff --git a/bin/uglifyjs b/bin/uglifyjs index 30d234fd..3f0c8254 100755 --- a/bin/uglifyjs +++ b/bin/uglifyjs @@ -273,6 +273,9 @@ if (ARGS.comments != null) { var files = ARGS._.slice(); +if (process.platform === "win32") + files = UglifyJS.simple_glob(files); + if (ARGS.self) { if (files.length > 0) { print_error("WARN: Ignoring input files since --self was passed"); diff --git a/tools/node.js b/tools/node.js index 179c69db..5a143759 100644 --- a/tools/node.js +++ b/tools/node.js @@ -261,3 +261,47 @@ exports.writeNameCache = function(filename, key, cache) { fs.writeFileSync(filename, JSON.stringify(data, null, 2), "utf8"); } }; + +// A file glob function that only supports "*" and "?" wildcards in the basename. +// Example: "foo/bar/*baz??.*.js" +// Argument `glob` may be a string or an array of strings. +// Returns an array of strings. Garbage in, garbage out. +exports.simple_glob = function simple_glob(glob) { + var results = []; + if (Array.isArray(glob)) { + glob.forEach(function(elem) { + results = results.concat(simple_glob(elem)); + }); + return results; + } + if (glob.match(/\*|\?/)) { + var dir = path.dirname(glob); + try { + var entries = fs.readdirSync(dir); + } catch (ex) {} + if (entries) { + var pattern = "^" + (path.basename(glob) + .replace(/\(/g, "\\(") + .replace(/\)/g, "\\)") + .replace(/\{/g, "\\{") + .replace(/\}/g, "\\}") + .replace(/\[/g, "\\[") + .replace(/\]/g, "\\]") + .replace(/\+/g, "\\+") + .replace(/\^/g, "\\^") + .replace(/\$/g, "\\$") + .replace(/\*/g, "[^/\\\\]*") + .replace(/\./g, "\\.") + .replace(/\?/g, ".")) + "$"; + var mod = process.platform === "win32" ? "i" : ""; + var rx = new RegExp(pattern, mod); + for (var i in entries) { + if (rx.test(entries[i])) + results.push(dir + "/" + entries[i]); + } + } + } + if (results.length === 0) + results = [ glob ]; + return results; +}; From dcdcfe4d39e8769e8d7504f167610883e250d266 Mon Sep 17 00:00:00 2001 From: kzc Date: Fri, 29 Jul 2016 21:27:30 -0400 Subject: [PATCH 17/21] Add input file glob support to minify() --- test/input/issue-1242/bar.es5 | 4 ++++ test/input/issue-1242/baz.es5 | 4 ++++ test/input/issue-1242/foo.es5 | 5 +++++ test/input/issue-1242/qux.js | 4 ++++ test/mocha/glob.js | 28 ++++++++++++++++++++++++++++ tools/node.js | 1 + 6 files changed, 46 insertions(+) create mode 100644 test/input/issue-1242/bar.es5 create mode 100644 test/input/issue-1242/baz.es5 create mode 100644 test/input/issue-1242/foo.es5 create mode 100644 test/input/issue-1242/qux.js create mode 100644 test/mocha/glob.js diff --git a/test/input/issue-1242/bar.es5 b/test/input/issue-1242/bar.es5 new file mode 100644 index 00000000..6e308a30 --- /dev/null +++ b/test/input/issue-1242/bar.es5 @@ -0,0 +1,4 @@ +function bar(x) { + var triple = x * (2 + 1); + return triple; +} diff --git a/test/input/issue-1242/baz.es5 b/test/input/issue-1242/baz.es5 new file mode 100644 index 00000000..83c98ef6 --- /dev/null +++ b/test/input/issue-1242/baz.es5 @@ -0,0 +1,4 @@ +function baz(x) { + var half = x / 2; + return half; +} diff --git a/test/input/issue-1242/foo.es5 b/test/input/issue-1242/foo.es5 new file mode 100644 index 00000000..4b439075 --- /dev/null +++ b/test/input/issue-1242/foo.es5 @@ -0,0 +1,5 @@ +var print = console.log.bind(console); +function foo(x) { + var twice = x * 2; + print('Foo:', twice); +} diff --git a/test/input/issue-1242/qux.js b/test/input/issue-1242/qux.js new file mode 100644 index 00000000..94171f38 --- /dev/null +++ b/test/input/issue-1242/qux.js @@ -0,0 +1,4 @@ +var a = bar(1+2); +var b = baz(3+9); +print('q' + 'u' + 'x', a, b); +foo(5+6); diff --git a/test/mocha/glob.js b/test/mocha/glob.js new file mode 100644 index 00000000..c2fc9464 --- /dev/null +++ b/test/mocha/glob.js @@ -0,0 +1,28 @@ +var Uglify = require('../../'); +var assert = require("assert"); + +describe("minify() with input file globs", function() { + it("minify() with one input file glob string.", function() { + var result = Uglify.minify("test/input/issue-1242/foo.*", { + compress: { collapse_vars: true } + }); + assert.strictEqual(result.code, 'function foo(o){print("Foo:",2*o)}var print=console.log.bind(console);'); + }); + it("minify() with an array of one input file glob.", function() { + var result = Uglify.minify([ + "test/input/issue-1242/b*.es5", + ], { + compress: { collapse_vars: true } + }); + assert.strictEqual(result.code, 'function bar(n){return 3*n}function baz(n){return n/2}'); + }); + it("minify() with an array of multiple input file globs.", function() { + var result = Uglify.minify([ + "test/input/issue-1242/???.es5", + "test/input/issue-1242/*.js", + ], { + compress: { collapse_vars: true } + }); + assert.strictEqual(result.code, 'function bar(n){return 3*n}function baz(n){return n/2}function foo(n){print("Foo:",2*n)}var print=console.log.bind(console);print("qux",bar(3),baz(12)),foo(11);'); + }); +}); diff --git a/tools/node.js b/tools/node.js index 5a143759..6712ccf6 100644 --- a/tools/node.js +++ b/tools/node.js @@ -73,6 +73,7 @@ exports.minify = function(files, options) { bare_returns: options.parse ? options.parse.bare_returns : undefined }); } + if (!options.fromString) files = UglifyJS.simple_glob(files); [].concat(files).forEach(function (files, i) { if (typeof files === 'string') { addFile(files, options.fromString ? i : files); From 86859f6d7e9e738ccf09a83a28962c9bad8e959f Mon Sep 17 00:00:00 2001 From: kzc Date: Sat, 30 Jul 2016 13:21:23 -0400 Subject: [PATCH 18/21] Additional object literal property tests --- test/compress/properties.js | 257 ++++++++++++++++++++++++++++++++++++ 1 file changed, 257 insertions(+) diff --git a/test/compress/properties.js b/test/compress/properties.js index cf52e631..4aaa92cb 100644 --- a/test/compress/properties.js +++ b/test/compress/properties.js @@ -124,3 +124,260 @@ mangle_unquoted_properties: { } } } + +first_256_chars_as_properties: { + beautify = { + ascii_only: true, + } + input: { + // Note: some of these unicode character keys are not visible on github.com + var o = { + "\0":0,"":1,"":2,"":3,"":4,"":5,"":6,"":7,"\b":8, + "\t":9,"\n":10,"\v":11,"\f":12,"\r":13,"":14,"":15,"":16,"":17, + "":18,"":19,"":20,"":21,"":22,"":23,"":24,"":25,"":26, + "":27,"":28,"":29,"":30,"":31," ":32,"!":33,'"':34,"#":35, + $:36,"%":37,"&":38,"'":39,"(":40,")":41,"*":42,"+":43,",":44, + "-":45,".":46,"/":47,"0":48,"1":49,"2":50,"3":51,"4":52,"5":53,"6":54,"7":55, + "8":56,"9":57,":":58,";":59,"<":60,"=":61,">":62,"?":63,"@":64,A:65, + B:66,C:67,D:68,E:69,F:70,G:71,H:72,I:73,J:74,K:75,L:76,M:77,N:78, + O:79,P:80,Q:81,R:82,S:83,T:84,U:85,V:86,W:87,X:88,Y:89,Z:90,"[":91, + "\\":92,"]":93,"^":94,_:95,"`":96,a:97,b:98,c:99,d:100,e:101, + f:102,g:103,h:104,i:105,j:106,k:107,l:108,m:109,n:110,o:111,p:112, + q:113,r:114,s:115,t:116,u:117,v:118,w:119,x:120,y:121,z:122,"{":123, + "|":124,"}":125,"~":126,"":127,"€":128,"":129,"‚":130,"ƒ":131, + "„":132,"…":133,"†":134,"‡":135,"ˆ":136,"‰":137,"Š":138,"‹":139, + "Œ":140,"":141,"Ž":142,"":143,"":144,"‘":145,"’":146,"“":147, + "”":148,"•":149,"–":150,"—":151,"˜":152,"™":153,"š":154,"›":155, + "œ":156,"":157,"ž":158,"Ÿ":159," ":160,"¡":161,"¢":162,"£":163, + "¤":164,"¥":165,"¦":166,"§":167,"¨":168,"©":169,"ª":170,"«":171, + "¬":172,"­":173,"®":174,"¯":175,"°":176,"±":177,"²":178,"³":179, + "´":180,"µ":181,"¶":182,"·":183,"¸":184,"¹":185,"º":186,"»":187, + "¼":188,"½":189,"¾":190,"¿":191,"À":192,"Á":193,"Â":194,"Ã":195, + "Ä":196,"Å":197,"Æ":198,"Ç":199,"È":200,"É":201,"Ê":202,"Ë":203, + "Ì":204,"Í":205,"Î":206,"Ï":207,"Ð":208,"Ñ":209,"Ò":210,"Ó":211, + "Ô":212,"Õ":213,"Ö":214,"×":215,"Ø":216,"Ù":217,"Ú":218,"Û":219, + "Ü":220,"Ý":221,"Þ":222,"ß":223,"à":224,"á":225,"â":226,"ã":227, + "ä":228,"å":229,"æ":230,"ç":231,"è":232,"é":233,"ê":234,"ë":235, + "ì":236,"í":237,"î":238,"ï":239,"ð":240,"ñ":241,"ò":242,"ó":243, + "ô":244,"õ":245,"ö":246,"÷":247,"ø":248,"ù":249,"ú":250,"û":251, + "ü":252,"ý":253,"þ":254,"ÿ":255 + }; + } + expect: { + var o = { + "\0":0,"\x01":1,"\x02":2,"\x03":3,"\x04":4,"\x05":5,"\x06":6, + "\x07":7,"\b":8,"\t":9,"\n":10,"\v":11,"\f":12,"\r":13,"\x0e":14, + "\x0f":15,"\x10":16,"\x11":17,"\x12":18,"\x13":19,"\x14":20,"\x15":21, + "\x16":22,"\x17":23,"\x18":24,"\x19":25,"\x1a":26,"\x1b":27,"\x1c":28, + "\x1d":29,"\x1e":30,"\x1f":31," ":32,"!":33,'"':34,"#":35,$:36, + "%":37,"&":38,"'":39,"(":40,")":41,"*":42,"+":43,",":44,"-":45, + ".":46,"/":47,0:48,1:49,2:50,3:51,4:52,5:53,6:54,7:55,8:56,9:57, + ":":58,";":59,"<":60,"=":61,">":62,"?":63,"@":64,A:65,B:66,C:67, + D:68,E:69,F:70,G:71,H:72,I:73,J:74,K:75,L:76,M:77,N:78,O:79,P:80, + Q:81,R:82,S:83,T:84,U:85,V:86,W:87,X:88,Y:89,Z:90,"[":91,"\\":92, + "]":93,"^":94,_:95,"`":96,a:97,b:98,c:99,d:100,e:101,f:102,g:103, + h:104,i:105,j:106,k:107,l:108,m:109,n:110,o:111,p:112,q:113,r:114, + s:115,t:116,u:117,v:118,w:119,x:120,y:121,z:122,"{":123,"|":124, + "}":125,"~":126,"\x7f":127,"\x80":128,"\x81":129,"\x82":130,"\x83":131, + "\x84":132,"\x85":133,"\x86":134,"\x87":135,"\x88":136,"\x89":137, + "\x8a":138,"\x8b":139,"\x8c":140,"\x8d":141,"\x8e":142,"\x8f":143, + "\x90":144,"\x91":145,"\x92":146,"\x93":147,"\x94":148,"\x95":149, + "\x96":150,"\x97":151,"\x98":152,"\x99":153,"\x9a":154,"\x9b":155, + "\x9c":156,"\x9d":157,"\x9e":158,"\x9f":159,"\xa0":160,"\xa1":161, + "\xa2":162,"\xa3":163,"\xa4":164,"\xa5":165,"\xa6":166,"\xa7":167, + "\xa8":168,"\xa9":169,"\xaa":170,"\xab":171,"\xac":172,"\xad":173, + "\xae":174,"\xaf":175,"\xb0":176,"\xb1":177,"\xb2":178,"\xb3":179, + "\xb4":180,"\xb5":181,"\xb6":182,"\xb7":183,"\xb8":184,"\xb9":185, + "\xba":186,"\xbb":187,"\xbc":188,"\xbd":189,"\xbe":190,"\xbf":191, + "\xc0":192,"\xc1":193,"\xc2":194,"\xc3":195,"\xc4":196,"\xc5":197, + "\xc6":198,"\xc7":199,"\xc8":200,"\xc9":201,"\xca":202,"\xcb":203, + "\xcc":204,"\xcd":205,"\xce":206,"\xcf":207,"\xd0":208,"\xd1":209, + "\xd2":210,"\xd3":211,"\xd4":212,"\xd5":213,"\xd6":214,"\xd7":215, + "\xd8":216,"\xd9":217,"\xda":218,"\xdb":219,"\xdc":220,"\xdd":221, + "\xde":222,"\xdf":223,"\xe0":224,"\xe1":225,"\xe2":226,"\xe3":227, + "\xe4":228,"\xe5":229,"\xe6":230,"\xe7":231,"\xe8":232,"\xe9":233, + "\xea":234,"\xeb":235,"\xec":236,"\xed":237,"\xee":238,"\xef":239, + "\xf0":240,"\xf1":241,"\xf2":242,"\xf3":243,"\xf4":244,"\xf5":245, + "\xf6":246,"\xf7":247,"\xf8":248,"\xf9":249,"\xfa":250,"\xfb":251, + "\xfc":252,"\xfd":253,"\xfe":254,"\xff":255 + }; + } +} + +first_256_unicode_chars_as_properties: { + input: { + var o = { + "\u0000": 0, "\u0001": 1, "\u0002": 2, "\u0003": 3, "\u0004": 4, "\u0005": 5, + "\u0006": 6, "\u0007": 7, "\u0008": 8, "\u0009": 9, "\u000A": 10, "\u000B": 11, + "\u000C": 12, "\u000D": 13, "\u000E": 14, "\u000F": 15, "\u0010": 16, "\u0011": 17, + "\u0012": 18, "\u0013": 19, "\u0014": 20, "\u0015": 21, "\u0016": 22, "\u0017": 23, + "\u0018": 24, "\u0019": 25, "\u001A": 26, "\u001B": 27, "\u001C": 28, "\u001D": 29, + "\u001E": 30, "\u001F": 31, "\u0020": 32, "\u0021": 33, "\u0022": 34, "\u0023": 35, + "\u0024": 36, "\u0025": 37, "\u0026": 38, "\u0027": 39, "\u0028": 40, "\u0029": 41, + "\u002A": 42, "\u002B": 43, "\u002C": 44, "\u002D": 45, "\u002E": 46, "\u002F": 47, + "\u0030": 48, "\u0031": 49, "\u0032": 50, "\u0033": 51, "\u0034": 52, "\u0035": 53, + "\u0036": 54, "\u0037": 55, "\u0038": 56, "\u0039": 57, "\u003A": 58, "\u003B": 59, + "\u003C": 60, "\u003D": 61, "\u003E": 62, "\u003F": 63, "\u0040": 64, "\u0041": 65, + "\u0042": 66, "\u0043": 67, "\u0044": 68, "\u0045": 69, "\u0046": 70, "\u0047": 71, + "\u0048": 72, "\u0049": 73, "\u004A": 74, "\u004B": 75, "\u004C": 76, "\u004D": 77, + "\u004E": 78, "\u004F": 79, "\u0050": 80, "\u0051": 81, "\u0052": 82, "\u0053": 83, + "\u0054": 84, "\u0055": 85, "\u0056": 86, "\u0057": 87, "\u0058": 88, "\u0059": 89, + "\u005A": 90, "\u005B": 91, "\u005C": 92, "\u005D": 93, "\u005E": 94, "\u005F": 95, + "\u0060": 96, "\u0061": 97, "\u0062": 98, "\u0063": 99, "\u0064": 100, "\u0065": 101, + "\u0066": 102, "\u0067": 103, "\u0068": 104, "\u0069": 105, "\u006A": 106, "\u006B": 107, + "\u006C": 108, "\u006D": 109, "\u006E": 110, "\u006F": 111, "\u0070": 112, "\u0071": 113, + "\u0072": 114, "\u0073": 115, "\u0074": 116, "\u0075": 117, "\u0076": 118, "\u0077": 119, + "\u0078": 120, "\u0079": 121, "\u007A": 122, "\u007B": 123, "\u007C": 124, "\u007D": 125, + "\u007E": 126, "\u007F": 127, "\u0080": 128, "\u0081": 129, "\u0082": 130, "\u0083": 131, + "\u0084": 132, "\u0085": 133, "\u0086": 134, "\u0087": 135, "\u0088": 136, "\u0089": 137, + "\u008A": 138, "\u008B": 139, "\u008C": 140, "\u008D": 141, "\u008E": 142, "\u008F": 143, + "\u0090": 144, "\u0091": 145, "\u0092": 146, "\u0093": 147, "\u0094": 148, "\u0095": 149, + "\u0096": 150, "\u0097": 151, "\u0098": 152, "\u0099": 153, "\u009A": 154, "\u009B": 155, + "\u009C": 156, "\u009D": 157, "\u009E": 158, "\u009F": 159, "\u00A0": 160, "\u00A1": 161, + "\u00A2": 162, "\u00A3": 163, "\u00A4": 164, "\u00A5": 165, "\u00A6": 166, "\u00A7": 167, + "\u00A8": 168, "\u00A9": 169, "\u00AA": 170, "\u00AB": 171, "\u00AC": 172, "\u00AD": 173, + "\u00AE": 174, "\u00AF": 175, "\u00B0": 176, "\u00B1": 177, "\u00B2": 178, "\u00B3": 179, + "\u00B4": 180, "\u00B5": 181, "\u00B6": 182, "\u00B7": 183, "\u00B8": 184, "\u00B9": 185, + "\u00BA": 186, "\u00BB": 187, "\u00BC": 188, "\u00BD": 189, "\u00BE": 190, "\u00BF": 191, + "\u00C0": 192, "\u00C1": 193, "\u00C2": 194, "\u00C3": 195, "\u00C4": 196, "\u00C5": 197, + "\u00C6": 198, "\u00C7": 199, "\u00C8": 200, "\u00C9": 201, "\u00CA": 202, "\u00CB": 203, + "\u00CC": 204, "\u00CD": 205, "\u00CE": 206, "\u00CF": 207, "\u00D0": 208, "\u00D1": 209, + "\u00D2": 210, "\u00D3": 211, "\u00D4": 212, "\u00D5": 213, "\u00D6": 214, "\u00D7": 215, + "\u00D8": 216, "\u00D9": 217, "\u00DA": 218, "\u00DB": 219, "\u00DC": 220, "\u00DD": 221, + "\u00DE": 222, "\u00DF": 223, "\u00E0": 224, "\u00E1": 225, "\u00E2": 226, "\u00E3": 227, + "\u00E4": 228, "\u00E5": 229, "\u00E6": 230, "\u00E7": 231, "\u00E8": 232, "\u00E9": 233, + "\u00EA": 234, "\u00EB": 235, "\u00EC": 236, "\u00ED": 237, "\u00EE": 238, "\u00EF": 239, + "\u00F0": 240, "\u00F1": 241, "\u00F2": 242, "\u00F3": 243, "\u00F4": 244, "\u00F5": 245, + "\u00F6": 246, "\u00F7": 247, "\u00F8": 248, "\u00F9": 249, "\u00FA": 250, "\u00FB": 251, + "\u00FC": 252, "\u00FD": 253, "\u00FE": 254, "\u00FF": 255 + }; + } + expect: { + var o = { + "\0":0,"\x01":1,"\x02":2,"\x03":3,"\x04":4,"\x05":5,"\x06":6, + "\x07":7,"\b":8,"\t":9,"\n":10,"\v":11,"\f":12,"\r":13,"\x0e":14, + "\x0f":15,"\x10":16,"\x11":17,"\x12":18,"\x13":19,"\x14":20,"\x15":21, + "\x16":22,"\x17":23,"\x18":24,"\x19":25,"\x1a":26,"\x1b":27,"\x1c":28, + "\x1d":29,"\x1e":30,"\x1f":31," ":32,"!":33,'"':34,"#":35,$:36, + "%":37,"&":38,"'":39,"(":40,")":41,"*":42,"+":43,",":44,"-":45, + ".":46,"/":47,0:48,1:49,2:50,3:51,4:52,5:53,6:54,7:55,8:56,9:57, + ":":58,";":59,"<":60,"=":61,">":62,"?":63,"@":64,A:65,B:66,C:67, + D:68,E:69,F:70,G:71,H:72,I:73,J:74,K:75,L:76,M:77,N:78,O:79,P:80, + Q:81,R:82,S:83,T:84,U:85,V:86,W:87,X:88,Y:89,Z:90,"[":91,"\\":92, + "]":93,"^":94,_:95,"`":96,a:97,b:98,c:99,d:100,e:101,f:102,g:103, + h:104,i:105,j:106,k:107,l:108,m:109,n:110,o:111,p:112,q:113,r:114, + s:115,t:116,u:117,v:118,w:119,x:120,y:121,z:122,"{":123,"|":124, + "}":125,"~":126,"\x7f":127,"\x80":128,"\x81":129,"\x82":130,"\x83":131, + "\x84":132,"\x85":133,"\x86":134,"\x87":135,"\x88":136,"\x89":137, + "\x8a":138,"\x8b":139,"\x8c":140,"\x8d":141,"\x8e":142,"\x8f":143, + "\x90":144,"\x91":145,"\x92":146,"\x93":147,"\x94":148,"\x95":149, + "\x96":150,"\x97":151,"\x98":152,"\x99":153,"\x9a":154,"\x9b":155, + "\x9c":156,"\x9d":157,"\x9e":158,"\x9f":159,"\xa0":160,"\xa1":161, + "\xa2":162,"\xa3":163,"\xa4":164,"\xa5":165,"\xa6":166,"\xa7":167, + "\xa8":168,"\xa9":169,"\xaa":170,"\xab":171,"\xac":172,"\xad":173, + "\xae":174,"\xaf":175,"\xb0":176,"\xb1":177,"\xb2":178,"\xb3":179, + "\xb4":180,"\xb5":181,"\xb6":182,"\xb7":183,"\xb8":184,"\xb9":185, + "\xba":186,"\xbb":187,"\xbc":188,"\xbd":189,"\xbe":190,"\xbf":191, + "\xc0":192,"\xc1":193,"\xc2":194,"\xc3":195,"\xc4":196,"\xc5":197, + "\xc6":198,"\xc7":199,"\xc8":200,"\xc9":201,"\xca":202,"\xcb":203, + "\xcc":204,"\xcd":205,"\xce":206,"\xcf":207,"\xd0":208,"\xd1":209, + "\xd2":210,"\xd3":211,"\xd4":212,"\xd5":213,"\xd6":214,"\xd7":215, + "\xd8":216,"\xd9":217,"\xda":218,"\xdb":219,"\xdc":220,"\xdd":221, + "\xde":222,"\xdf":223,"\xe0":224,"\xe1":225,"\xe2":226,"\xe3":227, + "\xe4":228,"\xe5":229,"\xe6":230,"\xe7":231,"\xe8":232,"\xe9":233, + "\xea":234,"\xeb":235,"\xec":236,"\xed":237,"\xee":238,"\xef":239, + "\xf0":240,"\xf1":241,"\xf2":242,"\xf3":243,"\xf4":244,"\xf5":245, + "\xf6":246,"\xf7":247,"\xf8":248,"\xf9":249,"\xfa":250,"\xfb":251, + "\xfc":252,"\xfd":253,"\xfe":254,"\xff":255 + }; + } +} + +first_256_hex_chars_as_properties: { + input: { + var o = { + "\x00": 0, "\x01": 1, "\x02": 2, "\x03": 3, "\x04": 4, "\x05": 5, + "\x06": 6, "\x07": 7, "\x08": 8, "\x09": 9, "\x0A": 10, "\x0B": 11, + "\x0C": 12, "\x0D": 13, "\x0E": 14, "\x0F": 15, "\x10": 16, "\x11": 17, + "\x12": 18, "\x13": 19, "\x14": 20, "\x15": 21, "\x16": 22, "\x17": 23, + "\x18": 24, "\x19": 25, "\x1A": 26, "\x1B": 27, "\x1C": 28, "\x1D": 29, + "\x1E": 30, "\x1F": 31, "\x20": 32, "\x21": 33, "\x22": 34, "\x23": 35, + "\x24": 36, "\x25": 37, "\x26": 38, "\x27": 39, "\x28": 40, "\x29": 41, + "\x2A": 42, "\x2B": 43, "\x2C": 44, "\x2D": 45, "\x2E": 46, "\x2F": 47, + "\x30": 48, "\x31": 49, "\x32": 50, "\x33": 51, "\x34": 52, "\x35": 53, + "\x36": 54, "\x37": 55, "\x38": 56, "\x39": 57, "\x3A": 58, "\x3B": 59, + "\x3C": 60, "\x3D": 61, "\x3E": 62, "\x3F": 63, "\x40": 64, "\x41": 65, + "\x42": 66, "\x43": 67, "\x44": 68, "\x45": 69, "\x46": 70, "\x47": 71, + "\x48": 72, "\x49": 73, "\x4A": 74, "\x4B": 75, "\x4C": 76, "\x4D": 77, + "\x4E": 78, "\x4F": 79, "\x50": 80, "\x51": 81, "\x52": 82, "\x53": 83, + "\x54": 84, "\x55": 85, "\x56": 86, "\x57": 87, "\x58": 88, "\x59": 89, + "\x5A": 90, "\x5B": 91, "\x5C": 92, "\x5D": 93, "\x5E": 94, "\x5F": 95, + "\x60": 96, "\x61": 97, "\x62": 98, "\x63": 99, "\x64": 100, "\x65": 101, + "\x66": 102, "\x67": 103, "\x68": 104, "\x69": 105, "\x6A": 106, "\x6B": 107, + "\x6C": 108, "\x6D": 109, "\x6E": 110, "\x6F": 111, "\x70": 112, "\x71": 113, + "\x72": 114, "\x73": 115, "\x74": 116, "\x75": 117, "\x76": 118, "\x77": 119, + "\x78": 120, "\x79": 121, "\x7A": 122, "\x7B": 123, "\x7C": 124, "\x7D": 125, + "\x7E": 126, "\x7F": 127, "\x80": 128, "\x81": 129, "\x82": 130, "\x83": 131, + "\x84": 132, "\x85": 133, "\x86": 134, "\x87": 135, "\x88": 136, "\x89": 137, + "\x8A": 138, "\x8B": 139, "\x8C": 140, "\x8D": 141, "\x8E": 142, "\x8F": 143, + "\x90": 144, "\x91": 145, "\x92": 146, "\x93": 147, "\x94": 148, "\x95": 149, + "\x96": 150, "\x97": 151, "\x98": 152, "\x99": 153, "\x9A": 154, "\x9B": 155, + "\x9C": 156, "\x9D": 157, "\x9E": 158, "\x9F": 159, "\xA0": 160, "\xA1": 161, + "\xA2": 162, "\xA3": 163, "\xA4": 164, "\xA5": 165, "\xA6": 166, "\xA7": 167, + "\xA8": 168, "\xA9": 169, "\xAA": 170, "\xAB": 171, "\xAC": 172, "\xAD": 173, + "\xAE": 174, "\xAF": 175, "\xB0": 176, "\xB1": 177, "\xB2": 178, "\xB3": 179, + "\xB4": 180, "\xB5": 181, "\xB6": 182, "\xB7": 183, "\xB8": 184, "\xB9": 185, + "\xBA": 186, "\xBB": 187, "\xBC": 188, "\xBD": 189, "\xBE": 190, "\xBF": 191, + "\xC0": 192, "\xC1": 193, "\xC2": 194, "\xC3": 195, "\xC4": 196, "\xC5": 197, + "\xC6": 198, "\xC7": 199, "\xC8": 200, "\xC9": 201, "\xCA": 202, "\xCB": 203, + "\xCC": 204, "\xCD": 205, "\xCE": 206, "\xCF": 207, "\xD0": 208, "\xD1": 209, + "\xD2": 210, "\xD3": 211, "\xD4": 212, "\xD5": 213, "\xD6": 214, "\xD7": 215, + "\xD8": 216, "\xD9": 217, "\xDA": 218, "\xDB": 219, "\xDC": 220, "\xDD": 221, + "\xDE": 222, "\xDF": 223, "\xE0": 224, "\xE1": 225, "\xE2": 226, "\xE3": 227, + "\xE4": 228, "\xE5": 229, "\xE6": 230, "\xE7": 231, "\xE8": 232, "\xE9": 233, + "\xEA": 234, "\xEB": 235, "\xEC": 236, "\xED": 237, "\xEE": 238, "\xEF": 239, + "\xF0": 240, "\xF1": 241, "\xF2": 242, "\xF3": 243, "\xF4": 244, "\xF5": 245, + "\xF6": 246, "\xF7": 247, "\xF8": 248, "\xF9": 249, "\xFA": 250, "\xFB": 251, + "\xFC": 252, "\xFD": 253, "\xFE": 254, "\xFF": 255 + }; + } + expect: { + var o = { + "\0":0,"\x01":1,"\x02":2,"\x03":3,"\x04":4,"\x05":5,"\x06":6, + "\x07":7,"\b":8,"\t":9,"\n":10,"\v":11,"\f":12,"\r":13,"\x0e":14, + "\x0f":15,"\x10":16,"\x11":17,"\x12":18,"\x13":19,"\x14":20,"\x15":21, + "\x16":22,"\x17":23,"\x18":24,"\x19":25,"\x1a":26,"\x1b":27,"\x1c":28, + "\x1d":29,"\x1e":30,"\x1f":31," ":32,"!":33,'"':34,"#":35,$:36, + "%":37,"&":38,"'":39,"(":40,")":41,"*":42,"+":43,",":44,"-":45, + ".":46,"/":47,0:48,1:49,2:50,3:51,4:52,5:53,6:54,7:55,8:56,9:57, + ":":58,";":59,"<":60,"=":61,">":62,"?":63,"@":64,A:65,B:66,C:67, + D:68,E:69,F:70,G:71,H:72,I:73,J:74,K:75,L:76,M:77,N:78,O:79,P:80, + Q:81,R:82,S:83,T:84,U:85,V:86,W:87,X:88,Y:89,Z:90,"[":91,"\\":92, + "]":93,"^":94,_:95,"`":96,a:97,b:98,c:99,d:100,e:101,f:102,g:103, + h:104,i:105,j:106,k:107,l:108,m:109,n:110,o:111,p:112,q:113,r:114, + s:115,t:116,u:117,v:118,w:119,x:120,y:121,z:122,"{":123,"|":124, + "}":125,"~":126,"\x7f":127,"\x80":128,"\x81":129,"\x82":130,"\x83":131, + "\x84":132,"\x85":133,"\x86":134,"\x87":135,"\x88":136,"\x89":137, + "\x8a":138,"\x8b":139,"\x8c":140,"\x8d":141,"\x8e":142,"\x8f":143, + "\x90":144,"\x91":145,"\x92":146,"\x93":147,"\x94":148,"\x95":149, + "\x96":150,"\x97":151,"\x98":152,"\x99":153,"\x9a":154,"\x9b":155, + "\x9c":156,"\x9d":157,"\x9e":158,"\x9f":159,"\xa0":160,"\xa1":161, + "\xa2":162,"\xa3":163,"\xa4":164,"\xa5":165,"\xa6":166,"\xa7":167, + "\xa8":168,"\xa9":169,"\xaa":170,"\xab":171,"\xac":172,"\xad":173, + "\xae":174,"\xaf":175,"\xb0":176,"\xb1":177,"\xb2":178,"\xb3":179, + "\xb4":180,"\xb5":181,"\xb6":182,"\xb7":183,"\xb8":184,"\xb9":185, + "\xba":186,"\xbb":187,"\xbc":188,"\xbd":189,"\xbe":190,"\xbf":191, + "\xc0":192,"\xc1":193,"\xc2":194,"\xc3":195,"\xc4":196,"\xc5":197, + "\xc6":198,"\xc7":199,"\xc8":200,"\xc9":201,"\xca":202,"\xcb":203, + "\xcc":204,"\xcd":205,"\xce":206,"\xcf":207,"\xd0":208,"\xd1":209, + "\xd2":210,"\xd3":211,"\xd4":212,"\xd5":213,"\xd6":214,"\xd7":215, + "\xd8":216,"\xd9":217,"\xda":218,"\xdb":219,"\xdc":220,"\xdd":221, + "\xde":222,"\xdf":223,"\xe0":224,"\xe1":225,"\xe2":226,"\xe3":227, + "\xe4":228,"\xe5":229,"\xe6":230,"\xe7":231,"\xe8":232,"\xe9":233, + "\xea":234,"\xeb":235,"\xec":236,"\xed":237,"\xee":238,"\xef":239, + "\xf0":240,"\xf1":241,"\xf2":242,"\xf3":243,"\xf4":244,"\xf5":245, + "\xf6":246,"\xf7":247,"\xf8":248,"\xf9":249,"\xfa":250,"\xfb":251, + "\xfc":252,"\xfd":253,"\xfe":254,"\xff":255 + }; + } +} From de619ae5a62472a76b0bfaa23d8e0b3068472196 Mon Sep 17 00:00:00 2001 From: kzc Date: Sun, 31 Jul 2016 02:35:14 -0400 Subject: [PATCH 19/21] Fix --mangle-props and --mangle-props=unquoted Fixes: #1247 Fix --mangle-props and --name-cache inconsistency. AST_Dot and AST_Sub properties are now mangled by --mangle-props without regard to being used in an assignment statement. Note: if --mangle-props is used then *all* javascript files used must be uglified with the same mangle options. Fix the ignore_quoted=true mangle option, also known as `--mangle-props=unquoted`. If a given property is quoted anywhere it will not be mangled in any quoted or non-quoted context. --- lib/propmangle.js | 25 +++++++++++++------------ test/compress/properties.js | 29 +++++++++++++++++++++++------ 2 files changed, 36 insertions(+), 18 deletions(-) diff --git a/lib/propmangle.js b/lib/propmangle.js index 08043d73..3923baa6 100644 --- a/lib/propmangle.js +++ b/lib/propmangle.js @@ -86,27 +86,22 @@ function mangle_properties(ast, options) { var names_to_mangle = []; var unmangleable = []; + var ignored = {}; // step 1: find candidates to mangle ast.walk(new TreeWalker(function(node){ if (node instanceof AST_ObjectKeyVal) { - if (!(ignore_quoted && node.quote)) - add(node.key); + add(node.key, ignore_quoted && node.quote); } else if (node instanceof AST_ObjectProperty) { // setter or getter, since KeyVal is handled above add(node.key.name); } else if (node instanceof AST_Dot) { - if (this.parent() instanceof AST_Assign) { - add(node.property); - } + add(node.property); } else if (node instanceof AST_Sub) { - if (this.parent() instanceof AST_Assign) { - if (!ignore_quoted) - addStrings(node.property); - } + addStrings(node.property, ignore_quoted); } })); @@ -154,13 +149,19 @@ function mangle_properties(ast, options) { } function should_mangle(name) { + if (ignore_quoted && name in ignored) return false; if (regex && !regex.test(name)) return false; if (reserved.indexOf(name) >= 0) return false; return cache.props.has(name) || names_to_mangle.indexOf(name) >= 0; } - function add(name) { + function add(name, ignore) { + if (ignore) { + ignored[name] = true; + return; + } + if (can_mangle(name)) push_uniq(names_to_mangle, name); @@ -184,7 +185,7 @@ function mangle_properties(ast, options) { return mangled; } - function addStrings(node) { + function addStrings(node, ignore) { var out = {}; try { (function walk(node){ @@ -194,7 +195,7 @@ function mangle_properties(ast, options) { return true; } if (node instanceof AST_String) { - add(node.value); + add(node.value, ignore); return true; } if (node instanceof AST_Conditional) { diff --git a/test/compress/properties.js b/test/compress/properties.js index 4aaa92cb..f1680808 100644 --- a/test/compress/properties.js +++ b/test/compress/properties.js @@ -82,15 +82,22 @@ mangle_properties: { a["foo"] = "bar"; a.color = "red"; x = {"bar": 10}; + a.run(x.bar, a.foo); + a['run']({color: "blue", foo: "baz"}); } expect: { a["a"] = "bar"; a.b = "red"; x = {c: 10}; + a.d(x.c, a.a); + a['d']({b: "blue", a: "baz"}); } } mangle_unquoted_properties: { + options = { + properties: false + } mangle_props = { ignore_quoted: true } @@ -100,27 +107,37 @@ mangle_unquoted_properties: { keep_quoted_props: true, } input: { + a.top = 1; function f1() { a["foo"] = "bar"; a.color = "red"; - x = {"bar": 10}; + a.stuff = 2; + x = {"bar": 10, size: 7}; + a.size = 9; } function f2() { a.foo = "bar"; a['color'] = "red"; - x = {bar: 10}; + x = {bar: 10, size: 7}; + a.size = 9; + a.stuff = 3; } } expect: { + a.a = 1; function f1() { a["foo"] = "bar"; - a.a = "red"; - x = {"bar": 10}; + a.color = "red"; + a.b = 2; + x = {"bar": 10, c: 7}; + a.c = 9; } function f2() { - a.b = "bar"; + a.foo = "bar"; a['color'] = "red"; - x = {c: 10}; + x = {bar: 10, c: 7}; + a.c = 9; + a.b = 3; } } } From 37f4395cc0a48b76258f576a0849a4fb35767541 Mon Sep 17 00:00:00 2001 From: Timothy Gu Date: Thu, 11 Aug 2016 18:21:21 -0700 Subject: [PATCH 20/21] Add missing `{` in README Also fix a trivial style mistake. --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 61a6000e..4f5b21a0 100644 --- a/README.md +++ b/README.md @@ -732,10 +732,10 @@ Other options: UglifyJS.minify("tst.js").code; // 'function funcName(a,n){}var globalVar;' - UglifyJS.minify("tst.js", { mangle: { except: ['firstLongName'] }}).code; + UglifyJS.minify("tst.js", { mangle: { except: ['firstLongName'] } }).code; // 'function funcName(firstLongName,a){}var globalVar;' - UglifyJS.minify("tst.js", { mangle: toplevel: true }}).code; + UglifyJS.minify("tst.js", { mangle: { toplevel: true } }).code; // 'function n(n,a){}var a;' ``` From 781f26eda1327265f15ef5a213c69b5f9a551ca2 Mon Sep 17 00:00:00 2001 From: Richard van Velzen Date: Sun, 14 Aug 2016 22:02:01 +0200 Subject: [PATCH 21/21] v2.7.1 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index cc0917ed..2af9005f 100644 --- a/package.json +++ b/package.json @@ -4,7 +4,7 @@ "homepage": "http://lisperator.net/uglifyjs", "author": "Mihai Bazon (http://lisperator.net/)", "license": "BSD-2-Clause", - "version": "2.7.0", + "version": "2.7.1", "engines": { "node": ">=0.8.0" },