uglifier 1.0.0 → 1.0.1
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of uglifier might be problematic. Click here for more details.
- data/.travis.yml +0 -1
- data/VERSION +1 -1
- data/lib/uglify.js +427 -108
- data/uglifier.gemspec +7 -6
- metadata +31 -46
data/.travis.yml
CHANGED
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
1.0.
|
1
|
+
1.0.1
|
data/lib/uglify.js
CHANGED
@@ -239,7 +239,7 @@ var OPERATORS = array_to_hash([
|
|
239
239
|
"||"
|
240
240
|
]);
|
241
241
|
|
242
|
-
var WHITESPACE_CHARS = array_to_hash(characters(" \u00a0\n\r\t\f\
|
242
|
+
var WHITESPACE_CHARS = array_to_hash(characters(" \u00a0\n\r\t\f\u000b\u200b"));
|
243
243
|
|
244
244
|
var PUNC_BEFORE_EXPRESSION = array_to_hash(characters("[{}(,.;:"));
|
245
245
|
|
@@ -454,11 +454,12 @@ function tokenizer($TEXT) {
|
|
454
454
|
case "r" : return "\r";
|
455
455
|
case "t" : return "\t";
|
456
456
|
case "b" : return "\b";
|
457
|
-
case "v" : return "\
|
457
|
+
case "v" : return "\u000b";
|
458
458
|
case "f" : return "\f";
|
459
459
|
case "0" : return "\0";
|
460
460
|
case "x" : return String.fromCharCode(hex_bytes(2));
|
461
461
|
case "u" : return String.fromCharCode(hex_bytes(4));
|
462
|
+
case "\n": return "";
|
462
463
|
default : return ch;
|
463
464
|
}
|
464
465
|
};
|
@@ -479,7 +480,24 @@ function tokenizer($TEXT) {
|
|
479
480
|
var quote = next(), ret = "";
|
480
481
|
for (;;) {
|
481
482
|
var ch = next(true);
|
482
|
-
if (ch == "\\")
|
483
|
+
if (ch == "\\") {
|
484
|
+
// read OctalEscapeSequence (XXX: deprecated if "strict mode")
|
485
|
+
// https://github.com/mishoo/UglifyJS/issues/178
|
486
|
+
var octal_len = 0, first = null;
|
487
|
+
ch = read_while(function(ch){
|
488
|
+
if (ch >= "0" && ch <= "7") {
|
489
|
+
if (!first) {
|
490
|
+
first = ch;
|
491
|
+
return ++octal_len;
|
492
|
+
}
|
493
|
+
else if (first <= "3" && octal_len <= 2) return ++octal_len;
|
494
|
+
else if (first >= "4" && octal_len <= 1) return ++octal_len;
|
495
|
+
}
|
496
|
+
return false;
|
497
|
+
});
|
498
|
+
if (octal_len > 0) ch = String.fromCharCode(parseInt(ch, 8));
|
499
|
+
else ch = read_escaped_char();
|
500
|
+
}
|
483
501
|
else if (ch == quote) break;
|
484
502
|
ret += ch;
|
485
503
|
}
|
@@ -1107,11 +1125,6 @@ function parse($TEXT, exigent_mode, embed_tokens) {
|
|
1107
1125
|
next();
|
1108
1126
|
return new_();
|
1109
1127
|
}
|
1110
|
-
if (is("operator") && HOP(UNARY_PREFIX, S.token.value)) {
|
1111
|
-
return make_unary("unary-prefix",
|
1112
|
-
prog1(S.token.value, next),
|
1113
|
-
expr_atom(allow_calls));
|
1114
|
-
}
|
1115
1128
|
if (is("punc")) {
|
1116
1129
|
switch (S.token.value) {
|
1117
1130
|
case "(":
|
@@ -1212,13 +1225,23 @@ function parse($TEXT, exigent_mode, embed_tokens) {
|
|
1212
1225
|
next();
|
1213
1226
|
return subscripts(as("call", expr, expr_list(")")), true);
|
1214
1227
|
}
|
1215
|
-
if (allow_calls && is("operator") && HOP(UNARY_POSTFIX, S.token.value)) {
|
1216
|
-
return prog1(curry(make_unary, "unary-postfix", S.token.value, expr),
|
1217
|
-
next);
|
1218
|
-
}
|
1219
1228
|
return expr;
|
1220
1229
|
};
|
1221
1230
|
|
1231
|
+
function maybe_unary(allow_calls) {
|
1232
|
+
if (is("operator") && HOP(UNARY_PREFIX, S.token.value)) {
|
1233
|
+
return make_unary("unary-prefix",
|
1234
|
+
prog1(S.token.value, next),
|
1235
|
+
maybe_unary(allow_calls));
|
1236
|
+
}
|
1237
|
+
var val = expr_atom(allow_calls);
|
1238
|
+
while (is("operator") && HOP(UNARY_POSTFIX, S.token.value) && !S.token.nlb) {
|
1239
|
+
val = make_unary("unary-postfix", S.token.value, val);
|
1240
|
+
next();
|
1241
|
+
}
|
1242
|
+
return val;
|
1243
|
+
};
|
1244
|
+
|
1222
1245
|
function make_unary(tag, op, expr) {
|
1223
1246
|
if ((op == "++" || op == "--") && !is_assignable(expr))
|
1224
1247
|
croak("Invalid use of " + op + " operator");
|
@@ -1231,14 +1254,14 @@ function parse($TEXT, exigent_mode, embed_tokens) {
|
|
1231
1254
|
var prec = op != null ? PRECEDENCE[op] : null;
|
1232
1255
|
if (prec != null && prec > min_prec) {
|
1233
1256
|
next();
|
1234
|
-
var right = expr_op(
|
1257
|
+
var right = expr_op(maybe_unary(true), prec, no_in);
|
1235
1258
|
return expr_op(as("binary", op, left, right), min_prec, no_in);
|
1236
1259
|
}
|
1237
1260
|
return left;
|
1238
1261
|
};
|
1239
1262
|
|
1240
1263
|
function expr_ops(no_in) {
|
1241
|
-
return expr_op(
|
1264
|
+
return expr_op(maybe_unary(true), 0, no_in);
|
1242
1265
|
};
|
1243
1266
|
|
1244
1267
|
function maybe_conditional(no_in) {
|
@@ -1707,20 +1730,27 @@ Scope.prototype = {
|
|
1707
1730
|
return m;
|
1708
1731
|
}
|
1709
1732
|
},
|
1733
|
+
set_mangle: function(name, m) {
|
1734
|
+
this.rev_mangled[m] = name;
|
1735
|
+
return this.mangled[name] = m;
|
1736
|
+
},
|
1710
1737
|
get_mangled: function(name, newMangle) {
|
1711
1738
|
if (this.uses_eval || this.uses_with) return name; // no mangle if eval or with is in use
|
1712
1739
|
var s = this.has(name);
|
1713
1740
|
if (!s) return name; // not in visible scope, no mangle
|
1714
1741
|
if (HOP(s.mangled, name)) return s.mangled[name]; // already mangled in this scope
|
1715
1742
|
if (!newMangle) return name; // not found and no mangling requested
|
1716
|
-
|
1717
|
-
|
1718
|
-
|
1719
|
-
return
|
1743
|
+
return s.set_mangle(name, s.next_mangled());
|
1744
|
+
},
|
1745
|
+
references: function(name) {
|
1746
|
+
return name && !this.parent || this.uses_with || this.uses_eval || this.refs[name];
|
1720
1747
|
},
|
1721
|
-
define: function(name) {
|
1722
|
-
if (name != null)
|
1723
|
-
|
1748
|
+
define: function(name, type) {
|
1749
|
+
if (name != null) {
|
1750
|
+
if (type == "var" || !HOP(this.names, name))
|
1751
|
+
this.names[name] = type || "var";
|
1752
|
+
return name;
|
1753
|
+
}
|
1724
1754
|
}
|
1725
1755
|
};
|
1726
1756
|
|
@@ -1738,8 +1768,8 @@ function ast_add_scope(ast) {
|
|
1738
1768
|
return ret;
|
1739
1769
|
};
|
1740
1770
|
|
1741
|
-
function define(name) {
|
1742
|
-
return current_scope.define(name);
|
1771
|
+
function define(name, type) {
|
1772
|
+
return current_scope.define(name, type);
|
1743
1773
|
};
|
1744
1774
|
|
1745
1775
|
function reference(name) {
|
@@ -1748,33 +1778,41 @@ function ast_add_scope(ast) {
|
|
1748
1778
|
|
1749
1779
|
function _lambda(name, args, body) {
|
1750
1780
|
var is_defun = this[0] == "defun";
|
1751
|
-
return [ this[0], is_defun ? define(name) : name, args, with_new_scope(function(){
|
1752
|
-
if (!is_defun) define(name);
|
1753
|
-
MAP(args, define);
|
1781
|
+
return [ this[0], is_defun ? define(name, "defun") : name, args, with_new_scope(function(){
|
1782
|
+
if (!is_defun) define(name, "lambda");
|
1783
|
+
MAP(args, function(name){ define(name, "arg") });
|
1754
1784
|
return MAP(body, walk);
|
1755
1785
|
})];
|
1756
1786
|
};
|
1757
1787
|
|
1788
|
+
function _vardefs(type) {
|
1789
|
+
return function(defs) {
|
1790
|
+
MAP(defs, function(d){
|
1791
|
+
define(d[0], type);
|
1792
|
+
if (d[1]) reference(d[0]);
|
1793
|
+
});
|
1794
|
+
};
|
1795
|
+
};
|
1796
|
+
|
1758
1797
|
return with_new_scope(function(){
|
1759
1798
|
// process AST
|
1760
1799
|
var ret = w.with_walkers({
|
1761
1800
|
"function": _lambda,
|
1762
1801
|
"defun": _lambda,
|
1802
|
+
"label": function(name, stat) { define(name, "label") },
|
1803
|
+
"break": function(label) { if (label) reference(label) },
|
1804
|
+
"continue": function(label) { if (label) reference(label) },
|
1763
1805
|
"with": function(expr, block) {
|
1764
1806
|
for (var s = current_scope; s; s = s.parent)
|
1765
1807
|
s.uses_with = true;
|
1766
1808
|
},
|
1767
|
-
"var":
|
1768
|
-
|
1769
|
-
},
|
1770
|
-
"const": function(defs) {
|
1771
|
-
MAP(defs, function(d){ define(d[0]) });
|
1772
|
-
},
|
1809
|
+
"var": _vardefs("var"),
|
1810
|
+
"const": _vardefs("const"),
|
1773
1811
|
"try": function(t, c, f) {
|
1774
1812
|
if (c != null) return [
|
1775
1813
|
this[0],
|
1776
1814
|
MAP(t, walk),
|
1777
|
-
[ define(c[0]), MAP(c[1], walk) ],
|
1815
|
+
[ define(c[0], "catch"), MAP(c[1], walk) ],
|
1778
1816
|
f != null ? MAP(f, walk) : null
|
1779
1817
|
];
|
1780
1818
|
},
|
@@ -1849,19 +1887,30 @@ function ast_mangle(ast, options) {
|
|
1849
1887
|
};
|
1850
1888
|
|
1851
1889
|
function _lambda(name, args, body) {
|
1852
|
-
var is_defun = this[0] == "defun";
|
1853
|
-
if (
|
1890
|
+
var is_defun = this[0] == "defun", extra;
|
1891
|
+
if (name) {
|
1892
|
+
if (is_defun) name = get_mangled(name);
|
1893
|
+
else {
|
1894
|
+
extra = {};
|
1895
|
+
if (!(scope.uses_eval || scope.uses_with))
|
1896
|
+
name = extra[name] = scope.next_mangled();
|
1897
|
+
else
|
1898
|
+
extra[name] = name;
|
1899
|
+
}
|
1900
|
+
}
|
1854
1901
|
body = with_scope(body.scope, function(){
|
1855
|
-
if (!is_defun && name) name = get_mangled(name);
|
1856
1902
|
args = MAP(args, function(name){ return get_mangled(name) });
|
1857
1903
|
return MAP(body, walk);
|
1858
|
-
});
|
1904
|
+
}, extra);
|
1859
1905
|
return [ this[0], name, args, body ];
|
1860
1906
|
};
|
1861
1907
|
|
1862
|
-
function with_scope(s, cont) {
|
1908
|
+
function with_scope(s, cont, extra) {
|
1863
1909
|
var _scope = scope;
|
1864
1910
|
scope = s;
|
1911
|
+
if (extra) for (var i in extra) if (HOP(extra, i)) {
|
1912
|
+
s.set_mangle(i, extra[i]);
|
1913
|
+
}
|
1865
1914
|
for (var i in s.names) if (HOP(s.names, i)) {
|
1866
1915
|
get_mangled(i, true);
|
1867
1916
|
}
|
@@ -1891,6 +1940,9 @@ function ast_mangle(ast, options) {
|
|
1891
1940
|
}
|
1892
1941
|
return ast;
|
1893
1942
|
},
|
1943
|
+
"label": function(label, stat) { return [ this[0], get_mangled(label), walk(stat) ] },
|
1944
|
+
"break": function(label) { if (label) return [ this[0], get_mangled(label) ] },
|
1945
|
+
"continue": function(label) { if (label) return [ this[0], get_mangled(label) ] },
|
1894
1946
|
"var": _vardefs,
|
1895
1947
|
"const": _vardefs,
|
1896
1948
|
"name": function(name) {
|
@@ -1937,10 +1989,12 @@ function last_stat(b) {
|
|
1937
1989
|
}
|
1938
1990
|
|
1939
1991
|
function aborts(t) {
|
1940
|
-
if (t) {
|
1941
|
-
|
1942
|
-
|
1943
|
-
|
1992
|
+
if (t) switch (last_stat(t)[0]) {
|
1993
|
+
case "return":
|
1994
|
+
case "break":
|
1995
|
+
case "continue":
|
1996
|
+
case "throw":
|
1997
|
+
return true;
|
1944
1998
|
}
|
1945
1999
|
};
|
1946
2000
|
|
@@ -2095,6 +2149,218 @@ function warn_unreachable(ast) {
|
|
2095
2149
|
warn("Dropping unreachable code: " + gen_code(ast, true));
|
2096
2150
|
};
|
2097
2151
|
|
2152
|
+
function prepare_ifs(ast) {
|
2153
|
+
var w = ast_walker(), walk = w.walk;
|
2154
|
+
// In this first pass, we rewrite ifs which abort with no else with an
|
2155
|
+
// if-else. For example:
|
2156
|
+
//
|
2157
|
+
// if (x) {
|
2158
|
+
// blah();
|
2159
|
+
// return y;
|
2160
|
+
// }
|
2161
|
+
// foobar();
|
2162
|
+
//
|
2163
|
+
// is rewritten into:
|
2164
|
+
//
|
2165
|
+
// if (x) {
|
2166
|
+
// blah();
|
2167
|
+
// return y;
|
2168
|
+
// } else {
|
2169
|
+
// foobar();
|
2170
|
+
// }
|
2171
|
+
function redo_if(statements) {
|
2172
|
+
statements = MAP(statements, walk);
|
2173
|
+
|
2174
|
+
for (var i = 0; i < statements.length; ++i) {
|
2175
|
+
var fi = statements[i];
|
2176
|
+
if (fi[0] != "if") continue;
|
2177
|
+
|
2178
|
+
if (fi[3] && walk(fi[3])) continue;
|
2179
|
+
|
2180
|
+
var t = walk(fi[2]);
|
2181
|
+
if (!aborts(t)) continue;
|
2182
|
+
|
2183
|
+
var conditional = walk(fi[1]);
|
2184
|
+
|
2185
|
+
var e_body = statements.slice(i + 1);
|
2186
|
+
var e = e_body.length == 1 ? e_body[0] : [ "block", e_body ];
|
2187
|
+
|
2188
|
+
var ret = statements.slice(0, i).concat([ [
|
2189
|
+
fi[0], // "if"
|
2190
|
+
conditional, // conditional
|
2191
|
+
t, // then
|
2192
|
+
e // else
|
2193
|
+
] ]);
|
2194
|
+
|
2195
|
+
return redo_if(ret);
|
2196
|
+
}
|
2197
|
+
|
2198
|
+
return statements;
|
2199
|
+
};
|
2200
|
+
|
2201
|
+
function redo_if_lambda(name, args, body) {
|
2202
|
+
body = redo_if(body);
|
2203
|
+
return [ this[0], name, args, body ];
|
2204
|
+
};
|
2205
|
+
|
2206
|
+
function redo_if_block(statements) {
|
2207
|
+
return [ this[0], statements != null ? redo_if(statements) : null ];
|
2208
|
+
};
|
2209
|
+
|
2210
|
+
return w.with_walkers({
|
2211
|
+
"defun": redo_if_lambda,
|
2212
|
+
"function": redo_if_lambda,
|
2213
|
+
"block": redo_if_block,
|
2214
|
+
"splice": redo_if_block,
|
2215
|
+
"toplevel": function(statements) {
|
2216
|
+
return [ this[0], redo_if(statements) ];
|
2217
|
+
},
|
2218
|
+
"try": function(t, c, f) {
|
2219
|
+
return [
|
2220
|
+
this[0],
|
2221
|
+
redo_if(t),
|
2222
|
+
c != null ? [ c[0], redo_if(c[1]) ] : null,
|
2223
|
+
f != null ? redo_if(f) : null
|
2224
|
+
];
|
2225
|
+
}
|
2226
|
+
}, function() {
|
2227
|
+
return walk(ast);
|
2228
|
+
});
|
2229
|
+
};
|
2230
|
+
|
2231
|
+
function for_side_effects(ast, handler) {
|
2232
|
+
var w = ast_walker(), walk = w.walk;
|
2233
|
+
var $stop = {}, $restart = {};
|
2234
|
+
function stop() { throw $stop };
|
2235
|
+
function restart() { throw $restart };
|
2236
|
+
function found(){ return handler.call(this, this, w, stop, restart) };
|
2237
|
+
function unary(op) {
|
2238
|
+
if (op == "++" || op == "--")
|
2239
|
+
return found.apply(this, arguments);
|
2240
|
+
};
|
2241
|
+
return w.with_walkers({
|
2242
|
+
"try": found,
|
2243
|
+
"throw": found,
|
2244
|
+
"return": found,
|
2245
|
+
"new": found,
|
2246
|
+
"switch": found,
|
2247
|
+
"break": found,
|
2248
|
+
"continue": found,
|
2249
|
+
"assign": found,
|
2250
|
+
"call": found,
|
2251
|
+
"if": found,
|
2252
|
+
"for": found,
|
2253
|
+
"for-in": found,
|
2254
|
+
"while": found,
|
2255
|
+
"do": found,
|
2256
|
+
"return": found,
|
2257
|
+
"unary-prefix": unary,
|
2258
|
+
"unary-postfix": unary,
|
2259
|
+
"defun": found
|
2260
|
+
}, function(){
|
2261
|
+
while (true) try {
|
2262
|
+
walk(ast);
|
2263
|
+
break;
|
2264
|
+
} catch(ex) {
|
2265
|
+
if (ex === $stop) break;
|
2266
|
+
if (ex === $restart) continue;
|
2267
|
+
throw ex;
|
2268
|
+
}
|
2269
|
+
});
|
2270
|
+
};
|
2271
|
+
|
2272
|
+
function ast_lift_variables(ast) {
|
2273
|
+
var w = ast_walker(), walk = w.walk, scope;
|
2274
|
+
function do_body(body, env) {
|
2275
|
+
var _scope = scope;
|
2276
|
+
scope = env;
|
2277
|
+
body = MAP(body, walk);
|
2278
|
+
var hash = {}, names = MAP(env.names, function(type, name){
|
2279
|
+
if (type != "var") return MAP.skip;
|
2280
|
+
if (!env.references(name)) return MAP.skip;
|
2281
|
+
hash[name] = true;
|
2282
|
+
return [ name ];
|
2283
|
+
});
|
2284
|
+
if (names.length > 0) {
|
2285
|
+
// looking for assignments to any of these variables.
|
2286
|
+
// we can save considerable space by moving the definitions
|
2287
|
+
// in the var declaration.
|
2288
|
+
for_side_effects([ "block", body ], function(ast, walker, stop, restart) {
|
2289
|
+
if (ast[0] == "assign"
|
2290
|
+
&& ast[1] === true
|
2291
|
+
&& ast[2][0] == "name"
|
2292
|
+
&& HOP(hash, ast[2][1])) {
|
2293
|
+
// insert the definition into the var declaration
|
2294
|
+
for (var i = names.length; --i >= 0;) {
|
2295
|
+
if (names[i][0] == ast[2][1]) {
|
2296
|
+
if (names[i][1]) // this name already defined, we must stop
|
2297
|
+
stop();
|
2298
|
+
names[i][1] = ast[3]; // definition
|
2299
|
+
names.push(names.splice(i, 1)[0]);
|
2300
|
+
break;
|
2301
|
+
}
|
2302
|
+
}
|
2303
|
+
// remove this assignment from the AST.
|
2304
|
+
var p = walker.parent();
|
2305
|
+
if (p[0] == "seq") {
|
2306
|
+
var a = p[2];
|
2307
|
+
a.unshift(0, p.length);
|
2308
|
+
p.splice.apply(p, a);
|
2309
|
+
}
|
2310
|
+
else if (p[0] == "stat") {
|
2311
|
+
p.splice(0, p.length, "block"); // empty statement
|
2312
|
+
}
|
2313
|
+
else {
|
2314
|
+
stop();
|
2315
|
+
}
|
2316
|
+
restart();
|
2317
|
+
}
|
2318
|
+
stop();
|
2319
|
+
});
|
2320
|
+
body.unshift([ "var", names ]);
|
2321
|
+
}
|
2322
|
+
scope = _scope;
|
2323
|
+
return body;
|
2324
|
+
};
|
2325
|
+
function _vardefs(defs) {
|
2326
|
+
var ret = null;
|
2327
|
+
for (var i = defs.length; --i >= 0;) {
|
2328
|
+
var d = defs[i];
|
2329
|
+
if (!d[1]) continue;
|
2330
|
+
d = [ "assign", true, [ "name", d[0] ], d[1] ];
|
2331
|
+
if (ret == null) ret = d;
|
2332
|
+
else ret = [ "seq", d, ret ];
|
2333
|
+
}
|
2334
|
+
if (ret == null) {
|
2335
|
+
if (w.parent()[0] == "for-in")
|
2336
|
+
return [ "name", defs[0][0] ];
|
2337
|
+
return MAP.skip;
|
2338
|
+
}
|
2339
|
+
return [ "stat", ret ];
|
2340
|
+
};
|
2341
|
+
function _toplevel(body) {
|
2342
|
+
return [ this[0], do_body(body, this.scope) ];
|
2343
|
+
};
|
2344
|
+
return w.with_walkers({
|
2345
|
+
"function": function(name, args, body){
|
2346
|
+
for (var i = args.length; --i >= 0 && !body.scope.references(args[i]);)
|
2347
|
+
args.pop();
|
2348
|
+
if (!body.scope.references(name)) name = null;
|
2349
|
+
return [ this[0], name, args, do_body(body, body.scope) ];
|
2350
|
+
},
|
2351
|
+
"defun": function(name, args, body){
|
2352
|
+
if (!scope.references(name)) return MAP.skip;
|
2353
|
+
for (var i = args.length; --i >= 0 && !body.scope.references(args[i]);)
|
2354
|
+
args.pop();
|
2355
|
+
return [ this[0], name, args, do_body(body, body.scope) ];
|
2356
|
+
},
|
2357
|
+
"var": _vardefs,
|
2358
|
+
"toplevel": _toplevel
|
2359
|
+
}, function(){
|
2360
|
+
return walk(ast_add_scope(ast));
|
2361
|
+
});
|
2362
|
+
};
|
2363
|
+
|
2098
2364
|
function ast_squeeze(ast, options) {
|
2099
2365
|
options = defaults(options, {
|
2100
2366
|
make_seqs : true,
|
@@ -2159,15 +2425,14 @@ function ast_squeeze(ast, options) {
|
|
2159
2425
|
function _lambda(name, args, body) {
|
2160
2426
|
var is_defun = this[0] == "defun";
|
2161
2427
|
body = with_scope(body.scope, function(){
|
2162
|
-
var ret = tighten(
|
2163
|
-
if (!is_defun && name && !
|
2428
|
+
var ret = tighten(body, "lambda");
|
2429
|
+
if (!is_defun && name && !scope.references(name))
|
2164
2430
|
name = null;
|
2165
2431
|
return ret;
|
2166
2432
|
});
|
2167
2433
|
return [ this[0], name, args, body ];
|
2168
2434
|
};
|
2169
2435
|
|
2170
|
-
// we get here for blocks that have been already transformed.
|
2171
2436
|
// this function does a few things:
|
2172
2437
|
// 1. discard useless blocks
|
2173
2438
|
// 2. join consecutive var declarations
|
@@ -2175,6 +2440,8 @@ function ast_squeeze(ast, options) {
|
|
2175
2440
|
// 4. transform consecutive statements using the comma operator
|
2176
2441
|
// 5. if block_type == "lambda" and it detects constructs like if(foo) return ... - rewrite like if (!foo) { ... }
|
2177
2442
|
function tighten(statements, block_type) {
|
2443
|
+
statements = MAP(statements, walk);
|
2444
|
+
|
2178
2445
|
statements = statements.reduce(function(a, stat){
|
2179
2446
|
if (stat[0] == "block") {
|
2180
2447
|
if (stat[1]) {
|
@@ -2202,7 +2469,17 @@ function ast_squeeze(ast, options) {
|
|
2202
2469
|
if (options.dead_code) statements = (function(a, has_quit){
|
2203
2470
|
statements.forEach(function(st){
|
2204
2471
|
if (has_quit) {
|
2205
|
-
if (
|
2472
|
+
if (st[0] == "function" || st[0] == "defun") {
|
2473
|
+
a.push(st);
|
2474
|
+
}
|
2475
|
+
else if (st[0] == "var" || st[0] == "const") {
|
2476
|
+
if (!options.no_warnings)
|
2477
|
+
warn("Variables declared in unreachable code");
|
2478
|
+
st[1] = MAP(st[1], function(def){
|
2479
|
+
if (def[1] && !options.no_warnings)
|
2480
|
+
warn_unreachable([ "assign", true, [ "name", def[0] ], def[1] ]);
|
2481
|
+
return [ def[0] ];
|
2482
|
+
});
|
2206
2483
|
a.push(st);
|
2207
2484
|
}
|
2208
2485
|
else if (!options.no_warnings)
|
@@ -2226,27 +2503,38 @@ function ast_squeeze(ast, options) {
|
|
2226
2503
|
prev = cur;
|
2227
2504
|
}
|
2228
2505
|
});
|
2506
|
+
if (a.length >= 2
|
2507
|
+
&& a[a.length-2][0] == "stat"
|
2508
|
+
&& (a[a.length-1][0] == "return" || a[a.length-1][0] == "throw")
|
2509
|
+
&& a[a.length-1][1])
|
2510
|
+
{
|
2511
|
+
a.splice(a.length - 2, 2,
|
2512
|
+
[ a[a.length-1][0],
|
2513
|
+
[ "seq", a[a.length-2][1], a[a.length-1][1] ]]);
|
2514
|
+
}
|
2229
2515
|
return a;
|
2230
2516
|
})([]);
|
2231
2517
|
|
2232
|
-
|
2233
|
-
|
2234
|
-
|
2235
|
-
|
2236
|
-
|
2237
|
-
|
2238
|
-
|
2239
|
-
|
2240
|
-
|
2241
|
-
|
2242
|
-
|
2243
|
-
|
2244
|
-
|
2245
|
-
|
2246
|
-
|
2247
|
-
|
2248
|
-
|
2249
|
-
}
|
2518
|
+
// this increases jQuery by 1K. Probably not such a good idea after all..
|
2519
|
+
// part of this is done in prepare_ifs anyway.
|
2520
|
+
// if (block_type == "lambda") statements = (function(i, a, stat){
|
2521
|
+
// while (i < statements.length) {
|
2522
|
+
// stat = statements[i++];
|
2523
|
+
// if (stat[0] == "if" && !stat[3]) {
|
2524
|
+
// if (stat[2][0] == "return" && stat[2][1] == null) {
|
2525
|
+
// a.push(make_if(negate(stat[1]), [ "block", statements.slice(i) ]));
|
2526
|
+
// break;
|
2527
|
+
// }
|
2528
|
+
// var last = last_stat(stat[2]);
|
2529
|
+
// if (last[0] == "return" && last[1] == null) {
|
2530
|
+
// a.push(make_if(stat[1], [ "block", stat[2][1].slice(0, -1) ], [ "block", statements.slice(i) ]));
|
2531
|
+
// break;
|
2532
|
+
// }
|
2533
|
+
// }
|
2534
|
+
// a.push(stat);
|
2535
|
+
// }
|
2536
|
+
// return a;
|
2537
|
+
// })(0, []);
|
2250
2538
|
|
2251
2539
|
return statements;
|
2252
2540
|
};
|
@@ -2355,13 +2643,13 @@ function ast_squeeze(ast, options) {
|
|
2355
2643
|
"if": make_if,
|
2356
2644
|
"toplevel": function(body) {
|
2357
2645
|
return [ "toplevel", with_scope(this.scope, function(){
|
2358
|
-
return tighten(
|
2646
|
+
return tighten(body);
|
2359
2647
|
}) ];
|
2360
2648
|
},
|
2361
2649
|
"switch": function(expr, body) {
|
2362
2650
|
var last = body.length - 1;
|
2363
2651
|
return [ "switch", walk(expr), MAP(body, function(branch, i){
|
2364
|
-
var block = tighten(
|
2652
|
+
var block = tighten(branch[1]);
|
2365
2653
|
if (i == last && block.length > 0) {
|
2366
2654
|
var node = block[block.length - 1];
|
2367
2655
|
if (node[0] == "break" && !node[1])
|
@@ -2373,7 +2661,7 @@ function ast_squeeze(ast, options) {
|
|
2373
2661
|
"function": _lambda,
|
2374
2662
|
"defun": _lambda,
|
2375
2663
|
"block": function(body) {
|
2376
|
-
if (body) return rmblock([ "block", tighten(
|
2664
|
+
if (body) return rmblock([ "block", tighten(body) ]);
|
2377
2665
|
},
|
2378
2666
|
"binary": function(op, left, right) {
|
2379
2667
|
return when_constant([ "binary", op, walk(left), walk(right) ], function yes(c){
|
@@ -2388,9 +2676,9 @@ function ast_squeeze(ast, options) {
|
|
2388
2676
|
"try": function(t, c, f) {
|
2389
2677
|
return [
|
2390
2678
|
"try",
|
2391
|
-
tighten(
|
2392
|
-
c != null ? [ c[0], tighten(
|
2393
|
-
f != null ? tighten(
|
2679
|
+
tighten(t),
|
2680
|
+
c != null ? [ c[0], tighten(c[1]) ] : null,
|
2681
|
+
f != null ? tighten(f) : null
|
2394
2682
|
];
|
2395
2683
|
},
|
2396
2684
|
"unary-prefix": function(op, expr) {
|
@@ -2424,7 +2712,12 @@ function ast_squeeze(ast, options) {
|
|
2424
2712
|
},
|
2425
2713
|
"while": _do_while
|
2426
2714
|
}, function() {
|
2427
|
-
|
2715
|
+
for (var i = 0; i < 2; ++i) {
|
2716
|
+
ast = prepare_ifs(ast);
|
2717
|
+
ast = ast_add_scope(ast);
|
2718
|
+
ast = walk(ast);
|
2719
|
+
}
|
2720
|
+
return ast;
|
2428
2721
|
});
|
2429
2722
|
};
|
2430
2723
|
|
@@ -2481,7 +2774,8 @@ function gen_code(ast, options) {
|
|
2481
2774
|
quote_keys : false,
|
2482
2775
|
space_colon : false,
|
2483
2776
|
beautify : false,
|
2484
|
-
ascii_only : false
|
2777
|
+
ascii_only : false,
|
2778
|
+
inline_script: false
|
2485
2779
|
});
|
2486
2780
|
var beautify = !!options.beautify;
|
2487
2781
|
var indentation = 0,
|
@@ -2489,7 +2783,10 @@ function gen_code(ast, options) {
|
|
2489
2783
|
space = beautify ? " " : "";
|
2490
2784
|
|
2491
2785
|
function encode_string(str) {
|
2492
|
-
|
2786
|
+
var ret = make_string(str, options.ascii_only);
|
2787
|
+
if (options.inline_script)
|
2788
|
+
ret = ret.replace(/<\x2fscript([>/\t\n\f\r ])/gi, "<\\/script$1");
|
2789
|
+
return ret;
|
2493
2790
|
};
|
2494
2791
|
|
2495
2792
|
function make_name(name) {
|
@@ -2566,7 +2863,7 @@ function gen_code(ast, options) {
|
|
2566
2863
|
// we're the first in this "seq" and the
|
2567
2864
|
// parent is "stat", and so on. Messy stuff,
|
2568
2865
|
// but it worths the trouble.
|
2569
|
-
var a = slice(
|
2866
|
+
var a = slice(w.stack()), self = a.pop(), p = a.pop();
|
2570
2867
|
while (p) {
|
2571
2868
|
if (p[0] == "stat") return true;
|
2572
2869
|
if (((p[0] == "seq" || p[0] == "call" || p[0] == "dot" || p[0] == "sub" || p[0] == "conditional") && p[1] === self) ||
|
@@ -2596,7 +2893,9 @@ function gen_code(ast, options) {
|
|
2596
2893
|
return best_of(a);
|
2597
2894
|
};
|
2598
2895
|
|
2599
|
-
var
|
2896
|
+
var w = ast_walker();
|
2897
|
+
var make = w.walk;
|
2898
|
+
return w.with_walkers({
|
2600
2899
|
"string": encode_string,
|
2601
2900
|
"num": make_num,
|
2602
2901
|
"name": make_name,
|
@@ -2605,7 +2904,7 @@ function gen_code(ast, options) {
|
|
2605
2904
|
.join(newline + newline);
|
2606
2905
|
},
|
2607
2906
|
"splice": function(statements) {
|
2608
|
-
var parent =
|
2907
|
+
var parent = w.parent();
|
2609
2908
|
if (HOP(SPLICE_NEEDS_BRACKETS, parent)) {
|
2610
2909
|
// we need block brackets in this case
|
2611
2910
|
return make_block.apply(this, arguments);
|
@@ -2745,6 +3044,10 @@ function gen_code(ast, options) {
|
|
2745
3044
|
!(rvalue[1] == operator && member(operator, [ "&&", "||", "*" ]))) {
|
2746
3045
|
right = "(" + right + ")";
|
2747
3046
|
}
|
3047
|
+
else if (!beautify && options.inline_script && (operator == "<" || operator == "<<")
|
3048
|
+
&& rvalue[0] == "regexp" && /^script/i.test(rvalue[1])) {
|
3049
|
+
right = " " + right;
|
3050
|
+
}
|
2748
3051
|
return add_spaces([ left, operator, right ]);
|
2749
3052
|
},
|
2750
3053
|
"unary-prefix": function(operator, expr) {
|
@@ -2775,7 +3078,7 @@ function gen_code(ast, options) {
|
|
2775
3078
|
// body in p[1][3] and type ("get" / "set") in p[2].
|
2776
3079
|
return indent(make_function(p[0], p[1][2], p[1][3], p[2]));
|
2777
3080
|
}
|
2778
|
-
var key = p[0], val =
|
3081
|
+
var key = p[0], val = parenthesize(p[1], "seq");
|
2779
3082
|
if (options.quote_keys) {
|
2780
3083
|
key = encode_string(key);
|
2781
3084
|
} else if ((typeof key == "number" || !beautify && +key + "" == key)
|
@@ -2815,7 +3118,7 @@ function gen_code(ast, options) {
|
|
2815
3118
|
"atom": function(name) {
|
2816
3119
|
return make_name(name);
|
2817
3120
|
}
|
2818
|
-
};
|
3121
|
+
}, function(){ return make(ast) });
|
2819
3122
|
|
2820
3123
|
// The squeezer replaces "block"-s that contain only a single
|
2821
3124
|
// statement with the statement itself; technically, the AST
|
@@ -2830,7 +3133,7 @@ function gen_code(ast, options) {
|
|
2830
3133
|
// IE croaks with "syntax error" on code like this:
|
2831
3134
|
// if (foo) do ... while(cond); else ...
|
2832
3135
|
// we need block brackets around do/while
|
2833
|
-
return
|
3136
|
+
return make_block([ th ]);
|
2834
3137
|
}
|
2835
3138
|
var b = th;
|
2836
3139
|
while (true) {
|
@@ -2857,20 +3160,31 @@ function gen_code(ast, options) {
|
|
2857
3160
|
return add_spaces([ out, make_block(body) ]);
|
2858
3161
|
};
|
2859
3162
|
|
3163
|
+
function must_has_semicolon(node) {
|
3164
|
+
switch (node[0]) {
|
3165
|
+
case "with":
|
3166
|
+
case "while":
|
3167
|
+
return empty(node[2]); // `with' or `while' with empty body?
|
3168
|
+
case "for":
|
3169
|
+
case "for-in":
|
3170
|
+
return empty(node[4]); // `for' with empty body?
|
3171
|
+
case "if":
|
3172
|
+
if (empty(node[2]) && !node[3]) return true; // `if' with empty `then' and no `else'
|
3173
|
+
if (node[3]) {
|
3174
|
+
if (empty(node[3])) return true; // `else' present but empty
|
3175
|
+
return must_has_semicolon(node[3]); // dive into the `else' branch
|
3176
|
+
}
|
3177
|
+
return must_has_semicolon(node[2]); // dive into the `then' branch
|
3178
|
+
}
|
3179
|
+
};
|
3180
|
+
|
2860
3181
|
function make_block_statements(statements, noindent) {
|
2861
3182
|
for (var a = [], last = statements.length - 1, i = 0; i <= last; ++i) {
|
2862
3183
|
var stat = statements[i];
|
2863
3184
|
var code = make(stat);
|
2864
3185
|
if (code != ";") {
|
2865
|
-
if (!beautify && i == last) {
|
2866
|
-
|
2867
|
-
(member(stat[0], [ "for", "for-in"] ) && empty(stat[4])) ||
|
2868
|
-
(stat[0] == "if" && empty(stat[2]) && !stat[3]) ||
|
2869
|
-
(stat[0] == "if" && stat[3] && empty(stat[3]))) {
|
2870
|
-
code = code.replace(/;*\s*$/, ";");
|
2871
|
-
} else {
|
2872
|
-
code = code.replace(/;+\s*$/, "");
|
2873
|
-
}
|
3186
|
+
if (!beautify && i == last && !must_has_semicolon(stat)) {
|
3187
|
+
code = code.replace(/;+\s*$/, "");
|
2874
3188
|
}
|
2875
3189
|
a.push(code);
|
2876
3190
|
}
|
@@ -2910,20 +3224,6 @@ function gen_code(ast, options) {
|
|
2910
3224
|
return name;
|
2911
3225
|
};
|
2912
3226
|
|
2913
|
-
var $stack = [];
|
2914
|
-
|
2915
|
-
function make(node) {
|
2916
|
-
var type = node[0];
|
2917
|
-
var gen = generators[type];
|
2918
|
-
if (!gen)
|
2919
|
-
throw new Error("Can't find generator for \"" + type + "\"");
|
2920
|
-
$stack.push(node);
|
2921
|
-
var ret = gen.apply(type, node.slice(1));
|
2922
|
-
$stack.pop();
|
2923
|
-
return ret;
|
2924
|
-
};
|
2925
|
-
|
2926
|
-
return make(ast);
|
2927
3227
|
};
|
2928
3228
|
|
2929
3229
|
function split_lines(code, max_line_length) {
|
@@ -3008,16 +3308,34 @@ var MAP;
|
|
3008
3308
|
|
3009
3309
|
(function(){
|
3010
3310
|
MAP = function(a, f, o) {
|
3011
|
-
var ret = [];
|
3012
|
-
|
3311
|
+
var ret = [], top = [], i;
|
3312
|
+
function doit() {
|
3013
3313
|
var val = f.call(o, a[i], i);
|
3014
|
-
if (val instanceof AtTop)
|
3015
|
-
|
3016
|
-
|
3017
|
-
|
3314
|
+
if (val instanceof AtTop) {
|
3315
|
+
val = val.v;
|
3316
|
+
if (val instanceof Splice) {
|
3317
|
+
top.push.apply(top, val.v);
|
3318
|
+
} else {
|
3319
|
+
top.push(val);
|
3320
|
+
}
|
3321
|
+
}
|
3322
|
+
else if (val != skip) {
|
3323
|
+
if (val instanceof Splice) {
|
3324
|
+
ret.push.apply(ret, val.v);
|
3325
|
+
} else {
|
3326
|
+
ret.push(val);
|
3327
|
+
}
|
3328
|
+
}
|
3329
|
+
};
|
3330
|
+
if (a instanceof Array) for (i = 0; i < a.length; ++i) doit();
|
3331
|
+
else for (i in a) if (HOP(a, i)) doit();
|
3332
|
+
return top.concat(ret);
|
3018
3333
|
};
|
3019
3334
|
MAP.at_top = function(val) { return new AtTop(val) };
|
3335
|
+
MAP.splice = function(val) { return new Splice(val) };
|
3336
|
+
var skip = MAP.skip = {};
|
3020
3337
|
function AtTop(val) { this.v = val };
|
3338
|
+
function Splice(val) { this.v = val };
|
3021
3339
|
})();
|
3022
3340
|
|
3023
3341
|
/* -----[ Exports ]----- */
|
@@ -3025,6 +3343,7 @@ var MAP;
|
|
3025
3343
|
exports.ast_walker = ast_walker;
|
3026
3344
|
exports.ast_mangle = ast_mangle;
|
3027
3345
|
exports.ast_squeeze = ast_squeeze;
|
3346
|
+
exports.ast_lift_variables = ast_lift_variables;
|
3028
3347
|
exports.gen_code = gen_code;
|
3029
3348
|
exports.ast_add_scope = ast_add_scope;
|
3030
3349
|
exports.set_logger = function(logger) { warn = logger };
|
data/uglifier.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{uglifier}
|
8
|
-
s.version = "1.0.
|
8
|
+
s.version = "1.0.1"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
|
-
s.authors = [
|
12
|
-
s.date = %q{2011-
|
11
|
+
s.authors = ["Ville Lautanala"]
|
12
|
+
s.date = %q{2011-08-15}
|
13
13
|
s.email = %q{lautis@gmail.com}
|
14
14
|
s.extra_rdoc_files = [
|
15
15
|
"LICENSE.txt",
|
@@ -34,14 +34,15 @@ Gem::Specification.new do |s|
|
|
34
34
|
"uglifier.gemspec"
|
35
35
|
]
|
36
36
|
s.homepage = %q{http://github.com/lautis/uglifier}
|
37
|
-
s.require_paths = [
|
38
|
-
s.rubygems_version = %q{1.
|
37
|
+
s.require_paths = ["lib"]
|
38
|
+
s.rubygems_version = %q{1.3.6}
|
39
39
|
s.summary = %q{Ruby wrapper for UglifyJS JavaScript compressor}
|
40
40
|
|
41
41
|
if s.respond_to? :specification_version then
|
42
|
+
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
42
43
|
s.specification_version = 3
|
43
44
|
|
44
|
-
if Gem::Version.new(Gem::
|
45
|
+
if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
|
45
46
|
s.add_runtime_dependency(%q<execjs>, [">= 0.3.0"])
|
46
47
|
s.add_runtime_dependency(%q<multi_json>, [">= 1.0.2"])
|
47
48
|
s.add_development_dependency(%q<rspec>, ["~> 2.6.0"])
|
metadata
CHANGED
@@ -1,13 +1,12 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: uglifier
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
|
5
|
-
prerelease:
|
4
|
+
prerelease: false
|
6
5
|
segments:
|
7
6
|
- 1
|
8
7
|
- 0
|
9
|
-
-
|
10
|
-
version: 1.0.
|
8
|
+
- 1
|
9
|
+
version: 1.0.1
|
11
10
|
platform: ruby
|
12
11
|
authors:
|
13
12
|
- Ville Lautanala
|
@@ -15,102 +14,91 @@ autorequire:
|
|
15
14
|
bindir: bin
|
16
15
|
cert_chain: []
|
17
16
|
|
18
|
-
date: 2011-
|
17
|
+
date: 2011-08-15 00:00:00 +03:00
|
18
|
+
default_executable:
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|
21
|
-
|
22
|
-
requirement: &id001 !ruby/object:Gem::Requirement
|
23
|
-
none: false
|
21
|
+
version_requirements: &id001 !ruby/object:Gem::Requirement
|
24
22
|
requirements:
|
25
23
|
- - ">="
|
26
24
|
- !ruby/object:Gem::Version
|
27
|
-
hash: 19
|
28
25
|
segments:
|
29
26
|
- 0
|
30
27
|
- 3
|
31
28
|
- 0
|
32
29
|
version: 0.3.0
|
33
|
-
|
34
|
-
version_requirements: *id001
|
30
|
+
requirement: *id001
|
35
31
|
name: execjs
|
36
|
-
|
32
|
+
prerelease: false
|
37
33
|
type: :runtime
|
38
|
-
|
39
|
-
|
34
|
+
- !ruby/object:Gem::Dependency
|
35
|
+
version_requirements: &id002 !ruby/object:Gem::Requirement
|
40
36
|
requirements:
|
41
37
|
- - ">="
|
42
38
|
- !ruby/object:Gem::Version
|
43
|
-
hash: 19
|
44
39
|
segments:
|
45
40
|
- 1
|
46
41
|
- 0
|
47
42
|
- 2
|
48
43
|
version: 1.0.2
|
49
|
-
|
50
|
-
version_requirements: *id002
|
44
|
+
requirement: *id002
|
51
45
|
name: multi_json
|
46
|
+
prerelease: false
|
47
|
+
type: :runtime
|
52
48
|
- !ruby/object:Gem::Dependency
|
53
|
-
|
54
|
-
requirement: &id003 !ruby/object:Gem::Requirement
|
55
|
-
none: false
|
49
|
+
version_requirements: &id003 !ruby/object:Gem::Requirement
|
56
50
|
requirements:
|
57
51
|
- - ~>
|
58
52
|
- !ruby/object:Gem::Version
|
59
|
-
hash: 23
|
60
53
|
segments:
|
61
54
|
- 2
|
62
55
|
- 6
|
63
56
|
- 0
|
64
57
|
version: 2.6.0
|
65
|
-
|
66
|
-
version_requirements: *id003
|
58
|
+
requirement: *id003
|
67
59
|
name: rspec
|
68
|
-
|
60
|
+
prerelease: false
|
69
61
|
type: :development
|
70
|
-
|
71
|
-
|
62
|
+
- !ruby/object:Gem::Dependency
|
63
|
+
version_requirements: &id004 !ruby/object:Gem::Requirement
|
72
64
|
requirements:
|
73
65
|
- - ~>
|
74
66
|
- !ruby/object:Gem::Version
|
75
|
-
hash: 23
|
76
67
|
segments:
|
77
68
|
- 1
|
78
69
|
- 0
|
79
70
|
- 0
|
80
71
|
version: 1.0.0
|
81
|
-
|
82
|
-
version_requirements: *id004
|
72
|
+
requirement: *id004
|
83
73
|
name: bundler
|
84
|
-
|
74
|
+
prerelease: false
|
85
75
|
type: :development
|
86
|
-
|
87
|
-
|
76
|
+
- !ruby/object:Gem::Dependency
|
77
|
+
version_requirements: &id005 !ruby/object:Gem::Requirement
|
88
78
|
requirements:
|
89
79
|
- - ~>
|
90
80
|
- !ruby/object:Gem::Version
|
91
|
-
hash: 15
|
92
81
|
segments:
|
93
82
|
- 1
|
94
83
|
- 6
|
95
84
|
- 0
|
96
85
|
version: 1.6.0
|
97
|
-
|
98
|
-
version_requirements: *id005
|
86
|
+
requirement: *id005
|
99
87
|
name: jeweler
|
100
|
-
|
88
|
+
prerelease: false
|
101
89
|
type: :development
|
102
|
-
|
103
|
-
|
90
|
+
- !ruby/object:Gem::Dependency
|
91
|
+
version_requirements: &id006 !ruby/object:Gem::Requirement
|
104
92
|
requirements:
|
105
93
|
- - ">="
|
106
94
|
- !ruby/object:Gem::Version
|
107
|
-
hash: 3
|
108
95
|
segments:
|
109
96
|
- 0
|
110
97
|
version: "0"
|
111
|
-
|
112
|
-
version_requirements: *id006
|
98
|
+
requirement: *id006
|
113
99
|
name: rcov
|
100
|
+
prerelease: false
|
101
|
+
type: :development
|
114
102
|
description:
|
115
103
|
email: lautis@gmail.com
|
116
104
|
executables: []
|
@@ -137,6 +125,7 @@ files:
|
|
137
125
|
- spec/spec_helper.rb
|
138
126
|
- spec/uglifier_spec.rb
|
139
127
|
- uglifier.gemspec
|
128
|
+
has_rdoc: true
|
140
129
|
homepage: http://github.com/lautis/uglifier
|
141
130
|
licenses: []
|
142
131
|
|
@@ -146,27 +135,23 @@ rdoc_options: []
|
|
146
135
|
require_paths:
|
147
136
|
- lib
|
148
137
|
required_ruby_version: !ruby/object:Gem::Requirement
|
149
|
-
none: false
|
150
138
|
requirements:
|
151
139
|
- - ">="
|
152
140
|
- !ruby/object:Gem::Version
|
153
|
-
hash: 3
|
154
141
|
segments:
|
155
142
|
- 0
|
156
143
|
version: "0"
|
157
144
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
158
|
-
none: false
|
159
145
|
requirements:
|
160
146
|
- - ">="
|
161
147
|
- !ruby/object:Gem::Version
|
162
|
-
hash: 3
|
163
148
|
segments:
|
164
149
|
- 0
|
165
150
|
version: "0"
|
166
151
|
requirements: []
|
167
152
|
|
168
153
|
rubyforge_project:
|
169
|
-
rubygems_version: 1.
|
154
|
+
rubygems_version: 1.3.6
|
170
155
|
signing_key:
|
171
156
|
specification_version: 3
|
172
157
|
summary: Ruby wrapper for UglifyJS JavaScript compressor
|