Compare commits
27 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 |
@@ -1,7 +1,6 @@
|
|||||||
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.10"
|
- "0.10"
|
||||||
- "4"
|
- "4"
|
||||||
|
|||||||
@@ -134,6 +134,8 @@ The available options are:
|
|||||||
--mangle-props Mangle property names
|
--mangle-props Mangle property names
|
||||||
--mangle-regex Only mangle property names matching the regex
|
--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
|
||||||
|
|||||||
79
bin/uglifyjs
79
bin/uglifyjs
@@ -72,6 +72,8 @@ You need to pass an argument to this option to specify the name that your module
|
|||||||
.describe("mangle-props", "Mangle property names")
|
.describe("mangle-props", "Mangle property names")
|
||||||
.describe("mangle-regex", "Only mangle property names matching the regex")
|
.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")
|
||||||
@@ -104,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")
|
||||||
@@ -115,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")
|
||||||
@@ -175,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*/);
|
||||||
}
|
}
|
||||||
@@ -401,14 +409,17 @@ async.eachLimit(files, 1, function (file, cb) {
|
|||||||
writeNameCache("props", cache);
|
writeNameCache("props", cache);
|
||||||
})();
|
})();
|
||||||
|
|
||||||
|
var SCOPE_IS_NEEDED = COMPRESS || MANGLE || ARGS.lint
|
||||||
var TL_CACHE = readNameCache("vars");
|
var TL_CACHE = readNameCache("vars");
|
||||||
|
|
||||||
time_it("scope", function(){
|
if (SCOPE_IS_NEEDED) {
|
||||||
TOPLEVEL.figure_out_scope({ screw_ie8: ARGS.screw_ie8, cache: TL_CACHE });
|
time_it("scope", function(){
|
||||||
if (ARGS.lint) {
|
TOPLEVEL.figure_out_scope({ screw_ie8: ARGS.screw_ie8, cache: TL_CACHE });
|
||||||
TOPLEVEL.scope_warnings();
|
if (ARGS.lint) {
|
||||||
}
|
TOPLEVEL.scope_warnings();
|
||||||
});
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
if (COMPRESS) {
|
if (COMPRESS) {
|
||||||
time_it("squeeze", function(){
|
time_it("squeeze", function(){
|
||||||
@@ -416,12 +427,14 @@ async.eachLimit(files, 1, function (file, cb) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
time_it("scope", function(){
|
if (SCOPE_IS_NEEDED) {
|
||||||
TOPLEVEL.figure_out_scope({ screw_ie8: ARGS.screw_ie8, cache: TL_CACHE });
|
time_it("scope", function(){
|
||||||
if (MANGLE && !TL_CACHE) {
|
TOPLEVEL.figure_out_scope({ screw_ie8: ARGS.screw_ie8, cache: TL_CACHE });
|
||||||
TOPLEVEL.compute_char_frequency(MANGLE);
|
if (MANGLE && !TL_CACHE) {
|
||||||
}
|
TOPLEVEL.compute_char_frequency(MANGLE);
|
||||||
});
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
if (MANGLE) time_it("mangle", function(){
|
if (MANGLE) time_it("mangle", function(){
|
||||||
MANGLE.cache = TL_CACHE;
|
MANGLE.cache = TL_CACHE;
|
||||||
@@ -438,26 +451,30 @@ async.eachLimit(files, 1, function (file, cb) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
time_it("generate", function(){
|
if (ARGS.dump_spidermonkey_ast) {
|
||||||
TOPLEVEL.print(output);
|
print(JSON.stringify(TOPLEVEL.to_mozilla_ast(), null, 2));
|
||||||
});
|
|
||||||
|
|
||||||
output = output.get();
|
|
||||||
|
|
||||||
if (SOURCE_MAP) {
|
|
||||||
fs.writeFileSync(ARGS.source_map, SOURCE_MAP, "utf8");
|
|
||||||
var source_map_url = ARGS.source_map_url || (
|
|
||||||
P_RELATIVE
|
|
||||||
? path.relative(path.dirname(OUTPUT_FILE), ARGS.source_map)
|
|
||||||
: ARGS.source_map
|
|
||||||
);
|
|
||||||
output += "\n//# sourceMappingURL=" + source_map_url;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (OUTPUT_FILE) {
|
|
||||||
fs.writeFileSync(OUTPUT_FILE, output, "utf8");
|
|
||||||
} else {
|
} else {
|
||||||
print(output);
|
time_it("generate", function(){
|
||||||
|
TOPLEVEL.print(output);
|
||||||
|
});
|
||||||
|
|
||||||
|
output = output.get();
|
||||||
|
|
||||||
|
if (SOURCE_MAP) {
|
||||||
|
fs.writeFileSync(ARGS.source_map, SOURCE_MAP, "utf8");
|
||||||
|
var source_map_url = ARGS.source_map_url || (
|
||||||
|
P_RELATIVE
|
||||||
|
? path.relative(path.dirname(OUTPUT_FILE), ARGS.source_map)
|
||||||
|
: ARGS.source_map
|
||||||
|
);
|
||||||
|
output += "\n//# sourceMappingURL=" + source_map_url;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (OUTPUT_FILE) {
|
||||||
|
fs.writeFileSync(OUTPUT_FILE, output, "utf8");
|
||||||
|
} else {
|
||||||
|
print(output);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ARGS.stats) {
|
if (ARGS.stats) {
|
||||||
|
|||||||
30
lib/ast.js
30
lib/ast.js
@@ -85,7 +85,7 @@ function DEFNODE(type, props, methods, base) {
|
|||||||
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", {
|
||||||
@@ -927,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];
|
||||||
@@ -960,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;
|
||||||
|
|||||||
@@ -991,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;
|
||||||
@@ -2519,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,7 +422,8 @@
|
|||||||
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),
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -88,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 '"';
|
||||||
@@ -125,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;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -378,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);
|
||||||
@@ -392,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){
|
||||||
@@ -1045,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);
|
||||||
output.space();
|
if (op[0] == ">" /* ">>" ">>>" ">" ">=" */
|
||||||
output.print(self.operator);
|
&& self.left instanceof AST_UnaryPostfix
|
||||||
if (self.operator == "<"
|
&& self.left.operator == "--") {
|
||||||
|
// space is mandatory to avoid outputting -->
|
||||||
|
output.print(" ");
|
||||||
|
} else {
|
||||||
|
// the space is optional depending on "beautify"
|
||||||
|
output.space();
|
||||||
|
}
|
||||||
|
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"
|
||||||
@@ -1158,10 +1178,8 @@ 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 (self.literal !== undefined
|
if (use_asm && self.start.raw != null) {
|
||||||
&& +self.literal === self.value /* paranoid check */
|
output.print(self.start.raw);
|
||||||
&& self.scope && self.scope.has_directive('use asm')) {
|
|
||||||
output.print(self.literal);
|
|
||||||
} else {
|
} else {
|
||||||
output.print(make_num(self.getValue()));
|
output.print(make_num(self.getValue()));
|
||||||
}
|
}
|
||||||
@@ -1340,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);
|
||||||
});
|
});
|
||||||
|
|||||||
17
lib/parse.js
17
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",
|
||||||
@@ -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;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -285,6 +285,9 @@ function tokenizer($TEXT, filename, html5_comments, shebang) {
|
|||||||
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 = [];
|
||||||
@@ -335,11 +338,7 @@ function tokenizer($TEXT, filename, html5_comments, shebang) {
|
|||||||
if (prefix) num = prefix + num;
|
if (prefix) num = prefix + num;
|
||||||
var valid = parse_js_number(num);
|
var valid = parse_js_number(num);
|
||||||
if (!isNaN(valid)) {
|
if (!isNaN(valid)) {
|
||||||
var tok = token("num", valid);
|
return token("num", valid);
|
||||||
if (num.indexOf('.') >= 0) {
|
|
||||||
tok.literal = num;
|
|
||||||
}
|
|
||||||
return tok;
|
|
||||||
} else {
|
} else {
|
||||||
parse_error("Invalid syntax: " + num);
|
parse_error("Invalid syntax: " + num);
|
||||||
}
|
}
|
||||||
@@ -1152,7 +1151,7 @@ function parse($TEXT, options) {
|
|||||||
ret = _make_symbol(AST_SymbolRef);
|
ret = _make_symbol(AST_SymbolRef);
|
||||||
break;
|
break;
|
||||||
case "num":
|
case "num":
|
||||||
ret = new AST_Number({ start: tok, end: tok, value: tok.value, literal: tok.literal });
|
ret = new AST_Number({ start: tok, end: tok, value: tok.value });
|
||||||
break;
|
break;
|
||||||
case "string":
|
case "string":
|
||||||
ret = new AST_String({
|
ret = new AST_String({
|
||||||
|
|||||||
48
lib/scope.js
48
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,20 +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));
|
||||||
}
|
}
|
||||||
if (node instanceof AST_Number) {
|
labels.set(l.name, l);
|
||||||
node.scope = scope;
|
descend();
|
||||||
return true;
|
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)
|
||||||
@@ -131,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);
|
||||||
}
|
}
|
||||||
@@ -152,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);
|
||||||
|
|
||||||
@@ -166,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);
|
||||||
@@ -202,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
|
||||||
@@ -213,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;
|
||||||
@@ -240,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;
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|||||||
6
npm-shrinkwrap.json
generated
6
npm-shrinkwrap.json
generated
@@ -115,9 +115,9 @@
|
|||||||
"resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.2.tgz"
|
"resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.2.tgz"
|
||||||
},
|
},
|
||||||
"yargs": {
|
"yargs": {
|
||||||
"version": "3.5.4",
|
"version": "3.10.0",
|
||||||
"from": "yargs@>=3.5.4 <3.6.0",
|
"from": "yargs@>=3.10.0 <3.11.0",
|
||||||
"resolved": "https://registry.npmjs.org/yargs/-/yargs-3.5.4.tgz"
|
"resolved": "https://registry.npmjs.org/yargs/-/yargs-3.10.0.tgz"
|
||||||
},
|
},
|
||||||
"zeparser": {
|
"zeparser": {
|
||||||
"version": "0.0.7",
|
"version": "0.0.7",
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
"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-2-Clause",
|
"license": "BSD-2-Clause",
|
||||||
"version": "2.5.0",
|
"version": "2.6.0",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=0.8.0"
|
"node": ">=0.8.0"
|
||||||
},
|
},
|
||||||
@@ -32,7 +32,7 @@
|
|||||||
"async": "~0.2.6",
|
"async": "~0.2.6",
|
||||||
"source-map": "~0.5.1",
|
"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",
|
||||||
|
|||||||
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"}';
|
||||||
|
}
|
||||||
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({
|
||||||
@@ -84,20 +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) {
|
if (test.mangle_props) {
|
||||||
input = U.mangle_properties(input, 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,
|
||||||
@@ -141,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 })
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -188,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();
|
||||||
|
}
|
||||||
|
|
||||||
@@ -45,7 +45,6 @@ exports.minify = function(files, options) {
|
|||||||
UglifyJS.base54.reset();
|
UglifyJS.base54.reset();
|
||||||
|
|
||||||
// 1. parse
|
// 1. parse
|
||||||
var haveScope = false;
|
|
||||||
var toplevel = null,
|
var toplevel = null,
|
||||||
sourcesContent = {};
|
sourcesContent = {};
|
||||||
|
|
||||||
@@ -74,7 +73,6 @@ exports.minify = function(files, options) {
|
|||||||
var compress = { warnings: options.warnings };
|
var compress = { warnings: options.warnings };
|
||||||
UglifyJS.merge(compress, options.compress);
|
UglifyJS.merge(compress, options.compress);
|
||||||
toplevel.figure_out_scope();
|
toplevel.figure_out_scope();
|
||||||
haveScope = true;
|
|
||||||
var sq = UglifyJS.Compressor(compress);
|
var sq = UglifyJS.Compressor(compress);
|
||||||
toplevel = toplevel.transform(sq);
|
toplevel = toplevel.transform(sq);
|
||||||
}
|
}
|
||||||
@@ -82,17 +80,11 @@ exports.minify = function(files, options) {
|
|||||||
// 3. mangle
|
// 3. mangle
|
||||||
if (options.mangle) {
|
if (options.mangle) {
|
||||||
toplevel.figure_out_scope(options.mangle);
|
toplevel.figure_out_scope(options.mangle);
|
||||||
haveScope = true;
|
|
||||||
toplevel.compute_char_frequency(options.mangle);
|
toplevel.compute_char_frequency(options.mangle);
|
||||||
toplevel.mangle_names(options.mangle);
|
toplevel.mangle_names(options.mangle);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 4. scope (if needed)
|
// 4. output
|
||||||
if (!haveScope) {
|
|
||||||
toplevel.figure_out_scope();
|
|
||||||
}
|
|
||||||
|
|
||||||
// 5. output
|
|
||||||
var inMap = options.inSourceMap;
|
var inMap = options.inSourceMap;
|
||||||
var output = {};
|
var output = {};
|
||||||
if (typeof options.inSourceMap == "string") {
|
if (typeof options.inSourceMap == "string") {
|
||||||
|
|||||||
Reference in New Issue
Block a user