Compare commits
83 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d895c09c70 | ||
|
|
08623aa6a7 | ||
|
|
c898a26117 | ||
|
|
619adb0308 | ||
|
|
7691bebea5 | ||
|
|
3c4346728e | ||
|
|
18d37ac761 | ||
|
|
63d35f8f6d | ||
|
|
7dbe961b2d | ||
|
|
94c4daaf9e | ||
|
|
37ee9de902 | ||
|
|
83db98ad3b | ||
|
|
bd0ae6569f | ||
|
|
841a661071 | ||
|
|
7491d07666 | ||
|
|
335e349314 | ||
|
|
2a88d07b3a | ||
|
|
a887cde9f2 | ||
|
|
b5623b19d4 | ||
|
|
6b2861e086 | ||
|
|
d5138f7467 | ||
|
|
eac67b2816 | ||
|
|
ce10072824 | ||
|
|
dff54a6552 | ||
|
|
1940fb682c | ||
|
|
17eef5a3c2 | ||
|
|
9f1f21b810 | ||
|
|
a8e67d157e | ||
|
|
e870c7db45 | ||
|
|
6500f8c52c | ||
|
|
4d2f7d83af | ||
|
|
99945fcd04 | ||
|
|
0d952ae43d | ||
|
|
593677d2ff | ||
|
|
c69294c449 | ||
|
|
2a06c7758e | ||
|
|
7ee1ec91a2 | ||
|
|
233fb62bd8 | ||
|
|
6637c267a5 | ||
|
|
99233c44cc | ||
|
|
33528002b4 | ||
|
|
20542a37a8 | ||
|
|
5fd12451f9 | ||
|
|
ba939ccd6c | ||
|
|
3a5f354846 | ||
|
|
fcde6109b0 | ||
|
|
e3bd223dac | ||
|
|
6c8db6eae1 | ||
|
|
3ff0b9e0c9 | ||
|
|
464a942a95 | ||
|
|
d7a4a4a462 | ||
|
|
759b3f7d6d | ||
|
|
958b6c2e57 | ||
|
|
ab15d676d7 | ||
|
|
66761d7ecf | ||
|
|
3afad58a93 | ||
|
|
170e8b519e | ||
|
|
f8684f418a | ||
|
|
881bda7f59 | ||
|
|
9854deb626 | ||
|
|
d6814050dd | ||
|
|
252fc65558 | ||
|
|
8108c7ffaf | ||
|
|
ba9936a572 | ||
|
|
905b601178 | ||
|
|
63fb2d5a44 | ||
|
|
85a5fc0aeb | ||
|
|
4fba3e0b80 | ||
|
|
9d398d999c | ||
|
|
f47b2b52a5 | ||
|
|
fedb6191a1 | ||
|
|
5bf617ebde | ||
|
|
0b82e1cd5b | ||
|
|
9aef34a816 | ||
|
|
0ac6918a41 | ||
|
|
65ee5af78c | ||
|
|
c6fa291571 | ||
|
|
bce4307e9e | ||
|
|
96ad94ab41 | ||
|
|
a5b60217ce | ||
|
|
44fd6694eb | ||
|
|
e48db3a8b6 | ||
|
|
e637bdaf4e |
@@ -1,10 +1,9 @@
|
|||||||
language: node_js
|
language: node_js
|
||||||
before_install: "npm install -g npm"
|
before_install: "npm install -g npm"
|
||||||
node_js:
|
node_js:
|
||||||
- "iojs"
|
|
||||||
- "0.12"
|
- "0.12"
|
||||||
- "0.11"
|
|
||||||
- "0.10"
|
- "0.10"
|
||||||
|
- "4"
|
||||||
matrix:
|
matrix:
|
||||||
fast_finish: true
|
fast_finish: true
|
||||||
sudo: false
|
sudo: false
|
||||||
|
|||||||
12
README.md
12
README.md
@@ -132,7 +132,10 @@ The available options are:
|
|||||||
--reserve-domprops Make (most?) DOM properties reserved for
|
--reserve-domprops Make (most?) DOM properties reserved for
|
||||||
--mangle-props
|
--mangle-props
|
||||||
--mangle-props Mangle property names
|
--mangle-props Mangle property names
|
||||||
|
--mangle-regex Only mangle property names matching the regex
|
||||||
--name-cache File to hold mangled names mappings
|
--name-cache File to hold mangled names mappings
|
||||||
|
--pure-funcs List of functions that can be safely removed if
|
||||||
|
their return value is not used [array]
|
||||||
```
|
```
|
||||||
|
|
||||||
Specify `--output` (`-o`) to declare the output file. Otherwise the output
|
Specify `--output` (`-o`) to declare the output file. Otherwise the output
|
||||||
@@ -251,6 +254,10 @@ A default exclusion file is provided in `tools/domprops.json` which should
|
|||||||
cover most standard JS and DOM properties defined in various browsers. Pass
|
cover most standard JS and DOM properties defined in various browsers. Pass
|
||||||
`--reserve-domprops` to read that in.
|
`--reserve-domprops` to read that in.
|
||||||
|
|
||||||
|
You can also use a regular expression to define which property names should be
|
||||||
|
mangled. For example, `--mangle-regex="/^_/"` will only mangle property names
|
||||||
|
that start with an underscore.
|
||||||
|
|
||||||
When you compress multiple files using this option, in order for them to
|
When you compress multiple files using this option, in order for them to
|
||||||
work together in the end we need to ensure somehow that one property gets
|
work together in the end we need to ensure somehow that one property gets
|
||||||
mangled to the same name in all of them. For this, pass `--name-cache
|
mangled to the same name in all of them. For this, pass `--name-cache
|
||||||
@@ -345,6 +352,11 @@ to set `true`; it's effectively a shortcut for `foo=true`).
|
|||||||
compressor from discarding unused function arguments. You need this
|
compressor from discarding unused function arguments. You need this
|
||||||
for code which relies on `Function.length`.
|
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`.
|
||||||
|
|
||||||
|
|
||||||
### The `unsafe` option
|
### The `unsafe` option
|
||||||
|
|
||||||
It enables some transformations that *might* break code logic in certain
|
It enables some transformations that *might* break code logic in certain
|
||||||
|
|||||||
40
bin/uglifyjs
40
bin/uglifyjs
@@ -70,7 +70,10 @@ You need to pass an argument to this option to specify the name that your module
|
|||||||
.describe("reserved-file", "File containing reserved names")
|
.describe("reserved-file", "File containing reserved names")
|
||||||
.describe("reserve-domprops", "Make (most?) DOM properties reserved for --mangle-props")
|
.describe("reserve-domprops", "Make (most?) DOM properties reserved for --mangle-props")
|
||||||
.describe("mangle-props", "Mangle property names")
|
.describe("mangle-props", "Mangle property names")
|
||||||
|
.describe("mangle-regex", "Only mangle property names matching the regex")
|
||||||
.describe("name-cache", "File to hold mangled names mappings")
|
.describe("name-cache", "File to hold mangled names mappings")
|
||||||
|
.describe("pure-funcs", "List of functions that can be safely removed if their return value is not used")
|
||||||
|
.describe("dump-spidermonkey-ast", "Dump SpiderMonkey AST to stdout.")
|
||||||
|
|
||||||
.alias("p", "prefix")
|
.alias("p", "prefix")
|
||||||
.alias("o", "output")
|
.alias("o", "output")
|
||||||
@@ -103,6 +106,7 @@ You need to pass an argument to this option to specify the name that your module
|
|||||||
.string("prefix")
|
.string("prefix")
|
||||||
.string("name-cache")
|
.string("name-cache")
|
||||||
.array("reserved-file")
|
.array("reserved-file")
|
||||||
|
.array("pure-funcs")
|
||||||
|
|
||||||
.boolean("expr")
|
.boolean("expr")
|
||||||
.boolean("source-map-include-sources")
|
.boolean("source-map-include-sources")
|
||||||
@@ -114,6 +118,7 @@ You need to pass an argument to this option to specify the name that your module
|
|||||||
.boolean("stats")
|
.boolean("stats")
|
||||||
.boolean("acorn")
|
.boolean("acorn")
|
||||||
.boolean("spidermonkey")
|
.boolean("spidermonkey")
|
||||||
|
.boolean("dump-spidermonkey-ast")
|
||||||
.boolean("lint")
|
.boolean("lint")
|
||||||
.boolean("V")
|
.boolean("V")
|
||||||
.boolean("version")
|
.boolean("version")
|
||||||
@@ -174,6 +179,10 @@ if (ARGS.d) {
|
|||||||
if (COMPRESS) COMPRESS.global_defs = getOptions("d");
|
if (COMPRESS) COMPRESS.global_defs = getOptions("d");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ARGS.pure_funcs) {
|
||||||
|
if (COMPRESS) COMPRESS.pure_funcs = ARGS.pure_funcs;
|
||||||
|
}
|
||||||
|
|
||||||
if (ARGS.r) {
|
if (ARGS.r) {
|
||||||
if (MANGLE) MANGLE.except = ARGS.r.replace(/^\s+|\s+$/g).split(/\s*,+\s*/);
|
if (MANGLE) MANGLE.except = ARGS.r.replace(/^\s+|\s+$/g).split(/\s*,+\s*/);
|
||||||
}
|
}
|
||||||
@@ -191,6 +200,15 @@ function writeNameCache(key, cache) {
|
|||||||
return UglifyJS.writeNameCache(ARGS.name_cache, key, cache);
|
return UglifyJS.writeNameCache(ARGS.name_cache, key, cache);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function extractRegex(str) {
|
||||||
|
if (/^\/.*\/[a-zA-Z]*$/.test(str)) {
|
||||||
|
var regex_pos = str.lastIndexOf("/");
|
||||||
|
return new RegExp(str.substr(1, regex_pos - 1), str.substr(regex_pos + 1));
|
||||||
|
} else {
|
||||||
|
throw new Error("Invalid regular expression: " + str);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (ARGS.quotes === true) {
|
if (ARGS.quotes === true) {
|
||||||
ARGS.quotes = 3;
|
ARGS.quotes = 3;
|
||||||
}
|
}
|
||||||
@@ -217,9 +235,8 @@ if (BEAUTIFY)
|
|||||||
|
|
||||||
if (ARGS.comments != null) {
|
if (ARGS.comments != null) {
|
||||||
if (/^\/.*\/[a-zA-Z]*$/.test(ARGS.comments)) {
|
if (/^\/.*\/[a-zA-Z]*$/.test(ARGS.comments)) {
|
||||||
var regex_pos = ARGS.comments.lastIndexOf("/");
|
|
||||||
try {
|
try {
|
||||||
OUTPUT_OPTIONS.comments = new RegExp(ARGS.comments.substr(1, regex_pos - 1), ARGS.comments.substr(regex_pos + 1));
|
OUTPUT_OPTIONS.comments = extractRegex(ARGS.comments);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
print_error("ERROR: Invalid --comments: " + e.message);
|
print_error("ERROR: Invalid --comments: " + e.message);
|
||||||
}
|
}
|
||||||
@@ -245,7 +262,6 @@ if (ARGS.self) {
|
|||||||
}
|
}
|
||||||
files = UglifyJS.FILES;
|
files = UglifyJS.FILES;
|
||||||
if (!ARGS.wrap) ARGS.wrap = "UglifyJS";
|
if (!ARGS.wrap) ARGS.wrap = "UglifyJS";
|
||||||
ARGS.export_all = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var ORIG_MAP = ARGS.in_source_map;
|
var ORIG_MAP = ARGS.in_source_map;
|
||||||
@@ -375,15 +391,25 @@ async.eachLimit(files, 1, function (file, cb) {
|
|||||||
if (ARGS.mangle_props || ARGS.name_cache) (function(){
|
if (ARGS.mangle_props || ARGS.name_cache) (function(){
|
||||||
var reserved = RESERVED ? RESERVED.props : null;
|
var reserved = RESERVED ? RESERVED.props : null;
|
||||||
var cache = readNameCache("props");
|
var cache = readNameCache("props");
|
||||||
|
var regex;
|
||||||
|
|
||||||
|
try {
|
||||||
|
regex = ARGS.mangle_regex ? extractRegex(ARGS.mangle_regex) : null;
|
||||||
|
} catch (e) {
|
||||||
|
print_error("ERROR: Invalid --mangle-regex: " + e.message);
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
TOPLEVEL = UglifyJS.mangle_properties(TOPLEVEL, {
|
TOPLEVEL = UglifyJS.mangle_properties(TOPLEVEL, {
|
||||||
reserved : reserved,
|
reserved : reserved,
|
||||||
cache : cache,
|
cache : cache,
|
||||||
only_cache : !ARGS.mangle_props
|
only_cache : !ARGS.mangle_props,
|
||||||
|
regex : regex
|
||||||
});
|
});
|
||||||
writeNameCache("props", cache);
|
writeNameCache("props", cache);
|
||||||
})();
|
})();
|
||||||
|
|
||||||
var SCOPE_IS_NEEDED = COMPRESS || MANGLE || ARGS.lint;
|
var SCOPE_IS_NEEDED = COMPRESS || MANGLE || ARGS.lint
|
||||||
var TL_CACHE = readNameCache("vars");
|
var TL_CACHE = readNameCache("vars");
|
||||||
|
|
||||||
if (SCOPE_IS_NEEDED) {
|
if (SCOPE_IS_NEEDED) {
|
||||||
@@ -425,6 +451,9 @@ async.eachLimit(files, 1, function (file, cb) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ARGS.dump_spidermonkey_ast) {
|
||||||
|
print(JSON.stringify(TOPLEVEL.to_mozilla_ast(), null, 2));
|
||||||
|
} else {
|
||||||
time_it("generate", function(){
|
time_it("generate", function(){
|
||||||
TOPLEVEL.print(output);
|
TOPLEVEL.print(output);
|
||||||
});
|
});
|
||||||
@@ -446,6 +475,7 @@ async.eachLimit(files, 1, function (file, cb) {
|
|||||||
} else {
|
} else {
|
||||||
print(output);
|
print(output);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (ARGS.stats) {
|
if (ARGS.stats) {
|
||||||
print_error(UglifyJS.string_template("Timing information (compressed {count} files):", {
|
print_error(UglifyJS.string_template("Timing information (compressed {count} files):", {
|
||||||
|
|||||||
43
lib/ast.js
43
lib/ast.js
@@ -81,10 +81,11 @@ function DEFNODE(type, props, methods, base) {
|
|||||||
ctor.DEFMETHOD = function(name, method) {
|
ctor.DEFMETHOD = function(name, method) {
|
||||||
this.prototype[name] = method;
|
this.prototype[name] = method;
|
||||||
};
|
};
|
||||||
|
exports["AST_" + type] = ctor;
|
||||||
return ctor;
|
return ctor;
|
||||||
};
|
};
|
||||||
|
|
||||||
var AST_Token = DEFNODE("Token", "type value line col pos endline endcol endpos nlb comments_before file", {
|
var AST_Token = DEFNODE("Token", "type value line col pos endline endcol endpos nlb comments_before file raw", {
|
||||||
}, null);
|
}, null);
|
||||||
|
|
||||||
var AST_Node = DEFNODE("Node", "start end", {
|
var AST_Node = DEFNODE("Node", "start end", {
|
||||||
@@ -329,12 +330,11 @@ var AST_Toplevel = DEFNODE("Toplevel", "globals", {
|
|||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
var wrapped_tl = "(function(exports, global){ global['" + name + "'] = exports; '$ORIG'; '$EXPORTS'; }({}, (function(){return this}())))";
|
var wrapped_tl = "(function(exports, global){ '$ORIG'; '$EXPORTS'; global['" + name + "'] = exports; }({}, (function(){return this}())))";
|
||||||
wrapped_tl = parse(wrapped_tl);
|
wrapped_tl = parse(wrapped_tl);
|
||||||
wrapped_tl = wrapped_tl.transform(new TreeTransformer(function before(node){
|
wrapped_tl = wrapped_tl.transform(new TreeTransformer(function before(node){
|
||||||
if (node instanceof AST_SimpleStatement) {
|
if (node instanceof AST_Directive) {
|
||||||
node = node.body;
|
switch (node.value) {
|
||||||
if (node instanceof AST_String) switch (node.getValue()) {
|
|
||||||
case "$ORIG":
|
case "$ORIG":
|
||||||
return MAP.splice(self.body);
|
return MAP.splice(self.body);
|
||||||
case "$EXPORTS":
|
case "$EXPORTS":
|
||||||
@@ -864,10 +864,11 @@ var AST_String = DEFNODE("String", "value quote", {
|
|||||||
}
|
}
|
||||||
}, AST_Constant);
|
}, AST_Constant);
|
||||||
|
|
||||||
var AST_Number = DEFNODE("Number", "value", {
|
var AST_Number = DEFNODE("Number", "value literal", {
|
||||||
$documentation: "A number literal",
|
$documentation: "A number literal",
|
||||||
$propdoc: {
|
$propdoc: {
|
||||||
value: "[number] the numeric value"
|
value: "[number] the numeric value",
|
||||||
|
literal: "[string] numeric value as string (optional)"
|
||||||
}
|
}
|
||||||
}, AST_Constant);
|
}, AST_Constant);
|
||||||
|
|
||||||
@@ -926,27 +927,36 @@ var AST_True = DEFNODE("True", null, {
|
|||||||
function TreeWalker(callback) {
|
function TreeWalker(callback) {
|
||||||
this.visit = callback;
|
this.visit = callback;
|
||||||
this.stack = [];
|
this.stack = [];
|
||||||
|
this.directives = Object.create(null);
|
||||||
};
|
};
|
||||||
TreeWalker.prototype = {
|
TreeWalker.prototype = {
|
||||||
_visit: function(node, descend) {
|
_visit: function(node, descend) {
|
||||||
this.stack.push(node);
|
this.push(node);
|
||||||
var ret = this.visit(node, descend ? function(){
|
var ret = this.visit(node, descend ? function(){
|
||||||
descend.call(node);
|
descend.call(node);
|
||||||
} : noop);
|
} : noop);
|
||||||
if (!ret && descend) {
|
if (!ret && descend) {
|
||||||
descend.call(node);
|
descend.call(node);
|
||||||
}
|
}
|
||||||
this.stack.pop();
|
this.pop(node);
|
||||||
return ret;
|
return ret;
|
||||||
},
|
},
|
||||||
parent: function(n) {
|
parent: function(n) {
|
||||||
return this.stack[this.stack.length - 2 - (n || 0)];
|
return this.stack[this.stack.length - 2 - (n || 0)];
|
||||||
},
|
},
|
||||||
push: function (node) {
|
push: function (node) {
|
||||||
|
if (node instanceof AST_Lambda) {
|
||||||
|
this.directives = Object.create(this.directives);
|
||||||
|
} else if (node instanceof AST_Directive) {
|
||||||
|
this.directives[node.value] = this.directives[node.value] ? "up" : true;
|
||||||
|
}
|
||||||
this.stack.push(node);
|
this.stack.push(node);
|
||||||
},
|
},
|
||||||
pop: function() {
|
pop: function(node) {
|
||||||
return this.stack.pop();
|
this.stack.pop();
|
||||||
|
if (node instanceof AST_Lambda) {
|
||||||
|
this.directives = Object.getPrototypeOf(this.directives);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
self: function() {
|
self: function() {
|
||||||
return this.stack[this.stack.length - 1];
|
return this.stack[this.stack.length - 1];
|
||||||
@@ -959,7 +969,16 @@ TreeWalker.prototype = {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
has_directive: function(type) {
|
has_directive: function(type) {
|
||||||
return this.find_parent(AST_Scope).has_directive(type);
|
var dir = this.directives[type];
|
||||||
|
if (dir) return dir;
|
||||||
|
var node = this.stack[this.stack.length - 1];
|
||||||
|
if (node instanceof AST_Scope) {
|
||||||
|
for (var i = 0; i < node.body.length; ++i) {
|
||||||
|
var st = node.body[i];
|
||||||
|
if (!(st instanceof AST_Directive)) break;
|
||||||
|
if (st.value == type) return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
in_boolean_context: function() {
|
in_boolean_context: function() {
|
||||||
var stack = this.stack;
|
var stack = this.stack;
|
||||||
|
|||||||
@@ -61,7 +61,7 @@ function Compressor(options, false_by_default) {
|
|||||||
loops : !false_by_default,
|
loops : !false_by_default,
|
||||||
unused : !false_by_default,
|
unused : !false_by_default,
|
||||||
hoist_funs : !false_by_default,
|
hoist_funs : !false_by_default,
|
||||||
keep_fargs : false,
|
keep_fargs : true,
|
||||||
keep_fnames : false,
|
keep_fnames : false,
|
||||||
hoist_vars : false,
|
hoist_vars : false,
|
||||||
if_return : !false_by_default,
|
if_return : !false_by_default,
|
||||||
@@ -111,6 +111,7 @@ merge(Compressor.prototype, {
|
|||||||
node.DEFMETHOD("optimize", function(compressor){
|
node.DEFMETHOD("optimize", function(compressor){
|
||||||
var self = this;
|
var self = this;
|
||||||
if (self._optimized) return self;
|
if (self._optimized) return self;
|
||||||
|
if (compressor.has_directive("use asm")) return self;
|
||||||
var opt = optimizer(self, compressor);
|
var opt = optimizer(self, compressor);
|
||||||
opt._optimized = true;
|
opt._optimized = true;
|
||||||
if (opt === self) return opt;
|
if (opt === self) return opt;
|
||||||
@@ -896,6 +897,7 @@ merge(Compressor.prototype, {
|
|||||||
def(AST_Call, function(compressor){
|
def(AST_Call, function(compressor){
|
||||||
var pure = compressor.option("pure_funcs");
|
var pure = compressor.option("pure_funcs");
|
||||||
if (!pure) return true;
|
if (!pure) return true;
|
||||||
|
if (typeof pure == "function") return pure(this);
|
||||||
return pure.indexOf(this.expression.print_to_string()) < 0;
|
return pure.indexOf(this.expression.print_to_string()) < 0;
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -989,7 +991,7 @@ merge(Compressor.prototype, {
|
|||||||
/* -----[ optimizers ]----- */
|
/* -----[ optimizers ]----- */
|
||||||
|
|
||||||
OPT(AST_Directive, function(self, compressor){
|
OPT(AST_Directive, function(self, compressor){
|
||||||
if (self.scope.has_directive(self.value) !== self.scope) {
|
if (compressor.has_directive(self.value) === "up") {
|
||||||
return make_node(AST_EmptyStatement, self);
|
return make_node(AST_EmptyStatement, self);
|
||||||
}
|
}
|
||||||
return self;
|
return self;
|
||||||
@@ -1025,6 +1027,7 @@ merge(Compressor.prototype, {
|
|||||||
|
|
||||||
AST_Scope.DEFMETHOD("drop_unused", function(compressor){
|
AST_Scope.DEFMETHOD("drop_unused", function(compressor){
|
||||||
var self = this;
|
var self = this;
|
||||||
|
if (compressor.has_directive("use asm")) return self;
|
||||||
if (compressor.option("unused")
|
if (compressor.option("unused")
|
||||||
&& !(self instanceof AST_Toplevel)
|
&& !(self instanceof AST_Toplevel)
|
||||||
&& !self.uses_eval
|
&& !self.uses_eval
|
||||||
@@ -1086,7 +1089,7 @@ merge(Compressor.prototype, {
|
|||||||
var tt = new TreeTransformer(
|
var tt = new TreeTransformer(
|
||||||
function before(node, descend, in_list) {
|
function before(node, descend, in_list) {
|
||||||
if (node instanceof AST_Lambda && !(node instanceof AST_Accessor)) {
|
if (node instanceof AST_Lambda && !(node instanceof AST_Accessor)) {
|
||||||
if (compressor.option("unsafe") && !compressor.option("keep_fargs")) {
|
if (!compressor.option("keep_fargs")) {
|
||||||
for (var a = node.argnames, i = a.length; --i >= 0;) {
|
for (var a = node.argnames, i = a.length; --i >= 0;) {
|
||||||
var sym = a[i];
|
var sym = a[i];
|
||||||
if (sym.unreferenced()) {
|
if (sym.unreferenced()) {
|
||||||
@@ -1204,9 +1207,10 @@ merge(Compressor.prototype, {
|
|||||||
});
|
});
|
||||||
|
|
||||||
AST_Scope.DEFMETHOD("hoist_declarations", function(compressor){
|
AST_Scope.DEFMETHOD("hoist_declarations", function(compressor){
|
||||||
|
var self = this;
|
||||||
|
if (compressor.has_directive("use asm")) return self;
|
||||||
var hoist_funs = compressor.option("hoist_funs");
|
var hoist_funs = compressor.option("hoist_funs");
|
||||||
var hoist_vars = compressor.option("hoist_vars");
|
var hoist_vars = compressor.option("hoist_vars");
|
||||||
var self = this;
|
|
||||||
if (hoist_funs || hoist_vars) {
|
if (hoist_funs || hoist_vars) {
|
||||||
var dirs = [];
|
var dirs = [];
|
||||||
var hoisted = [];
|
var hoisted = [];
|
||||||
@@ -1909,15 +1913,11 @@ merge(Compressor.prototype, {
|
|||||||
if (!compressor.option("side_effects"))
|
if (!compressor.option("side_effects"))
|
||||||
return self;
|
return self;
|
||||||
if (!self.car.has_side_effects(compressor)) {
|
if (!self.car.has_side_effects(compressor)) {
|
||||||
// we shouldn't compress (1,eval)(something) to
|
// we shouldn't compress (1,func)(something) to
|
||||||
// eval(something) because that changes the meaning of
|
// func(something) because that changes the meaning of
|
||||||
// eval (becomes lexical instead of global).
|
// the func (becomes lexical instead of global).
|
||||||
var p;
|
var p = compressor.parent();
|
||||||
if (!(self.cdr instanceof AST_SymbolRef
|
if (!(p instanceof AST_Call && p.expression === self)) {
|
||||||
&& self.cdr.name == "eval"
|
|
||||||
&& self.cdr.undeclared()
|
|
||||||
&& (p = compressor.parent()) instanceof AST_Call
|
|
||||||
&& p.expression === self)) {
|
|
||||||
return self.cdr;
|
return self.cdr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2031,15 +2031,14 @@ merge(Compressor.prototype, {
|
|||||||
var commutativeOperators = makePredicate("== === != !== * & | ^");
|
var commutativeOperators = makePredicate("== === != !== * & | ^");
|
||||||
|
|
||||||
OPT(AST_Binary, function(self, compressor){
|
OPT(AST_Binary, function(self, compressor){
|
||||||
var reverse = compressor.has_directive("use asm") ? noop
|
function reverse(op, force) {
|
||||||
: function(op, force) {
|
|
||||||
if (force || !(self.left.has_side_effects(compressor) || self.right.has_side_effects(compressor))) {
|
if (force || !(self.left.has_side_effects(compressor) || self.right.has_side_effects(compressor))) {
|
||||||
if (op) self.operator = op;
|
if (op) self.operator = op;
|
||||||
var tmp = self.left;
|
var tmp = self.left;
|
||||||
self.left = self.right;
|
self.left = self.right;
|
||||||
self.right = tmp;
|
self.right = tmp;
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
if (commutativeOperators(self.operator)) {
|
if (commutativeOperators(self.operator)) {
|
||||||
if (self.right instanceof AST_Constant
|
if (self.right instanceof AST_Constant
|
||||||
&& !(self.left instanceof AST_Constant)) {
|
&& !(self.left instanceof AST_Constant)) {
|
||||||
@@ -2104,6 +2103,34 @@ merge(Compressor.prototype, {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
if (compressor.option("conditionals")) {
|
||||||
|
if (self.operator == "&&") {
|
||||||
|
var ll = self.left.evaluate(compressor);
|
||||||
|
if (ll.length > 1) {
|
||||||
|
if (ll[1]) {
|
||||||
|
compressor.warn("Condition left of && always true [{file}:{line},{col}]", self.start);
|
||||||
|
var rr = self.right.evaluate(compressor);
|
||||||
|
return rr[0];
|
||||||
|
} else {
|
||||||
|
compressor.warn("Condition left of && always false [{file}:{line},{col}]", self.start);
|
||||||
|
return ll[0];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (self.operator == "||") {
|
||||||
|
var ll = self.left.evaluate(compressor);
|
||||||
|
if (ll.length > 1) {
|
||||||
|
if (ll[1]) {
|
||||||
|
compressor.warn("Condition left of || always true [{file}:{line},{col}]", self.start);
|
||||||
|
return ll[0];
|
||||||
|
} else {
|
||||||
|
compressor.warn("Condition left of || always false [{file}:{line},{col}]", self.start);
|
||||||
|
var rr = self.right.evaluate(compressor);
|
||||||
|
return rr[0];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
if (compressor.option("booleans") && compressor.in_boolean_context()) switch (self.operator) {
|
if (compressor.option("booleans") && compressor.in_boolean_context()) switch (self.operator) {
|
||||||
case "&&":
|
case "&&":
|
||||||
var ll = self.left.evaluate(compressor);
|
var ll = self.left.evaluate(compressor);
|
||||||
@@ -2155,7 +2182,7 @@ merge(Compressor.prototype, {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (compressor.option("comparisons")) {
|
if (compressor.option("comparisons") && self.is_boolean()) {
|
||||||
if (!(compressor.parent() instanceof AST_Binary)
|
if (!(compressor.parent() instanceof AST_Binary)
|
||||||
|| compressor.parent() instanceof AST_Assign) {
|
|| compressor.parent() instanceof AST_Assign) {
|
||||||
var negated = make_node(AST_UnaryPrefix, self, {
|
var negated = make_node(AST_UnaryPrefix, self, {
|
||||||
@@ -2230,10 +2257,11 @@ merge(Compressor.prototype, {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// x * (y * z) ==> x * y * z
|
// x && (y && z) ==> x && y && z
|
||||||
|
// x || (y || z) ==> x || y || z
|
||||||
if (self.right instanceof AST_Binary
|
if (self.right instanceof AST_Binary
|
||||||
&& self.right.operator == self.operator
|
&& self.right.operator == self.operator
|
||||||
&& (self.operator == "*" || self.operator == "&&" || self.operator == "||"))
|
&& (self.operator == "&&" || self.operator == "||"))
|
||||||
{
|
{
|
||||||
self.left = make_node(AST_Binary, self.left, {
|
self.left = make_node(AST_Binary, self.left, {
|
||||||
operator : self.operator,
|
operator : self.operator,
|
||||||
@@ -2247,7 +2275,15 @@ merge(Compressor.prototype, {
|
|||||||
});
|
});
|
||||||
|
|
||||||
OPT(AST_SymbolRef, function(self, compressor){
|
OPT(AST_SymbolRef, function(self, compressor){
|
||||||
if (self.undeclared()) {
|
function isLHS(symbol, parent) {
|
||||||
|
return (
|
||||||
|
parent instanceof AST_Binary &&
|
||||||
|
parent.operator === '=' &&
|
||||||
|
parent.left === symbol
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (self.undeclared() && !isLHS(self, compressor.parent())) {
|
||||||
var defines = compressor.option("global_defs");
|
var defines = compressor.option("global_defs");
|
||||||
if (defines && defines.hasOwnProperty(self.name)) {
|
if (defines && defines.hasOwnProperty(self.name)) {
|
||||||
return make_node_from_constant(compressor, defines[self.name], self);
|
return make_node_from_constant(compressor, defines[self.name], self);
|
||||||
@@ -2356,6 +2392,7 @@ merge(Compressor.prototype, {
|
|||||||
if (consequent instanceof AST_Call
|
if (consequent instanceof AST_Call
|
||||||
&& alternative.TYPE === consequent.TYPE
|
&& alternative.TYPE === consequent.TYPE
|
||||||
&& consequent.args.length == alternative.args.length
|
&& consequent.args.length == alternative.args.length
|
||||||
|
&& !consequent.expression.has_side_effects(compressor)
|
||||||
&& consequent.expression.equivalent_to(alternative.expression)) {
|
&& consequent.expression.equivalent_to(alternative.expression)) {
|
||||||
if (consequent.args.length == 0) {
|
if (consequent.args.length == 0) {
|
||||||
return make_node(AST_Seq, self, {
|
return make_node(AST_Seq, self, {
|
||||||
@@ -2482,4 +2519,11 @@ merge(Compressor.prototype, {
|
|||||||
OPT(AST_Object, literals_in_boolean_context);
|
OPT(AST_Object, literals_in_boolean_context);
|
||||||
OPT(AST_RegExp, literals_in_boolean_context);
|
OPT(AST_RegExp, literals_in_boolean_context);
|
||||||
|
|
||||||
|
OPT(AST_Return, function(self, compressor){
|
||||||
|
if (self.value instanceof AST_Undefined) {
|
||||||
|
self.value = null;
|
||||||
|
}
|
||||||
|
return self;
|
||||||
|
});
|
||||||
|
|
||||||
})();
|
})();
|
||||||
|
|||||||
@@ -146,7 +146,14 @@
|
|||||||
case "boolean":
|
case "boolean":
|
||||||
return new (val ? AST_True : AST_False)(args);
|
return new (val ? AST_True : AST_False)(args);
|
||||||
default:
|
default:
|
||||||
args.value = val;
|
var rx = M.regex;
|
||||||
|
if (rx && rx.pattern) {
|
||||||
|
// RegExpLiteral as per ESTree AST spec
|
||||||
|
args.value = new RegExp(rx.pattern, rx.flags).toString();
|
||||||
|
} else {
|
||||||
|
// support legacy RegExp
|
||||||
|
args.value = M.regex && M.raw ? M.raw : val;
|
||||||
|
}
|
||||||
return new AST_RegExp(args);
|
return new AST_RegExp(args);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -334,6 +341,19 @@
|
|||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
|
def_to_moz(AST_RegExp, function To_Moz_RegExpLiteral(M) {
|
||||||
|
var value = M.value;
|
||||||
|
return {
|
||||||
|
type: "Literal",
|
||||||
|
value: value,
|
||||||
|
raw: value.toString(),
|
||||||
|
regex: {
|
||||||
|
pattern: value.source,
|
||||||
|
flags: value.toString().match(/[gimuy]*$/)[0]
|
||||||
|
}
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
def_to_moz(AST_Constant, function To_Moz_Literal(M) {
|
def_to_moz(AST_Constant, function To_Moz_Literal(M) {
|
||||||
var value = M.value;
|
var value = M.value;
|
||||||
if (typeof value === 'number' && (value < 0 || (value === 0 && 1 / value < 0))) {
|
if (typeof value === 'number' && (value < 0 || (value === 0 && 1 / value < 0))) {
|
||||||
@@ -343,13 +363,15 @@
|
|||||||
prefix: true,
|
prefix: true,
|
||||||
argument: {
|
argument: {
|
||||||
type: "Literal",
|
type: "Literal",
|
||||||
value: -value
|
value: -value,
|
||||||
|
raw: M.start.raw
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
return {
|
return {
|
||||||
type: "Literal",
|
type: "Literal",
|
||||||
value: value
|
value: value,
|
||||||
|
raw: M.start.raw
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -369,6 +391,12 @@
|
|||||||
|
|
||||||
/* -----[ tools ]----- */
|
/* -----[ tools ]----- */
|
||||||
|
|
||||||
|
function raw_token(moznode) {
|
||||||
|
if (moznode.type == "Literal") {
|
||||||
|
return moznode.raw != null ? moznode.raw : moznode.value + "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function my_start_token(moznode) {
|
function my_start_token(moznode) {
|
||||||
var loc = moznode.loc, start = loc && loc.start;
|
var loc = moznode.loc, start = loc && loc.start;
|
||||||
var range = moznode.range;
|
var range = moznode.range;
|
||||||
@@ -379,7 +407,8 @@
|
|||||||
pos : range ? range[0] : moznode.start,
|
pos : range ? range[0] : moznode.start,
|
||||||
endline : start && start.line,
|
endline : start && start.line,
|
||||||
endcol : start && start.column,
|
endcol : start && start.column,
|
||||||
endpos : range ? range[0] : moznode.start
|
endpos : range ? range[0] : moznode.start,
|
||||||
|
raw : raw_token(moznode),
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -393,13 +422,14 @@
|
|||||||
pos : range ? range[1] : moznode.end,
|
pos : range ? range[1] : moznode.end,
|
||||||
endline : end && end.line,
|
endline : end && end.line,
|
||||||
endcol : end && end.column,
|
endcol : end && end.column,
|
||||||
endpos : range ? range[1] : moznode.end
|
endpos : range ? range[1] : moznode.end,
|
||||||
|
raw : raw_token(moznode),
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
function map(moztype, mytype, propmap) {
|
function map(moztype, mytype, propmap) {
|
||||||
var moz_to_me = "function From_Moz_" + moztype + "(M){\n";
|
var moz_to_me = "function From_Moz_" + moztype + "(M){\n";
|
||||||
moz_to_me += "return new " + mytype.name + "({\n" +
|
moz_to_me += "return new U2." + mytype.name + "({\n" +
|
||||||
"start: my_start_token(M),\n" +
|
"start: my_start_token(M),\n" +
|
||||||
"end: my_end_token(M)";
|
"end: my_end_token(M)";
|
||||||
|
|
||||||
@@ -442,8 +472,8 @@
|
|||||||
//me_to_moz = parse(me_to_moz).print_to_string({ beautify: true });
|
//me_to_moz = parse(me_to_moz).print_to_string({ beautify: true });
|
||||||
//console.log(moz_to_me);
|
//console.log(moz_to_me);
|
||||||
|
|
||||||
moz_to_me = new Function("my_start_token", "my_end_token", "from_moz", "return(" + moz_to_me + ")")(
|
moz_to_me = new Function("U2", "my_start_token", "my_end_token", "from_moz", "return(" + moz_to_me + ")")(
|
||||||
my_start_token, my_end_token, from_moz
|
exports, my_start_token, my_end_token, from_moz
|
||||||
);
|
);
|
||||||
me_to_moz = new Function("to_moz", "to_moz_block", "return(" + me_to_moz + ")")(
|
me_to_moz = new Function("to_moz", "to_moz_block", "return(" + me_to_moz + ")")(
|
||||||
to_moz, to_moz_block
|
to_moz, to_moz_block
|
||||||
|
|||||||
@@ -60,6 +60,7 @@ function OutputStream(options) {
|
|||||||
bracketize : false,
|
bracketize : false,
|
||||||
semicolons : true,
|
semicolons : true,
|
||||||
comments : false,
|
comments : false,
|
||||||
|
shebang : true,
|
||||||
preserve_line : false,
|
preserve_line : false,
|
||||||
screw_ie8 : false,
|
screw_ie8 : false,
|
||||||
preamble : null,
|
preamble : null,
|
||||||
@@ -87,13 +88,14 @@ function OutputStream(options) {
|
|||||||
|
|
||||||
function make_string(str, quote) {
|
function make_string(str, quote) {
|
||||||
var dq = 0, sq = 0;
|
var dq = 0, sq = 0;
|
||||||
str = str.replace(/[\\\b\f\n\r\t\x22\x27\u2028\u2029\0\ufeff]/g, function(s){
|
str = str.replace(/[\\\b\f\n\r\v\t\x22\x27\u2028\u2029\0\ufeff]/g, function(s){
|
||||||
switch (s) {
|
switch (s) {
|
||||||
case "\\": return "\\\\";
|
case "\\": return "\\\\";
|
||||||
case "\b": return "\\b";
|
case "\b": return "\\b";
|
||||||
case "\f": return "\\f";
|
case "\f": return "\\f";
|
||||||
case "\n": return "\\n";
|
case "\n": return "\\n";
|
||||||
case "\r": return "\\r";
|
case "\r": return "\\r";
|
||||||
|
case "\x0B": return options.screw_ie8 ? "\\v" : "\\x0B";
|
||||||
case "\u2028": return "\\u2028";
|
case "\u2028": return "\\u2028";
|
||||||
case "\u2029": return "\\u2029";
|
case "\u2029": return "\\u2029";
|
||||||
case '"': ++dq; return '"';
|
case '"': ++dq; return '"';
|
||||||
@@ -124,8 +126,11 @@ function OutputStream(options) {
|
|||||||
|
|
||||||
function encode_string(str, quote) {
|
function encode_string(str, quote) {
|
||||||
var ret = make_string(str, quote);
|
var ret = make_string(str, quote);
|
||||||
if (options.inline_script)
|
if (options.inline_script) {
|
||||||
ret = ret.replace(/<\x2fscript([>\/\t\n\f\r ])/gi, "<\\/script$1");
|
ret = ret.replace(/<\x2fscript([>\/\t\n\f\r ])/gi, "<\\/script$1");
|
||||||
|
ret = ret.replace(/\x3c!--/g, "\\x3c!--");
|
||||||
|
ret = ret.replace(/--\x3e/g, "--\\x3e");
|
||||||
|
}
|
||||||
return ret;
|
return ret;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -161,6 +166,8 @@ function OutputStream(options) {
|
|||||||
str = String(str);
|
str = String(str);
|
||||||
var ch = str.charAt(0);
|
var ch = str.charAt(0);
|
||||||
if (might_need_semicolon) {
|
if (might_need_semicolon) {
|
||||||
|
might_need_semicolon = false;
|
||||||
|
|
||||||
if ((!ch || ";}".indexOf(ch) < 0) && !/[;]$/.test(last)) {
|
if ((!ch || ";}".indexOf(ch) < 0) && !/[;]$/.test(last)) {
|
||||||
if (options.semicolons || requireSemicolonChars(ch)) {
|
if (options.semicolons || requireSemicolonChars(ch)) {
|
||||||
OUTPUT += ";";
|
OUTPUT += ";";
|
||||||
@@ -171,11 +178,17 @@ function OutputStream(options) {
|
|||||||
current_pos++;
|
current_pos++;
|
||||||
current_line++;
|
current_line++;
|
||||||
current_col = 0;
|
current_col = 0;
|
||||||
|
|
||||||
|
if (/^\s+$/.test(str)) {
|
||||||
|
// reset the semicolon flag, since we didn't print one
|
||||||
|
// now and might still have to later
|
||||||
|
might_need_semicolon = true;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!options.beautify)
|
if (!options.beautify)
|
||||||
might_need_space = false;
|
might_need_space = false;
|
||||||
}
|
}
|
||||||
might_need_semicolon = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!options.beautify && options.preserve_line && stack[stack.length - 1]) {
|
if (!options.beautify && options.preserve_line && stack[stack.length - 1]) {
|
||||||
@@ -369,8 +382,13 @@ function OutputStream(options) {
|
|||||||
nodetype.DEFMETHOD("_codegen", generator);
|
nodetype.DEFMETHOD("_codegen", generator);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
var use_asm = false;
|
||||||
|
|
||||||
AST_Node.DEFMETHOD("print", function(stream, force_parens){
|
AST_Node.DEFMETHOD("print", function(stream, force_parens){
|
||||||
var self = this, generator = self._codegen;
|
var self = this, generator = self._codegen, prev_use_asm = use_asm;
|
||||||
|
if (self instanceof AST_Directive && self.value == "use asm") {
|
||||||
|
use_asm = true;
|
||||||
|
}
|
||||||
function doit() {
|
function doit() {
|
||||||
self.add_comments(stream);
|
self.add_comments(stream);
|
||||||
self.add_source_map(stream);
|
self.add_source_map(stream);
|
||||||
@@ -383,6 +401,9 @@ function OutputStream(options) {
|
|||||||
doit();
|
doit();
|
||||||
}
|
}
|
||||||
stream.pop_node();
|
stream.pop_node();
|
||||||
|
if (self instanceof AST_Lambda) {
|
||||||
|
use_asm = prev_use_asm;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
AST_Node.DEFMETHOD("print_to_string", function(options){
|
AST_Node.DEFMETHOD("print_to_string", function(options){
|
||||||
@@ -395,7 +416,6 @@ function OutputStream(options) {
|
|||||||
|
|
||||||
AST_Node.DEFMETHOD("add_comments", function(output){
|
AST_Node.DEFMETHOD("add_comments", function(output){
|
||||||
var c = output.option("comments"), self = this;
|
var c = output.option("comments"), self = this;
|
||||||
if (c) {
|
|
||||||
var start = self.start;
|
var start = self.start;
|
||||||
if (start && !start._comments_dumped) {
|
if (start && !start._comments_dumped) {
|
||||||
start._comments_dumped = true;
|
start._comments_dumped = true;
|
||||||
@@ -418,13 +438,17 @@ function OutputStream(options) {
|
|||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (c.test) {
|
if (!c) {
|
||||||
|
comments = comments.filter(function(comment) {
|
||||||
|
return comment.type == "comment5";
|
||||||
|
});
|
||||||
|
} else if (c.test) {
|
||||||
comments = comments.filter(function(comment){
|
comments = comments.filter(function(comment){
|
||||||
return c.test(comment.value);
|
return c.test(comment.value) || comment.type == "comment5";
|
||||||
});
|
});
|
||||||
} else if (typeof c == "function") {
|
} else if (typeof c == "function") {
|
||||||
comments = comments.filter(function(comment){
|
comments = comments.filter(function(comment){
|
||||||
return c(self, comment);
|
return c(self, comment) || comment.type == "comment5";
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -450,8 +474,11 @@ function OutputStream(options) {
|
|||||||
output.space();
|
output.space();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
else if (output.pos() === 0 && c.type == "comment5" && output.option("shebang")) {
|
||||||
|
output.print("#!" + c.value + "\n");
|
||||||
|
output.indent();
|
||||||
}
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -1030,16 +1057,24 @@ function OutputStream(options) {
|
|||||||
output.print(self.operator);
|
output.print(self.operator);
|
||||||
});
|
});
|
||||||
DEFPRINT(AST_Binary, function(self, output){
|
DEFPRINT(AST_Binary, function(self, output){
|
||||||
|
var op = self.operator;
|
||||||
self.left.print(output);
|
self.left.print(output);
|
||||||
|
if (op[0] == ">" /* ">>" ">>>" ">" ">=" */
|
||||||
|
&& self.left instanceof AST_UnaryPostfix
|
||||||
|
&& self.left.operator == "--") {
|
||||||
|
// space is mandatory to avoid outputting -->
|
||||||
|
output.print(" ");
|
||||||
|
} else {
|
||||||
|
// the space is optional depending on "beautify"
|
||||||
output.space();
|
output.space();
|
||||||
output.print(self.operator);
|
}
|
||||||
if (self.operator == "<"
|
output.print(op);
|
||||||
|
if ((op == "<" || op == "<<")
|
||||||
&& self.right instanceof AST_UnaryPrefix
|
&& self.right instanceof AST_UnaryPrefix
|
||||||
&& self.right.operator == "!"
|
&& self.right.operator == "!"
|
||||||
&& self.right.expression instanceof AST_UnaryPrefix
|
&& self.right.expression instanceof AST_UnaryPrefix
|
||||||
&& self.right.expression.operator == "--") {
|
&& self.right.expression.operator == "--") {
|
||||||
// space is mandatory to avoid outputting <!--
|
// space is mandatory to avoid outputting <!--
|
||||||
// http://javascript.spec.whatwg.org/#comment-syntax
|
|
||||||
output.print(" ");
|
output.print(" ");
|
||||||
} else {
|
} else {
|
||||||
// the space is optional depending on "beautify"
|
// the space is optional depending on "beautify"
|
||||||
@@ -1143,7 +1178,11 @@ function OutputStream(options) {
|
|||||||
output.print_string(self.getValue(), self.quote);
|
output.print_string(self.getValue(), self.quote);
|
||||||
});
|
});
|
||||||
DEFPRINT(AST_Number, function(self, output){
|
DEFPRINT(AST_Number, function(self, output){
|
||||||
|
if (use_asm && self.start.raw != null) {
|
||||||
|
output.print(self.start.raw);
|
||||||
|
} else {
|
||||||
output.print(make_num(self.getValue()));
|
output.print(make_num(self.getValue()));
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
function regexp_safe_literal(code) {
|
function regexp_safe_literal(code) {
|
||||||
@@ -1319,6 +1358,12 @@ function OutputStream(options) {
|
|||||||
DEFMAP(AST_Finally, basic_sourcemap_gen);
|
DEFMAP(AST_Finally, basic_sourcemap_gen);
|
||||||
DEFMAP(AST_Definitions, basic_sourcemap_gen);
|
DEFMAP(AST_Definitions, basic_sourcemap_gen);
|
||||||
DEFMAP(AST_Constant, basic_sourcemap_gen);
|
DEFMAP(AST_Constant, basic_sourcemap_gen);
|
||||||
|
DEFMAP(AST_ObjectSetter, function(self, output){
|
||||||
|
output.add_mapping(self.start, self.key.name);
|
||||||
|
});
|
||||||
|
DEFMAP(AST_ObjectGetter, function(self, output){
|
||||||
|
output.add_mapping(self.start, self.key.name);
|
||||||
|
});
|
||||||
DEFMAP(AST_ObjectProperty, function(self, output){
|
DEFMAP(AST_ObjectProperty, function(self, output){
|
||||||
output.add_mapping(self.start, self.key);
|
output.add_mapping(self.start, self.key);
|
||||||
});
|
});
|
||||||
|
|||||||
35
lib/parse.js
35
lib/parse.js
@@ -59,7 +59,6 @@ var OPERATOR_CHARS = makePredicate(characters("+-*&%=<>!?|~^"));
|
|||||||
|
|
||||||
var RE_HEX_NUMBER = /^0x[0-9a-f]+$/i;
|
var RE_HEX_NUMBER = /^0x[0-9a-f]+$/i;
|
||||||
var RE_OCT_NUMBER = /^0[0-7]+$/;
|
var RE_OCT_NUMBER = /^0[0-7]+$/;
|
||||||
var RE_DEC_NUMBER = /^\d*\.?\d*(?:e[+-]?\d*(?:\d\.?|\.?\d)\d*)?$/i;
|
|
||||||
|
|
||||||
var OPERATORS = makePredicate([
|
var OPERATORS = makePredicate([
|
||||||
"in",
|
"in",
|
||||||
@@ -108,7 +107,7 @@ var OPERATORS = makePredicate([
|
|||||||
"||"
|
"||"
|
||||||
]);
|
]);
|
||||||
|
|
||||||
var WHITESPACE_CHARS = makePredicate(characters(" \u00a0\n\r\t\f\u000b\u200b\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000"));
|
var WHITESPACE_CHARS = makePredicate(characters(" \u00a0\n\r\t\f\u000b\u200b\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000\uFEFF"));
|
||||||
|
|
||||||
var PUNC_BEFORE_EXPRESSION = makePredicate(characters("[{(,.;:"));
|
var PUNC_BEFORE_EXPRESSION = makePredicate(characters("[{(,.;:"));
|
||||||
|
|
||||||
@@ -182,8 +181,9 @@ function parse_js_number(num) {
|
|||||||
return parseInt(num.substr(2), 16);
|
return parseInt(num.substr(2), 16);
|
||||||
} else if (RE_OCT_NUMBER.test(num)) {
|
} else if (RE_OCT_NUMBER.test(num)) {
|
||||||
return parseInt(num.substr(1), 8);
|
return parseInt(num.substr(1), 8);
|
||||||
} else if (RE_DEC_NUMBER.test(num)) {
|
} else {
|
||||||
return parseFloat(num);
|
var val = parseFloat(num);
|
||||||
|
if (val == num) return val;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -210,10 +210,10 @@ function is_token(token, type, val) {
|
|||||||
|
|
||||||
var EX_EOF = {};
|
var EX_EOF = {};
|
||||||
|
|
||||||
function tokenizer($TEXT, filename, html5_comments) {
|
function tokenizer($TEXT, filename, html5_comments, shebang) {
|
||||||
|
|
||||||
var S = {
|
var S = {
|
||||||
text : $TEXT.replace(/\uFEFF/g, ''),
|
text : $TEXT,
|
||||||
filename : filename,
|
filename : filename,
|
||||||
pos : 0,
|
pos : 0,
|
||||||
tokpos : 0,
|
tokpos : 0,
|
||||||
@@ -285,6 +285,9 @@ function tokenizer($TEXT, filename, html5_comments) {
|
|||||||
nlb : S.newline_before,
|
nlb : S.newline_before,
|
||||||
file : filename
|
file : filename
|
||||||
};
|
};
|
||||||
|
if (/^(?:num|string|regexp)$/i.test(type)) {
|
||||||
|
ret.raw = $TEXT.substring(ret.pos, ret.endpos);
|
||||||
|
}
|
||||||
if (!is_comment) {
|
if (!is_comment) {
|
||||||
ret.comments_before = S.comments_before;
|
ret.comments_before = S.comments_before;
|
||||||
S.comments_before = [];
|
S.comments_before = [];
|
||||||
@@ -480,7 +483,11 @@ function tokenizer($TEXT, filename, html5_comments) {
|
|||||||
regexp += ch;
|
regexp += ch;
|
||||||
}
|
}
|
||||||
var mods = read_name();
|
var mods = read_name();
|
||||||
|
try {
|
||||||
return token("regexp", new RegExp(regexp, mods));
|
return token("regexp", new RegExp(regexp, mods));
|
||||||
|
} catch(e) {
|
||||||
|
parse_error(e.message);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
function read_operator(prefix) {
|
function read_operator(prefix) {
|
||||||
@@ -564,6 +571,13 @@ function tokenizer($TEXT, filename, html5_comments) {
|
|||||||
if (PUNC_CHARS(ch)) return token("punc", next());
|
if (PUNC_CHARS(ch)) return token("punc", next());
|
||||||
if (OPERATOR_CHARS(ch)) return read_operator();
|
if (OPERATOR_CHARS(ch)) return read_operator();
|
||||||
if (code == 92 || is_identifier_start(code)) return read_word();
|
if (code == 92 || is_identifier_start(code)) return read_word();
|
||||||
|
|
||||||
|
if (shebang) {
|
||||||
|
if (S.pos == 0 && looking_at("#!")) {
|
||||||
|
forward(2);
|
||||||
|
return skip_line_comment("comment5");
|
||||||
|
}
|
||||||
|
}
|
||||||
parse_error("Unexpected character '" + ch + "'");
|
parse_error("Unexpected character '" + ch + "'");
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -633,12 +647,13 @@ function parse($TEXT, options) {
|
|||||||
expression : false,
|
expression : false,
|
||||||
html5_comments : true,
|
html5_comments : true,
|
||||||
bare_returns : false,
|
bare_returns : false,
|
||||||
|
shebang : true,
|
||||||
});
|
});
|
||||||
|
|
||||||
var S = {
|
var S = {
|
||||||
input : (typeof $TEXT == "string"
|
input : (typeof $TEXT == "string"
|
||||||
? tokenizer($TEXT, options.filename,
|
? tokenizer($TEXT, options.filename,
|
||||||
options.html5_comments)
|
options.html5_comments, options.shebang)
|
||||||
: $TEXT),
|
: $TEXT),
|
||||||
token : null,
|
token : null,
|
||||||
prev : null,
|
prev : null,
|
||||||
@@ -1110,7 +1125,7 @@ function parse($TEXT, options) {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
var new_ = function() {
|
var new_ = function(allow_calls) {
|
||||||
var start = S.token;
|
var start = S.token;
|
||||||
expect_token("operator", "new");
|
expect_token("operator", "new");
|
||||||
var newexp = expr_atom(false), args;
|
var newexp = expr_atom(false), args;
|
||||||
@@ -1125,7 +1140,7 @@ function parse($TEXT, options) {
|
|||||||
expression : newexp,
|
expression : newexp,
|
||||||
args : args,
|
args : args,
|
||||||
end : prev()
|
end : prev()
|
||||||
}), true);
|
}), allow_calls);
|
||||||
};
|
};
|
||||||
|
|
||||||
function as_atom_node() {
|
function as_atom_node() {
|
||||||
@@ -1169,7 +1184,7 @@ function parse($TEXT, options) {
|
|||||||
|
|
||||||
var expr_atom = function(allow_calls) {
|
var expr_atom = function(allow_calls) {
|
||||||
if (is("operator", "new")) {
|
if (is("operator", "new")) {
|
||||||
return new_();
|
return new_(allow_calls);
|
||||||
}
|
}
|
||||||
var start = S.token;
|
var start = S.token;
|
||||||
if (is("punc")) {
|
if (is("punc")) {
|
||||||
|
|||||||
@@ -64,7 +64,8 @@ function mangle_properties(ast, options) {
|
|||||||
options = defaults(options, {
|
options = defaults(options, {
|
||||||
reserved : null,
|
reserved : null,
|
||||||
cache : null,
|
cache : null,
|
||||||
only_cache : false
|
only_cache : false,
|
||||||
|
regex : null
|
||||||
});
|
});
|
||||||
|
|
||||||
var reserved = options.reserved;
|
var reserved = options.reserved;
|
||||||
@@ -79,7 +80,10 @@ function mangle_properties(ast, options) {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var regex = options.regex;
|
||||||
|
|
||||||
var names_to_mangle = [];
|
var names_to_mangle = [];
|
||||||
|
var unmangleable = [];
|
||||||
|
|
||||||
// step 1: find candidates to mangle
|
// step 1: find candidates to mangle
|
||||||
ast.walk(new TreeWalker(function(node){
|
ast.walk(new TreeWalker(function(node){
|
||||||
@@ -105,21 +109,15 @@ function mangle_properties(ast, options) {
|
|||||||
// step 2: transform the tree, renaming properties
|
// step 2: transform the tree, renaming properties
|
||||||
return ast.transform(new TreeTransformer(function(node){
|
return ast.transform(new TreeTransformer(function(node){
|
||||||
if (node instanceof AST_ObjectKeyVal) {
|
if (node instanceof AST_ObjectKeyVal) {
|
||||||
if (should_mangle(node.key)) {
|
|
||||||
node.key = mangle(node.key);
|
node.key = mangle(node.key);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
else if (node instanceof AST_ObjectProperty) {
|
else if (node instanceof AST_ObjectProperty) {
|
||||||
// setter or getter
|
// setter or getter
|
||||||
if (should_mangle(node.key.name)) {
|
|
||||||
node.key.name = mangle(node.key.name);
|
node.key.name = mangle(node.key.name);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
else if (node instanceof AST_Dot) {
|
else if (node instanceof AST_Dot) {
|
||||||
if (should_mangle(node.property)) {
|
|
||||||
node.property = mangle(node.property);
|
node.property = mangle(node.property);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
else if (node instanceof AST_Sub) {
|
else if (node instanceof AST_Sub) {
|
||||||
node.property = mangleStrings(node.property);
|
node.property = mangleStrings(node.property);
|
||||||
}
|
}
|
||||||
@@ -140,15 +138,18 @@ function mangle_properties(ast, options) {
|
|||||||
// only function declarations after this line
|
// only function declarations after this line
|
||||||
|
|
||||||
function can_mangle(name) {
|
function can_mangle(name) {
|
||||||
|
if (unmangleable.indexOf(name) >= 0) return false;
|
||||||
|
if (reserved.indexOf(name) >= 0) return false;
|
||||||
if (options.only_cache) {
|
if (options.only_cache) {
|
||||||
return cache.props.has(name);
|
return cache.props.has(name);
|
||||||
}
|
}
|
||||||
if (reserved.indexOf(name) >= 0) return false;
|
|
||||||
if (/^[0-9.]+$/.test(name)) return false;
|
if (/^[0-9.]+$/.test(name)) return false;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
function should_mangle(name) {
|
function should_mangle(name) {
|
||||||
|
if (regex && !regex.test(name)) return false;
|
||||||
|
if (reserved.indexOf(name) >= 0) return false;
|
||||||
return cache.props.has(name)
|
return cache.props.has(name)
|
||||||
|| names_to_mangle.indexOf(name) >= 0;
|
|| names_to_mangle.indexOf(name) >= 0;
|
||||||
}
|
}
|
||||||
@@ -156,9 +157,17 @@ function mangle_properties(ast, options) {
|
|||||||
function add(name) {
|
function add(name) {
|
||||||
if (can_mangle(name))
|
if (can_mangle(name))
|
||||||
push_uniq(names_to_mangle, name);
|
push_uniq(names_to_mangle, name);
|
||||||
|
|
||||||
|
if (!should_mangle(name)) {
|
||||||
|
push_uniq(unmangleable, name);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function mangle(name) {
|
function mangle(name) {
|
||||||
|
if (!should_mangle(name)) {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
var mangled = cache.props.get(name);
|
var mangled = cache.props.get(name);
|
||||||
if (!mangled) {
|
if (!mangled) {
|
||||||
do {
|
do {
|
||||||
@@ -201,10 +210,8 @@ function mangle_properties(ast, options) {
|
|||||||
node.cdr = mangleStrings(node.cdr);
|
node.cdr = mangleStrings(node.cdr);
|
||||||
}
|
}
|
||||||
else if (node instanceof AST_String) {
|
else if (node instanceof AST_String) {
|
||||||
if (should_mangle(node.value)) {
|
|
||||||
node.value = mangle(node.value);
|
node.value = mangle(node.value);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
else if (node instanceof AST_Conditional) {
|
else if (node instanceof AST_Conditional) {
|
||||||
node.consequent = mangleStrings(node.consequent);
|
node.consequent = mangleStrings(node.consequent);
|
||||||
node.alternative = mangleStrings(node.alternative);
|
node.alternative = mangleStrings(node.alternative);
|
||||||
|
|||||||
44
lib/scope.js
44
lib/scope.js
@@ -92,6 +92,7 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options){
|
|||||||
// pass 1: setup scope chaining and handle definitions
|
// pass 1: setup scope chaining and handle definitions
|
||||||
var self = this;
|
var self = this;
|
||||||
var scope = self.parent_scope = null;
|
var scope = self.parent_scope = null;
|
||||||
|
var labels = new Dictionary();
|
||||||
var defun = null;
|
var defun = null;
|
||||||
var nesting = 0;
|
var nesting = 0;
|
||||||
var tw = new TreeWalker(function(node, descend){
|
var tw = new TreeWalker(function(node, descend){
|
||||||
@@ -108,16 +109,24 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options){
|
|||||||
node.init_scope_vars(nesting);
|
node.init_scope_vars(nesting);
|
||||||
var save_scope = node.parent_scope = scope;
|
var save_scope = node.parent_scope = scope;
|
||||||
var save_defun = defun;
|
var save_defun = defun;
|
||||||
|
var save_labels = labels;
|
||||||
defun = scope = node;
|
defun = scope = node;
|
||||||
|
labels = new Dictionary();
|
||||||
++nesting; descend(); --nesting;
|
++nesting; descend(); --nesting;
|
||||||
scope = save_scope;
|
scope = save_scope;
|
||||||
defun = save_defun;
|
defun = save_defun;
|
||||||
|
labels = save_labels;
|
||||||
return true; // don't descend again in TreeWalker
|
return true; // don't descend again in TreeWalker
|
||||||
}
|
}
|
||||||
if (node instanceof AST_Directive) {
|
if (node instanceof AST_LabeledStatement) {
|
||||||
node.scope = scope;
|
var l = node.label;
|
||||||
push_uniq(scope.directives, node.value);
|
if (labels.has(l.name)) {
|
||||||
return true;
|
throw new Error(string_template("Label {name} defined twice", l));
|
||||||
|
}
|
||||||
|
labels.set(l.name, l);
|
||||||
|
descend();
|
||||||
|
labels.del(l.name);
|
||||||
|
return true; // no descend again
|
||||||
}
|
}
|
||||||
if (node instanceof AST_With) {
|
if (node instanceof AST_With) {
|
||||||
for (var s = scope; s; s = s.parent_scope)
|
for (var s = scope; s; s = s.parent_scope)
|
||||||
@@ -127,6 +136,10 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options){
|
|||||||
if (node instanceof AST_Symbol) {
|
if (node instanceof AST_Symbol) {
|
||||||
node.scope = scope;
|
node.scope = scope;
|
||||||
}
|
}
|
||||||
|
if (node instanceof AST_Label) {
|
||||||
|
node.thedef = node;
|
||||||
|
node.references = [];
|
||||||
|
}
|
||||||
if (node instanceof AST_SymbolLambda) {
|
if (node instanceof AST_SymbolLambda) {
|
||||||
defun.def_function(node);
|
defun.def_function(node);
|
||||||
}
|
}
|
||||||
@@ -148,6 +161,15 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options){
|
|||||||
(options.screw_ie8 ? scope : defun)
|
(options.screw_ie8 ? scope : defun)
|
||||||
.def_variable(node);
|
.def_variable(node);
|
||||||
}
|
}
|
||||||
|
else if (node instanceof AST_LabelRef) {
|
||||||
|
var sym = labels.get(node.name);
|
||||||
|
if (!sym) throw new Error(string_template("Undefined label {name} [{line},{col}]", {
|
||||||
|
name: node.name,
|
||||||
|
line: node.start.line,
|
||||||
|
col: node.start.col
|
||||||
|
}));
|
||||||
|
node.thedef = sym;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
self.walk(tw);
|
self.walk(tw);
|
||||||
|
|
||||||
@@ -162,6 +184,10 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options){
|
|||||||
func = prev_func;
|
func = prev_func;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
if (node instanceof AST_LoopControl && node.label) {
|
||||||
|
node.label.thedef.references.push(node);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
if (node instanceof AST_SymbolRef) {
|
if (node instanceof AST_SymbolRef) {
|
||||||
var name = node.name;
|
var name = node.name;
|
||||||
var sym = node.scope.find_variable(name);
|
var sym = node.scope.find_variable(name);
|
||||||
@@ -198,7 +224,6 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options){
|
|||||||
});
|
});
|
||||||
|
|
||||||
AST_Scope.DEFMETHOD("init_scope_vars", function(nesting){
|
AST_Scope.DEFMETHOD("init_scope_vars", function(nesting){
|
||||||
this.directives = []; // contains the directives defined in this scope, i.e. "use strict"
|
|
||||||
this.variables = new Dictionary(); // map name to AST_SymbolVar (variables defined in this scope; includes functions)
|
this.variables = new Dictionary(); // map name to AST_SymbolVar (variables defined in this scope; includes functions)
|
||||||
this.functions = new Dictionary(); // map name to AST_SymbolDefun (functions defined in this scope)
|
this.functions = new Dictionary(); // map name to AST_SymbolDefun (functions defined in this scope)
|
||||||
this.uses_with = false; // will be set to true if this or some nested scope uses the `with` statement
|
this.uses_with = false; // will be set to true if this or some nested scope uses the `with` statement
|
||||||
@@ -209,10 +234,6 @@ AST_Scope.DEFMETHOD("init_scope_vars", function(nesting){
|
|||||||
this.nesting = nesting; // the nesting level of this scope (0 means toplevel)
|
this.nesting = nesting; // the nesting level of this scope (0 means toplevel)
|
||||||
});
|
});
|
||||||
|
|
||||||
AST_Scope.DEFMETHOD("strict", function(){
|
|
||||||
return this.has_directive("use strict");
|
|
||||||
});
|
|
||||||
|
|
||||||
AST_Lambda.DEFMETHOD("init_scope_vars", function(){
|
AST_Lambda.DEFMETHOD("init_scope_vars", function(){
|
||||||
AST_Scope.prototype.init_scope_vars.apply(this, arguments);
|
AST_Scope.prototype.init_scope_vars.apply(this, arguments);
|
||||||
this.uses_arguments = false;
|
this.uses_arguments = false;
|
||||||
@@ -236,11 +257,6 @@ AST_Scope.DEFMETHOD("find_variable", function(name){
|
|||||||
|| (this.parent_scope && this.parent_scope.find_variable(name));
|
|| (this.parent_scope && this.parent_scope.find_variable(name));
|
||||||
});
|
});
|
||||||
|
|
||||||
AST_Scope.DEFMETHOD("has_directive", function(value){
|
|
||||||
return this.parent_scope && this.parent_scope.has_directive(value)
|
|
||||||
|| (this.directives.indexOf(value) >= 0 ? this : null);
|
|
||||||
});
|
|
||||||
|
|
||||||
AST_Scope.DEFMETHOD("def_function", function(symbol){
|
AST_Scope.DEFMETHOD("def_function", function(symbol){
|
||||||
this.functions.set(symbol.name, this.def_variable(symbol));
|
this.functions.set(symbol.name, this.def_variable(symbol));
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -70,7 +70,7 @@ TreeTransformer.prototype = new TreeWalker;
|
|||||||
if (y !== undefined) x = y;
|
if (y !== undefined) x = y;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
tw.pop();
|
tw.pop(this);
|
||||||
return x;
|
return x;
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|||||||
128
npm-shrinkwrap.json
generated
Normal file
128
npm-shrinkwrap.json
generated
Normal file
@@ -0,0 +1,128 @@
|
|||||||
|
{
|
||||||
|
"name": "uglify-js",
|
||||||
|
"version": "2.4.24",
|
||||||
|
"dependencies": {
|
||||||
|
"abbrev": {
|
||||||
|
"version": "1.0.7",
|
||||||
|
"from": "abbrev@>=1.0.0 <2.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.0.7.tgz"
|
||||||
|
},
|
||||||
|
"amdefine": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"from": "amdefine@>=0.0.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.0.tgz"
|
||||||
|
},
|
||||||
|
"async": {
|
||||||
|
"version": "0.2.10",
|
||||||
|
"from": "async@>=0.2.6 <0.3.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/async/-/async-0.2.10.tgz"
|
||||||
|
},
|
||||||
|
"camelcase": {
|
||||||
|
"version": "1.2.1",
|
||||||
|
"from": "camelcase@>=1.0.2 <2.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/camelcase/-/camelcase-1.2.1.tgz"
|
||||||
|
},
|
||||||
|
"decamelize": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"from": "decamelize@>=1.0.0 <2.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.0.0.tgz"
|
||||||
|
},
|
||||||
|
"deep-is": {
|
||||||
|
"version": "0.1.3",
|
||||||
|
"from": "deep-is@>=0.1.2 <0.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz"
|
||||||
|
},
|
||||||
|
"esprima": {
|
||||||
|
"version": "1.1.1",
|
||||||
|
"from": "esprima@>=1.1.1 <1.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/esprima/-/esprima-1.1.1.tgz"
|
||||||
|
},
|
||||||
|
"estraverse": {
|
||||||
|
"version": "1.5.1",
|
||||||
|
"from": "estraverse@>=1.5.1 <1.6.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/estraverse/-/estraverse-1.5.1.tgz"
|
||||||
|
},
|
||||||
|
"esutils": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"from": "esutils@>=1.0.0 <1.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/esutils/-/esutils-1.0.0.tgz"
|
||||||
|
},
|
||||||
|
"fast-levenshtein": {
|
||||||
|
"version": "1.0.7",
|
||||||
|
"from": "fast-levenshtein@>=1.0.0 <1.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-1.0.7.tgz"
|
||||||
|
},
|
||||||
|
"levn": {
|
||||||
|
"version": "0.2.5",
|
||||||
|
"from": "levn@>=0.2.5 <0.3.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/levn/-/levn-0.2.5.tgz"
|
||||||
|
},
|
||||||
|
"nopt": {
|
||||||
|
"version": "2.1.2",
|
||||||
|
"from": "nopt@>=2.1.2 <2.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/nopt/-/nopt-2.1.2.tgz"
|
||||||
|
},
|
||||||
|
"optionator": {
|
||||||
|
"version": "0.5.0",
|
||||||
|
"from": "optionator@>=0.5.0 <0.6.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/optionator/-/optionator-0.5.0.tgz"
|
||||||
|
},
|
||||||
|
"prelude-ls": {
|
||||||
|
"version": "1.1.2",
|
||||||
|
"from": "prelude-ls@>=1.1.1 <1.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz"
|
||||||
|
},
|
||||||
|
"reflect": {
|
||||||
|
"version": "0.1.3",
|
||||||
|
"from": "git://github.com/zaach/reflect.js.git",
|
||||||
|
"resolved": "git://github.com/zaach/reflect.js.git#286bcd79661c96ecc404357d3c0e35fdb54a6967"
|
||||||
|
},
|
||||||
|
"source-map": {
|
||||||
|
"version": "0.5.1",
|
||||||
|
"from": "source-map@>=0.5.1 <0.6.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.1.tgz"
|
||||||
|
},
|
||||||
|
"type-check": {
|
||||||
|
"version": "0.3.1",
|
||||||
|
"from": "type-check@>=0.3.1 <0.4.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.1.tgz"
|
||||||
|
},
|
||||||
|
"uglify-js": {
|
||||||
|
"version": "2.4.24",
|
||||||
|
"from": "git://github.com/mishoo/UglifyJS2.git",
|
||||||
|
"resolved": "git://github.com/mishoo/UglifyJS2.git#2a06c7758e24a64740473c8031eafbb7fefa213f",
|
||||||
|
"dependencies": {
|
||||||
|
"source-map": {
|
||||||
|
"version": "0.1.34",
|
||||||
|
"from": "source-map@0.1.34",
|
||||||
|
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.1.34.tgz"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"uglify-to-browserify": {
|
||||||
|
"version": "1.0.2",
|
||||||
|
"from": "uglify-to-browserify@>=1.0.0 <1.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/uglify-to-browserify/-/uglify-to-browserify-1.0.2.tgz"
|
||||||
|
},
|
||||||
|
"window-size": {
|
||||||
|
"version": "0.1.0",
|
||||||
|
"from": "window-size@0.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/window-size/-/window-size-0.1.0.tgz"
|
||||||
|
},
|
||||||
|
"wordwrap": {
|
||||||
|
"version": "0.0.2",
|
||||||
|
"from": "wordwrap@0.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.2.tgz"
|
||||||
|
},
|
||||||
|
"yargs": {
|
||||||
|
"version": "3.10.0",
|
||||||
|
"from": "yargs@>=3.10.0 <3.11.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/yargs/-/yargs-3.10.0.tgz"
|
||||||
|
},
|
||||||
|
"zeparser": {
|
||||||
|
"version": "0.0.7",
|
||||||
|
"from": "git://github.com/qfox/ZeParser.git",
|
||||||
|
"resolved": "git://github.com/qfox/ZeParser.git#c99240c5ba7054c467733800ff38265958a2dda9"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
11
package.json
11
package.json
@@ -3,10 +3,10 @@
|
|||||||
"description": "JavaScript parser, mangler/compressor and beautifier toolkit",
|
"description": "JavaScript parser, mangler/compressor and beautifier toolkit",
|
||||||
"homepage": "http://lisperator.net/uglifyjs",
|
"homepage": "http://lisperator.net/uglifyjs",
|
||||||
"author": "Mihai Bazon <mihai.bazon@gmail.com> (http://lisperator.net/)",
|
"author": "Mihai Bazon <mihai.bazon@gmail.com> (http://lisperator.net/)",
|
||||||
"license": "BSD",
|
"license": "BSD-2-Clause",
|
||||||
"version": "2.4.21",
|
"version": "2.6.0",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=0.4.0"
|
"node": ">=0.8.0"
|
||||||
},
|
},
|
||||||
"maintainers": [
|
"maintainers": [
|
||||||
"Mihai Bazon <mihai.bazon@gmail.com> (http://lisperator.net/)"
|
"Mihai Bazon <mihai.bazon@gmail.com> (http://lisperator.net/)"
|
||||||
@@ -30,9 +30,9 @@
|
|||||||
],
|
],
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"async": "~0.2.6",
|
"async": "~0.2.6",
|
||||||
"source-map": "0.1.34",
|
"source-map": "~0.5.1",
|
||||||
"uglify-to-browserify": "~1.0.0",
|
"uglify-to-browserify": "~1.0.0",
|
||||||
"yargs": "~3.5.4"
|
"yargs": "~3.10.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"acorn": "~0.6.0",
|
"acorn": "~0.6.0",
|
||||||
@@ -46,6 +46,7 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
"shrinkwrap": "rm ./npm-shrinkwrap.json; rm -rf ./node_modules; npm i && npm shrinkwrap && npm outdated",
|
||||||
"test": "node test/run-tests.js"
|
"test": "node test/run-tests.js"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
106
test/compress/asm.js
Normal file
106
test/compress/asm.js
Normal file
@@ -0,0 +1,106 @@
|
|||||||
|
asm_mixed: {
|
||||||
|
options = {
|
||||||
|
sequences : true,
|
||||||
|
properties : true,
|
||||||
|
dead_code : true,
|
||||||
|
drop_debugger : true,
|
||||||
|
conditionals : true,
|
||||||
|
comparisons : true,
|
||||||
|
evaluate : true,
|
||||||
|
booleans : true,
|
||||||
|
loops : true,
|
||||||
|
unused : true,
|
||||||
|
hoist_funs : true,
|
||||||
|
keep_fargs : true,
|
||||||
|
keep_fnames : false,
|
||||||
|
hoist_vars : true,
|
||||||
|
if_return : true,
|
||||||
|
join_vars : true,
|
||||||
|
cascade : true,
|
||||||
|
side_effects : true,
|
||||||
|
negate_iife : true
|
||||||
|
};
|
||||||
|
input: {
|
||||||
|
// adapted from http://asmjs.org/spec/latest/
|
||||||
|
function asm_GeometricMean(stdlib, foreign, buffer) {
|
||||||
|
"use asm";
|
||||||
|
var exp = stdlib.Math.exp;
|
||||||
|
var log = stdlib.Math.log;
|
||||||
|
var values = new stdlib.Float64Array(buffer);
|
||||||
|
function logSum(start, end) {
|
||||||
|
start = start|0;
|
||||||
|
end = end|0;
|
||||||
|
var sum = 0.0, p = 0, q = 0;
|
||||||
|
// asm.js forces byte addressing of the heap by requiring shifting by 3
|
||||||
|
for (p = start << 3, q = end << 3; (p|0) < (q|0); p = (p + 8)|0) {
|
||||||
|
sum = sum + +log(values[p>>3]);
|
||||||
|
}
|
||||||
|
return +sum;
|
||||||
|
}
|
||||||
|
function geometricMean(start, end) {
|
||||||
|
start = start|0;
|
||||||
|
end = end|0;
|
||||||
|
return +exp(+logSum(start, end) / +((end - start)|0));
|
||||||
|
}
|
||||||
|
return { geometricMean: geometricMean };
|
||||||
|
}
|
||||||
|
function no_asm_GeometricMean(stdlib, foreign, buffer) {
|
||||||
|
var exp = stdlib.Math.exp;
|
||||||
|
var log = stdlib.Math.log;
|
||||||
|
var values = new stdlib.Float64Array(buffer);
|
||||||
|
function logSum(start, end) {
|
||||||
|
start = start|0;
|
||||||
|
end = end|0;
|
||||||
|
var sum = 0.0, p = 0, q = 0;
|
||||||
|
// asm.js forces byte addressing of the heap by requiring shifting by 3
|
||||||
|
for (p = start << 3, q = end << 3; (p|0) < (q|0); p = (p + 8)|0) {
|
||||||
|
sum = sum + +log(values[p>>3]);
|
||||||
|
}
|
||||||
|
return +sum;
|
||||||
|
}
|
||||||
|
function geometricMean(start, end) {
|
||||||
|
start = start|0;
|
||||||
|
end = end|0;
|
||||||
|
return +exp(+logSum(start, end) / +((end - start)|0));
|
||||||
|
}
|
||||||
|
return { geometricMean: geometricMean };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function asm_GeometricMean(stdlib, foreign, buffer) {
|
||||||
|
"use asm";
|
||||||
|
var exp = stdlib.Math.exp;
|
||||||
|
var log = stdlib.Math.log;
|
||||||
|
var values = new stdlib.Float64Array(buffer);
|
||||||
|
function logSum(start, end) {
|
||||||
|
start = start | 0;
|
||||||
|
end = end | 0;
|
||||||
|
var sum = 0.0, p = 0, q = 0;
|
||||||
|
for (p = start << 3, q = end << 3; (p | 0) < (q | 0); p = p + 8 | 0) {
|
||||||
|
sum = sum + +log(values[p >> 3]);
|
||||||
|
}
|
||||||
|
return +sum;
|
||||||
|
}
|
||||||
|
function geometricMean(start, end) {
|
||||||
|
start = start | 0;
|
||||||
|
end = end | 0;
|
||||||
|
return +exp(+logSum(start, end) / +(end - start | 0));
|
||||||
|
}
|
||||||
|
return { geometricMean: geometricMean };
|
||||||
|
}
|
||||||
|
function no_asm_GeometricMean(stdlib, foreign, buffer) {
|
||||||
|
function logSum(start, end) {
|
||||||
|
start = 0 | start, end = 0 | end;
|
||||||
|
var sum = 0, p = 0, q = 0;
|
||||||
|
for (p = start << 3, q = end << 3; (0 | q) > (0 | p); p = p + 8 | 0) sum += +log(values[p >> 3]);
|
||||||
|
return +sum;
|
||||||
|
}
|
||||||
|
function geometricMean(start, end) {
|
||||||
|
return start = 0 | start, end = 0 | end, +exp(+logSum(start, end) / +(end - start | 0));
|
||||||
|
}
|
||||||
|
var exp = stdlib.Math.exp, log = stdlib.Math.log, values = new stdlib.Float64Array(buffer);
|
||||||
|
return { geometricMean: geometricMean };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -153,6 +153,7 @@ cond_1: {
|
|||||||
conditionals: true
|
conditionals: true
|
||||||
};
|
};
|
||||||
input: {
|
input: {
|
||||||
|
var do_something; // if undeclared it's assumed to have side-effects
|
||||||
if (some_condition()) {
|
if (some_condition()) {
|
||||||
do_something(x);
|
do_something(x);
|
||||||
} else {
|
} else {
|
||||||
@@ -160,6 +161,7 @@ cond_1: {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
|
var do_something;
|
||||||
do_something(some_condition() ? x : y);
|
do_something(some_condition() ? x : y);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -169,7 +171,7 @@ cond_2: {
|
|||||||
conditionals: true
|
conditionals: true
|
||||||
};
|
};
|
||||||
input: {
|
input: {
|
||||||
var x;
|
var x, FooBar;
|
||||||
if (some_condition()) {
|
if (some_condition()) {
|
||||||
x = new FooBar(1);
|
x = new FooBar(1);
|
||||||
} else {
|
} else {
|
||||||
@@ -177,7 +179,7 @@ cond_2: {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
var x;
|
var x, FooBar;
|
||||||
x = new FooBar(some_condition() ? 1 : 2);
|
x = new FooBar(some_condition() ? 1 : 2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -187,6 +189,7 @@ cond_3: {
|
|||||||
conditionals: true
|
conditionals: true
|
||||||
};
|
};
|
||||||
input: {
|
input: {
|
||||||
|
var FooBar;
|
||||||
if (some_condition()) {
|
if (some_condition()) {
|
||||||
new FooBar(1);
|
new FooBar(1);
|
||||||
} else {
|
} else {
|
||||||
@@ -194,6 +197,7 @@ cond_3: {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
|
var FooBar;
|
||||||
some_condition() ? new FooBar(1) : FooBar(2);
|
some_condition() ? new FooBar(1) : FooBar(2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -203,6 +207,7 @@ cond_4: {
|
|||||||
conditionals: true
|
conditionals: true
|
||||||
};
|
};
|
||||||
input: {
|
input: {
|
||||||
|
var do_something;
|
||||||
if (some_condition()) {
|
if (some_condition()) {
|
||||||
do_something();
|
do_something();
|
||||||
} else {
|
} else {
|
||||||
@@ -210,6 +215,7 @@ cond_4: {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
|
var do_something;
|
||||||
some_condition(), do_something();
|
some_condition(), do_something();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -378,3 +384,163 @@ cond_8: {
|
|||||||
a = condition ? 1 : 0;
|
a = condition ? 1 : 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
conditional_and: {
|
||||||
|
options = {
|
||||||
|
conditionals: true,
|
||||||
|
evaluate : true
|
||||||
|
};
|
||||||
|
input: {
|
||||||
|
var a;
|
||||||
|
// compress these
|
||||||
|
|
||||||
|
a = true && condition;
|
||||||
|
a = 1 && console.log("a");
|
||||||
|
a = 2 * 3 && 2 * condition;
|
||||||
|
a = 5 == 5 && condition + 3;
|
||||||
|
a = "string" && 4 - condition;
|
||||||
|
a = 5 + "" && condition / 5;
|
||||||
|
a = -4.5 && 6 << condition;
|
||||||
|
a = 6 && 7;
|
||||||
|
|
||||||
|
a = false && condition;
|
||||||
|
a = NaN && console.log("b");
|
||||||
|
a = 0 && console.log("c");
|
||||||
|
a = undefined && 2 * condition;
|
||||||
|
a = null && condition + 3;
|
||||||
|
a = 2 * 3 - 6 && 4 - condition;
|
||||||
|
a = 10 == 7 && condition / 5;
|
||||||
|
a = !"string" && 6 % condition;
|
||||||
|
a = 0 && 7;
|
||||||
|
|
||||||
|
// don't compress these
|
||||||
|
|
||||||
|
a = condition && true;
|
||||||
|
a = console.log("a") && 2;
|
||||||
|
a = 4 - condition && "string";
|
||||||
|
a = 6 << condition && -4.5;
|
||||||
|
|
||||||
|
a = condition && false;
|
||||||
|
a = console.log("b") && NaN;
|
||||||
|
a = console.log("c") && 0;
|
||||||
|
a = 2 * condition && undefined;
|
||||||
|
a = condition + 3 && null;
|
||||||
|
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a;
|
||||||
|
|
||||||
|
a = condition;
|
||||||
|
a = console.log("a");
|
||||||
|
a = 2 * condition;
|
||||||
|
a = condition + 3;
|
||||||
|
a = 4 - condition;
|
||||||
|
a = condition / 5;
|
||||||
|
a = 6 << condition;
|
||||||
|
a = 7;
|
||||||
|
|
||||||
|
a = false;
|
||||||
|
a = NaN;
|
||||||
|
a = 0;
|
||||||
|
a = void 0;
|
||||||
|
a = null;
|
||||||
|
a = 0;
|
||||||
|
a = false;
|
||||||
|
a = false;
|
||||||
|
a = 0;
|
||||||
|
|
||||||
|
a = condition && true;
|
||||||
|
a = console.log("a") && 2;
|
||||||
|
a = 4 - condition && "string";
|
||||||
|
a = 6 << condition && -4.5;
|
||||||
|
|
||||||
|
a = condition && false;
|
||||||
|
a = console.log("b") && NaN;
|
||||||
|
a = console.log("c") && 0;
|
||||||
|
a = 2 * condition && void 0;
|
||||||
|
a = condition + 3 && null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
conditional_or: {
|
||||||
|
options = {
|
||||||
|
conditionals: true,
|
||||||
|
evaluate : true
|
||||||
|
};
|
||||||
|
input: {
|
||||||
|
var a;
|
||||||
|
// compress these
|
||||||
|
|
||||||
|
a = true || condition;
|
||||||
|
a = 1 || console.log("a");
|
||||||
|
a = 2 * 3 || 2 * condition;
|
||||||
|
a = 5 == 5 || condition + 3;
|
||||||
|
a = "string" || 4 - condition;
|
||||||
|
a = 5 + "" || condition / 5;
|
||||||
|
a = -4.5 || 6 << condition;
|
||||||
|
a = 6 || 7;
|
||||||
|
|
||||||
|
a = false || condition;
|
||||||
|
a = 0 || console.log("b");
|
||||||
|
a = NaN || console.log("c");
|
||||||
|
a = undefined || 2 * condition;
|
||||||
|
a = null || condition + 3;
|
||||||
|
a = 2 * 3 - 6 || 4 - condition;
|
||||||
|
a = 10 == 7 || condition / 5;
|
||||||
|
a = !"string" || 6 % condition;
|
||||||
|
a = null || 7;
|
||||||
|
|
||||||
|
a = console.log(undefined && condition || null);
|
||||||
|
a = console.log(undefined || condition && null);
|
||||||
|
|
||||||
|
// don't compress these
|
||||||
|
|
||||||
|
a = condition || true;
|
||||||
|
a = console.log("a") || 2;
|
||||||
|
a = 4 - condition || "string";
|
||||||
|
a = 6 << condition || -4.5;
|
||||||
|
|
||||||
|
a = condition || false;
|
||||||
|
a = console.log("b") || NaN;
|
||||||
|
a = console.log("c") || 0;
|
||||||
|
a = 2 * condition || undefined;
|
||||||
|
a = condition + 3 || null;
|
||||||
|
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a;
|
||||||
|
|
||||||
|
a = true;
|
||||||
|
a = 1;
|
||||||
|
a = 6;
|
||||||
|
a = true;
|
||||||
|
a = "string";
|
||||||
|
a = "5";
|
||||||
|
a = -4.5;
|
||||||
|
a = 6;
|
||||||
|
|
||||||
|
a = condition;
|
||||||
|
a = console.log("b");
|
||||||
|
a = console.log("c");
|
||||||
|
a = 2 * condition;
|
||||||
|
a = condition + 3;
|
||||||
|
a = 4 - condition;
|
||||||
|
a = condition / 5;
|
||||||
|
a = 6 % condition;
|
||||||
|
a = 7;
|
||||||
|
|
||||||
|
a = console.log(null);
|
||||||
|
a = console.log(condition && null);
|
||||||
|
|
||||||
|
a = condition || true;
|
||||||
|
a = console.log("a") || 2;
|
||||||
|
a = 4 - condition || "string";
|
||||||
|
a = 6 << condition || -4.5;
|
||||||
|
|
||||||
|
a = condition || false;
|
||||||
|
a = console.log("b") || NaN;
|
||||||
|
a = console.log("c") || 0;
|
||||||
|
a = 2 * condition || void 0;
|
||||||
|
a = condition + 3 || null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
unused_funarg_1: {
|
unused_funarg_1: {
|
||||||
options = { unused: true, unsafe: true };
|
options = { unused: true, keep_fargs: false };
|
||||||
input: {
|
input: {
|
||||||
function f(a, b, c, d, e) {
|
function f(a, b, c, d, e) {
|
||||||
return a + b;
|
return a + b;
|
||||||
@@ -13,7 +13,7 @@ unused_funarg_1: {
|
|||||||
}
|
}
|
||||||
|
|
||||||
unused_funarg_2: {
|
unused_funarg_2: {
|
||||||
options = { unused: true, unsafe: true };
|
options = { unused: true, keep_fargs: false };
|
||||||
input: {
|
input: {
|
||||||
function f(a, b, c, d, e) {
|
function f(a, b, c, d, e) {
|
||||||
return a + c;
|
return a + c;
|
||||||
@@ -173,7 +173,7 @@ keep_fnames: {
|
|||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
function foo() {
|
function foo() {
|
||||||
return function bar() {};
|
return function bar(baz) {};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
71
test/compress/html_comments.js
Normal file
71
test/compress/html_comments.js
Normal file
@@ -0,0 +1,71 @@
|
|||||||
|
html_comment_in_expression: {
|
||||||
|
input: {
|
||||||
|
function f(a, b, x, y) { return a < !--b && x-- > y; }
|
||||||
|
}
|
||||||
|
expect_exact: "function f(a,b,x,y){return a< !--b&&x-- >y}";
|
||||||
|
}
|
||||||
|
|
||||||
|
html_comment_in_less_than: {
|
||||||
|
input: {
|
||||||
|
function f(a, b) { return a < !--b; }
|
||||||
|
}
|
||||||
|
expect_exact: "function f(a,b){return a< !--b}";
|
||||||
|
}
|
||||||
|
|
||||||
|
html_comment_in_left_shift: {
|
||||||
|
input: {
|
||||||
|
function f(a, b) { return a << !--b; }
|
||||||
|
}
|
||||||
|
expect_exact: "function f(a,b){return a<< !--b}";
|
||||||
|
}
|
||||||
|
|
||||||
|
html_comment_in_right_shift: {
|
||||||
|
input: {
|
||||||
|
function f(a, b) { return a-- >> b; }
|
||||||
|
}
|
||||||
|
expect_exact: "function f(a,b){return a-- >>b}";
|
||||||
|
}
|
||||||
|
|
||||||
|
html_comment_in_zero_fill_right_shift: {
|
||||||
|
input: {
|
||||||
|
function f(a, b) { return a-- >>> b; }
|
||||||
|
}
|
||||||
|
expect_exact: "function f(a,b){return a-- >>>b}";
|
||||||
|
}
|
||||||
|
|
||||||
|
html_comment_in_greater_than: {
|
||||||
|
input: {
|
||||||
|
function f(a, b) { return a-- > b; }
|
||||||
|
}
|
||||||
|
expect_exact: "function f(a,b){return a-- >b}";
|
||||||
|
}
|
||||||
|
|
||||||
|
html_comment_in_greater_than_or_equal: {
|
||||||
|
input: {
|
||||||
|
function f(a, b) { return a-- >= b; }
|
||||||
|
}
|
||||||
|
expect_exact: "function f(a,b){return a-- >=b}";
|
||||||
|
}
|
||||||
|
|
||||||
|
html_comment_in_right_shift_assign: {
|
||||||
|
input: {
|
||||||
|
// Note: illegal javascript
|
||||||
|
function f(a, b) { return a-- >>= b; }
|
||||||
|
}
|
||||||
|
expect_exact: "function f(a,b){return a-- >>=b}";
|
||||||
|
}
|
||||||
|
|
||||||
|
html_comment_in_zero_fill_right_shift_assign: {
|
||||||
|
input: {
|
||||||
|
// Note: illegal javascript
|
||||||
|
function f(a, b) { return a-- >>>= b; }
|
||||||
|
}
|
||||||
|
expect_exact: "function f(a,b){return a-- >>>=b}";
|
||||||
|
}
|
||||||
|
|
||||||
|
html_comment_in_string_literal: {
|
||||||
|
input: {
|
||||||
|
function f() { return "<!--HTML-->comment in<!--string literal-->"; }
|
||||||
|
}
|
||||||
|
expect_exact: 'function f(){return"\\x3c!--HTML--\\x3ecomment in\\x3c!--string literal--\\x3e"}';
|
||||||
|
}
|
||||||
11
test/compress/issue-208.js
Normal file
11
test/compress/issue-208.js
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
do_not_update_lhs: {
|
||||||
|
options = { global_defs: { DEBUG: false } };
|
||||||
|
input: { DEBUG = false; }
|
||||||
|
expect: { DEBUG = false; }
|
||||||
|
}
|
||||||
|
|
||||||
|
do_update_rhs: {
|
||||||
|
options = { global_defs: { DEBUG: false } };
|
||||||
|
input: { MY_DEBUG = DEBUG; }
|
||||||
|
expect: { MY_DEBUG = false; }
|
||||||
|
}
|
||||||
37
test/compress/issue-747.js
Normal file
37
test/compress/issue-747.js
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
dont_reuse_prop: {
|
||||||
|
mangle_props = {
|
||||||
|
regex: /asd/
|
||||||
|
};
|
||||||
|
|
||||||
|
input: {
|
||||||
|
var obj = {};
|
||||||
|
obj.a = 123;
|
||||||
|
obj.asd = 256;
|
||||||
|
console.log(obj.a);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var obj = {};
|
||||||
|
obj.a = 123;
|
||||||
|
obj.b = 256;
|
||||||
|
console.log(obj.a);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
unmangleable_props_should_always_be_reserved: {
|
||||||
|
mangle_props = {
|
||||||
|
regex: /asd/
|
||||||
|
};
|
||||||
|
|
||||||
|
input: {
|
||||||
|
var obj = {};
|
||||||
|
obj.asd = 256;
|
||||||
|
obj.a = 123;
|
||||||
|
console.log(obj.a);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var obj = {};
|
||||||
|
obj.b = 256;
|
||||||
|
obj.a = 123;
|
||||||
|
console.log(obj.a);
|
||||||
|
}
|
||||||
|
}
|
||||||
29
test/compress/issue-751.js
Normal file
29
test/compress/issue-751.js
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
negate_booleans_1: {
|
||||||
|
options = {
|
||||||
|
comparisons: true
|
||||||
|
};
|
||||||
|
input: {
|
||||||
|
var a = !a || !b || !c || !d || !e || !f;
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a = !(a && b && c && d && e && f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
negate_booleans_2: {
|
||||||
|
options = {
|
||||||
|
comparisons: true
|
||||||
|
};
|
||||||
|
input: {
|
||||||
|
var match = !x && // should not touch this one
|
||||||
|
(!z || c) &&
|
||||||
|
(!k || d) &&
|
||||||
|
the_stuff();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var match = !x &&
|
||||||
|
(!z || c) &&
|
||||||
|
(!k || d) &&
|
||||||
|
the_stuff();
|
||||||
|
}
|
||||||
|
}
|
||||||
23
test/compress/issue-782.js
Normal file
23
test/compress/issue-782.js
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
remove_redundant_sequence_items: {
|
||||||
|
options = { side_effects: true };
|
||||||
|
input: {
|
||||||
|
(0, 1, logThis)();
|
||||||
|
(0, 1, _decorators.logThis)();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
(0, logThis)();
|
||||||
|
(0, _decorators.logThis)();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dont_remove_lexical_binding_sequence: {
|
||||||
|
options = { side_effects: true };
|
||||||
|
input: {
|
||||||
|
(0, logThis)();
|
||||||
|
(0, _decorators.logThis)();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
(0, logThis)();
|
||||||
|
(0, _decorators.logThis)();
|
||||||
|
}
|
||||||
|
}
|
||||||
12
test/compress/new.js
Normal file
12
test/compress/new.js
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
new_statement: {
|
||||||
|
input: {
|
||||||
|
new x(1);
|
||||||
|
new x(1)(2);
|
||||||
|
new x(1)(2)(3);
|
||||||
|
new new x(1);
|
||||||
|
new new x(1)(2);
|
||||||
|
new (new x(1))(2);
|
||||||
|
(new new x(1))(2);
|
||||||
|
}
|
||||||
|
expect_exact: "new x(1);new x(1)(2);new x(1)(2)(3);new new x(1);new new x(1)(2);new new x(1)(2);(new new x(1))(2);"
|
||||||
|
}
|
||||||
124
test/compress/return_undefined.js
Normal file
124
test/compress/return_undefined.js
Normal file
@@ -0,0 +1,124 @@
|
|||||||
|
return_undefined: {
|
||||||
|
options = {
|
||||||
|
sequences : false,
|
||||||
|
if_return : true,
|
||||||
|
evaluate : true,
|
||||||
|
dead_code : true,
|
||||||
|
conditionals : true,
|
||||||
|
comparisons : true,
|
||||||
|
booleans : true,
|
||||||
|
unused : true,
|
||||||
|
side_effects : true,
|
||||||
|
properties : true,
|
||||||
|
drop_debugger : true,
|
||||||
|
loops : true,
|
||||||
|
hoist_funs : true,
|
||||||
|
keep_fargs : true,
|
||||||
|
keep_fnames : false,
|
||||||
|
hoist_vars : true,
|
||||||
|
join_vars : true,
|
||||||
|
cascade : true,
|
||||||
|
negate_iife : true
|
||||||
|
};
|
||||||
|
input: {
|
||||||
|
function f0() {
|
||||||
|
}
|
||||||
|
function f1() {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
function f2() {
|
||||||
|
return void 0;
|
||||||
|
}
|
||||||
|
function f3() {
|
||||||
|
return void 123;
|
||||||
|
}
|
||||||
|
function f4() {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
function f5(a, b) {
|
||||||
|
console.log(a, b);
|
||||||
|
baz(a);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
function f6(a, b) {
|
||||||
|
console.log(a, b);
|
||||||
|
if (a) {
|
||||||
|
foo(b);
|
||||||
|
baz(a);
|
||||||
|
return a + b;
|
||||||
|
}
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
function f7(a, b) {
|
||||||
|
console.log(a, b);
|
||||||
|
if (a) {
|
||||||
|
foo(b);
|
||||||
|
baz(a);
|
||||||
|
return void 0;
|
||||||
|
}
|
||||||
|
return a + b;
|
||||||
|
}
|
||||||
|
function f8(a, b) {
|
||||||
|
foo(a);
|
||||||
|
bar(b);
|
||||||
|
return void 0;
|
||||||
|
}
|
||||||
|
function f9(a, b) {
|
||||||
|
foo(a);
|
||||||
|
bar(b);
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
function f10() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
function f11() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
function f12() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function f0() {}
|
||||||
|
function f1() {}
|
||||||
|
function f2() {}
|
||||||
|
function f3() {}
|
||||||
|
function f4() {}
|
||||||
|
function f5(a, b) {
|
||||||
|
console.log(a, b);
|
||||||
|
baz(a);
|
||||||
|
}
|
||||||
|
function f6(a, b) {
|
||||||
|
console.log(a, b);
|
||||||
|
if (a) {
|
||||||
|
foo(b);
|
||||||
|
baz(a);
|
||||||
|
return a + b;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function f7(a, b) {
|
||||||
|
console.log(a, b);
|
||||||
|
if (!a)
|
||||||
|
return a + b;
|
||||||
|
foo(b);
|
||||||
|
baz(a);
|
||||||
|
}
|
||||||
|
function f8(a, b) {
|
||||||
|
foo(a);
|
||||||
|
bar(b);
|
||||||
|
}
|
||||||
|
function f9(a, b) {
|
||||||
|
foo(a);
|
||||||
|
bar(b);
|
||||||
|
}
|
||||||
|
function f10() {
|
||||||
|
return !1;
|
||||||
|
}
|
||||||
|
function f11() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
function f12() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
18
test/compress/screw-ie8.js
Normal file
18
test/compress/screw-ie8.js
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
do_screw: {
|
||||||
|
options = { screw_ie8: true };
|
||||||
|
beautify = {
|
||||||
|
screw_ie8: true,
|
||||||
|
ascii_only: true
|
||||||
|
};
|
||||||
|
|
||||||
|
input: f("\v");
|
||||||
|
expect_exact: 'f("\\v");';
|
||||||
|
}
|
||||||
|
|
||||||
|
dont_screw: {
|
||||||
|
options = { screw_ie8: false };
|
||||||
|
beautify = { screw_ie8: false, ascii_only: true };
|
||||||
|
|
||||||
|
input: f("\v");
|
||||||
|
expect_exact: 'f("\\x0B");';
|
||||||
|
}
|
||||||
@@ -4,7 +4,6 @@ var U = require("../tools/node");
|
|||||||
var path = require("path");
|
var path = require("path");
|
||||||
var fs = require("fs");
|
var fs = require("fs");
|
||||||
var assert = require("assert");
|
var assert = require("assert");
|
||||||
var sys = require("util");
|
|
||||||
|
|
||||||
var tests_dir = path.dirname(module.filename);
|
var tests_dir = path.dirname(module.filename);
|
||||||
var failures = 0;
|
var failures = 0;
|
||||||
@@ -12,11 +11,14 @@ var failed_files = {};
|
|||||||
|
|
||||||
run_compress_tests();
|
run_compress_tests();
|
||||||
if (failures) {
|
if (failures) {
|
||||||
sys.error("\n!!! Failed " + failures + " test cases.");
|
console.error("\n!!! Failed " + failures + " test cases.");
|
||||||
sys.error("!!! " + Object.keys(failed_files).join(", "));
|
console.error("!!! " + Object.keys(failed_files).join(", "));
|
||||||
process.exit(1);
|
process.exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var run_sourcemaps_tests = require('./sourcemaps');
|
||||||
|
run_sourcemaps_tests();
|
||||||
|
|
||||||
var run_ast_conversion_tests = require("./mozilla-ast");
|
var run_ast_conversion_tests = require("./mozilla-ast");
|
||||||
|
|
||||||
run_ast_conversion_tests({
|
run_ast_conversion_tests({
|
||||||
@@ -31,7 +33,7 @@ function tmpl() {
|
|||||||
|
|
||||||
function log() {
|
function log() {
|
||||||
var txt = tmpl.apply(this, arguments);
|
var txt = tmpl.apply(this, arguments);
|
||||||
sys.puts(txt);
|
console.log("%s", txt);
|
||||||
}
|
}
|
||||||
|
|
||||||
function log_directory(dir) {
|
function log_directory(dir) {
|
||||||
@@ -84,17 +86,21 @@ function run_compress_tests() {
|
|||||||
warnings: false
|
warnings: false
|
||||||
});
|
});
|
||||||
var cmp = new U.Compressor(options, true);
|
var cmp = new U.Compressor(options, true);
|
||||||
|
var output_options = test.beautify || {};
|
||||||
var expect;
|
var expect;
|
||||||
if (test.expect) {
|
if (test.expect) {
|
||||||
expect = make_code(as_toplevel(test.expect), false);
|
expect = make_code(as_toplevel(test.expect), output_options);
|
||||||
} else {
|
} else {
|
||||||
expect = test.expect_exact;
|
expect = test.expect_exact;
|
||||||
}
|
}
|
||||||
var input = as_toplevel(test.input);
|
var input = as_toplevel(test.input);
|
||||||
var input_code = make_code(test.input);
|
var input_code = make_code(test.input, { beautify: true });
|
||||||
|
if (test.mangle_props) {
|
||||||
|
input = U.mangle_properties(input, test.mangle_props);
|
||||||
|
}
|
||||||
var output = input.transform(cmp);
|
var output = input.transform(cmp);
|
||||||
output.figure_out_scope();
|
output.figure_out_scope();
|
||||||
output = make_code(output, false);
|
output = make_code(output, output_options);
|
||||||
if (expect != output) {
|
if (expect != output) {
|
||||||
log("!!! failed\n---INPUT---\n{input}\n---OUTPUT---\n{output}\n---EXPECTED---\n{expected}\n\n", {
|
log("!!! failed\n---INPUT---\n{input}\n---OUTPUT---\n{output}\n---EXPECTED---\n{expected}\n\n", {
|
||||||
input: input_code,
|
input: input_code,
|
||||||
@@ -138,7 +144,7 @@ function parse_test(file) {
|
|||||||
file: file,
|
file: file,
|
||||||
line: node.start.line,
|
line: node.start.line,
|
||||||
col: node.start.col,
|
col: node.start.col,
|
||||||
code: make_code(node, false)
|
code: make_code(node, { beautify: false })
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -185,15 +191,15 @@ function parse_test(file) {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
function make_code(ast, beautify) {
|
function make_code(ast, options) {
|
||||||
if (arguments.length == 1) beautify = true;
|
options.inline_script = true;
|
||||||
var stream = U.OutputStream({ beautify: beautify });
|
var stream = U.OutputStream(options);
|
||||||
ast.print(stream);
|
ast.print(stream);
|
||||||
return stream.get();
|
return stream.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
function evaluate(code) {
|
function evaluate(code) {
|
||||||
if (code instanceof U.AST_Node)
|
if (code instanceof U.AST_Node)
|
||||||
code = make_code(code);
|
code = make_code(code, { beautify: true });
|
||||||
return new Function("return(" + code + ")")();
|
return new Function("return(" + code + ")")();
|
||||||
}
|
}
|
||||||
|
|||||||
40
test/sourcemaps.js
Normal file
40
test/sourcemaps.js
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
var UglifyJS = require("..");
|
||||||
|
var ok = require("assert");
|
||||||
|
|
||||||
|
module.exports = function () {
|
||||||
|
console.log("--- Sourcemaps tests");
|
||||||
|
|
||||||
|
var basic = source_map([
|
||||||
|
'var x = 1 + 1;'
|
||||||
|
].join('\n'));
|
||||||
|
|
||||||
|
ok.equal(basic.version, 3);
|
||||||
|
ok.deepEqual(basic.names, ['x']);
|
||||||
|
|
||||||
|
var issue836 = source_map([
|
||||||
|
"({",
|
||||||
|
" get enabled() {",
|
||||||
|
" return 3;",
|
||||||
|
" },",
|
||||||
|
" set enabled(x) {",
|
||||||
|
" ;",
|
||||||
|
" }",
|
||||||
|
"});",
|
||||||
|
].join("\n"));
|
||||||
|
|
||||||
|
ok.deepEqual(issue836.names, ['enabled', 'x']);
|
||||||
|
}
|
||||||
|
|
||||||
|
function source_map(js) {
|
||||||
|
var source_map = UglifyJS.SourceMap();
|
||||||
|
var stream = UglifyJS.OutputStream({ source_map: source_map });
|
||||||
|
var parsed = UglifyJS.parse(js);
|
||||||
|
parsed.print(stream);
|
||||||
|
return JSON.parse(source_map.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Run standalone
|
||||||
|
if (module.parent === null) {
|
||||||
|
module.exports();
|
||||||
|
}
|
||||||
|
|
||||||
17
tools/exports.js
Normal file
17
tools/exports.js
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
exports["Compressor"] = Compressor;
|
||||||
|
exports["DefaultsError"] = DefaultsError;
|
||||||
|
exports["Dictionary"] = Dictionary;
|
||||||
|
exports["JS_Parse_Error"] = JS_Parse_Error;
|
||||||
|
exports["MAP"] = MAP;
|
||||||
|
exports["OutputStream"] = OutputStream;
|
||||||
|
exports["SourceMap"] = SourceMap;
|
||||||
|
exports["TreeTransformer"] = TreeTransformer;
|
||||||
|
exports["TreeWalker"] = TreeWalker;
|
||||||
|
exports["base54"] = base54;
|
||||||
|
exports["defaults"] = defaults;
|
||||||
|
exports["mangle_properties"] = mangle_properties;
|
||||||
|
exports["merge"] = merge;
|
||||||
|
exports["parse"] = parse;
|
||||||
|
exports["push_uniq"] = push_uniq;
|
||||||
|
exports["string_template"] = string_template;
|
||||||
|
exports["is_identifier"] = is_identifier;
|
||||||
@@ -1,26 +1,5 @@
|
|||||||
var path = require("path");
|
var path = require("path");
|
||||||
var fs = require("fs");
|
var fs = require("fs");
|
||||||
var vm = require("vm");
|
|
||||||
|
|
||||||
var UglifyJS = vm.createContext({
|
|
||||||
console : console,
|
|
||||||
process : process,
|
|
||||||
Buffer : Buffer,
|
|
||||||
MOZ_SourceMap : require("source-map")
|
|
||||||
});
|
|
||||||
|
|
||||||
function load_global(file) {
|
|
||||||
file = path.resolve(path.dirname(module.filename), file);
|
|
||||||
try {
|
|
||||||
var code = fs.readFileSync(file, "utf8");
|
|
||||||
return vm.runInContext(code, UglifyJS, file);
|
|
||||||
} catch(ex) {
|
|
||||||
// XXX: in case of a syntax error, the message is kinda
|
|
||||||
// useless. (no location information).
|
|
||||||
console.log("ERROR in file: " + file + " / " + ex);
|
|
||||||
process.exit(1);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
var FILES = exports.FILES = [
|
var FILES = exports.FILES = [
|
||||||
"../lib/utils.js",
|
"../lib/utils.js",
|
||||||
@@ -32,24 +11,25 @@ var FILES = exports.FILES = [
|
|||||||
"../lib/compress.js",
|
"../lib/compress.js",
|
||||||
"../lib/sourcemap.js",
|
"../lib/sourcemap.js",
|
||||||
"../lib/mozilla-ast.js",
|
"../lib/mozilla-ast.js",
|
||||||
"../lib/propmangle.js"
|
"../lib/propmangle.js",
|
||||||
|
"./exports.js",
|
||||||
].map(function(file){
|
].map(function(file){
|
||||||
return fs.realpathSync(path.join(path.dirname(__filename), file));
|
return fs.realpathSync(path.join(path.dirname(__filename), file));
|
||||||
});
|
});
|
||||||
|
|
||||||
FILES.forEach(load_global);
|
var UglifyJS = exports;
|
||||||
|
|
||||||
|
new Function("MOZ_SourceMap", "exports", FILES.map(function(file){
|
||||||
|
return fs.readFileSync(file, "utf8");
|
||||||
|
}).join("\n\n"))(
|
||||||
|
require("source-map"),
|
||||||
|
UglifyJS
|
||||||
|
);
|
||||||
|
|
||||||
UglifyJS.AST_Node.warn_function = function(txt) {
|
UglifyJS.AST_Node.warn_function = function(txt) {
|
||||||
console.error("WARN: %s", txt);
|
console.error("WARN: %s", txt);
|
||||||
};
|
};
|
||||||
|
|
||||||
// XXX: perhaps we shouldn't export everything but heck, I'm lazy.
|
|
||||||
for (var i in UglifyJS) {
|
|
||||||
if (UglifyJS.hasOwnProperty(i)) {
|
|
||||||
exports[i] = UglifyJS[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
exports.minify = function(files, options) {
|
exports.minify = function(files, options) {
|
||||||
options = UglifyJS.defaults(options, {
|
options = UglifyJS.defaults(options, {
|
||||||
spidermonkey : false,
|
spidermonkey : false,
|
||||||
@@ -73,17 +53,20 @@ exports.minify = function(files, options) {
|
|||||||
} else {
|
} else {
|
||||||
if (typeof files == "string")
|
if (typeof files == "string")
|
||||||
files = [ files ];
|
files = [ files ];
|
||||||
files.forEach(function(file){
|
files.forEach(function(file, i){
|
||||||
var code = options.fromString
|
var code = options.fromString
|
||||||
? file
|
? file
|
||||||
: fs.readFileSync(file, "utf8");
|
: fs.readFileSync(file, "utf8");
|
||||||
sourcesContent[file] = code;
|
sourcesContent[file] = code;
|
||||||
toplevel = UglifyJS.parse(code, {
|
toplevel = UglifyJS.parse(code, {
|
||||||
filename: options.fromString ? "?" : file,
|
filename: options.fromString ? i : file,
|
||||||
toplevel: toplevel
|
toplevel: toplevel
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
if (options.wrap) {
|
||||||
|
toplevel = toplevel.wrap_commonjs(options.wrap, options.exportAll);
|
||||||
|
}
|
||||||
|
|
||||||
// 2. compress
|
// 2. compress
|
||||||
if (options.compress) {
|
if (options.compress) {
|
||||||
@@ -128,7 +111,7 @@ exports.minify = function(files, options) {
|
|||||||
var stream = UglifyJS.OutputStream(output);
|
var stream = UglifyJS.OutputStream(output);
|
||||||
toplevel.print(stream);
|
toplevel.print(stream);
|
||||||
|
|
||||||
if(options.outSourceMap){
|
if (options.outSourceMap && "string" === typeof options.outSourceMap) {
|
||||||
stream += "\n//# sourceMappingURL=" + options.outSourceMap;
|
stream += "\n//# sourceMappingURL=" + options.outSourceMap;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user