Merge 1bc9ddea7e into a4889a0f2e
This commit is contained in:
commit
35ed802a42
|
|
@ -59,6 +59,8 @@ function Compressor(options, false_by_default) {
|
|||
evaluate : !false_by_default,
|
||||
booleans : !false_by_default,
|
||||
loops : !false_by_default,
|
||||
inlineconst : false,
|
||||
inlinestr : false,
|
||||
unused : !false_by_default,
|
||||
hoist_funs : !false_by_default,
|
||||
hoist_vars : false,
|
||||
|
|
@ -83,6 +85,7 @@ merge(Compressor.prototype, {
|
|||
before: function(node, descend, in_list) {
|
||||
if (node._squeezed) return node;
|
||||
if (node instanceof AST_Scope) {
|
||||
node.inline_const_primitive(this);
|
||||
node.drop_unused(this);
|
||||
node = node.hoist_declarations(this);
|
||||
}
|
||||
|
|
@ -165,7 +168,9 @@ merge(Compressor.prototype, {
|
|||
return make_node(AST_Null, orig).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
|
||||
|
|
@ -593,8 +598,8 @@ merge(Compressor.prototype, {
|
|||
// of the array is always an AST_Node descendant; when
|
||||
// evaluation was successful it's a node that represents the
|
||||
// constant; otherwise it's the original node.
|
||||
AST_Node.DEFMETHOD("evaluate", function(compressor){
|
||||
if (!compressor.option("evaluate")) return [ this ];
|
||||
AST_Node.DEFMETHOD("evaluate", function(compressor, ignore_setting){
|
||||
if (!compressor.option("evaluate") && !ignore_setting) return [ this ];
|
||||
try {
|
||||
var val = this._eval(), ast = make_node_from_constant(compressor, val, this);
|
||||
return [ best_of(ast, this), val ];
|
||||
|
|
@ -886,6 +891,68 @@ merge(Compressor.prototype, {
|
|||
return self;
|
||||
});
|
||||
|
||||
AST_Scope.DEFMETHOD("inline_const_primitive", function(compressor){
|
||||
var self = this;
|
||||
var inlineStringThreshold = compressor.option("inlinestr");
|
||||
if (compressor.option("inlineconst")
|
||||
&& !(self instanceof AST_Toplevel)
|
||||
&& !self.uses_eval
|
||||
) {
|
||||
var in_use = [];
|
||||
var definitions = {};
|
||||
// pass 1: find out symbols defined for only once and has
|
||||
// could be evaluate as number or bool constant.
|
||||
var scope = this;
|
||||
var tw = new TreeWalker(function(node, descend){
|
||||
if (node !== self) {
|
||||
if (node instanceof AST_Definitions && scope === self) {
|
||||
node.definitions.forEach(function(def){
|
||||
if (def.value) {
|
||||
var value = def.value.evaluate(compressor, true);
|
||||
def.value = value[0];
|
||||
if (value.length > 1) {
|
||||
if (typeof value[1] === 'string' && value[1].length < inlineStringThreshold
|
||||
|| typeof value[1] === 'number'
|
||||
|| typeof value[1] === 'boolean'
|
||||
|| value[1] === null
|
||||
)
|
||||
definitions[def.name.name] = value[1];
|
||||
}
|
||||
}
|
||||
});
|
||||
return true;
|
||||
}
|
||||
if (node instanceof AST_Assign) {
|
||||
if (definitions.hasOwnProperty(node.left.name))
|
||||
delete definitions[node.left.name];
|
||||
return true;
|
||||
}
|
||||
if (node instanceof AST_Scope) {
|
||||
var save_scope = scope;
|
||||
scope = node;
|
||||
descend();
|
||||
scope = save_scope;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
});
|
||||
self.walk(tw);
|
||||
|
||||
// pass 2: we should replace symbols refer to constants
|
||||
// with corresponding values.
|
||||
var tt = new TreeTransformer(
|
||||
function before(node, descend, in_list) {
|
||||
if (node instanceof AST_SymbolRef) {
|
||||
if (definitions.hasOwnProperty(node.name)) {
|
||||
return make_node_from_constant(compressor, definitions[node.name], node.orig);
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
self.transform(tt);
|
||||
}
|
||||
});
|
||||
|
||||
AST_Scope.DEFMETHOD("drop_unused", function(compressor){
|
||||
var self = this;
|
||||
if (compressor.option("unused")
|
||||
|
|
|
|||
67
test/compress/inlineconst.js
Normal file
67
test/compress/inlineconst.js
Normal file
|
|
@ -0,0 +1,67 @@
|
|||
inlineconst_number: {
|
||||
options = { inlineconst: true };
|
||||
input: {
|
||||
function f(c) {
|
||||
var a = 5, b = 10;
|
||||
return a + b + c;
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
function f(c) {
|
||||
var a = 5, b = 10;
|
||||
return 5 + 10 + c;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
inlineconst_bool_and_null: {
|
||||
options = { inlineconst: true };
|
||||
input: {
|
||||
function f(c) {
|
||||
var a = true, b = false, n = null;
|
||||
return (n || b || a) ^ c;
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
function f(c) {
|
||||
var a = true, b = false, n = null;
|
||||
return (null || false || true) ^ c;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
inlineconst_string: {
|
||||
options = { inlineconst: true, inlinestr: 2 };
|
||||
input: {
|
||||
function f() {
|
||||
var s1 = "1", s2 = "12";
|
||||
return s1 + s2;
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
function f() {
|
||||
var s1 = "1", s2 = "12";
|
||||
return "1" + s2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
inlineconst_in_nested_function: {
|
||||
options = { inlineconst: true };
|
||||
input: {
|
||||
function f() {
|
||||
var x = 1;
|
||||
return function t() {
|
||||
return x + 1;
|
||||
};
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
function f() {
|
||||
var x = 1;
|
||||
return function t() {
|
||||
return 1 + 1;
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user