Skip to content

Commit

Permalink
fix(es/minifier): Fix minifier (#2711)
Browse files Browse the repository at this point in the history
swc_ecma_minifier:
 - Respect `inline_prevented`.
 - Mark the LHS of an assignment pattern property as a pattern. (vercel/next.js#30498)
  • Loading branch information
kdy1 authored Nov 10, 2021
1 parent cb68956 commit df635c9
Show file tree
Hide file tree
Showing 26 changed files with 160 additions and 54 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
var _c;
let d;
let a, d;
(function(source, excluded) {
if (null == source) return {
};
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
var _c, ref, d;
var _c, ref, a, d;
(function(source, excluded) {
if (null == source) return {
};
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
var foo = {
var bar, foo = {
foo: 1,
bar: 2
};
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
var a;
let a1, a2, a3;
let x, y, z, a1, a2, a3;
({} = { x , y , z } = a), [] = [a1, a2, a3] = a;
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
var a;
let a1, a2, a3;
let x, y, z, a1, a2, a3;
({} = { x , y , z } = a), [] = [a1, a2, a3] = a;
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
var a;
let a1, a2, a3;
let x, y, z, a1, a2, a3;
({} = { x , y , z } = a), [] = [a1, a2, a3] = a;
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
var a;
let a1, a2, a3;
let x, y, z, a1, a2, a3;
({ x , y , z } = {} = a), [a1, a2, a3] = [] = a;
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
var a;
let a1, a2, a3;
let x, y, z, a1, a2, a3;
({ x , y , z } = {} = a), [a1, a2, a3] = [] = a;
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
var a;
let a1, a2, a3;
let x, y, z, a1, a2, a3;
({ x , y , z } = {} = a), [a1, a2, a3] = [] = a;
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
var a;
var a, b;
[...{ 0: a = "" , b }] = [
"",
1
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
var a;
var a, b;
({ 0: a = "" , b } = [
"",
1
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
var a;
var a, b;
[...{ 0: a = "" , b }] = [
"",
1
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
var y, E, E1;
var x, y, E, E1;
for ({ x , y: y = E.x } of ((E1 = E || (E = {
}))[E1.x = 0] = "x", [
{
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
var E, E1;
var x, y, E, E1;
for ({ x , y =E.x } of ((E1 = E || (E = {
}))[E1.x = 0] = "x", [
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,4 +42,10 @@ t2.z.toString();
"x"
]);
x.toFixed(), q.y.toFixed(), q.z.toFixed();
}[target_string] = strArray, [target_string_undef] = strArray, [, , , ...target_string_arr] = strArray, ({ x , y , z } = numMapPoint), { q } = numMapPoint;
}[target_string] = strArray, [target_string_undef] = strArray, [, , , ...target_string_arr] = strArray;
{
let x, y, z;
({ x , y , z } = numMapPoint);
let q;
({ q } = numMapPoint);
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
const hardline = {
type: "hard"
};
module.exports = {
hardline: {
type: "hard"
}
hardline
}, module.exports = {
nested: require("./first")
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,9 @@ _n1.y, _n1.n2.z, _extends({
}, nestedrest.n1.n2.n3), _objectWithoutProperties(nestedrest, [
"x",
"n1"
]), complex.x.ka, complex.y, _objectWithoutProperties(complex.x, [
]);
var ka = complex.x.ka;
complex.y, _objectWithoutProperties(complex.x, [
"ka"
]), _objectWithoutProperties(complex, [
"x",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ function _objectWithoutPropertiesLoose(source, excluded) {
for(i = 0; i < sourceKeys.length; i++)key = sourceKeys[i], excluded.indexOf(key) >= 0 || (target[key] = source[key]);
return target;
}
let other;
let ka, other;
_objectWithoutProperties((_complex = void 0).x, [
"ka"
]), _objectWithoutProperties(_complex, [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,16 +31,16 @@ _objectWithoutProperties((_complex = complex).x, [
"x",
"y"
]), ref = _complex, { ka } = ref.x;
var arr, complex, _complex, ref, overEmit, _overEmit, ref1, _a = function(arr) {
var arr, ka, complex, _complex, ref, overEmit, _overEmit, ref1, _a = function(arr) {
if (Array.isArray(arr)) return arr;
}(arr = overEmit.a) || function(iter) {
if (Symbol.iterator in Object(iter) || "[object Arguments]" === Object.prototype.toString.call(iter)) return Array.from(iter);
}(arr) || function() {
throw new TypeError("Invalid attempt to destructure non-iterable instance");
}(), ref2 = _a[0], ref2 = null !== ref2 ? ref2 : function(e) {
throw e;
}(new TypeError("Cannot destructure undefined")), y = _a.slice(1);
overEmit.b.z, _extends({
}(new TypeError("Cannot destructure undefined")), y = _a.slice(1), z = overEmit.b.z;
_extends({
}, overEmit.a[0]), _objectWithoutProperties(overEmit.b, [
"z"
]), _objectWithoutProperties(overEmit, [
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
var _o;
var b, _o;
function _defineProperty(obj, key, value) {
return key in obj ? Object.defineProperty(obj, key, {
value: value,
Expand Down
70 changes: 40 additions & 30 deletions crates/swc_ecma_minifier/src/analyzer/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,34 @@ where
ret
}

fn visit_pat_id(&mut self, i: &Ident) {
let Ctx {
in_left_of_for_loop,
in_pat_of_param,
..
} = self.ctx;

if self.ctx.in_pat_of_var_decl || self.ctx.in_pat_of_param || self.ctx.in_catch_param {
let v = self.declare_decl(
&i,
self.ctx.in_pat_of_var_decl_with_init,
self.ctx.var_decl_kind_of_pat,
false,
);

if in_pat_of_param {
v.mark_declared_as_fn_param();
}

if in_left_of_for_loop {
v.mark_reassigned();
v.mark_mutated();
}
} else {
self.report_usage(&i, true);
}
}

fn report_usage(&mut self, i: &Ident, is_assign: bool) {
self.data.report_usage(self.ctx, i, is_assign)
}
Expand Down Expand Up @@ -590,6 +618,17 @@ where
}
}

fn visit_object_pat_prop(&mut self, n: &ObjectPatProp, _: &dyn Node) {
n.visit_children_with(self);

match n {
ObjectPatProp::Assign(p) => {
self.visit_pat_id(&p.key);
}
_ => {}
}
}

fn visit_param(&mut self, n: &Param, _: &dyn Node) {
let ctx = Ctx {
in_pat_of_param: false,
Expand All @@ -608,37 +647,8 @@ where
fn visit_pat(&mut self, n: &Pat, _: &dyn Node) {
n.visit_children_with(self);

let Ctx {
in_left_of_for_loop,
in_pat_of_param,
..
} = self.ctx;

match n {
Pat::Ident(i) => {
if self.ctx.in_pat_of_var_decl
|| self.ctx.in_pat_of_param
|| self.ctx.in_catch_param
{
let v = self.declare_decl(
&i.id,
self.ctx.in_pat_of_var_decl_with_init,
self.ctx.var_decl_kind_of_pat,
false,
);

if in_pat_of_param {
v.mark_declared_as_fn_param();
}

if in_left_of_for_loop {
v.mark_reassigned();
v.mark_mutated();
}
} else {
self.report_usage(&i.id, true);
}
}
Pat::Ident(i) => self.visit_pat_id(&i.id),
_ => {}
}
}
Expand Down
2 changes: 2 additions & 0 deletions crates/swc_ecma_minifier/src/compress/optimize/inline.rs
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,7 @@ where
// Single use => inlined
if is_inline_enabled
&& !should_preserve
&& !usage.reassigned
&& (!usage.mutated || usage.is_mutated_only_by_one_call())
&& usage.ref_count == 1
{
Expand Down Expand Up @@ -471,6 +472,7 @@ where
&& usage.ref_count == 1
&& (usage.is_fn_local || (usage.used_as_callee && !usage.used_above_decl))
&& !usage.used_in_loop
&& !usage.inline_prevented
&& (match decl {
Decl::Class(..) => !usage.used_above_decl,
Decl::Fn(..) => true,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
function string_create() {
return new StringSchema();
}
class StringSchema extends BaseSchema {

matches(regex, options) {
let excludeEmptyString = false;
let message;
let name;

if (options) {
if (typeof options === 'object') {
({
excludeEmptyString = false,
message,
name
} = options);
} else {
message = options;
}
}

return this.test({
name: name || 'matches',
message: message || string.matches,
params: {
regex
},
test: value => isAbsent(value) || value === '' && excludeEmptyString || value.search(regex) !== -1
});
}

}
string_create.prototype = StringSchema.prototype;
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
class StringSchema extends BaseSchema {
matches(regex, options) {
let excludeEmptyString = !1, message, name;
return options && ("object" == typeof options ? { excludeEmptyString =!1 , message , name } = options : message = options), this.test({
name: name || "matches",
message: message || string.matches,
params: {
regex
},
test: (value)=>isAbsent(value) || "" === value && excludeEmptyString || -1 !== value.search(regex)
});
}
}
(function() {
return new StringSchema();
}).prototype = StringSchema.prototype;
34 changes: 34 additions & 0 deletions crates/swc_ecma_minifier/tests/full/next-30498/1/input.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
function string_create() {
return new StringSchema();
}
class StringSchema extends BaseSchema {

matches(regex, options) {
let excludeEmptyString = false;
let message;
let name;

if (options) {
if (typeof options === 'object') {
({
excludeEmptyString = false,
message,
name
} = options);
} else {
message = options;
}
}

return this.test({
name: name || 'matches',
message: message || string.matches,
params: {
regex
},
test: value => isAbsent(value) || value === '' && excludeEmptyString || value.search(regex) !== -1
});
}

}
string_create.prototype = StringSchema.prototype;
1 change: 1 addition & 0 deletions crates/swc_ecma_minifier/tests/full/next-30498/1/output.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit df635c9

Please sign in to comment.