Skip to content

Commit

Permalink
Merge pull request #1885 from alexlamsl/harmony-v3.0.1
Browse files Browse the repository at this point in the history
Merging from master for 3.0.1
  • Loading branch information
alexlamsl authored May 8, 2017
2 parents 2433bb4 + 81f1311 commit e0ae8da
Show file tree
Hide file tree
Showing 41 changed files with 194 additions and 139 deletions.
19 changes: 10 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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.
Expand Down
69 changes: 57 additions & 12 deletions bin/uglifyjs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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 = {};
Expand All @@ -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");
Expand Down Expand Up @@ -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) {
Expand All @@ -185,9 +192,13 @@ function run() {
});
}
}
var result = UglifyJS.minify(files, options);
} catch (ex) {
if (ex instanceof UglifyJS.JS_Parse_Error) {
fatal("ERROR: " + ex.message);
}
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/);
Expand All @@ -210,9 +221,31 @@ function run() {
console.error(ex.defs);
}
fatal("ERROR: " + ex.message);
}
if (program.output == "spidermonkey") {
console.log(JSON.stringify(UglifyJS.parse(result.code).to_mozilla_ast(), null, 2));
} 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) {
Expand All @@ -230,8 +263,8 @@ function run() {
}

function fatal(message) {
console.error(message);
process.exit(1);
console.error(message);
process.exit(1);
}

// A file glob function that only supports "*" and "?" wildcards in the basename.
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -337,3 +378,7 @@ function to_cache(key) {
}
return cache[key];
}

function skip_key(key) {
return skip_keys.indexOf(key) >= 0;
}
2 changes: 1 addition & 1 deletion lib/ast.js
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
56 changes: 32 additions & 24 deletions lib/minify.js
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
"homepage": "http://lisperator.net/uglifyjs",
"author": "Mihai Bazon <[email protected]> (http://lisperator.net/)",
"license": "BSD-2-Clause",
"version": "3.0.0",
"version": "3.0.1",
"engines": {
"node": ">=0.8.0"
},
Expand Down
13 changes: 13 additions & 0 deletions test/exports.js
Original file line number Diff line number Diff line change
@@ -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;
2 changes: 1 addition & 1 deletion test/mocha/accessorTokens-1492.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
var UglifyJS = require('../../');
var UglifyJS = require("../node");
var assert = require("assert");

describe("Accessor tokens", function() {
Expand Down
2 changes: 1 addition & 1 deletion test/mocha/arguments.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
var UglifyJS = require('../../');
var UglifyJS = require("../node");
var assert = require("assert");

describe("arguments", function() {
Expand Down
2 changes: 1 addition & 1 deletion test/mocha/arrow.js
Original file line number Diff line number Diff line change
@@ -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() {
Expand Down
2 changes: 1 addition & 1 deletion test/mocha/class.js
Original file line number Diff line number Diff line change
@@ -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() {
Expand Down
13 changes: 12 additions & 1 deletion test/mocha/cli.js
Original file line number Diff line number Diff line change
Expand Up @@ -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();
});
Expand Down Expand Up @@ -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();
});
});
});
2 changes: 1 addition & 1 deletion test/mocha/comment-filter.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
var UglifyJS = require('../../');
var UglifyJS = require("../node");
var assert = require("assert");

describe("comment filters", function() {
Expand Down
2 changes: 1 addition & 1 deletion test/mocha/comment.js
Original file line number Diff line number Diff line change
@@ -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() {
Expand Down
2 changes: 1 addition & 1 deletion test/mocha/destructuring.js
Original file line number Diff line number Diff line change
@@ -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() {
Expand Down
2 changes: 1 addition & 1 deletion test/mocha/directives.js
Original file line number Diff line number Diff line change
@@ -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() {
Expand Down
2 changes: 1 addition & 1 deletion test/mocha/eof.js
Original file line number Diff line number Diff line change
@@ -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() {
Expand Down
2 changes: 1 addition & 1 deletion test/mocha/export.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
var assert = require("assert");
var uglify = require("../../");
var uglify = require("../node");

describe("Export", function() {
it ("Should parse export directives", function() {
Expand Down
2 changes: 1 addition & 1 deletion test/mocha/expression.js
Original file line number Diff line number Diff line change
@@ -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() {
Expand Down
2 changes: 1 addition & 1 deletion test/mocha/function.js
Original file line number Diff line number Diff line change
@@ -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() {
Expand Down
2 changes: 1 addition & 1 deletion test/mocha/getter-setter.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
var UglifyJS = require('../../');
var UglifyJS = require("../node");
var assert = require("assert");

describe("Getters and setters", function() {
Expand Down
2 changes: 1 addition & 1 deletion test/mocha/lhs-expressions.js
Original file line number Diff line number Diff line change
@@ -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 () {
Expand Down
2 changes: 1 addition & 1 deletion test/mocha/line-endings.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
var Uglify = require('../../');
var Uglify = require("../node");
var assert = require("assert");

describe("line-endings", function() {
Expand Down
Loading

0 comments on commit e0ae8da

Please sign in to comment.