Merge branch 'master' into harmony-v3.0.16
This commit is contained in:
102
lib/compress.js
102
lib/compress.js
@@ -64,6 +64,7 @@ function Compressor(options, false_by_default) {
|
||||
hoist_vars : false,
|
||||
ie8 : false,
|
||||
if_return : !false_by_default,
|
||||
inline : !false_by_default,
|
||||
join_vars : !false_by_default,
|
||||
keep_fargs : true,
|
||||
keep_fnames : false,
|
||||
@@ -1459,7 +1460,7 @@ merge(Compressor.prototype, {
|
||||
});
|
||||
if (value && typeof value == "object") {
|
||||
var props = [];
|
||||
for (var key in value) {
|
||||
for (var key in value) if (HOP(value, key)) {
|
||||
props.push(make_node(AST_ObjectKeyVal, orig, {
|
||||
key: key,
|
||||
value: to_node(value[key], orig)
|
||||
@@ -3112,24 +3113,9 @@ merge(Compressor.prototype, {
|
||||
|
||||
OPT(AST_Call, function(self, compressor){
|
||||
var exp = self.expression;
|
||||
if (compressor.option("reduce_vars")
|
||||
&& exp instanceof AST_SymbolRef) {
|
||||
var def = exp.definition();
|
||||
if (compressor.option("reduce_vars") && exp instanceof AST_SymbolRef) {
|
||||
var fixed = exp.fixed_value();
|
||||
if (fixed instanceof AST_Defun) {
|
||||
def.fixed = fixed = make_node(AST_Function, fixed, fixed).clone(true);
|
||||
}
|
||||
if (fixed instanceof AST_Function) {
|
||||
exp = fixed;
|
||||
if (compressor.option("unused")
|
||||
&& def.references.length == 1
|
||||
&& !(def.scope.uses_arguments
|
||||
&& def.orig[0] instanceof AST_SymbolFunarg)
|
||||
&& !def.scope.uses_eval
|
||||
&& compressor.find_parent(AST_Scope) === def.scope) {
|
||||
self.expression = exp;
|
||||
}
|
||||
}
|
||||
if (fixed instanceof AST_Function) exp = fixed;
|
||||
}
|
||||
if (compressor.option("unused")
|
||||
&& exp instanceof AST_Function
|
||||
@@ -3344,13 +3330,70 @@ merge(Compressor.prototype, {
|
||||
}
|
||||
}
|
||||
if (exp instanceof AST_Function && !self.expression.is_generator) {
|
||||
if (exp.body[0] instanceof AST_Return) {
|
||||
var value = exp.body[0].value;
|
||||
var stat = exp.body[0];
|
||||
if (compressor.option("inline") && stat instanceof AST_Return) {
|
||||
var value = stat && stat.value;
|
||||
if (!value || value.is_constant_expression()) {
|
||||
var args = self.args.concat(value || make_node(AST_Undefined, self));
|
||||
return make_sequence(self, args).transform(compressor);
|
||||
}
|
||||
}
|
||||
if (compressor.option("inline")
|
||||
&& !exp.name
|
||||
&& exp.body.length == 1
|
||||
&& !exp.uses_arguments
|
||||
&& !exp.uses_eval
|
||||
&& !self.has_pure_annotation(compressor)) {
|
||||
var value;
|
||||
if (stat instanceof AST_Return) {
|
||||
value = stat.value.clone(true);
|
||||
} else if (stat instanceof AST_SimpleStatement) {
|
||||
value = make_node(AST_UnaryPrefix, stat, {
|
||||
operator: "void",
|
||||
expression: stat.body.clone(true)
|
||||
});
|
||||
}
|
||||
if (value) {
|
||||
var fn = exp.clone();
|
||||
fn.argnames = [];
|
||||
fn.body = [];
|
||||
if (exp.argnames.length > 0) {
|
||||
fn.body.push(make_node(AST_Var, self, {
|
||||
definitions: exp.argnames.map(function(sym, i) {
|
||||
return make_node(AST_VarDef, sym, {
|
||||
name: sym,
|
||||
value: self.args[i] || make_node(AST_Undefined, self)
|
||||
});
|
||||
})
|
||||
}));
|
||||
}
|
||||
if (self.args.length > exp.argnames.length) {
|
||||
fn.body.push(make_node(AST_SimpleStatement, self, {
|
||||
body: make_sequence(self, self.args.slice(exp.argnames.length))
|
||||
}));
|
||||
}
|
||||
fn.body.push(make_node(AST_Return, self, {
|
||||
value: value
|
||||
}));
|
||||
var body = fn.transform(compressor).body;
|
||||
if (body.length == 0) return make_node(AST_Undefined, self);
|
||||
if (body.length == 1 && body[0] instanceof AST_Return) {
|
||||
value = body[0].value;
|
||||
if (!value) return make_node(AST_Undefined, self);
|
||||
value.walk(new TreeWalker(function(node) {
|
||||
if (value === self) return true;
|
||||
if (node instanceof AST_SymbolRef && exp.variables.has(node.name)) {
|
||||
value = self;
|
||||
return true;
|
||||
}
|
||||
}));
|
||||
if (value !== self) value = best_of(compressor, value, self);
|
||||
} else {
|
||||
value = self;
|
||||
}
|
||||
if (value !== self) return value;
|
||||
}
|
||||
}
|
||||
if (compressor.option("side_effects") && all(exp.body, is_empty)) {
|
||||
var args = self.args.concat(make_node(AST_Undefined, self));
|
||||
return make_sequence(self, args).transform(compressor);
|
||||
@@ -3453,6 +3496,7 @@ merge(Compressor.prototype, {
|
||||
continue;
|
||||
}
|
||||
var parent = null, field;
|
||||
expressions[j] = cdr = cdr.clone();
|
||||
while (true) {
|
||||
if (cdr.equivalent_to(left)) {
|
||||
var car = expressions[i];
|
||||
@@ -3489,7 +3533,7 @@ merge(Compressor.prototype, {
|
||||
break;
|
||||
}
|
||||
parent = cdr;
|
||||
cdr = cdr[field];
|
||||
cdr = cdr[field] = cdr[field].clone();
|
||||
}
|
||||
}
|
||||
end = i;
|
||||
@@ -4009,12 +4053,22 @@ merge(Compressor.prototype, {
|
||||
return make_node(AST_Infinity, self).optimize(compressor);
|
||||
}
|
||||
}
|
||||
if (compressor.option("evaluate")
|
||||
&& compressor.option("reduce_vars")
|
||||
if (compressor.option("reduce_vars")
|
||||
&& is_lhs(self, compressor.parent()) !== self) {
|
||||
var d = self.definition();
|
||||
var fixed = self.fixed_value();
|
||||
if (fixed) {
|
||||
if (fixed instanceof AST_Defun) {
|
||||
d.fixed = fixed = make_node(AST_Function, fixed, fixed).clone(true);
|
||||
}
|
||||
if (compressor.option("unused")
|
||||
&& fixed instanceof AST_Function
|
||||
&& d.references.length == 1
|
||||
&& !(d.scope.uses_arguments && d.orig[0] instanceof AST_SymbolFunarg)
|
||||
&& !d.scope.uses_eval
|
||||
&& compressor.find_parent(AST_Scope) === fixed.parent_scope) {
|
||||
return fixed;
|
||||
}
|
||||
if (compressor.option("evaluate") && fixed) {
|
||||
if (d.should_replace === undefined) {
|
||||
var init = fixed.evaluate(compressor);
|
||||
if (init !== fixed && (compressor.option("unsafe_regexp") || !(init instanceof RegExp))) {
|
||||
|
||||
@@ -88,7 +88,7 @@ function minify(files, options) {
|
||||
}
|
||||
options.parse = options.parse || {};
|
||||
options.parse.toplevel = null;
|
||||
for (var name in files) {
|
||||
for (var name in files) if (HOP(files, name)) {
|
||||
options.parse.filename = name;
|
||||
options.parse.toplevel = parse(files[name], options.parse);
|
||||
if (options.sourceMap && options.sourceMap.content == "inline") {
|
||||
@@ -136,7 +136,7 @@ function minify(files, options) {
|
||||
if (options.sourceMap.includeSources) {
|
||||
if (files instanceof AST_Toplevel) {
|
||||
throw new Error("original source content unavailable");
|
||||
} else for (var name in files) {
|
||||
} else for (var name in files) if (HOP(files, name)) {
|
||||
options.output.source_map.get().setSourceContent(name, files[name]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -73,6 +73,7 @@ function OutputStream(options) {
|
||||
shebang : true,
|
||||
shorthand : undefined,
|
||||
source_map : null,
|
||||
webkit : false,
|
||||
width : 80,
|
||||
wrap_iife : false,
|
||||
}, true);
|
||||
@@ -629,6 +630,13 @@ function OutputStream(options) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (output.option('webkit')) {
|
||||
var p = output.parent();
|
||||
if (p instanceof AST_PropAccess && p.expression === this) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if (output.option('wrap_iife')) {
|
||||
var p = output.parent();
|
||||
return p instanceof AST_Call && p.expression === this;
|
||||
|
||||
16
lib/parse.js
16
lib/parse.js
@@ -122,8 +122,6 @@ var PUNC_BEFORE_EXPRESSION = makePredicate(characters("[{(,;:"));
|
||||
|
||||
var PUNC_CHARS = makePredicate(characters("[]{}(),;:"));
|
||||
|
||||
var REGEXP_MODIFIERS = makePredicate(characters("gmsiy"));
|
||||
|
||||
/* -----[ Tokenizer ]----- */
|
||||
|
||||
// surrogate safe regexps adapted from https://github.com/mathiasbynens/unicode-8.0.0/tree/89b412d8a71ecca9ed593d9e9fa073ab64acfebe/Binary_Property
|
||||
@@ -850,9 +848,7 @@ var PRECEDENCE = (function(a, ret){
|
||||
{}
|
||||
);
|
||||
|
||||
var STATEMENTS_WITH_LABELS = array_to_hash([ "for", "do", "while", "switch" ]);
|
||||
|
||||
var ATOMIC_START_TOKEN = array_to_hash([ "atom", "num", "string", "regexp", "name" ]);
|
||||
var ATOMIC_START_TOKEN = makePredicate([ "atom", "num", "string", "regexp", "name" ]);
|
||||
|
||||
/* -----[ Parser ]----- */
|
||||
|
||||
@@ -1872,7 +1868,6 @@ function parse($TEXT, options) {
|
||||
var tok = S.token, ret;
|
||||
switch (tok.type) {
|
||||
case "name":
|
||||
case "keyword":
|
||||
ret = _make_symbol(AST_SymbolRef);
|
||||
break;
|
||||
case "num":
|
||||
@@ -1902,13 +1897,6 @@ function parse($TEXT, options) {
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case "operator":
|
||||
if (!is_identifier_string(tok.value)) {
|
||||
croak("Invalid getter/setter name: " + tok.value,
|
||||
tok.line, tok.col, tok.pos);
|
||||
}
|
||||
ret = _make_symbol(AST_SymbolRef);
|
||||
break;
|
||||
}
|
||||
next();
|
||||
return ret;
|
||||
@@ -2015,7 +2003,7 @@ function parse($TEXT, options) {
|
||||
if (is("template_head")) {
|
||||
return subscripts(template_string(), allow_calls);
|
||||
}
|
||||
if (ATOMIC_START_TOKEN[S.token.type]) {
|
||||
if (ATOMIC_START_TOKEN(S.token.type)) {
|
||||
return subscripts(as_atom_node(), allow_calls);
|
||||
}
|
||||
unexpected();
|
||||
|
||||
@@ -96,7 +96,8 @@ function mangle_properties(ast, options) {
|
||||
reserved: null,
|
||||
});
|
||||
|
||||
var reserved = options.reserved || [];
|
||||
var reserved = options.reserved;
|
||||
if (!Array.isArray(reserved)) reserved = [];
|
||||
if (!options.builtins) find_builtins(reserved);
|
||||
|
||||
var cache = options.cache;
|
||||
|
||||
@@ -450,7 +450,7 @@ AST_Symbol.DEFMETHOD("global", function(){
|
||||
});
|
||||
|
||||
AST_Toplevel.DEFMETHOD("_default_mangler_options", function(options){
|
||||
return defaults(options, {
|
||||
options = defaults(options, {
|
||||
eval : false,
|
||||
ie8 : false,
|
||||
keep_classnames: false,
|
||||
@@ -458,6 +458,8 @@ AST_Toplevel.DEFMETHOD("_default_mangler_options", function(options){
|
||||
reserved : [],
|
||||
toplevel : false,
|
||||
});
|
||||
if (!Array.isArray(options.reserved)) options.reserved = [];
|
||||
return options;
|
||||
});
|
||||
|
||||
AST_Toplevel.DEFMETHOD("mangle_names", function(options){
|
||||
|
||||
@@ -43,13 +43,6 @@
|
||||
|
||||
"use strict";
|
||||
|
||||
function array_to_hash(a) {
|
||||
var ret = Object.create(null);
|
||||
for (var i = 0; i < a.length; ++i)
|
||||
ret[a[i]] = true;
|
||||
return ret;
|
||||
};
|
||||
|
||||
function slice(a, start) {
|
||||
return Array.prototype.slice.call(a, start || 0);
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user