Skip to content

Commit 66c126f

Browse files
authored
fix corner case in ie8 (#3207)
fixes #3206
1 parent fdee083 commit 66c126f

File tree

2 files changed

+101
-56
lines changed

2 files changed

+101
-56
lines changed

lib/compress.js

Lines changed: 56 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -336,13 +336,10 @@ merge(Compressor.prototype, {
336336
def.chained = false;
337337
def.direct_access = false;
338338
def.escaped = false;
339-
if (def.scope.pinned()) {
340-
def.fixed = false;
341-
} else if (!compressor.exposed(def)) {
342-
def.fixed = def.init;
343-
} else {
344-
def.fixed = false;
345-
}
339+
def.fixed = !def.scope.pinned()
340+
&& !compressor.exposed(def)
341+
&& !(def.init instanceof AST_Function && def.init !== def.scope)
342+
&& def.init;
346343
if (def.fixed instanceof AST_Defun && !all(def.references, function(ref) {
347344
var scope = ref.scope;
348345
do {
@@ -3444,6 +3441,7 @@ merge(Compressor.prototype, {
34443441
if (scope !== self) return;
34453442
if (node instanceof AST_Function
34463443
&& node.name
3444+
&& !compressor.option("ie8")
34473445
&& !compressor.option("keep_fnames")) {
34483446
var def = node.name.definition();
34493447
// any declarations with same name will overshadow
@@ -3927,8 +3925,39 @@ merge(Compressor.prototype, {
39273925
}
39283926

39293927
def(AST_Node, return_this);
3930-
def(AST_Constant, return_null);
3931-
def(AST_This, return_null);
3928+
def(AST_Accessor, return_null);
3929+
def(AST_Array, function(compressor, first_in_statement) {
3930+
var values = trim(this.elements, compressor, first_in_statement);
3931+
return values && make_sequence(this, values);
3932+
});
3933+
def(AST_Assign, function(compressor) {
3934+
var left = this.left;
3935+
if (left.has_side_effects(compressor)
3936+
|| compressor.has_directive("use strict")
3937+
&& left instanceof AST_PropAccess
3938+
&& left.expression.is_constant()) {
3939+
return this;
3940+
}
3941+
this.write_only = true;
3942+
if (root_expr(left).is_constant_expression(compressor.find_parent(AST_Scope))) {
3943+
return this.right.drop_side_effect_free(compressor);
3944+
}
3945+
return this;
3946+
});
3947+
def(AST_Binary, function(compressor, first_in_statement) {
3948+
var right = this.right.drop_side_effect_free(compressor);
3949+
if (!right) return this.left.drop_side_effect_free(compressor, first_in_statement);
3950+
if (lazy_op[this.operator]) {
3951+
if (right === this.right) return this;
3952+
var node = this.clone();
3953+
node.right = right;
3954+
return node;
3955+
} else {
3956+
var left = this.left.drop_side_effect_free(compressor, first_in_statement);
3957+
if (!left) return this.right.drop_side_effect_free(compressor, first_in_statement);
3958+
return make_sequence(this, [ left, right ]);
3959+
}
3960+
});
39323961
def(AST_Call, function(compressor, first_in_statement) {
39333962
if (!this.is_expr_pure(compressor)) {
39343963
if (this.expression.is_call_pure(compressor)) {
@@ -3959,36 +3988,6 @@ merge(Compressor.prototype, {
39593988
var args = trim(this.args, compressor, first_in_statement);
39603989
return args && make_sequence(this, args);
39613990
});
3962-
def(AST_Accessor, return_null);
3963-
def(AST_Function, return_null);
3964-
def(AST_Binary, function(compressor, first_in_statement) {
3965-
var right = this.right.drop_side_effect_free(compressor);
3966-
if (!right) return this.left.drop_side_effect_free(compressor, first_in_statement);
3967-
if (lazy_op[this.operator]) {
3968-
if (right === this.right) return this;
3969-
var node = this.clone();
3970-
node.right = right;
3971-
return node;
3972-
} else {
3973-
var left = this.left.drop_side_effect_free(compressor, first_in_statement);
3974-
if (!left) return this.right.drop_side_effect_free(compressor, first_in_statement);
3975-
return make_sequence(this, [ left, right ]);
3976-
}
3977-
});
3978-
def(AST_Assign, function(compressor) {
3979-
var left = this.left;
3980-
if (left.has_side_effects(compressor)
3981-
|| compressor.has_directive("use strict")
3982-
&& left instanceof AST_PropAccess
3983-
&& left.expression.is_constant()) {
3984-
return this;
3985-
}
3986-
this.write_only = true;
3987-
if (root_expr(left).is_constant_expression(compressor.find_parent(AST_Scope))) {
3988-
return this.right.drop_side_effect_free(compressor);
3989-
}
3990-
return this;
3991-
});
39923991
def(AST_Conditional, function(compressor) {
39933992
var consequent = this.consequent.drop_side_effect_free(compressor);
39943993
var alternative = this.alternative.drop_side_effect_free(compressor);
@@ -4008,6 +4007,14 @@ merge(Compressor.prototype, {
40084007
node.alternative = alternative;
40094008
return node;
40104009
});
4010+
def(AST_Constant, return_null);
4011+
def(AST_Dot, function(compressor, first_in_statement) {
4012+
if (this.expression.may_throw_on_access(compressor)) return this;
4013+
return this.expression.drop_side_effect_free(compressor, first_in_statement);
4014+
});
4015+
def(AST_Function, function(compressor) {
4016+
return this.name && compressor.option("ie8") ? this : null;
4017+
});
40114018
def(AST_Unary, function(compressor, first_in_statement) {
40124019
if (unary_side_effects[this.operator]) {
40134020
this.write_only = !this.expression.has_side_effects(compressor);
@@ -4021,23 +4028,20 @@ merge(Compressor.prototype, {
40214028
}
40224029
return expression;
40234030
});
4024-
def(AST_SymbolRef, function(compressor) {
4025-
return this.is_declared(compressor) ? null : this;
4026-
});
40274031
def(AST_Object, function(compressor, first_in_statement) {
40284032
var values = trim(this.properties, compressor, first_in_statement);
40294033
return values && make_sequence(this, values);
40304034
});
40314035
def(AST_ObjectProperty, function(compressor, first_in_statement) {
40324036
return this.value.drop_side_effect_free(compressor, first_in_statement);
40334037
});
4034-
def(AST_Array, function(compressor, first_in_statement) {
4035-
var values = trim(this.elements, compressor, first_in_statement);
4036-
return values && make_sequence(this, values);
4037-
});
4038-
def(AST_Dot, function(compressor, first_in_statement) {
4039-
if (this.expression.may_throw_on_access(compressor)) return this;
4040-
return this.expression.drop_side_effect_free(compressor, first_in_statement);
4038+
def(AST_Sequence, function(compressor) {
4039+
var last = this.tail_node();
4040+
var expr = last.drop_side_effect_free(compressor);
4041+
if (expr === last) return this;
4042+
var expressions = this.expressions.slice(0, -1);
4043+
if (expr) expressions.push(expr);
4044+
return make_sequence(this, expressions);
40414045
});
40424046
def(AST_Sub, function(compressor, first_in_statement) {
40434047
if (this.expression.may_throw_on_access(compressor)) return this;
@@ -4047,14 +4051,10 @@ merge(Compressor.prototype, {
40474051
if (!property) return expression;
40484052
return make_sequence(this, [ expression, property ]);
40494053
});
4050-
def(AST_Sequence, function(compressor) {
4051-
var last = this.tail_node();
4052-
var expr = last.drop_side_effect_free(compressor);
4053-
if (expr === last) return this;
4054-
var expressions = this.expressions.slice(0, -1);
4055-
if (expr) expressions.push(expr);
4056-
return make_sequence(this, expressions);
4054+
def(AST_SymbolRef, function(compressor) {
4055+
return this.is_declared(compressor) ? null : this;
40574056
});
4057+
def(AST_This, return_null);
40584058
})(function(node, func) {
40594059
node.DEFMETHOD("drop_side_effect_free", func);
40604060
});

test/compress/ie8.js

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -666,3 +666,48 @@ issue_3197_2_ie8: {
666666
}
667667
expect_stdout: "true"
668668
}
669+
670+
issue_3206_1: {
671+
options = {
672+
evaluate: true,
673+
ie8: false,
674+
reduce_vars: true,
675+
typeofs: true,
676+
unused: true,
677+
}
678+
input: {
679+
console.log(function() {
680+
var foo = function bar() {};
681+
return "function" == typeof bar;
682+
}());
683+
}
684+
expect: {
685+
console.log(function() {
686+
return "function" == typeof bar;
687+
}());
688+
}
689+
expect_stdout: "false"
690+
}
691+
692+
issue_3206_2: {
693+
options = {
694+
evaluate: true,
695+
ie8: true,
696+
reduce_vars: true,
697+
typeofs: true,
698+
unused: true,
699+
}
700+
input: {
701+
console.log(function() {
702+
var foo = function bar() {};
703+
return "function" == typeof bar;
704+
}());
705+
}
706+
expect: {
707+
console.log(function() {
708+
(function bar() {});
709+
return "function" == typeof bar;
710+
}());
711+
}
712+
expect_stdout: "false"
713+
}

0 commit comments

Comments
 (0)