Compare commits
17 Commits
harmony-v3
...
harmony-v3
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1e9ef17e32 | ||
|
|
222100ea4c | ||
|
|
5fd8244a2e | ||
|
|
93db48a317 | ||
|
|
2944e3df7d | ||
|
|
c14e280585 | ||
|
|
bc3fa78e8c | ||
|
|
8c7c107765 | ||
|
|
e0ae8da089 | ||
|
|
81f1311b24 | ||
|
|
2433bb4e52 | ||
|
|
3dd328dce3 | ||
|
|
014f428153 | ||
|
|
a3b2eb75bd | ||
|
|
da295de82b | ||
|
|
4f8ca4626e | ||
|
|
e54748365c |
22
README.md
22
README.md
@@ -95,8 +95,9 @@ The available options are:
|
||||
`wrap_iife` Wrap IIFEs in parenthesis. Note: you may
|
||||
want to disable `negate_iife` under
|
||||
compressor options.
|
||||
-o, --output <file> Output file (default STDOUT). Specify "spidermonkey"
|
||||
to dump SpiderMonkey AST format (as JSON) to STDOUT.
|
||||
-o, --output <file> Output file path (default STDOUT). Specify `ast` or
|
||||
`spidermonkey` to write UglifyJS or SpiderMonkey AST
|
||||
as JSON to STDOUT respectively.
|
||||
--comments [filter] Preserve copyright comments in the output. By
|
||||
default this works like Google Closure, keeping
|
||||
JSDoc-style comments that contain "@license" or
|
||||
@@ -489,21 +490,21 @@ can pass additional arguments that control the code output:
|
||||
Passing `-b` will set this to true, but you might need to pass `-b` even
|
||||
when you want to generate minified code, in order to specify additional
|
||||
arguments, so you can use `-b beautify=false` to override it.
|
||||
- `indent-level` (default 4)
|
||||
- `indent-start` (default 0) -- prefix all lines by that many spaces
|
||||
- `quote-keys` (default `false`) -- pass `true` to quote all keys in literal
|
||||
- `indent_level` (default 4)
|
||||
- `indent_start` (default 0) -- prefix all lines by that many spaces
|
||||
- `quote_keys` (default `false`) -- pass `true` to quote all keys in literal
|
||||
objects
|
||||
- `space-colon` (default `true`) -- insert a space after the colon signs
|
||||
- `ascii-only` (default `false`) -- escape Unicode characters in strings and
|
||||
- `space_colon` (default `true`) -- insert a space after the colon signs
|
||||
- `ascii_only` (default `false`) -- escape Unicode characters in strings and
|
||||
regexps (affects directives with non-ascii characters becoming invalid)
|
||||
- `inline-script` (default `false`) -- escape the slash in occurrences of
|
||||
- `inline_script` (default `false`) -- escape the slash in occurrences of
|
||||
`</script` in strings
|
||||
- `width` (default 80) -- only takes effect when beautification is on, this
|
||||
specifies an (orientative) line width that the beautifier will try to
|
||||
obey. It refers to the width of the line text (excluding indentation).
|
||||
It doesn't work very well currently, but it does make the code generated
|
||||
by UglifyJS more readable.
|
||||
- `max-line-len` (default 32000) -- maximum line length (for uglified code)
|
||||
- `max_line_len` (default 32000) -- maximum line length (for uglified code)
|
||||
- `bracketize` (default `false`) -- always insert brackets in `if`, `for`,
|
||||
`do`, `while` or `with` statements, even if their body is a single
|
||||
statement.
|
||||
@@ -598,7 +599,8 @@ performs all the steps in a configurable manner.
|
||||
Example:
|
||||
```javascript
|
||||
var result = UglifyJS.minify("var b = function() {};");
|
||||
console.log(result.code); // minified output
|
||||
console.log(result.code); // minified output
|
||||
console.log(result.error); // runtime error
|
||||
```
|
||||
|
||||
You can also compress multiple files:
|
||||
|
||||
73
bin/uglifyjs
73
bin/uglifyjs
@@ -15,6 +15,7 @@ var path = require("path");
|
||||
var program = require("commander");
|
||||
var UglifyJS = require("../tools/node");
|
||||
|
||||
var skip_keys = [ "cname", "enclosed", "parent_scope", "scope", "thedef", "uses_eval", "uses_with" ];
|
||||
var files = {};
|
||||
var options = {
|
||||
compress: false,
|
||||
@@ -89,7 +90,7 @@ if (program.mangleProps) {
|
||||
if (typeof program.mangleProps != "object") program.mangleProps = {};
|
||||
if (!Array.isArray(program.mangleProps.reserved)) program.mangleProps.reserved = [];
|
||||
require("../tools/domprops").forEach(function(name) {
|
||||
UglifyJS.push_uniq(program.mangleProps.reserved, name);
|
||||
UglifyJS._push_uniq(program.mangleProps.reserved, name);
|
||||
});
|
||||
}
|
||||
if (typeof options.mangle != "object") options.mangle = {};
|
||||
@@ -107,6 +108,12 @@ if (program.nameCache) {
|
||||
}
|
||||
}
|
||||
}
|
||||
if (program.output == "ast") {
|
||||
options.output = {
|
||||
ast: true,
|
||||
code: false
|
||||
};
|
||||
}
|
||||
if (program.parse) {
|
||||
if (program.parse.acorn || program.parse.spidermonkey) {
|
||||
if (program.sourceMap) fatal("ERROR: inline source map only works with built-in parser");
|
||||
@@ -165,7 +172,7 @@ function run() {
|
||||
UglifyJS.AST_Node.warn_function = function(msg) {
|
||||
console.error("WARN:", msg);
|
||||
};
|
||||
if (program.stats) program.stats = Date.now();
|
||||
if (program.stats) program.stats = Date.now();
|
||||
try {
|
||||
if (program.parse) {
|
||||
if (program.parse.acorn) {
|
||||
@@ -185,9 +192,13 @@ function run() {
|
||||
});
|
||||
}
|
||||
}
|
||||
var result = UglifyJS.minify(files, options);
|
||||
} catch (ex) {
|
||||
if (ex instanceof UglifyJS.JS_Parse_Error) {
|
||||
fatal(ex.stack);
|
||||
}
|
||||
var result = UglifyJS.minify(files, options);
|
||||
if (result.error) {
|
||||
var ex = result.error;
|
||||
if (ex.name == "SyntaxError") {
|
||||
console.error("Parse error at " + ex.filename + ":" + ex.line + "," + ex.col);
|
||||
var col = ex.col;
|
||||
var lines = files[ex.filename].split(/\r?\n/);
|
||||
@@ -209,10 +220,32 @@ function run() {
|
||||
console.error("Supported options:");
|
||||
console.error(ex.defs);
|
||||
}
|
||||
fatal("ERROR: " + ex.message);
|
||||
}
|
||||
if (program.output == "spidermonkey") {
|
||||
console.log(JSON.stringify(UglifyJS.parse(new Buffer(result.code).toString()).to_mozilla_ast(), null, 2));
|
||||
fatal(ex.stack);
|
||||
} else if (program.output == "ast") {
|
||||
console.log(JSON.stringify(result.ast, function(key, value) {
|
||||
if (skip_key(key)) return;
|
||||
if (value instanceof UglifyJS.AST_Token) return;
|
||||
if (value instanceof UglifyJS.Dictionary) return;
|
||||
if (value instanceof UglifyJS.AST_Node) {
|
||||
var result = {
|
||||
_class: "AST_" + value.TYPE
|
||||
};
|
||||
value.CTOR.PROPS.forEach(function(prop) {
|
||||
result[prop] = value[prop];
|
||||
});
|
||||
return result;
|
||||
}
|
||||
return value;
|
||||
}, 2));
|
||||
} else if (program.output == "spidermonkey") {
|
||||
console.log(JSON.stringify(UglifyJS.minify(result.code, {
|
||||
compress: false,
|
||||
mangle: false,
|
||||
output: {
|
||||
ast: true,
|
||||
code: false
|
||||
}
|
||||
}).ast.to_mozilla_ast(), null, 2));
|
||||
} else if (program.output) {
|
||||
fs.writeFileSync(program.output, result.code);
|
||||
if (result.map) {
|
||||
@@ -230,8 +263,8 @@ function run() {
|
||||
}
|
||||
|
||||
function fatal(message) {
|
||||
console.error(message);
|
||||
process.exit(1);
|
||||
console.error(message.replace(/^\S*?Error:/, "ERROR:"));
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
// A file glob function that only supports "*" and "?" wildcards in the basename.
|
||||
@@ -270,7 +303,7 @@ function read_file(path, default_value) {
|
||||
return fs.readFileSync(path, "utf8");
|
||||
} catch (ex) {
|
||||
if (ex.code == "ENOENT" && default_value != null) return default_value;
|
||||
fatal("ERROR: " + ex.message);
|
||||
fatal(ex.stack);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -278,9 +311,17 @@ function parse_js(flag, constants) {
|
||||
return function(value, options) {
|
||||
options = options || {};
|
||||
try {
|
||||
UglifyJS.parse(value, {
|
||||
expression: true
|
||||
}).walk(new UglifyJS.TreeWalker(function(node) {
|
||||
UglifyJS.minify(value, {
|
||||
parse: {
|
||||
expression: true
|
||||
},
|
||||
compress: false,
|
||||
mangle: false,
|
||||
output: {
|
||||
ast: true,
|
||||
code: false
|
||||
}
|
||||
}).ast.walk(new UglifyJS.TreeWalker(function(node) {
|
||||
if (node instanceof UglifyJS.AST_Assign) {
|
||||
var name = node.left.print_to_string();
|
||||
var value = node.right;
|
||||
@@ -337,3 +378,7 @@ function to_cache(key) {
|
||||
}
|
||||
return cache[key];
|
||||
}
|
||||
|
||||
function skip_key(key) {
|
||||
return skip_keys.indexOf(key) >= 0;
|
||||
}
|
||||
|
||||
@@ -857,7 +857,7 @@ var AST_UnaryPostfix = DEFNODE("UnaryPostfix", null, {
|
||||
$documentation: "Unary postfix expression, i.e. `i++`"
|
||||
}, AST_Unary);
|
||||
|
||||
var AST_Binary = DEFNODE("Binary", "left operator right", {
|
||||
var AST_Binary = DEFNODE("Binary", "operator left right", {
|
||||
$documentation: "Binary expression, i.e. `a + b`",
|
||||
$propdoc: {
|
||||
left: "[AST_Node] left-hand side expression",
|
||||
|
||||
@@ -799,7 +799,7 @@ merge(Compressor.prototype, {
|
||||
}
|
||||
|
||||
function get_lhs(expr) {
|
||||
if (expr instanceof AST_VarDef) {
|
||||
if (expr instanceof AST_VarDef && expr.name instanceof AST_SymbolDeclaration) {
|
||||
var def = expr.name.definition();
|
||||
if (def.orig.length > 1
|
||||
|| def.references.length == 1 && (!def.global || compressor.toplevel(def))) {
|
||||
|
||||
@@ -108,38 +108,46 @@ function minify(files, options) {
|
||||
toplevel = mangle_properties(toplevel, options.mangle.properties);
|
||||
}
|
||||
}
|
||||
if (options.sourceMap) {
|
||||
if (typeof options.sourceMap.content == "string") {
|
||||
options.sourceMap.content = JSON.parse(options.sourceMap.content);
|
||||
}
|
||||
options.output.source_map = SourceMap({
|
||||
file: options.sourceMap.filename,
|
||||
orig: options.sourceMap.content,
|
||||
root: options.sourceMap.root
|
||||
});
|
||||
if (options.sourceMap.includeSources) {
|
||||
for (var name in files) {
|
||||
options.output.source_map.get().setSourceContent(name, files[name]);
|
||||
var result = {};
|
||||
if (options.output.ast) {
|
||||
result.ast = toplevel;
|
||||
}
|
||||
if (!HOP(options.output, "code") || options.output.code) {
|
||||
if (options.sourceMap) {
|
||||
if (typeof options.sourceMap.content == "string") {
|
||||
options.sourceMap.content = JSON.parse(options.sourceMap.content);
|
||||
}
|
||||
options.output.source_map = SourceMap({
|
||||
file: options.sourceMap.filename,
|
||||
orig: options.sourceMap.content,
|
||||
root: options.sourceMap.root
|
||||
});
|
||||
if (options.sourceMap.includeSources) {
|
||||
for (var name in files) {
|
||||
options.output.source_map.get().setSourceContent(name, files[name]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
var stream = OutputStream(options.output);
|
||||
toplevel.print(stream);
|
||||
var result = {
|
||||
code: stream.get()
|
||||
};
|
||||
if (options.sourceMap) {
|
||||
result.map = options.output.source_map.toString();
|
||||
if (options.sourceMap.url == "inline") {
|
||||
result.code += "\n//# sourceMappingURL=data:application/json;charset=utf-8;base64," + to_base64(result.map);
|
||||
} else if (options.sourceMap.url) {
|
||||
result.code += "\n//# sourceMappingURL=" + options.sourceMap.url;
|
||||
delete options.output.ast;
|
||||
delete options.output.code;
|
||||
var stream = OutputStream(options.output);
|
||||
toplevel.print(stream);
|
||||
result.code = stream.get();
|
||||
if (options.sourceMap) {
|
||||
result.map = options.output.source_map.toString();
|
||||
if (options.sourceMap.url == "inline") {
|
||||
result.code += "\n//# sourceMappingURL=data:application/json;charset=utf-8;base64," + to_base64(result.map);
|
||||
} else if (options.sourceMap.url) {
|
||||
result.code += "\n//# sourceMappingURL=" + options.sourceMap.url;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (warnings.length) {
|
||||
result.warnings = warnings;
|
||||
}
|
||||
return result;
|
||||
} catch (ex) {
|
||||
return { error: ex };
|
||||
} finally {
|
||||
AST_Node.warn_function = warn_function;
|
||||
}
|
||||
|
||||
@@ -215,16 +215,6 @@ function OutputStream(options) {
|
||||
var might_add_newline = 0;
|
||||
var last = "";
|
||||
|
||||
function last_char() {
|
||||
var char = last.charAt(last.length - 1);
|
||||
|
||||
if (is_surrogate_pair_tail(char)) {
|
||||
return last.charAt(last.length - 2) + char;
|
||||
}
|
||||
|
||||
return char;
|
||||
};
|
||||
|
||||
var ensure_line_len = options.max_line_len ? function() {
|
||||
if (current_col > options.max_line_len) {
|
||||
if (might_add_newline) {
|
||||
@@ -247,7 +237,7 @@ function OutputStream(options) {
|
||||
function print(str) {
|
||||
str = String(str);
|
||||
var ch = get_full_char(str, 0);
|
||||
var prev = last_char();
|
||||
var prev = get_full_char(last, last.length - 1);
|
||||
if (might_need_semicolon) {
|
||||
might_need_semicolon = false;
|
||||
|
||||
|
||||
19
lib/parse.js
19
lib/parse.js
@@ -134,8 +134,17 @@ var UNICODE = {
|
||||
|
||||
function get_full_char(str, pos) {
|
||||
var char = str.charAt(pos);
|
||||
if (char >= "\ud800" && char <= "\udbff") {
|
||||
return char + str.charAt(pos + 1);
|
||||
if (is_surrogate_pair_head(char)) {
|
||||
var next = str.charAt(pos + 1);
|
||||
if (is_surrogate_pair_tail(next)) {
|
||||
return char + next;
|
||||
}
|
||||
}
|
||||
if (is_surrogate_pair_tail(char)) {
|
||||
var prev = str.charAt(pos - 1);
|
||||
if (is_surrogate_pair_head(prev)) {
|
||||
return prev + char;
|
||||
}
|
||||
}
|
||||
return char;
|
||||
}
|
||||
@@ -152,8 +161,8 @@ function get_full_char_length(str) {
|
||||
var surrogates = 0;
|
||||
|
||||
for (var i = 0; i < str.length; i++) {
|
||||
if (str.charCodeAt(i) >= 0xd800 && str.charCodeAt(i) <= 0xdbff) {
|
||||
if (str.charCodeAt(i + 1) >= 0xdc00 && str.charCodeAt(i + 1) <= 0xdfff) {
|
||||
if (is_surrogate_pair_head(str.charCodeAt(i))) {
|
||||
if (is_surrogate_pair_tail(str.charCodeAt(i + 1))) {
|
||||
surrogates++;
|
||||
i++;
|
||||
}
|
||||
@@ -291,7 +300,7 @@ function tokenizer($TEXT, filename, html5_comments, shebang) {
|
||||
ch = "\n";
|
||||
}
|
||||
} else {
|
||||
if (is_surrogate_pair_head(ch)) {
|
||||
if (ch.length > 1) {
|
||||
++S.pos;
|
||||
++S.col;
|
||||
}
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
{
|
||||
"name": "uglify-js",
|
||||
"name": "uglify-es",
|
||||
"description": "JavaScript parser, mangler/compressor and beautifier toolkit",
|
||||
"homepage": "http://lisperator.net/uglifyjs",
|
||||
"author": "Mihai Bazon <mihai.bazon@gmail.com> (http://lisperator.net/)",
|
||||
"license": "BSD-2-Clause",
|
||||
"version": "3.0.0",
|
||||
"version": "3.0.2",
|
||||
"engines": {
|
||||
"node": ">=0.8.0"
|
||||
},
|
||||
|
||||
@@ -315,3 +315,18 @@ unused: {
|
||||
console.log(a);
|
||||
}
|
||||
}
|
||||
|
||||
issue_1886: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
}
|
||||
input: {
|
||||
let [a] = [1];
|
||||
console.log(a);
|
||||
}
|
||||
expect: {
|
||||
let [a] = [1];
|
||||
console.log(a);
|
||||
}
|
||||
expect_exact: "1"
|
||||
}
|
||||
|
||||
13
test/exports.js
Normal file
13
test/exports.js
Normal file
@@ -0,0 +1,13 @@
|
||||
exports["Compressor"] = Compressor;
|
||||
exports["JS_Parse_Error"] = JS_Parse_Error;
|
||||
exports["OutputStream"] = OutputStream;
|
||||
exports["SourceMap"] = SourceMap;
|
||||
exports["TreeWalker"] = TreeWalker;
|
||||
exports["base54"] = base54;
|
||||
exports["defaults"] = defaults;
|
||||
exports["mangle_properties"] = mangle_properties;
|
||||
exports["minify"] = minify;
|
||||
exports["parse"] = parse;
|
||||
exports["string_template"] = string_template;
|
||||
exports["tokenizer"] = tokenizer;
|
||||
exports["is_identifier"] = is_identifier;
|
||||
@@ -1,4 +1,4 @@
|
||||
var UglifyJS = require('../../');
|
||||
var UglifyJS = require("../node");
|
||||
var assert = require("assert");
|
||||
|
||||
describe("Accessor tokens", function() {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
var UglifyJS = require('../../');
|
||||
var UglifyJS = require("../node");
|
||||
var assert = require("assert");
|
||||
|
||||
describe("arguments", function() {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
var assert = require("assert");
|
||||
var uglify = require("../../");
|
||||
var uglify = require("../node");
|
||||
|
||||
describe("Arrow functions", function() {
|
||||
it("Should not accept spread tokens on non-last parameters or without arguments parentheses", function() {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
var assert = require("assert");
|
||||
var uglify = require("../../");
|
||||
var uglify = require("../node");
|
||||
|
||||
describe("Class", function() {
|
||||
it("Should not accept spread on non-last parameters in methods", function() {
|
||||
|
||||
@@ -19,7 +19,7 @@ describe("bin/uglifyjs", function () {
|
||||
eval(stdout);
|
||||
|
||||
assert.strictEqual(typeof WrappedUglifyJS, 'object');
|
||||
assert.strictEqual(true, WrappedUglifyJS.parse('foo;') instanceof WrappedUglifyJS.AST_Node);
|
||||
assert.strictEqual(WrappedUglifyJS.minify("foo([true,,2+3]);").code, "foo([!0,,5]);");
|
||||
|
||||
done();
|
||||
});
|
||||
@@ -185,7 +185,7 @@ describe("bin/uglifyjs", function () {
|
||||
|
||||
exec(command, function (err, stdout, stderr) {
|
||||
assert.ok(err);
|
||||
assert.strictEqual(stderr, "ERROR: inline source map only works with singular input\n");
|
||||
assert.strictEqual(stderr.split(/\n/)[0], "ERROR: inline source map only works with singular input");
|
||||
done();
|
||||
});
|
||||
});
|
||||
@@ -509,4 +509,15 @@ describe("bin/uglifyjs", function () {
|
||||
return JSON.stringify(map).replace(/"/g, '\\"');
|
||||
}
|
||||
});
|
||||
it("Should dump AST as JSON", function(done) {
|
||||
var command = uglifyjscmd + " test/input/global_defs/simple.js -mco ast";
|
||||
exec(command, function (err, stdout) {
|
||||
if (err) throw err;
|
||||
|
||||
var ast = JSON.parse(stdout);
|
||||
assert.strictEqual(ast._class, "AST_Toplevel");
|
||||
assert.ok(Array.isArray(ast.body));
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
var UglifyJS = require('../../');
|
||||
var UglifyJS = require("../node");
|
||||
var assert = require("assert");
|
||||
|
||||
describe("comment filters", function() {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
var assert = require("assert");
|
||||
var uglify = require("../../");
|
||||
var uglify = require("../node");
|
||||
|
||||
describe("Comment", function() {
|
||||
it("Should recognize eol of single line comments", function() {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
var assert = require("assert");
|
||||
var uglify = require("../../");
|
||||
var uglify = require("../node");
|
||||
|
||||
describe("Destructuring", function() {
|
||||
it("Should generate similar trees for destructuring in left hand side expressions, definitions, functions and arrow functions", function() {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
var assert = require("assert");
|
||||
var uglify = require("../../");
|
||||
var uglify = require("../node");
|
||||
|
||||
describe("Directives", function() {
|
||||
it ("Should allow tokenizer to store directives state", function() {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
var assert = require("assert");
|
||||
var uglify = require("../../");
|
||||
var uglify = require("../node");
|
||||
|
||||
describe("EOF", function() {
|
||||
it("Should test code for at least throwing syntax error when incomplete", function() {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
var assert = require("assert");
|
||||
var uglify = require("../../");
|
||||
var uglify = require("../node");
|
||||
|
||||
describe("Export", function() {
|
||||
it ("Should parse export directives", function() {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
var assert = require("assert");
|
||||
var uglify = require("../../");
|
||||
var uglify = require("../node");
|
||||
|
||||
describe("Expression", function() {
|
||||
it("Should not allow the first exponentiation operator to be prefixed with an unary operator", function() {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
var assert = require("assert");
|
||||
var uglify = require("../../");
|
||||
var uglify = require("../node");
|
||||
|
||||
describe("Function", function() {
|
||||
it ("Should parse binding patterns correctly", function() {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
var UglifyJS = require('../../');
|
||||
var UglifyJS = require("../node");
|
||||
var assert = require("assert");
|
||||
|
||||
describe("Getters and setters", function() {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
var assert = require("assert");
|
||||
var uglify = require("../../");
|
||||
var uglify = require("../node");
|
||||
|
||||
describe("Left-hand side expressions", function () {
|
||||
it("Should parse destructuring with const/let/var correctly", function () {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
var Uglify = require('../../');
|
||||
var Uglify = require("../node");
|
||||
var assert = require("assert");
|
||||
|
||||
describe("line-endings", function() {
|
||||
|
||||
@@ -114,17 +114,18 @@ describe("minify", function() {
|
||||
}
|
||||
});
|
||||
it("Should fail with multiple input and inline source map", function() {
|
||||
assert.throws(function() {
|
||||
Uglify.minify([
|
||||
read("./test/input/issue-520/input.js"),
|
||||
read("./test/input/issue-520/output.js")
|
||||
], {
|
||||
sourceMap: {
|
||||
content: "inline",
|
||||
url: "inline"
|
||||
}
|
||||
});
|
||||
var result = Uglify.minify([
|
||||
read("./test/input/issue-520/input.js"),
|
||||
read("./test/input/issue-520/output.js")
|
||||
], {
|
||||
sourceMap: {
|
||||
content: "inline",
|
||||
url: "inline"
|
||||
}
|
||||
});
|
||||
var err = result.error;
|
||||
assert.ok(err instanceof Error);
|
||||
assert.strictEqual(err.stack.split(/\n/)[0], "Error: inline source map only works with singular input");
|
||||
});
|
||||
});
|
||||
|
||||
@@ -170,26 +171,14 @@ describe("minify", function() {
|
||||
});
|
||||
|
||||
describe("JS_Parse_Error", function() {
|
||||
it("should throw syntax error", function() {
|
||||
assert.throws(function() {
|
||||
Uglify.minify("function f(a{}");
|
||||
}, function(err) {
|
||||
assert.ok(err instanceof Error);
|
||||
assert.strictEqual(err.stack.split(/\n/)[0], "SyntaxError: Unexpected token punc «{», expected punc «,»");
|
||||
assert.strictEqual(err.filename, "0");
|
||||
assert.strictEqual(err.line, 1);
|
||||
assert.strictEqual(err.col, 12);
|
||||
return true;
|
||||
});
|
||||
it("should return syntax error", function() {
|
||||
var result = Uglify.minify("function f(a{}");
|
||||
var err = result.error;
|
||||
assert.ok(err instanceof Error);
|
||||
assert.strictEqual(err.stack.split(/\n/)[0], "SyntaxError: Unexpected token punc «{», expected punc «,»");
|
||||
assert.strictEqual(err.filename, "0");
|
||||
assert.strictEqual(err.line, 1);
|
||||
assert.strictEqual(err.col, 12);
|
||||
});
|
||||
});
|
||||
|
||||
describe("Compressor", function() {
|
||||
it("should be backward compatible with ast.transform(compressor)", function() {
|
||||
var ast = Uglify.parse("function f(a){for(var i=0;i<a;i++)console.log(i)}");
|
||||
ast.figure_out_scope();
|
||||
ast = ast.transform(Uglify.Compressor());
|
||||
assert.strictEqual(ast.print_to_string(), "function f(a){for(var i=0;i<a;i++)console.log(i)}");
|
||||
});
|
||||
})
|
||||
});
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
var assert = require("assert");
|
||||
var uglify = require("../../");
|
||||
var uglify = require("../node");
|
||||
|
||||
describe("New", function() {
|
||||
it("Should add trailing parentheses for new expressions with zero arguments in beautify mode", function() {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
var assert = require("assert");
|
||||
var uglify = require("../../");
|
||||
var uglify = require("../node");
|
||||
|
||||
describe("Number literals", function () {
|
||||
it("Should not allow legacy octal literals in strict mode", function() {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
var Uglify = require("../../");
|
||||
var Uglify = require("../node");
|
||||
var assert = require("assert");
|
||||
|
||||
describe("Object", function() {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
var UglifyJS = require("../../");
|
||||
var UglifyJS = require("../node");
|
||||
var assert = require("assert");
|
||||
|
||||
describe("operator", function() {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
var assert = require("assert");
|
||||
var exec = require("child_process").exec;
|
||||
var uglify = require("../../");
|
||||
var uglify = require("../node");
|
||||
|
||||
describe("spidermonkey export/import sanity test", function() {
|
||||
it("should produce a functional build when using --self with spidermonkey", function(done) {
|
||||
@@ -15,18 +15,7 @@ describe("spidermonkey export/import sanity test", function() {
|
||||
|
||||
eval(stdout);
|
||||
assert.strictEqual(typeof SpiderUglify, "object");
|
||||
|
||||
var ast = SpiderUglify.parse("foo([true,,2+3]);");
|
||||
assert.strictEqual(true, ast instanceof SpiderUglify.AST_Node);
|
||||
|
||||
ast.figure_out_scope();
|
||||
ast = SpiderUglify.Compressor({}).compress(ast);
|
||||
assert.strictEqual(true, ast instanceof SpiderUglify.AST_Node);
|
||||
|
||||
var stream = SpiderUglify.OutputStream({});
|
||||
ast.print(stream);
|
||||
var code = stream.toString();
|
||||
assert.strictEqual(code, "foo([!0,,5]);");
|
||||
assert.strictEqual(SpiderUglify.minify("foo([true,,2+3]);").code, "foo([!0,,5]);");
|
||||
|
||||
done();
|
||||
});
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
var UglifyJS = require('../../');
|
||||
var UglifyJS = require("../node");
|
||||
var assert = require("assert");
|
||||
|
||||
describe("String literals", function() {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
var assert = require("assert");
|
||||
var uglify = require("../../");
|
||||
var uglify = require("../node");
|
||||
|
||||
describe("Template string", function() {
|
||||
it("Should not accept invalid sequences", function() {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
var assert = require("assert");
|
||||
var uglify = require("../../");
|
||||
var uglify = require("../node");
|
||||
|
||||
describe("Try", function() {
|
||||
it("Should not allow catch with an empty parameter", function() {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
var assert = require("assert");
|
||||
var uglify = require("../../");
|
||||
var uglify = require("../node");
|
||||
|
||||
describe("Unicode", function() {
|
||||
it("Should not accept invalid code ranges in unicode escape", function() {
|
||||
@@ -135,4 +135,11 @@ describe("Unicode", function() {
|
||||
}).code, tests[i][1]);
|
||||
}
|
||||
});
|
||||
|
||||
it("Should parse raw characters correctly", function() {
|
||||
var ast = uglify.parse('console.log("\\udbff");');
|
||||
assert.strictEqual(ast.print_to_string(), 'console.log("\udbff");');
|
||||
ast = uglify.parse(ast.print_to_string());
|
||||
assert.strictEqual(ast.print_to_string(), 'console.log("\udbff");');
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
var assert = require("assert");
|
||||
var uglify = require("../../");
|
||||
var uglify = require("../node");
|
||||
|
||||
describe("With", function() {
|
||||
it("Should throw syntaxError when using with statement in strict mode", function() {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
var UglifyJS = require("../../");
|
||||
var UglifyJS = require("../node");
|
||||
var assert = require("assert");
|
||||
|
||||
describe("Yield", function() {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// Testing UglifyJS <-> SpiderMonkey AST conversion
|
||||
// through generative testing.
|
||||
|
||||
var UglifyJS = require(".."),
|
||||
var UglifyJS = require("./node"),
|
||||
escodegen = require("escodegen"),
|
||||
esfuzz = require("esfuzz"),
|
||||
estraverse = require("estraverse"),
|
||||
|
||||
6
test/node.js
Normal file
6
test/node.js
Normal file
@@ -0,0 +1,6 @@
|
||||
var fs = require("fs");
|
||||
|
||||
new Function("MOZ_SourceMap", "exports", require("../tools/node").FILES.map(function(file) {
|
||||
if (/exports\.js$/.test(file)) file = require.resolve("./exports");
|
||||
return fs.readFileSync(file, "utf8");
|
||||
}).join("\n\n"))(require("source-map"), exports);
|
||||
@@ -1,6 +1,6 @@
|
||||
#! /usr/bin/env node
|
||||
|
||||
var U = require("../tools/node");
|
||||
var U = require("./node");
|
||||
var path = require("path");
|
||||
var fs = require("fs");
|
||||
var assert = require("assert");
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
var UglifyJS = require("..");
|
||||
var UglifyJS = require("./node");
|
||||
var ok = require("assert");
|
||||
|
||||
module.exports = function () {
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
stream._handle.setBlocking(true);
|
||||
});
|
||||
|
||||
var UglifyJS = require("..");
|
||||
var UglifyJS = require("./node");
|
||||
var randomBytes = require("crypto").randomBytes;
|
||||
var sandbox = require("./sandbox");
|
||||
|
||||
@@ -856,23 +856,21 @@ function createVarName(maybe, dontStore) {
|
||||
}
|
||||
|
||||
function try_beautify(code, result) {
|
||||
try {
|
||||
var beautified = UglifyJS.minify(code, {
|
||||
compress: false,
|
||||
mangle: false,
|
||||
output: {
|
||||
beautify: true,
|
||||
bracketize: true,
|
||||
},
|
||||
}).code;
|
||||
if (sandbox.same_stdout(sandbox.run_code(beautified), result)) {
|
||||
console.log("// (beautified)");
|
||||
console.log(beautified);
|
||||
return;
|
||||
}
|
||||
} catch (e) {
|
||||
var beautified = UglifyJS.minify(code, {
|
||||
compress: false,
|
||||
mangle: false,
|
||||
output: {
|
||||
beautify: true,
|
||||
bracketize: true,
|
||||
},
|
||||
});
|
||||
if (beautified.error) {
|
||||
console.log("// !!! beautify failed !!!");
|
||||
console.log(e.stack);
|
||||
console.log(beautified.error.stack);
|
||||
} else if (sandbox.same_stdout(sandbox.run_code(beautified.code), result)) {
|
||||
console.log("// (beautified)");
|
||||
console.log(beautified.code);
|
||||
return;
|
||||
}
|
||||
console.log("//");
|
||||
console.log(code);
|
||||
@@ -908,12 +906,13 @@ function log_suspects(minify_options, component) {
|
||||
var o = JSON.parse(JSON.stringify(options));
|
||||
o[name] = false;
|
||||
m[component] = o;
|
||||
try {
|
||||
var r = sandbox.run_code(UglifyJS.minify(original_code, m).code);
|
||||
return sandbox.same_stdout(original_result, r);
|
||||
} catch (e) {
|
||||
var result = UglifyJS.minify(original_code, m);
|
||||
if (result.error) {
|
||||
console.log("Error testing options." + component + "." + name);
|
||||
console.log(e);
|
||||
console.log(result.error);
|
||||
} else {
|
||||
var r = sandbox.run_code(result.code);
|
||||
return sandbox.same_stdout(original_result, r);
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -981,18 +980,16 @@ for (var round = 1; round <= num_iterations; round++) {
|
||||
original_code = createTopLevelCode();
|
||||
original_result = sandbox.run_code(original_code);
|
||||
(typeof original_result != "string" ? fallback_options : minify_options).forEach(function(options) {
|
||||
try {
|
||||
uglify_code = UglifyJS.minify(original_code, JSON.parse(options)).code;
|
||||
} catch (e) {
|
||||
uglify_code = e;
|
||||
}
|
||||
|
||||
ok = typeof uglify_code == "string";
|
||||
if (ok) {
|
||||
uglify_code = UglifyJS.minify(original_code, JSON.parse(options));
|
||||
if (!uglify_code.error) {
|
||||
uglify_code = uglify_code.code;
|
||||
uglify_result = sandbox.run_code(uglify_code);
|
||||
ok = sandbox.same_stdout(original_result, uglify_result);
|
||||
} else if (typeof original_result != "string") {
|
||||
ok = uglify_code.name == original_result.name;
|
||||
} else {
|
||||
uglify_code = uglify_code.error;
|
||||
if (typeof original_result != "string") {
|
||||
ok = uglify_code.name == original_result.name;
|
||||
}
|
||||
}
|
||||
if (verbose || (verbose_interval && !(round % INTERVAL_COUNT)) || !ok) log(options);
|
||||
else if (verbose_error && typeof original_result != "string") {
|
||||
|
||||
@@ -1,15 +1,4 @@
|
||||
exports["Compressor"] = Compressor;
|
||||
exports["Dictionary"] = Dictionary;
|
||||
exports["JS_Parse_Error"] = JS_Parse_Error;
|
||||
exports["OutputStream"] = OutputStream;
|
||||
exports["SourceMap"] = SourceMap;
|
||||
exports["TreeWalker"] = TreeWalker;
|
||||
exports["base54"] = base54;
|
||||
exports["defaults"] = defaults;
|
||||
exports["mangle_properties"] = mangle_properties;
|
||||
exports["minify"] = minify;
|
||||
exports["parse"] = parse;
|
||||
exports["push_uniq"] = push_uniq;
|
||||
exports["string_template"] = string_template;
|
||||
exports["tokenizer"] = tokenizer;
|
||||
exports["is_identifier"] = is_identifier;
|
||||
exports["_push_uniq"] = push_uniq;
|
||||
|
||||
@@ -18,15 +18,19 @@ var FILES = UglifyJS.FILES = [
|
||||
return require.resolve(file);
|
||||
});
|
||||
|
||||
new Function("MOZ_SourceMap", "exports", FILES.map(function(file){
|
||||
return fs.readFileSync(file, "utf8");
|
||||
}).join("\n\n"))(
|
||||
new Function("MOZ_SourceMap", "exports", function() {
|
||||
var code = FILES.map(function(file) {
|
||||
return fs.readFileSync(file, "utf8");
|
||||
});
|
||||
code.push("exports.describe_ast = " + describe_ast.toString());
|
||||
return code.join("\n\n");
|
||||
}())(
|
||||
require("source-map"),
|
||||
UglifyJS
|
||||
);
|
||||
|
||||
UglifyJS.describe_ast = function() {
|
||||
var out = UglifyJS.OutputStream({ beautify: true });
|
||||
function describe_ast() {
|
||||
var out = OutputStream({ beautify: true });
|
||||
function doitem(ctor) {
|
||||
out.print("AST_" + ctor.TYPE);
|
||||
var props = ctor.SELF_PROPS.filter(function(prop){
|
||||
@@ -56,6 +60,6 @@ UglifyJS.describe_ast = function() {
|
||||
});
|
||||
}
|
||||
};
|
||||
doitem(UglifyJS.AST_Node);
|
||||
doitem(AST_Node);
|
||||
return out + "";
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user