aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/compress.js112
-rw-r--r--test/compress/ie8.js45
2 files changed, 101 insertions, 56 deletions
diff --git a/lib/compress.js b/lib/compress.js
index da84df17..c28305a4 100644
--- a/lib/compress.js
+++ b/lib/compress.js
@@ -336,13 +336,10 @@ merge(Compressor.prototype, {
def.chained = false;
def.direct_access = false;
def.escaped = false;
- if (def.scope.pinned()) {
- def.fixed = false;
- } else if (!compressor.exposed(def)) {
- def.fixed = def.init;
- } else {
- def.fixed = false;
- }
+ def.fixed = !def.scope.pinned()
+ && !compressor.exposed(def)
+ && !(def.init instanceof AST_Function && def.init !== def.scope)
+ && def.init;
if (def.fixed instanceof AST_Defun && !all(def.references, function(ref) {
var scope = ref.scope;
do {
@@ -3444,6 +3441,7 @@ merge(Compressor.prototype, {
if (scope !== self) return;
if (node instanceof AST_Function
&& node.name
+ && !compressor.option("ie8")
&& !compressor.option("keep_fnames")) {
var def = node.name.definition();
// any declarations with same name will overshadow
@@ -3927,8 +3925,39 @@ merge(Compressor.prototype, {
}
def(AST_Node, return_this);
- def(AST_Constant, return_null);
- def(AST_This, return_null);
+ def(AST_Accessor, return_null);
+ def(AST_Array, function(compressor, first_in_statement) {
+ var values = trim(this.elements, compressor, first_in_statement);
+ return values && make_sequence(this, values);
+ });
+ def(AST_Assign, function(compressor) {
+ var left = this.left;
+ if (left.has_side_effects(compressor)
+ || compressor.has_directive("use strict")
+ && left instanceof AST_PropAccess
+ && left.expression.is_constant()) {
+ return this;
+ }
+ this.write_only = true;
+ if (root_expr(left).is_constant_expression(compressor.find_parent(AST_Scope))) {
+ return this.right.drop_side_effect_free(compressor);
+ }
+ return this;
+ });
+ def(AST_Binary, function(compressor, first_in_statement) {
+ var right = this.right.drop_side_effect_free(compressor);
+ if (!right) return this.left.drop_side_effect_free(compressor, first_in_statement);
+ if (lazy_op[this.operator]) {
+ if (right === this.right) return this;
+ var node = this.clone();
+ node.right = right;
+ return node;
+ } else {
+ var left = this.left.drop_side_effect_free(compressor, first_in_statement);
+ if (!left) return this.right.drop_side_effect_free(compressor, first_in_statement);
+ return make_sequence(this, [ left, right ]);
+ }
+ });
def(AST_Call, function(compressor, first_in_statement) {
if (!this.is_expr_pure(compressor)) {
if (this.expression.is_call_pure(compressor)) {
@@ -3959,36 +3988,6 @@ merge(Compressor.prototype, {
var args = trim(this.args, compressor, first_in_statement);
return args && make_sequence(this, args);
});
- def(AST_Accessor, return_null);
- def(AST_Function, return_null);
- def(AST_Binary, function(compressor, first_in_statement) {
- var right = this.right.drop_side_effect_free(compressor);
- if (!right) return this.left.drop_side_effect_free(compressor, first_in_statement);
- if (lazy_op[this.operator]) {
- if (right === this.right) return this;
- var node = this.clone();
- node.right = right;
- return node;
- } else {
- var left = this.left.drop_side_effect_free(compressor, first_in_statement);
- if (!left) return this.right.drop_side_effect_free(compressor, first_in_statement);
- return make_sequence(this, [ left, right ]);
- }
- });
- def(AST_Assign, function(compressor) {
- var left = this.left;
- if (left.has_side_effects(compressor)
- || compressor.has_directive("use strict")
- && left instanceof AST_PropAccess
- && left.expression.is_constant()) {
- return this;
- }
- this.write_only = true;
- if (root_expr(left).is_constant_expression(compressor.find_parent(AST_Scope))) {
- return this.right.drop_side_effect_free(compressor);
- }
- return this;
- });
def(AST_Conditional, function(compressor) {
var consequent = this.consequent.drop_side_effect_free(compressor);
var alternative = this.alternative.drop_side_effect_free(compressor);
@@ -4008,6 +4007,14 @@ merge(Compressor.prototype, {
node.alternative = alternative;
return node;
});
+ def(AST_Constant, return_null);
+ def(AST_Dot, function(compressor, first_in_statement) {
+ if (this.expression.may_throw_on_access(compressor)) return this;
+ return this.expression.drop_side_effect_free(compressor, first_in_statement);
+ });
+ def(AST_Function, function(compressor) {
+ return this.name && compressor.option("ie8") ? this : null;
+ });
def(AST_Unary, function(compressor, first_in_statement) {
if (unary_side_effects[this.operator]) {
this.write_only = !this.expression.has_side_effects(compressor);
@@ -4021,9 +4028,6 @@ merge(Compressor.prototype, {
}
return expression;
});
- def(AST_SymbolRef, function(compressor) {
- return this.is_declared(compressor) ? null : this;
- });
def(AST_Object, function(compressor, first_in_statement) {
var values = trim(this.properties, compressor, first_in_statement);
return values && make_sequence(this, values);
@@ -4031,13 +4035,13 @@ merge(Compressor.prototype, {
def(AST_ObjectProperty, function(compressor, first_in_statement) {
return this.value.drop_side_effect_free(compressor, first_in_statement);
});
- def(AST_Array, function(compressor, first_in_statement) {
- var values = trim(this.elements, compressor, first_in_statement);
- return values && make_sequence(this, values);
- });
- def(AST_Dot, function(compressor, first_in_statement) {
- if (this.expression.may_throw_on_access(compressor)) return this;
- return this.expression.drop_side_effect_free(compressor, first_in_statement);
+ def(AST_Sequence, function(compressor) {
+ var last = this.tail_node();
+ var expr = last.drop_side_effect_free(compressor);
+ if (expr === last) return this;
+ var expressions = this.expressions.slice(0, -1);
+ if (expr) expressions.push(expr);
+ return make_sequence(this, expressions);
});
def(AST_Sub, function(compressor, first_in_statement) {
if (this.expression.may_throw_on_access(compressor)) return this;
@@ -4047,14 +4051,10 @@ merge(Compressor.prototype, {
if (!property) return expression;
return make_sequence(this, [ expression, property ]);
});
- def(AST_Sequence, function(compressor) {
- var last = this.tail_node();
- var expr = last.drop_side_effect_free(compressor);
- if (expr === last) return this;
- var expressions = this.expressions.slice(0, -1);
- if (expr) expressions.push(expr);
- return make_sequence(this, expressions);
+ def(AST_SymbolRef, function(compressor) {
+ return this.is_declared(compressor) ? null : this;
});
+ def(AST_This, return_null);
})(function(node, func) {
node.DEFMETHOD("drop_side_effect_free", func);
});
diff --git a/test/compress/ie8.js b/test/compress/ie8.js
index d5b61cbd..3fce9ef4 100644
--- a/test/compress/ie8.js
+++ b/test/compress/ie8.js
@@ -666,3 +666,48 @@ issue_3197_2_ie8: {
}
expect_stdout: "true"
}
+
+issue_3206_1: {
+ options = {
+ evaluate: true,
+ ie8: false,
+ reduce_vars: true,
+ typeofs: true,
+ unused: true,
+ }
+ input: {
+ console.log(function() {
+ var foo = function bar() {};
+ return "function" == typeof bar;
+ }());
+ }
+ expect: {
+ console.log(function() {
+ return "function" == typeof bar;
+ }());
+ }
+ expect_stdout: "false"
+}
+
+issue_3206_2: {
+ options = {
+ evaluate: true,
+ ie8: true,
+ reduce_vars: true,
+ typeofs: true,
+ unused: true,
+ }
+ input: {
+ console.log(function() {
+ var foo = function bar() {};
+ return "function" == typeof bar;
+ }());
+ }
+ expect: {
+ console.log(function() {
+ (function bar() {});
+ return "function" == typeof bar;
+ }());
+ }
+ expect_stdout: "false"
+}