harmony-v3.0.26
This commit is contained in:
@@ -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)
|
||||||
|
|||||||
@@ -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": {
|
||||||
|
|||||||
@@ -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 = {
|
||||||
input: {
|
ascii_only: true,
|
||||||
var µþ = "µþ";
|
|
||||||
}
|
}
|
||||||
expect_exact: 'var µþ="\\xb5\\xfe";'
|
input: {
|
||||||
|
console.log("\ud83d", "\ude00", "\ud83d\ude00", "\ud83d@\ude00");
|
||||||
|
}
|
||||||
|
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");'
|
||||||
}
|
}
|
||||||
@@ -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));
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -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));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user