Merge remote-tracking branch 'upstream/master' into ternary-improvements
This commit is contained in:
commit
d522107537
|
|
@ -1,6 +1,6 @@
|
|||
UglifyJS 2
|
||||
==========
|
||||
[](https://travis-ci.org/mishoo/UglifyJS2)
|
||||
[](https://travis-ci.org/mishoo/UglifyJS2)
|
||||
|
||||
UglifyJS is a JavaScript parser, minifier, compressor or beautifier toolkit.
|
||||
|
||||
|
|
@ -44,6 +44,11 @@ variable/function declared in another file will be matched properly.
|
|||
If you want to read from STDIN instead, pass a single dash instead of input
|
||||
files.
|
||||
|
||||
If you wish to pass your options before the input files, separate the two with
|
||||
a double dash to prevent input files being used as option arguments:
|
||||
|
||||
uglifyjs --compress --mangle -- input.js
|
||||
|
||||
The available options are:
|
||||
|
||||
```
|
||||
|
|
@ -612,7 +617,7 @@ or, for a shortcut you can do:
|
|||
var code = compressed_ast.print_to_string(options);
|
||||
```
|
||||
|
||||
As usual, `options` is optional. The output stream accepts a lot of otions,
|
||||
As usual, `options` is optional. The output stream accepts a lot of options,
|
||||
most of them documented above in section “Beautifier options”. The two
|
||||
which we care about here are `source_map` and `comments`.
|
||||
|
||||
|
|
|
|||
18
bin/uglifyjs
18
bin/uglifyjs
|
|
@ -5,12 +5,12 @@
|
|||
|
||||
var UglifyJS = require("../tools/node");
|
||||
var sys = require("util");
|
||||
var optimist = require("optimist");
|
||||
var yargs = require("yargs");
|
||||
var fs = require("fs");
|
||||
var path = require("path");
|
||||
var async = require("async");
|
||||
var acorn;
|
||||
var ARGS = optimist
|
||||
var ARGS = yargs
|
||||
.usage("$0 input1.js [input2.js ...] [options]\n\
|
||||
Use a single dash to read input from the standard input.\
|
||||
\n\n\
|
||||
|
|
@ -64,6 +64,8 @@ You need to pass an argument to this option to specify the name that your module
|
|||
.describe("v", "Verbose")
|
||||
.describe("V", "Print version number and exit.")
|
||||
.describe("noerr", "Don't throw an error for unknown options in -c, -b or -m.")
|
||||
.describe("bare-returns", "Allow return outside of functions. Useful when minifying CommonJS modules.")
|
||||
.describe("keep-fnames", "Do not mangle/drop function names. Useful for code relying on Function.prototype.name.")
|
||||
|
||||
.alias("p", "prefix")
|
||||
.alias("o", "output")
|
||||
|
|
@ -100,6 +102,8 @@ You need to pass an argument to this option to specify the name that your module
|
|||
.boolean("lint")
|
||||
.boolean("V")
|
||||
.boolean("noerr")
|
||||
.boolean("bare-returns")
|
||||
.boolean("keep-fnames")
|
||||
|
||||
.wrap(80)
|
||||
|
||||
|
|
@ -127,7 +131,7 @@ if (ARGS.ast_help) {
|
|||
}
|
||||
|
||||
if (ARGS.h || ARGS.help) {
|
||||
sys.puts(optimist.help());
|
||||
sys.puts(yargs.help());
|
||||
process.exit(0);
|
||||
}
|
||||
|
||||
|
|
@ -158,6 +162,11 @@ if (ARGS.screw_ie8) {
|
|||
OUTPUT_OPTIONS.screw_ie8 = true;
|
||||
}
|
||||
|
||||
if (ARGS.keep_fnames) {
|
||||
if (COMPRESS) COMPRESS.keep_fnames = true;
|
||||
if (MANGLE) MANGLE.keep_fnames = true;
|
||||
}
|
||||
|
||||
if (BEAUTIFY)
|
||||
UglifyJS.merge(OUTPUT_OPTIONS, BEAUTIFY);
|
||||
|
||||
|
|
@ -250,7 +259,7 @@ async.eachLimit(files, 1, function (file, cb) {
|
|||
}
|
||||
if (ARGS.p != null) {
|
||||
if (P_RELATIVE) {
|
||||
file = path.relative(path.dirname(ARGS.source_map), file);
|
||||
file = path.relative(path.dirname(ARGS.source_map), file).replace(/\\/g, '/');
|
||||
} else {
|
||||
var p = parseInt(ARGS.p, 10);
|
||||
if (!isNaN(p)) {
|
||||
|
|
@ -278,6 +287,7 @@ async.eachLimit(files, 1, function (file, cb) {
|
|||
filename : file,
|
||||
toplevel : TOPLEVEL,
|
||||
expression : ARGS.expr,
|
||||
bare_returns : ARGS.bare_returns,
|
||||
});
|
||||
} catch(ex) {
|
||||
if (ex instanceof UglifyJS.JS_Parse_Error) {
|
||||
|
|
|
|||
26
lib/ast.js
26
lib/ast.js
|
|
@ -84,7 +84,7 @@ function DEFNODE(type, props, methods, base) {
|
|||
return ctor;
|
||||
};
|
||||
|
||||
var AST_Token = DEFNODE("Token", "type value line col pos endpos nlb comments_before file", {
|
||||
var AST_Token = DEFNODE("Token", "type value line col pos endline endcol endpos nlb comments_before file", {
|
||||
}, null);
|
||||
|
||||
var AST_Node = DEFNODE("Node", "start end", {
|
||||
|
|
@ -205,21 +205,27 @@ var AST_DWLoop = DEFNODE("DWLoop", "condition", {
|
|||
$documentation: "Base class for do/while statements",
|
||||
$propdoc: {
|
||||
condition: "[AST_Node] the loop condition. Should not be instanceof AST_Statement"
|
||||
},
|
||||
}
|
||||
}, AST_IterationStatement);
|
||||
|
||||
var AST_Do = DEFNODE("Do", null, {
|
||||
$documentation: "A `do` statement",
|
||||
_walk: function(visitor) {
|
||||
return visitor._visit(this, function(){
|
||||
this.body._walk(visitor);
|
||||
this.condition._walk(visitor);
|
||||
});
|
||||
}
|
||||
}, AST_DWLoop);
|
||||
|
||||
var AST_While = DEFNODE("While", null, {
|
||||
$documentation: "A `while` statement",
|
||||
_walk: function(visitor) {
|
||||
return visitor._visit(this, function(){
|
||||
this.condition._walk(visitor);
|
||||
this.body._walk(visitor);
|
||||
});
|
||||
}
|
||||
}, AST_IterationStatement);
|
||||
|
||||
var AST_Do = DEFNODE("Do", null, {
|
||||
$documentation: "A `do` statement",
|
||||
}, AST_DWLoop);
|
||||
|
||||
var AST_While = DEFNODE("While", null, {
|
||||
$documentation: "A `while` statement",
|
||||
}, AST_DWLoop);
|
||||
|
||||
var AST_For = DEFNODE("For", "init condition step", {
|
||||
|
|
|
|||
|
|
@ -62,6 +62,7 @@ function Compressor(options, false_by_default) {
|
|||
unused : !false_by_default,
|
||||
hoist_funs : !false_by_default,
|
||||
keep_fargs : false,
|
||||
keep_fnames : false,
|
||||
hoist_vars : false,
|
||||
if_return : !false_by_default,
|
||||
join_vars : !false_by_default,
|
||||
|
|
@ -162,10 +163,10 @@ merge(Compressor.prototype, {
|
|||
return make_node(AST_Undefined, orig).optimize(compressor);
|
||||
default:
|
||||
if (val === null) {
|
||||
return make_node(AST_Null, orig).optimize(compressor);
|
||||
return make_node(AST_Null, orig, { value: null }).optimize(compressor);
|
||||
}
|
||||
if (val instanceof RegExp) {
|
||||
return make_node(AST_RegExp, orig).optimize(compressor);
|
||||
return make_node(AST_RegExp, orig, { value: val }).optimize(compressor);
|
||||
}
|
||||
throw new Error(string_template("Can't handle constant of type: {type}", {
|
||||
type: typeof val
|
||||
|
|
@ -225,6 +226,17 @@ merge(Compressor.prototype, {
|
|||
return statements;
|
||||
|
||||
function process_for_angular(statements) {
|
||||
function has_inject(comment) {
|
||||
return /@ngInject/.test(comment.value);
|
||||
}
|
||||
function make_arguments_names_list(func) {
|
||||
return func.argnames.map(function(sym){
|
||||
return make_node(AST_String, sym, { value: sym.name });
|
||||
});
|
||||
}
|
||||
function make_array(orig, elements) {
|
||||
return make_node(AST_Array, orig, { elements: elements });
|
||||
}
|
||||
function make_injector(func, name) {
|
||||
return make_node(AST_SimpleStatement, func, {
|
||||
body: make_node(AST_Assign, func, {
|
||||
|
|
@ -233,27 +245,44 @@ merge(Compressor.prototype, {
|
|||
expression: make_node(AST_SymbolRef, name, name),
|
||||
property: "$inject"
|
||||
}),
|
||||
right: make_node(AST_Array, func, {
|
||||
elements: func.argnames.map(function(sym){
|
||||
return make_node(AST_String, sym, { value: sym.name });
|
||||
})
|
||||
})
|
||||
right: make_array(func, make_arguments_names_list(func))
|
||||
})
|
||||
});
|
||||
}
|
||||
function check_expression(body) {
|
||||
if (body && body.args) {
|
||||
// if this is a function call check all of arguments passed
|
||||
body.args.forEach(function(argument, index, array) {
|
||||
var comments = argument.start.comments_before;
|
||||
// if the argument is function preceded by @ngInject
|
||||
if (argument instanceof AST_Lambda && comments.length && has_inject(comments[0])) {
|
||||
// replace the function with an array of names of its parameters and function at the end
|
||||
array[index] = make_array(argument, make_arguments_names_list(argument).concat(argument));
|
||||
}
|
||||
});
|
||||
// if this is chained call check previous one recursively
|
||||
if (body.expression && body.expression.expression) {
|
||||
check_expression(body.expression.expression);
|
||||
}
|
||||
}
|
||||
}
|
||||
return statements.reduce(function(a, stat){
|
||||
a.push(stat);
|
||||
|
||||
if (stat.body && stat.body.args) {
|
||||
check_expression(stat.body);
|
||||
} else {
|
||||
var token = stat.start;
|
||||
var comments = token.comments_before;
|
||||
if (comments && comments.length > 0) {
|
||||
var last = comments.pop();
|
||||
if (/@ngInject/.test(last.value)) {
|
||||
if (has_inject(last)) {
|
||||
// case 1: defun
|
||||
if (stat instanceof AST_Defun) {
|
||||
a.push(make_injector(stat, stat.name));
|
||||
}
|
||||
else if (stat instanceof AST_Definitions) {
|
||||
stat.definitions.forEach(function(def){
|
||||
stat.definitions.forEach(function(def) {
|
||||
if (def.value && def.value instanceof AST_Lambda) {
|
||||
a.push(make_injector(def.value, def.name));
|
||||
}
|
||||
|
|
@ -264,6 +293,8 @@ merge(Compressor.prototype, {
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return a;
|
||||
}, []);
|
||||
}
|
||||
|
|
@ -949,7 +980,7 @@ merge(Compressor.prototype, {
|
|||
def(AST_BlockStatement, block_aborts);
|
||||
def(AST_SwitchBranch, block_aborts);
|
||||
def(AST_If, function(){
|
||||
return this.alternative && aborts(this.body) && aborts(this.alternative);
|
||||
return this.alternative && aborts(this.body) && aborts(this.alternative) && this;
|
||||
});
|
||||
})(function(node, func){
|
||||
node.DEFMETHOD("aborts", func);
|
||||
|
|
@ -1666,7 +1697,7 @@ merge(Compressor.prototype, {
|
|||
|
||||
OPT(AST_Function, function(self, compressor){
|
||||
self = AST_Lambda.prototype.optimize.call(self, compressor);
|
||||
if (compressor.option("unused")) {
|
||||
if (compressor.option("unused") && !compressor.option("keep_fnames")) {
|
||||
if (self.name && self.name.unreferenced()) {
|
||||
self.name = null;
|
||||
}
|
||||
|
|
@ -1722,6 +1753,11 @@ merge(Compressor.prototype, {
|
|||
}).transform(compressor);
|
||||
break;
|
||||
case "Function":
|
||||
// new Function() => function(){}
|
||||
if (self.args.length == 0) return make_node(AST_Function, self, {
|
||||
argnames: [],
|
||||
body: []
|
||||
});
|
||||
if (all(self.args, function(x){ return x instanceof AST_String })) {
|
||||
// quite a corner-case, but we can handle it:
|
||||
// https://github.com/mishoo/UglifyJS2/issues/203
|
||||
|
|
@ -1901,7 +1937,7 @@ merge(Compressor.prototype, {
|
|||
if (self.cdr instanceof AST_UnaryPrefix
|
||||
&& self.cdr.operator == "void"
|
||||
&& !self.cdr.expression.has_side_effects(compressor)) {
|
||||
self.cdr.operator = self.car;
|
||||
self.cdr.expression = self.car;
|
||||
return self.cdr;
|
||||
}
|
||||
if (self.cdr instanceof AST_Undefined) {
|
||||
|
|
@ -2203,14 +2239,30 @@ merge(Compressor.prototype, {
|
|||
case "undefined":
|
||||
return make_node(AST_Undefined, self);
|
||||
case "NaN":
|
||||
return make_node(AST_NaN, self);
|
||||
return make_node(AST_NaN, self).transform(compressor);
|
||||
case "Infinity":
|
||||
return make_node(AST_Infinity, self);
|
||||
return make_node(AST_Infinity, self).transform(compressor);
|
||||
}
|
||||
}
|
||||
return self;
|
||||
});
|
||||
|
||||
OPT(AST_Infinity, function (self, compressor) {
|
||||
return make_node(AST_Binary, self, {
|
||||
operator : '/',
|
||||
left : make_node(AST_Number, null, {value: 1}),
|
||||
right : make_node(AST_Number, null, {value: 0})
|
||||
});
|
||||
});
|
||||
|
||||
OPT(AST_NaN, function (self, compressor) {
|
||||
return make_node(AST_Binary, self, {
|
||||
operator : '/',
|
||||
left : make_node(AST_Number, null, {value: 0}),
|
||||
right : make_node(AST_Number, null, {value: 0})
|
||||
});
|
||||
});
|
||||
|
||||
OPT(AST_Undefined, function(self, compressor){
|
||||
if (compressor.option("unsafe")) {
|
||||
var scope = compressor.find_parent(AST_Scope);
|
||||
|
|
|
|||
|
|
@ -370,25 +370,29 @@
|
|||
/* -----[ tools ]----- */
|
||||
|
||||
function my_start_token(moznode) {
|
||||
var loc = moznode.loc;
|
||||
var loc = moznode.loc, start = loc && loc.start;
|
||||
var range = moznode.range;
|
||||
return new AST_Token({
|
||||
file : loc && loc.source,
|
||||
line : loc && loc.start.line,
|
||||
col : loc && loc.start.column,
|
||||
line : start && start.line,
|
||||
col : start && start.column,
|
||||
pos : range ? range[0] : moznode.start,
|
||||
endline : start && start.line,
|
||||
endcol : start && start.column,
|
||||
endpos : range ? range[0] : moznode.start
|
||||
});
|
||||
};
|
||||
|
||||
function my_end_token(moznode) {
|
||||
var loc = moznode.loc;
|
||||
var loc = moznode.loc, end = loc && loc.end;
|
||||
var range = moznode.range;
|
||||
return new AST_Token({
|
||||
file : loc && loc.source,
|
||||
line : loc && loc.end.line,
|
||||
col : loc && loc.end.column,
|
||||
line : end && end.line,
|
||||
col : end && end.column,
|
||||
pos : range ? range[1] : moznode.end,
|
||||
endline : end && end.line,
|
||||
endcol : end && end.column,
|
||||
endpos : range ? range[1] : moznode.end
|
||||
});
|
||||
};
|
||||
|
|
@ -465,23 +469,16 @@
|
|||
return ast;
|
||||
};
|
||||
|
||||
function moz_sub_loc(token) {
|
||||
return token.line ? {
|
||||
line: token.line,
|
||||
column: token.col
|
||||
} : null;
|
||||
};
|
||||
|
||||
function set_moz_loc(mynode, moznode) {
|
||||
function set_moz_loc(mynode, moznode, myparent) {
|
||||
var start = mynode.start;
|
||||
var end = mynode.end;
|
||||
if (start.pos != null && end.pos != null) {
|
||||
moznode.range = [start.pos, end.pos];
|
||||
if (start.pos != null && end.endpos != null) {
|
||||
moznode.range = [start.pos, end.endpos];
|
||||
}
|
||||
if (start.line) {
|
||||
moznode.loc = {
|
||||
start: moz_sub_loc(start),
|
||||
end: moz_sub_loc(end)
|
||||
start: {line: start.line, column: start.col},
|
||||
end: end.endline ? {line: end.endline, column: end.endcol} : null
|
||||
};
|
||||
if (start.file) {
|
||||
moznode.loc.source = start.file;
|
||||
|
|
|
|||
|
|
@ -86,7 +86,7 @@ function OutputStream(options) {
|
|||
|
||||
function make_string(str) {
|
||||
var dq = 0, sq = 0;
|
||||
str = str.replace(/[\\\b\f\n\r\t\x22\x27\u2028\u2029\0]/g, function(s){
|
||||
str = str.replace(/[\\\b\f\n\r\t\x22\x27\u2028\u2029\0\ufeff]/g, function(s){
|
||||
switch (s) {
|
||||
case "\\": return "\\\\";
|
||||
case "\b": return "\\b";
|
||||
|
|
@ -98,6 +98,7 @@ function OutputStream(options) {
|
|||
case '"': ++dq; return '"';
|
||||
case "'": ++sq; return "'";
|
||||
case "\0": return "\\x00";
|
||||
case "\ufeff": return "\\ufeff";
|
||||
}
|
||||
return s;
|
||||
});
|
||||
|
|
@ -221,7 +222,7 @@ function OutputStream(options) {
|
|||
|
||||
var newline = options.beautify ? function() {
|
||||
print("\n");
|
||||
} : noop;
|
||||
} : maybe_newline;
|
||||
|
||||
var semicolon = options.beautify ? function() {
|
||||
print(";");
|
||||
|
|
@ -549,12 +550,6 @@ function OutputStream(options) {
|
|||
return true;
|
||||
});
|
||||
|
||||
PARENS(AST_NaN, function(output){
|
||||
var p = output.parent();
|
||||
if (p instanceof AST_PropAccess && p.expression === this)
|
||||
return true;
|
||||
});
|
||||
|
||||
PARENS([ AST_Assign, AST_Conditional ], function (output){
|
||||
var p = output.parent();
|
||||
// !(a = false) → true
|
||||
|
|
@ -1109,10 +1104,10 @@ function OutputStream(options) {
|
|||
});
|
||||
DEFPRINT(AST_Hole, noop);
|
||||
DEFPRINT(AST_Infinity, function(self, output){
|
||||
output.print("1/0");
|
||||
output.print("Infinity");
|
||||
});
|
||||
DEFPRINT(AST_NaN, function(self, output){
|
||||
output.print("0/0");
|
||||
output.print("NaN");
|
||||
});
|
||||
DEFPRINT(AST_This, function(self, output){
|
||||
output.print("this");
|
||||
|
|
|
|||
15
lib/parse.js
15
lib/parse.js
|
|
@ -206,7 +206,7 @@ var EX_EOF = {};
|
|||
function tokenizer($TEXT, filename, html5_comments) {
|
||||
|
||||
var S = {
|
||||
text : $TEXT.replace(/\r\n?|[\n\u2028\u2029]/g, "\n").replace(/\uFEFF/g, ''),
|
||||
text : $TEXT.replace(/\uFEFF/g, ''),
|
||||
filename : filename,
|
||||
pos : 0,
|
||||
tokpos : 0,
|
||||
|
|
@ -225,10 +225,15 @@ function tokenizer($TEXT, filename, html5_comments) {
|
|||
var ch = S.text.charAt(S.pos++);
|
||||
if (signal_eof && !ch)
|
||||
throw EX_EOF;
|
||||
if (ch == "\n") {
|
||||
if ("\r\n\u2028\u2029".indexOf(ch) >= 0) {
|
||||
S.newline_before = S.newline_before || !in_string;
|
||||
++S.line;
|
||||
S.col = 0;
|
||||
if (!in_string && ch == "\r" && peek() == "\n") {
|
||||
// treat a \r\n sequence as a single \n
|
||||
++S.pos;
|
||||
ch = "\n";
|
||||
}
|
||||
} else {
|
||||
++S.col;
|
||||
}
|
||||
|
|
@ -267,6 +272,8 @@ function tokenizer($TEXT, filename, html5_comments) {
|
|||
line : S.tokline,
|
||||
col : S.tokcol,
|
||||
pos : S.tokpos,
|
||||
endline : S.line,
|
||||
endcol : S.col,
|
||||
endpos : S.pos,
|
||||
nlb : S.newline_before,
|
||||
file : filename
|
||||
|
|
@ -392,6 +399,7 @@ function tokenizer($TEXT, filename, html5_comments) {
|
|||
ret = S.text.substring(S.pos, i);
|
||||
S.pos = i;
|
||||
}
|
||||
S.col = S.tokcol + (S.pos - S.tokpos);
|
||||
S.comments_before.push(token(type, ret, true));
|
||||
S.regex_allowed = regex_allowed;
|
||||
return next_token();
|
||||
|
|
@ -609,6 +617,7 @@ function parse($TEXT, options) {
|
|||
toplevel : null,
|
||||
expression : false,
|
||||
html5_comments : true,
|
||||
bare_returns : false,
|
||||
});
|
||||
|
||||
var S = {
|
||||
|
|
@ -788,7 +797,7 @@ function parse($TEXT, options) {
|
|||
return if_();
|
||||
|
||||
case "return":
|
||||
if (S.in_function == 0)
|
||||
if (S.in_function == 0 && !options.bare_returns)
|
||||
croak("'return' outside of function");
|
||||
return new AST_Return({
|
||||
value: ( is("punc", ";")
|
||||
|
|
|
|||
14
lib/scope.js
14
lib/scope.js
|
|
@ -57,9 +57,14 @@ function SymbolDef(scope, index, orig) {
|
|||
|
||||
SymbolDef.prototype = {
|
||||
unmangleable: function(options) {
|
||||
return (this.global && !(options && options.toplevel))
|
||||
if (!options) options = {};
|
||||
|
||||
return (this.global && !options.toplevel)
|
||||
|| this.undeclared
|
||||
|| (!(options && options.eval) && (this.scope.uses_eval || this.scope.uses_with));
|
||||
|| (!options.eval && (this.scope.uses_eval || this.scope.uses_with))
|
||||
|| (options.keep_fnames
|
||||
&& (this.orig[0] instanceof AST_SymbolLambda
|
||||
|| this.orig[0] instanceof AST_SymbolDefun));
|
||||
},
|
||||
mangle: function(options) {
|
||||
if (!this.mangled_name && !this.unmangleable(options)) {
|
||||
|
|
@ -326,7 +331,8 @@ AST_Toplevel.DEFMETHOD("_default_mangler_options", function(options){
|
|||
eval : false,
|
||||
sort : false,
|
||||
toplevel : false,
|
||||
screw_ie8 : false
|
||||
screw_ie8 : false,
|
||||
keep_fnames : false
|
||||
});
|
||||
});
|
||||
|
||||
|
|
@ -471,7 +477,9 @@ var base54 = (function() {
|
|||
base54.freq = function(){ return frequency };
|
||||
function base54(num) {
|
||||
var ret = "", base = 54;
|
||||
num++;
|
||||
do {
|
||||
num--;
|
||||
ret += String.fromCharCode(chars[num % base]);
|
||||
num = Math.floor(num / base);
|
||||
base = 64;
|
||||
|
|
|
|||
|
|
@ -53,11 +53,16 @@ function SourceMap(options) {
|
|||
orig_line_diff : 0,
|
||||
dest_line_diff : 0,
|
||||
});
|
||||
var generator = new MOZ_SourceMap.SourceMapGenerator({
|
||||
var orig_map = options.orig && new MOZ_SourceMap.SourceMapConsumer(options.orig);
|
||||
var generator;
|
||||
if (orig_map) {
|
||||
generator = MOZ_SourceMap.SourceMapGenerator.fromSourceMap(orig_map);
|
||||
} else {
|
||||
generator = new MOZ_SourceMap.SourceMapGenerator({
|
||||
file : options.file,
|
||||
sourceRoot : options.root
|
||||
});
|
||||
var orig_map = options.orig && new MOZ_SourceMap.SourceMapConsumer(options.orig);
|
||||
}
|
||||
function add(source, gen_line, gen_col, orig_line, orig_col, name) {
|
||||
if (orig_map) {
|
||||
var info = orig_map.originalPositionFor({
|
||||
|
|
@ -70,7 +75,7 @@ function SourceMap(options) {
|
|||
source = info.source;
|
||||
orig_line = info.line;
|
||||
orig_col = info.column;
|
||||
name = info.name;
|
||||
name = info.name || name;
|
||||
}
|
||||
generator.addMapping({
|
||||
generated : { line: gen_line + options.dest_line_diff, column: gen_col },
|
||||
|
|
@ -78,7 +83,7 @@ function SourceMap(options) {
|
|||
source : source,
|
||||
name : name
|
||||
});
|
||||
};
|
||||
}
|
||||
return {
|
||||
add : add,
|
||||
get : function() { return generator },
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
"description": "JavaScript parser, mangler/compressor and beautifier toolkit",
|
||||
"homepage": "http://lisperator.net/uglifyjs",
|
||||
"main": "tools/node.js",
|
||||
"version": "2.4.15",
|
||||
"version": "2.4.16",
|
||||
"engines": { "node" : ">=0.4.0" },
|
||||
"maintainers": [{
|
||||
"name": "Mihai Bazon",
|
||||
|
|
@ -17,7 +17,7 @@
|
|||
"dependencies": {
|
||||
"async" : "~0.2.6",
|
||||
"source-map" : "0.1.34",
|
||||
"optimist": "~0.3.5",
|
||||
"yargs": "~1.3.3",
|
||||
"uglify-to-browserify": "~1.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
|
|
|||
67
test/compress/angular-inject.js
vendored
Normal file
67
test/compress/angular-inject.js
vendored
Normal file
|
|
@ -0,0 +1,67 @@
|
|||
ng_inject_defun: {
|
||||
options = {
|
||||
angular: true
|
||||
};
|
||||
input: {
|
||||
/*@ngInject*/
|
||||
function Controller(dependency) {
|
||||
return dependency;
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
function Controller(dependency) {
|
||||
return dependency;
|
||||
}
|
||||
Controller.$inject=['dependency']
|
||||
}
|
||||
}
|
||||
|
||||
ng_inject_assignment: {
|
||||
options = {
|
||||
angular: true
|
||||
};
|
||||
input: {
|
||||
/*@ngInject*/
|
||||
var Controller = function(dependency) {
|
||||
return dependency;
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
var Controller = function(dependency) {
|
||||
return dependency;
|
||||
}
|
||||
Controller.$inject=['dependency']
|
||||
}
|
||||
}
|
||||
|
||||
ng_inject_inline: {
|
||||
options = {
|
||||
angular: true
|
||||
};
|
||||
input: {
|
||||
angular.module('a').
|
||||
factory('b',
|
||||
/*@ngInject*/
|
||||
function(dependency) {
|
||||
return dependency;
|
||||
}).
|
||||
directive('c',
|
||||
/*@ngInject*/
|
||||
function(anotherDependency) {
|
||||
return anotherDependency;
|
||||
})
|
||||
}
|
||||
expect: {
|
||||
angular.module('a').
|
||||
factory('b',[
|
||||
'dependency',
|
||||
function(dependency) {
|
||||
return dependency;
|
||||
}]).
|
||||
directive('c',[
|
||||
'anotherDependency',
|
||||
function(anotherDependency) {
|
||||
return anotherDependency;
|
||||
}])
|
||||
}
|
||||
}
|
||||
|
|
@ -163,3 +163,17 @@ used_var_in_catch: {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
keep_fnames: {
|
||||
options = { unused: true, keep_fnames: true };
|
||||
input: {
|
||||
function foo() {
|
||||
return function bar(baz) {};
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
function foo() {
|
||||
return function bar() {};
|
||||
}
|
||||
}
|
||||
}
|
||||
25
test/compress/issue-597.js
Normal file
25
test/compress/issue-597.js
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
NaN_and_Infinity_must_have_parens: {
|
||||
options = {};
|
||||
input: {
|
||||
Infinity.toString();
|
||||
NaN.toString();
|
||||
}
|
||||
expect: {
|
||||
(1/0).toString();
|
||||
(0/0).toString();
|
||||
}
|
||||
}
|
||||
|
||||
NaN_and_Infinity_should_not_be_replaced_when_they_are_redefined: {
|
||||
options = {};
|
||||
input: {
|
||||
var Infinity, NaN;
|
||||
Infinity.toString();
|
||||
NaN.toString();
|
||||
}
|
||||
expect: {
|
||||
var Infinity, NaN;
|
||||
Infinity.toString();
|
||||
NaN.toString();
|
||||
}
|
||||
}
|
||||
21
test/compress/issue-611.js
Normal file
21
test/compress/issue-611.js
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
issue_611: {
|
||||
options = {
|
||||
sequences: true,
|
||||
side_effects: true
|
||||
};
|
||||
input: {
|
||||
define(function() {
|
||||
function fn() {}
|
||||
if (fn()) {
|
||||
fn();
|
||||
return void 0;
|
||||
}
|
||||
});
|
||||
}
|
||||
expect: {
|
||||
define(function() {
|
||||
function fn(){}
|
||||
if (fn()) return void fn();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -6,6 +6,8 @@ var sys = require("util");
|
|||
var UglifyJS = vm.createContext({
|
||||
sys : sys,
|
||||
console : console,
|
||||
process : process,
|
||||
Buffer : Buffer,
|
||||
MOZ_SourceMap : require("source-map")
|
||||
});
|
||||
|
||||
|
|
@ -33,7 +35,7 @@ var FILES = exports.FILES = [
|
|||
"../lib/sourcemap.js",
|
||||
"../lib/mozilla-ast.js"
|
||||
].map(function(file){
|
||||
return path.join(path.dirname(fs.realpathSync(__filename)), file);
|
||||
return fs.realpathSync(path.join(path.dirname(__filename), file));
|
||||
});
|
||||
|
||||
FILES.forEach(load_global);
|
||||
|
|
@ -95,8 +97,8 @@ exports.minify = function(files, options) {
|
|||
|
||||
// 3. mangle
|
||||
if (options.mangle) {
|
||||
toplevel.figure_out_scope();
|
||||
toplevel.compute_char_frequency();
|
||||
toplevel.figure_out_scope(options.mangle);
|
||||
toplevel.compute_char_frequency(options.mangle);
|
||||
toplevel.mangle_names(options.mangle);
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user