harmony-v3.0.26

This commit is contained in:
Alex Lam S.L
2017-07-23 16:54:46 +08:00
committed by GitHub
5 changed files with 123 additions and 64 deletions

View File

@@ -54,7 +54,6 @@ function OutputStream(options) {
options = defaults(options, { options = defaults(options, {
ascii_only : false, ascii_only : false,
ascii_identifiers: undefined,
beautify : false, beautify : false,
bracketize : false, bracketize : false,
comments : false, comments : false,
@@ -78,9 +77,6 @@ function OutputStream(options) {
wrap_iife : false, wrap_iife : false,
}, true); }, true);
if (typeof options.ascii_identifiers === 'undefined')
options.ascii_identifiers = options.ascii_only;
if (options.shorthand === undefined) if (options.shorthand === undefined)
options.shorthand = options.ecma > 5; options.shorthand = options.ecma > 5;
@@ -118,20 +114,16 @@ function OutputStream(options) {
var current_pos = 0; var current_pos = 0;
var OUTPUT = ""; var OUTPUT = "";
function to_ascii(str, identifier) { var to_utf8 = options.ascii_only ? function(str, identifier) {
return str.replace(/[\ud800-\udbff][\udc00-\udfff]|[\u0000-\u001f\u007f-\uffff]/g, function(ch) { if (options.ecma >= 6) {
str = str.replace(/[\ud800-\udbff][\udc00-\udfff]/g, function(ch) {
var code = get_full_char_code(ch, 0).toString(16); var code = get_full_char_code(ch, 0).toString(16);
if ((identifier && code.length === 1 && options.ecma >= 6) || code.length > 4) {
if (options.ecma < 6) {
if (identifier) {
return ch; // no \u{} support
}
return "\\u" + ch.charCodeAt(0).toString(16) + "\\u"
+ ch.charCodeAt(1).toString(16);
}
return "\\u{" + code + "}"; return "\\u{" + code + "}";
} else if (code.length <= 2 && !identifier) { });
}
return str.replace(/[\u0000-\u001f\u007f-\uffff]/g, function(ch) {
var code = ch.charCodeAt(0).toString(16);
if (code.length <= 2 && !identifier) {
while (code.length < 2) code = "0" + code; while (code.length < 2) code = "0" + code;
return "\\x" + code; return "\\x" + code;
} else { } else {
@@ -139,6 +131,12 @@ function OutputStream(options) {
return "\\u" + code; return "\\u" + code;
} }
}); });
} : function(str) {
return str.replace(/[\ud800-\udbff](?![\udc00-\udfff])/g, function(ch) {
return "\\u" + ch.charCodeAt(0).toString(16);
}).replace(/(^|[^\ud800-\udbff])([\udc00-\udfff])/g, function(match, prefix, ch) {
return prefix + "\\u" + ch.charCodeAt(0).toString(16);
});
}; };
function make_string(str, quote) { function make_string(str, quote) {
@@ -172,7 +170,7 @@ function OutputStream(options) {
function quote_template() { function quote_template() {
return '`' + str.replace(/`/g, '\\`') + '`'; return '`' + str.replace(/`/g, '\\`') + '`';
} }
if (options.ascii_only) str = to_ascii(str); str = to_utf8(str);
if (quote === "`") return quote_template(); if (quote === "`") return quote_template();
switch (options.quote_style) { switch (options.quote_style) {
case 1: case 1:
@@ -198,8 +196,7 @@ function OutputStream(options) {
function make_name(name) { function make_name(name) {
name = name.toString(); name = name.toString();
if (options.ascii_identifiers) name = to_utf8(name, true);
name = to_ascii(name, true);
return name; return name;
}; };
@@ -461,7 +458,7 @@ function OutputStream(options) {
last : function() { return last }, last : function() { return last },
semicolon : semicolon, semicolon : semicolon,
force_semicolon : force_semicolon, force_semicolon : force_semicolon,
to_ascii : to_ascii, to_utf8 : to_utf8,
print_name : function(name) { print(make_name(name)) }, print_name : function(name) { print(make_name(name)) },
print_string : function(str, quote, escape_directive) { print_string : function(str, quote, escape_directive) {
var encoded = encode_string(str, quote); var encoded = encode_string(str, quote);
@@ -1713,9 +1710,7 @@ function OutputStream(options) {
if (regexp.raw_source) { if (regexp.raw_source) {
str = "/" + regexp.raw_source + str.slice(str.lastIndexOf("/")); str = "/" + regexp.raw_source + str.slice(str.lastIndexOf("/"));
} }
if (output.option("ascii_only")) { str = output.to_utf8(str);
str = output.to_ascii(str);
}
output.print(str); output.print(str);
var p = output.parent(); var p = output.parent();
if (p instanceof AST_Binary && /^in/.test(p.operator) && p.left === self) if (p instanceof AST_Binary && /^in/.test(p.operator) && p.left === self)

View File

@@ -4,7 +4,7 @@
"homepage": "https://github.com/mishoo/UglifyJS2/tree/harmony", "homepage": "https://github.com/mishoo/UglifyJS2/tree/harmony",
"author": "Mihai Bazon <mihai.bazon@gmail.com> (http://lisperator.net/)", "author": "Mihai Bazon <mihai.bazon@gmail.com> (http://lisperator.net/)",
"license": "BSD-2-Clause", "license": "BSD-2-Clause",
"version": "3.0.25", "version": "3.0.26",
"engines": { "engines": {
"node": ">=0.8.0" "node": ">=0.8.0"
}, },
@@ -26,12 +26,12 @@
"LICENSE" "LICENSE"
], ],
"dependencies": { "dependencies": {
"commander": "~2.9.0", "commander": "~2.11.0",
"source-map": "~0.5.1" "source-map": "~0.5.1"
}, },
"devDependencies": { "devDependencies": {
"acorn": "~5.0.3", "acorn": "~5.1.1",
"mocha": "~2.3.4", "mocha": "~3.4.2",
"semver": "~5.3.0" "semver": "~5.3.0"
}, },
"scripts": { "scripts": {

View File

@@ -43,15 +43,6 @@ unicode_string_literals: {
expect_exact: 'var a="6 length unicode character: \\u{101111}";' expect_exact: 'var a="6 length unicode character: \\u{101111}";'
} }
// Don't escape identifiers below es6 (or in this case double escaped in expect_exact)
unicode_output_es5_surrogates: {
beautify = {ascii_only: true, ecma: 5}
input: {
var \u{10000} = "6 length unicode character: \u{10FFFF}";
}
expect_exact: 'var \u{10000}="6 length unicode character: \\udbff\\udfff";'
}
check_escape_style: { check_escape_style: {
beautify = {ascii_only: true, ecma: 6} beautify = {ascii_only: true, ecma: 6}
input: { input: {
@@ -65,20 +56,6 @@ check_escape_style: {
expect_exact: 'var a="\\x01";var \\ua0081="\\x10";var \\u0100="\\u0100";var \\u1000="\\u1000";var \\u{10000}="\\u{10000}";var \\u{2f800}="\\u{100000}";' expect_exact: 'var a="\\x01";var \\ua0081="\\x10";var \\u0100="\\u0100";var \\u1000="\\u1000";var \\u{10000}="\\u{10000}";var \\u{2f800}="\\u{100000}";'
} }
// Don't escape identifiers below es6, no escaped identifiers support and no \u{} syntax
check_escape_style_es5: {
beautify = {ascii_only: true, ecma: 5}
input: {
var a = "\x01";
var \ua0081 = "\x10"; // \u0081 only in ID_Continue
var \u0100 = "\u0100";
var \u1000 = "\u1000";
var \u{10000} = "\u{10000}"; // Identifier won't be escaped in es 5.1
var \u{2f800} = "\u{100000}"; // Same
}
expect_exact: 'var a="\\x01";var \\ua0081="\\x10";var \\u0100="\\u0100";var \\u1000="\\u1000";var \ud800\udc00="\\ud800\\udc00";var \ud87e\udc00="\\udbc0\\udc00";'
}
ID_continue_with_surrogate_pair: { ID_continue_with_surrogate_pair: {
beautify = {ascii_only: true, ecma: 6} beautify = {ascii_only: true, ecma: 6}
input: { input: {
@@ -103,18 +80,42 @@ non_escape_2_non_escape: {
expect_exact: 'var µþ="µþ";' expect_exact: 'var µþ="µþ";'
} }
non_escape_2_half_escape1: { issue_2242_1: {
beautify = {ascii_only: false, ascii_identifiers: true, ecma: 6} beautify = {
input: { ascii_only: false,
var µþ = "µþ";
} }
expect_exact: 'var \\u00b5\\u00fe="µþ";' input: {
console.log("\ud83d", "\ude00", "\ud83d\ude00", "\ud83d@\ude00");
}
expect_exact: 'console.log("\\ud83d","\\ude00","\ud83d\ude00","\\ud83d@\\ude00");'
} }
non_escape_2_half_escape2: { issue_2242_2: {
beautify = {ascii_only: true, ascii_identifiers: false, ecma: 6} beautify = {
ascii_only: true,
}
input: { input: {
var µþ = "µþ"; console.log("\ud83d", "\ude00", "\ud83d\ude00", "\ud83d@\ude00");
} }
expect_exact: 'var µþ="\\xb5\\xfe";' expect_exact: 'console.log("\\ud83d","\\ude00","\\ud83d\\ude00","\\ud83d@\\ude00");'
}
issue_2242_3: {
options = {
evaluate: false,
}
input: {
console.log("\ud83d" + "\ude00", "\ud83d" + "@" + "\ude00");
}
expect_exact: 'console.log("\\ud83d"+"\\ude00","\\ud83d"+"@"+"\\ude00");'
}
issue_2242_4: {
options = {
evaluate: true,
}
input: {
console.log("\ud83d" + "\ude00", "\ud83d" + "@" + "\ude00");
}
expect_exact: 'console.log("\ud83d\ude00","\\ud83d@\\ude00");'
} }

View File

@@ -78,4 +78,41 @@ describe("String literals", function() {
assert.equal(UglifyJS.parse('"use strict";"\\08"').print_to_string(), '"use strict";"\\08";'); assert.equal(UglifyJS.parse('"use strict";"\\08"').print_to_string(), '"use strict";"\\08";');
assert.equal(UglifyJS.parse('"use strict";"\\09"').print_to_string(), '"use strict";"\\09";'); assert.equal(UglifyJS.parse('"use strict";"\\09"').print_to_string(), '"use strict";"\\09";');
}); });
it("Should not unescape unpaired surrogates", function() {
var code = [];
for (var i = 0; i <= 0xF; i++) {
code.push("\\u000" + i.toString(16));
}
for (;i <= 0xFF; i++) {
code.push("\\u00" + i.toString(16));
}
for (;i <= 0xFFF; i++) {
code.push("\\u0" + i.toString(16));
}
for (; i <= 0xFFFF; i++) {
code.push("\\u" + i.toString(16));
}
code = '"' + code.join() + '"';
var normal = UglifyJS.minify(code, {
compress: false,
mangle: false,
output: {
ascii_only: false
}
});
if (normal.error) throw normal.error;
assert.ok(code.length > normal.code.length);
assert.strictEqual(eval(code), eval(normal.code));
var ascii = UglifyJS.minify(code, {
compress: false,
mangle: false,
output: {
ascii_only: false
}
});
if (ascii.error) throw ascii.error;
assert.ok(code.length > ascii.code.length);
assert.strictEqual(eval(code), eval(ascii.code));
});
}); });

View File

@@ -1,4 +1,5 @@
var assert = require("assert"); var assert = require("assert");
var semver = require("semver");
var uglify = require("../node"); var uglify = require("../node");
describe("Unicode", function() { describe("Unicode", function() {
@@ -138,8 +139,33 @@ describe("Unicode", function() {
it("Should parse raw characters correctly", function() { it("Should parse raw characters correctly", function() {
var ast = uglify.parse('console.log("\\udbff");'); var ast = uglify.parse('console.log("\\udbff");');
assert.strictEqual(ast.print_to_string(), 'console.log("\udbff");'); assert.strictEqual(ast.print_to_string(), 'console.log("\\udbff");');
ast = uglify.parse(ast.print_to_string()); ast = uglify.parse(ast.print_to_string());
assert.strictEqual(ast.print_to_string(), 'console.log("\udbff");'); assert.strictEqual(ast.print_to_string(), 'console.log("\\udbff");');
});
if (semver.satisfies(process.version, ">=4")) {
it("Should not unescape unpaired surrogates", function() {
var code = [];
for (var i = 0; i <= 0xFFFF; i++) {
code.push("\\u{" + i.toString(16) + "}");
}
code = '"' + code.join() + '"';
[true, false].forEach(function(ascii_only) {
[5, 6].forEach(function(ecma) {
var result = uglify.minify(code, {
compress: false,
mangle: false,
output: {
ascii_only: ascii_only
},
ecma: ecma
});
if (result.error) throw result.error;
assert.ok(code.length > result.code.length);
assert.strictEqual(eval(code), eval(result.code));
}); });
}); });
});
}
});