Skip to content

Commit

Permalink
fix(es/minifier): Don't skip unresolved identifiers (#6050)
Browse files Browse the repository at this point in the history
**Related issue:**

 - Closes #6049
  • Loading branch information
kdy1 committed Oct 5, 2022
1 parent d01887e commit c5fb774
Show file tree
Hide file tree
Showing 18 changed files with 54 additions and 24 deletions.
@@ -1,5 +1,9 @@
//// [classAbstractSingleLineDecl.ts]
import _class_call_check from "@swc/helpers/src/_class_call_check.mjs";
var A = function A() {
"use strict";
_class_call_check(this, A);
};
abstract;
var B = function B() {
"use strict";
Expand All @@ -10,7 +14,4 @@ var C = function C() {
"use strict";
_class_call_check(this, C);
};
new function A() {
"use strict";
_class_call_check(this, A);
}, new B, new C;
new A, new B, new C;
4 changes: 3 additions & 1 deletion crates/swc/tests/vercel/full/react-hooks/1/output/index.js
Expand Up @@ -4,5 +4,7 @@ import { useProject as o } from "@swr/use-project";
import a from "@swr/use-team";
export default function m() {
var m = e().query.project, u = o(m).data;
return a().teamSlug, useProjectBranches(null == u ? void 0 : u.id).data, r(t, {});
a().teamSlug;
var s = null == u ? void 0 : u.id;
return useProjectBranches(s).data, r(t, {});
}
4 changes: 3 additions & 1 deletion crates/swc/tests/vercel/full/utf8-1/output/index.js
Expand Up @@ -5,7 +5,9 @@ import r from "./on-demand-entries-client";
import { addMessageListener as n, connectHMR as c } from "./error-overlay/websocket";
var o = JSON.parse(document.getElementById("__NEXT_DATA__").textContent);
window.__NEXT_DATA__ = o;
var s = o.assetPrefix, i = o.page, _ = null, u = __webpack_hash__, d = (s = s || "") + (s.endsWith("/") ? "" : "/") + "_next/static/webpack/";
var s = o.assetPrefix, i = o.page;
s = s || "";
var _ = null, u = __webpack_hash__, d = s + (s.endsWith("/") ? "" : "/") + "_next/static/webpack/";
function p() {
return (p = e(function() {
var e, a, r, n, c;
Expand Down
11 changes: 10 additions & 1 deletion crates/swc_ecma_minifier/src/compress/optimize/sequences.rs
Expand Up @@ -20,7 +20,9 @@ use crate::{
alias::{collect_infects_from, AliasConfig},
compress::{
optimize::{unused::PropertyAccessOpts, util::replace_id_with_expr},
util::{is_directive, is_ident_used_by, replace_expr},
util::{
is_directive, is_global_var_with_pure_property_access, is_ident_used_by, replace_expr,
},
},
mode::Mode,
option::CompressOptions,
Expand Down Expand Up @@ -944,6 +946,13 @@ where

match e {
Expr::Ident(e) => {
if e.span.ctxt == self.expr_ctx.unresolved_ctxt
&& !is_global_var_with_pure_property_access(&e.sym)
{
log_abort!("Undeclared");
return false;
}

if let Some(a) = a {
match a {
Mergable::Var(a) => {
Expand Down
3 changes: 3 additions & 0 deletions crates/swc_ecma_minifier/src/compress/util/mod.rs
Expand Up @@ -743,6 +743,7 @@ pub(super) fn is_global_var_with_pure_property_access(s: &str) -> bool {
| "clearTimeout"
| "setInterval"
| "setTimeout"
| "btoa"
| "Boolean"
| "Date"
| "decodeURI"
Expand All @@ -751,7 +752,9 @@ pub(super) fn is_global_var_with_pure_property_access(s: &str) -> bool {
| "encodeURIComponent"
| "escape"
| "eval"
| "Error"
| "EvalError"
| "Function"
| "isFinite"
| "isNaN"
| "JSON"
Expand Down
1 change: 0 additions & 1 deletion crates/swc_ecma_minifier/tests/TODO.txt
Expand Up @@ -39,7 +39,6 @@ collapse_vars/collapse_vars_repeated/input.js
collapse_vars/collapse_vars_short_circuit/input.js
collapse_vars/collapse_vars_short_circuited_conditions/input.js
collapse_vars/collapse_vars_side_effects_1/input.js
collapse_vars/collapse_vars_side_effects_2/input.js
collapse_vars/collapse_vars_switch/input.js
collapse_vars/collapse_vars_unary/input.js
collapse_vars/cond_branch_1/input.js
Expand Down
2 changes: 1 addition & 1 deletion crates/swc_ecma_minifier/tests/benches-full/victory.js
Expand Up @@ -8121,7 +8121,7 @@
};
},
"../../../node_modules/lodash/isPlainObject.js": function(module1, exports1, __webpack_require__) {
var baseGetTag = __webpack_require__("../../../node_modules/lodash/_baseGetTag.js"), getPrototype = __webpack_require__("../../../node_modules/lodash/_getPrototype.js"), isObjectLike = __webpack_require__("../../../node_modules/lodash/isObjectLike.js"), funcProto = Function.prototype, objectProto = Object.prototype, funcToString = funcProto.toString, hasOwnProperty = objectProto.hasOwnProperty, objectCtorString = funcToString.call(Object);
var baseGetTag = __webpack_require__("../../../node_modules/lodash/_baseGetTag.js"), getPrototype = __webpack_require__("../../../node_modules/lodash/_getPrototype.js"), isObjectLike = __webpack_require__("../../../node_modules/lodash/isObjectLike.js"), objectProto = Object.prototype, funcToString = Function.prototype.toString, hasOwnProperty = objectProto.hasOwnProperty, objectCtorString = funcToString.call(Object);
module1.exports = function(value) {
if (!isObjectLike(value) || '[object Object]' != baseGetTag(value)) return !1;
var proto = getPrototype(value);
Expand Down
3 changes: 3 additions & 0 deletions crates/swc_ecma_minifier/tests/fixture/issues/6049/1/input.js
@@ -0,0 +1,3 @@
var a = z()

g(a)
@@ -0,0 +1,2 @@
var a = z();
g(a);
Expand Up @@ -1787,7 +1787,7 @@
};
},
function(module1, exports1, __webpack_require__) {
var isFunction = __webpack_require__(36), isMasked = __webpack_require__(105), isObject = __webpack_require__(14), toSource = __webpack_require__(107), reIsHostCtor = /^\[object .+?Constructor\]$/, funcProto = Function.prototype, objectProto = Object.prototype, funcToString = funcProto.toString, hasOwnProperty = objectProto.hasOwnProperty, reIsNative = RegExp("^" + funcToString.call(hasOwnProperty).replace(/[\\^$.*+?()[\]{}|]/g, "\\$&").replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, "$1.*?") + "$");
var isFunction = __webpack_require__(36), isMasked = __webpack_require__(105), isObject = __webpack_require__(14), toSource = __webpack_require__(107), reIsHostCtor = /^\[object .+?Constructor\]$/, objectProto = Object.prototype, funcToString = Function.prototype.toString, hasOwnProperty = objectProto.hasOwnProperty, reIsNative = RegExp("^" + funcToString.call(hasOwnProperty).replace(/[\\^$.*+?()[\]{}|]/g, "\\$&").replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, "$1.*?") + "$");
module1.exports = function(value) {
return !(!isObject(value) || isMasked(value)) && (isFunction(value) ? reIsNative : reIsHostCtor).test(toSource(value));
};
Expand Down Expand Up @@ -2039,7 +2039,7 @@
};
},
function(module1, exports1, __webpack_require__) {
var baseGetTag = __webpack_require__(22), getPrototype = __webpack_require__(50), isObjectLike = __webpack_require__(18), funcProto = Function.prototype, objectProto = Object.prototype, funcToString = funcProto.toString, hasOwnProperty = objectProto.hasOwnProperty, objectCtorString = funcToString.call(Object);
var baseGetTag = __webpack_require__(22), getPrototype = __webpack_require__(50), isObjectLike = __webpack_require__(18), objectProto = Object.prototype, funcToString = Function.prototype.toString, hasOwnProperty = objectProto.hasOwnProperty, objectCtorString = funcToString.call(Object);
module1.exports = function(value) {
if (!isObjectLike(value) || "[object Object]" != baseGetTag(value)) return !1;
var proto = getPrototype(value);
Expand Down
Expand Up @@ -4,5 +4,7 @@ import { useProject } from "@swr/use-project";
import useTeam from "@swr/use-team";
export default function MyComp() {
var projectName = useRouter().query.project, projectInfo = useProject(projectName).data;
return useTeam().teamSlug, useProjectBranches(null == projectInfo ? void 0 : projectInfo.id).data, _jsx(_Fragment, {});
useTeam().teamSlug;
var projectId = null == projectInfo ? void 0 : projectInfo.id;
return useProjectBranches(projectId).data, _jsx(_Fragment, {});
}
Expand Up @@ -15119,7 +15119,7 @@
module.exports = baseIsMap;
},
8458: function(module, __unused_webpack_exports, __webpack_require__) {
var isFunction = __webpack_require__(3560), isMasked = __webpack_require__(5346), isObject = __webpack_require__(3218), toSource = __webpack_require__(346), reRegExpChar = /[\\^$.*+?()[\]{}|]/g, reIsHostCtor = /^\[object .+?Constructor\]$/, funcProto = Function.prototype, objectProto = Object.prototype, funcToString = funcProto.toString, hasOwnProperty = objectProto.hasOwnProperty, reIsNative = RegExp('^' + funcToString.call(hasOwnProperty).replace(reRegExpChar, '\\$&').replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$');
var isFunction = __webpack_require__(3560), isMasked = __webpack_require__(5346), isObject = __webpack_require__(3218), toSource = __webpack_require__(346), reRegExpChar = /[\\^$.*+?()[\]{}|]/g, reIsHostCtor = /^\[object .+?Constructor\]$/, objectProto = Object.prototype, funcToString = Function.prototype.toString, hasOwnProperty = objectProto.hasOwnProperty, reIsNative = RegExp('^' + funcToString.call(hasOwnProperty).replace(reRegExpChar, '\\$&').replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$');
function baseIsNative(value) {
return !(!isObject(value) || isMasked(value)) && (isFunction(value) ? reIsNative : reIsHostCtor).test(toSource(value));
}
Expand Down
@@ -1,6 +1,6 @@
function setCurrentlyValidatingElement$1(element) {
if (element) {
var owner = element._owner;
setExtraStackFrame(describeUnknownElementTypeFrameInDEV(element.type, element._source, owner ? owner.type : null));
var owner = element._owner, stack = describeUnknownElementTypeFrameInDEV(element.type, element._source, owner ? owner.type : null);
setExtraStackFrame(stack);
} else setExtraStackFrame(null);
}
Expand Up @@ -24,7 +24,11 @@ function validatePropTypes(element) {
!error$1 || error$1 instanceof Error || (setCurrentlyValidatingElement(element), error("%s: type specification of %s `%s` is invalid; the type checker function must return `null` or an `Error` but returned a %s. You may have forgotten to pass an argument to the type checker creator (arrayOf, instanceOf, objectOf, oneOf, oneOfType, and shape all require an argument).", componentName || "React class", location, typeSpecName, typeof error$1), setCurrentlyValidatingElement(null)), error$1 instanceof Error && !(error$1.message in loggedTypeFailures) && (loggedTypeFailures[error$1.message] = !0, setCurrentlyValidatingElement(element), error("Failed %s type: %s", location, error$1.message), setCurrentlyValidatingElement(null));
}
}(propTypes, element.props, "prop", name, element);
} else void 0 === type.PropTypes || propTypesMisspellWarningShown || (propTypesMisspellWarningShown = !0, error("Component %s declared `PropTypes` instead of `propTypes`. Did you misspell the property assignment?", getComponentName(type) || "Unknown"));
} else if (void 0 !== type.PropTypes && !propTypesMisspellWarningShown) {
propTypesMisspellWarningShown = !0;
var _name = getComponentName(type);
error("Component %s declared `PropTypes` instead of `propTypes`. Did you misspell the property assignment?", _name || "Unknown");
}
"function" != typeof type.getDefaultProps || type.getDefaultProps.isReactClassApproved || error("getDefaultProps is only used on classic React.createClass definitions. Use a static property named `defaultProps` instead.");
}
}
Expand Up @@ -26,13 +26,13 @@ function mapIntoArray(children, array, escapedPrefix, nameSoFar, callback) {
return 1;
}
var subtreeCount = 0, nextNamePrefix = "" === nameSoFar ? "." : nameSoFar + SUBSEPARATOR;
if (Array.isArray(children)) for(var i = 0; i < children.length; i++)nextName = nextNamePrefix + getElementKey(child = children[i], i), subtreeCount += mapIntoArray(child, array, escapedPrefix, nextName, callback);
if (Array.isArray(children)) for(var i = 0; i < children.length; i++)child = children[i], nextName = nextNamePrefix + getElementKey(child, i), subtreeCount += mapIntoArray(child, array, escapedPrefix, nextName, callback);
else {
var iteratorFn = getIteratorFn(children);
if ("function" == typeof iteratorFn) {
var child, nextName, step, iterableChildren = children;
iteratorFn === iterableChildren.entries && (didWarnAboutMaps || warn("Using Maps as children is not supported. Use an array of keyed ReactElements instead."), didWarnAboutMaps = !0);
for(var iterator = iteratorFn.call(iterableChildren), ii = 0; !(step = iterator.next()).done;)nextName = nextNamePrefix + getElementKey(child = step.value, ii++), subtreeCount += mapIntoArray(child, array, escapedPrefix, nextName, callback);
for(var iterator = iteratorFn.call(iterableChildren), ii = 0; !(step = iterator.next()).done;)child = step.value, nextName = nextNamePrefix + getElementKey(child, ii++), subtreeCount += mapIntoArray(child, array, escapedPrefix, nextName, callback);
} else if ("object" === type) {
var childrenString = "" + children;
throw Error("Objects are not valid as a React child (found: " + ("[object Object]" === childrenString ? "object with keys {" + Object.keys(children).join(", ") + "}" : childrenString) + "). If you meant to render a collection of children, use an array instead.");
Expand Down
5 changes: 4 additions & 1 deletion crates/swc_ecma_minifier/tests/fixture/reduced/3/output.js
@@ -1,2 +1,5 @@
var element = jqLite(element);
if (element.injector()) throw ngMinErr("btstrpd", "App Already Bootstrapped with this Element '{0}'", element[0] === document ? "document" : startingTag(element));
if (element.injector()) {
var tag = element[0] === document ? "document" : startingTag(element);
throw ngMinErr("btstrpd", "App Already Bootstrapped with this Element '{0}'", tag);
}
1 change: 1 addition & 0 deletions crates/swc_ecma_minifier/tests/passing.txt
Expand Up @@ -148,6 +148,7 @@ collapse_vars/collapse_vars_properties/input.js
collapse_vars/collapse_vars_regexp/input.js
collapse_vars/collapse_vars_self_reference/input.js
collapse_vars/collapse_vars_seq/input.js
collapse_vars/collapse_vars_side_effects_2/input.js
collapse_vars/collapse_vars_throw/input.js
collapse_vars/collapse_vars_try/input.js
collapse_vars/collapse_vars_unary_2/input.js
Expand Down
@@ -1,5 +1,4 @@
console.log(
(function n(o) {
return x(y(n(o)));
})(c)
);
console.log(function n(o) {
var r;
return x((r = o, y(n(r))));
}(c));

1 comment on commit c5fb774

@github-actions
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Benchmark

Benchmark suite Current: c5fb774 Previous: 51e935e Ratio
es/full/minify/libraries/antd 2094328030 ns/iter (± 129335348) 1997747508 ns/iter (± 33051380) 1.05
es/full/minify/libraries/d3 376506083 ns/iter (± 26660409) 394111173 ns/iter (± 14322295) 0.96
es/full/minify/libraries/echarts 1571798858 ns/iter (± 136902642) 1515866725 ns/iter (± 26755333) 1.04
es/full/minify/libraries/jquery 102795240 ns/iter (± 17538307) 94471586 ns/iter (± 3537167) 1.09
es/full/minify/libraries/lodash 114068275 ns/iter (± 2827714) 124284697 ns/iter (± 3246706) 0.92
es/full/minify/libraries/moment 52251785 ns/iter (± 1250420) 55206043 ns/iter (± 2454398) 0.95
es/full/minify/libraries/react 22656378 ns/iter (± 2283777) 20124855 ns/iter (± 478926) 1.13
es/full/minify/libraries/terser 319431133 ns/iter (± 42625519) 304196856 ns/iter (± 8324871) 1.05
es/full/minify/libraries/three 596442752 ns/iter (± 132817412) 517714404 ns/iter (± 16127325) 1.15
es/full/minify/libraries/typescript 3419017243 ns/iter (± 157753282) 3397829595 ns/iter (± 137925066) 1.01
es/full/minify/libraries/victory 780752659 ns/iter (± 11018167) 786785904 ns/iter (± 47403482) 0.99
es/full/minify/libraries/vue 143968224 ns/iter (± 10070664) 185897872 ns/iter (± 63095804) 0.77
es/full/codegen/es3 35061 ns/iter (± 2855) 34230 ns/iter (± 1900) 1.02
es/full/codegen/es5 34533 ns/iter (± 2480) 34597 ns/iter (± 3899) 1.00
es/full/codegen/es2015 34595 ns/iter (± 3024) 33862 ns/iter (± 760) 1.02
es/full/codegen/es2016 35409 ns/iter (± 4733) 33732 ns/iter (± 791) 1.05
es/full/codegen/es2017 34915 ns/iter (± 1999) 34100 ns/iter (± 1170) 1.02
es/full/codegen/es2018 35486 ns/iter (± 2781) 34041 ns/iter (± 1288) 1.04
es/full/codegen/es2019 35080 ns/iter (± 6583) 33930 ns/iter (± 1213) 1.03
es/full/codegen/es2020 34763 ns/iter (± 8534) 34161 ns/iter (± 1949) 1.02
es/full/all/es3 226992374 ns/iter (± 24107119) 210590664 ns/iter (± 12246497) 1.08
es/full/all/es5 187755036 ns/iter (± 18028554) 180812011 ns/iter (± 10085557) 1.04
es/full/all/es2015 149688452 ns/iter (± 13151111) 147516001 ns/iter (± 7182205) 1.01
es/full/all/es2016 154771277 ns/iter (± 28261866) 148839453 ns/iter (± 12373104) 1.04
es/full/all/es2017 165910761 ns/iter (± 20555440) 161912009 ns/iter (± 12536180) 1.02
es/full/all/es2018 146397418 ns/iter (± 27927707) 143113620 ns/iter (± 9285824) 1.02
es/full/all/es2019 157410143 ns/iter (± 17267880) 144692920 ns/iter (± 12466087) 1.09
es/full/all/es2020 141048301 ns/iter (± 12532030) 140915806 ns/iter (± 8079051) 1.00
es/full/parser 746663 ns/iter (± 58993) 738163 ns/iter (± 26148) 1.01
es/full/base/fixer 27181 ns/iter (± 1992) 26430 ns/iter (± 857) 1.03
es/full/base/resolver_and_hygiene 97142 ns/iter (± 4050) 93923 ns/iter (± 3597) 1.03
serialization of ast node 219 ns/iter (± 11) 224 ns/iter (± 8) 0.98
serialization of serde 221 ns/iter (± 3) 220 ns/iter (± 6) 1.00

This comment was automatically generated by workflow using github-action-benchmark.

Please sign in to comment.