Skip to content

Commit

Permalink
fix(es/es2015): Fix typeof comparions with "object" (#8976)
Browse files Browse the repository at this point in the history
**Related issue:**

 - Closes #8971
  • Loading branch information
kdy1 committed May 26, 2024
1 parent 7c62a79 commit 51e0639
Show file tree
Hide file tree
Showing 21 changed files with 128 additions and 32 deletions.
4 changes: 2 additions & 2 deletions crates/swc/tests/fixture/issues-2xxx/2056/1/output/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ export var preTransforms = Object.freeze([
_classCallCheck(this, Mat4);
var _this;
_this = _possibleConstructorReturn(this, _getPrototypeOf(Mat4).call(this));
if (m00 && typeof m00 === "object") {
if (m00 && (typeof m00 === "undefined" ? "undefined" : _type_of(m00)) === "object") {
if (ArrayBuffer.isView(m00)) {
_this._array = m00;
_this._array.set([
Expand Down Expand Up @@ -399,7 +399,7 @@ export var preTransforms = Object.freeze([
key: "set",
value: function set(param, param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11, param12, param13, param14, param15) {
var m00 = param === void 0 ? 1 : param, m01 = param1 === void 0 ? 0 : param1, m02 = param2 === void 0 ? 0 : param2, m03 = param3 === void 0 ? 0 : param3, m04 = param4 === void 0 ? 0 : param4, m05 = param5 === void 0 ? 1 : param5, m06 = param6 === void 0 ? 0 : param6, m07 = param7 === void 0 ? 0 : param7, m08 = param8 === void 0 ? 0 : param8, m09 = param9 === void 0 ? 0 : param9, m10 = param10 === void 0 ? 1 : param10, m11 = param11 === void 0 ? 0 : param11, m12 = param12 === void 0 ? 0 : param12, m13 = param13 === void 0 ? 0 : param13, m14 = param14 === void 0 ? 0 : param14, m15 = param15 === void 0 ? 1 : param15;
if (m00 && typeof m00 === "object") {
if (m00 && (typeof m00 === "undefined" ? "undefined" : _type_of(m00)) === "object") {
var v = m00.array;
this._array[1] = v[1];
this._array[2] = v[2];
Expand Down
3 changes: 2 additions & 1 deletion crates/swc/tests/fixture/issues-8xxx/8616/output/1.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
var _type_of = require("@swc/helpers/_/_type_of");
var Module = (function() {
var _scriptDir = typeof document !== 'undefined' && document.currentScript ? document.currentScript.src : undefined;
if (typeof __filename !== 'undefined') _scriptDir || (_scriptDir = __filename);
Expand All @@ -13,7 +14,7 @@ var Module = (function() {
return moduleArg;
};
})()();
if (typeof exports === 'object' && typeof module === 'object') module.exports = Module;
if ((typeof exports === "undefined" ? "undefined" : _type_of._(exports)) === 'object' && (typeof module === "undefined" ? "undefined" : _type_of._(module)) === 'object') module.exports = Module;
else if (typeof define === 'function' && define['amd']) define([], function() {
return Module;
});
65 changes: 65 additions & 0 deletions crates/swc/tests/fixture/issues-8xxx/8971/input/.swcrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
{
"jsc": {
"parser": {
"syntax": "ecmascript",
"jsx": false
},
"target": "es5",
"loose": false,
"minify": {
"compress": {
"arguments": false,
"arrows": true,
"booleans": true,
"booleans_as_integers": false,
"collapse_vars": true,
"comparisons": true,
"computed_props": true,
"conditionals": true,
"dead_code": true,
"directives": true,
"drop_console": false,
"drop_debugger": true,
"evaluate": true,
"expression": false,
"hoist_funs": false,
"hoist_props": true,
"hoist_vars": false,
"if_return": true,
"join_vars": true,
"keep_classnames": false,
"keep_fargs": true,
"keep_fnames": false,
"keep_infinity": false,
"loops": true,
"negate_iife": true,
"properties": true,
"reduce_funcs": false,
"reduce_vars": false,
"side_effects": true,
"switches": true,
"typeofs": true,
"unsafe": false,
"unsafe_arrows": false,
"unsafe_comps": false,
"unsafe_Function": false,
"unsafe_math": false,
"unsafe_symbols": true,
"unsafe_methods": false,
"unsafe_proto": false,
"unsafe_regexp": false,
"unsafe_undefined": false,
"unused": true,
"const_to_let": true,
"pristine_globals": true
},
"mangle": false
},
"externalHelpers": true
},
"module": {
"type": "es6"
},
"minify": false,
"isModule": true
}
7 changes: 7 additions & 0 deletions crates/swc/tests/fixture/issues-8xxx/8971/input/1.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
export function f() {
return [
typeof a === 'object', /* if a is a polyfilled symbol the result is wrong */
typeof b === 'symbol',
typeof c
]
}
8 changes: 8 additions & 0 deletions crates/swc/tests/fixture/issues-8xxx/8971/output/1.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { _ as _type_of } from "@swc/helpers/_/_type_of";
export function f() {
return [
("undefined" == typeof a ? "undefined" : _type_of(a)) === 'object',
("undefined" == typeof b ? "undefined" : _type_of(b)) === 'symbol',
"undefined" == typeof c ? "undefined" : _type_of(c)
];
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
//// [TypeGuardWithEnumUnion.ts]
import { _ as _type_of } from "@swc/helpers/_/_type_of";
var Color;
(function(Color) {
Color[Color["R"] = 0] = "R";
Expand All @@ -15,7 +16,7 @@ function f1(x) {
}
}
function f2(x) {
if (typeof x === "object") {
if ((typeof x === "undefined" ? "undefined" : _type_of(x)) === "object") {
var y = x;
var y;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
//// [TypeGuardWithEnumUnion.ts]
var Color, Color1;
import "@swc/helpers/_/_type_of";
(Color1 = Color || (Color = {}))[Color1.R = 0] = "R", Color1[Color1.G = 1] = "G", Color1[Color1.B = 2] = "B";
Original file line number Diff line number Diff line change
@@ -1,33 +1,34 @@
//// [controlFlowTypeofObject.ts]
import { _ as _type_of } from "@swc/helpers/_/_type_of";
function f1(x) {
if (!x) {
return;
}
if (typeof x === 'object') {
if ((typeof x === "undefined" ? "undefined" : _type_of(x)) === 'object') {
obj(x);
}
}
function f2(x) {
if (x === null) {
return;
}
if (typeof x === 'object') {
if ((typeof x === "undefined" ? "undefined" : _type_of(x)) === 'object') {
obj(x);
}
}
function f3(x) {
if (x == null) {
return;
}
if (typeof x === 'object') {
if ((typeof x === "undefined" ? "undefined" : _type_of(x)) === 'object') {
obj(x);
}
}
function f4(x) {
if (x == undefined) {
return;
}
if (typeof x === 'object') {
if ((typeof x === "undefined" ? "undefined" : _type_of(x)) === 'object') {
obj(x);
}
}
Expand All @@ -41,7 +42,7 @@ function f5(x) {
return;
}
}
if (typeof x === 'object') {
if ((typeof x === "undefined" ? "undefined" : _type_of(x)) === 'object') {
obj(x);
}
}
Expand All @@ -50,11 +51,11 @@ function f6(x) {
x;
} else {
x;
if (typeof x === 'object') {
if ((typeof x === "undefined" ? "undefined" : _type_of(x)) === 'object') {
obj(x);
}
}
if (typeof x === 'object') {
if ((typeof x === "undefined" ? "undefined" : _type_of(x)) === 'object') {
obj(x); // Error
}
}
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
//// [controlFlowTypeofObject.ts]
import "@swc/helpers/_/_type_of";
3 changes: 2 additions & 1 deletion crates/swc/tests/tsc-references/mappedTypes4.1.normal.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
//// [mappedTypes4.ts]
import { _ as _type_of } from "@swc/helpers/_/_type_of";
function boxify(obj) {
if (typeof obj === "object") {
if ((typeof obj === "undefined" ? "undefined" : _type_of(obj)) === "object") {
var result = {};
for(var k in obj){
result[k] = {
Expand Down
1 change: 1 addition & 0 deletions crates/swc/tests/tsc-references/mappedTypes4.2.minified.js
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
//// [mappedTypes4.ts]
import "@swc/helpers/_/_type_of";
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
//// [nonPrimitiveNarrow.ts]
import { _ as _class_call_check } from "@swc/helpers/_/_class_call_check";
import { _ as _instanceof } from "@swc/helpers/_/_instanceof";
import { _ as _type_of } from "@swc/helpers/_/_type_of";
var Narrow = function Narrow() {
"use strict";
_class_call_check(this, Narrow);
Expand All @@ -14,7 +15,7 @@ if (typeof a === 'number') {
a.toFixed(); // error, never
}
var b;
if (typeof b === 'object') {
if ((typeof b === "undefined" ? "undefined" : _type_of(b)) === 'object') {
b.toString(); // ok, object | null
} else {
b.toString(); // error, never
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
var a, b;
import { _ as _class_call_check } from "@swc/helpers/_/_class_call_check";
import { _ as _instanceof } from "@swc/helpers/_/_instanceof";
import { _ as _type_of } from "@swc/helpers/_/_type_of";
_instanceof(a, function Narrow() {
_class_call_check(this, Narrow);
}) && (a.narrowed, a = 123), 'number' == typeof a && a.toFixed(), b.toString();
}) && (a.narrowed, a = 123), 'number' == typeof a && a.toFixed(), void 0 === b || _type_of(b), b.toString();
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
//// [typeGuardOfFormTypeOfFunction.ts]
import { _ as _type_of } from "@swc/helpers/_/_type_of";
function f1(x) {
if (typeof x === "function") {
x; // any
Expand Down Expand Up @@ -82,5 +83,5 @@ function configureStore(reducer) {
}
}
function f101(x) {
return typeof x === "object" && x.anything;
return (typeof x === "undefined" ? "undefined" : _type_of(x)) === "object" && x.anything;
}
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
//// [typeGuardOfFormTypeOfFunction.ts]
import "@swc/helpers/_/_type_of";
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
//// [typeGuardsWithAny.ts]
import { _ as _instanceof } from "@swc/helpers/_/_instanceof";
import { _ as _type_of } from "@swc/helpers/_/_type_of";
var x = {
p: 0
};
Expand All @@ -23,7 +24,7 @@ if (typeof x === "boolean") {
} else {
x.p; // No error, type unaffected in this branch
}
if (typeof x === "object") {
if ((typeof x === "undefined" ? "undefined" : _type_of(x)) === "object") {
x.p; // No error, type any only affected by primitive type check
} else {
x.p; // No error, type unaffected in this branch
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
//// [typeGuardsWithAny.ts]
import { _ as _instanceof } from "@swc/helpers/_/_instanceof";
import { _ as _type_of } from "@swc/helpers/_/_type_of";
var x = {
p: 0
};
_instanceof(x, Object), x.p, x.p, x.p, x.p, x.p;
_instanceof(x, Object), x.p, x.p, x.p, x.p, _type_of(x), x.p;
13 changes: 7 additions & 6 deletions crates/swc/tests/tsc-references/unknownControlFlow.1.normal.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
//// [unknownControlFlow.ts]
import { _ as _type_of } from "@swc/helpers/_/_type_of";
function f01(u) {
var x1 = u; // Error
var x2 = u;
Expand Down Expand Up @@ -132,23 +133,23 @@ function f23(x) {
}
}
function f30(x) {
if (typeof x === "object") {
if ((typeof x === "undefined" ? "undefined" : _type_of(x)) === "object") {
x; // object
}
}
function f31(x) {
if (typeof x === "object") {
if ((typeof x === "undefined" ? "undefined" : _type_of(x)) === "object") {
x; // T & object | T & null
}
if (x && typeof x === "object") {
if (x && (typeof x === "undefined" ? "undefined" : _type_of(x)) === "object") {
x; // T & object
}
if (typeof x === "object" && x) {
if ((typeof x === "undefined" ? "undefined" : _type_of(x)) === "object" && x) {
x; // T & object
}
}
function f32(x) {
if (typeof x === "object") {
if ((typeof x === "undefined" ? "undefined" : _type_of(x)) === "object") {
x; // T & object
}
}
Expand Down Expand Up @@ -189,7 +190,7 @@ function f41(a) {
}
// Repro from #48468
function deepEquals(a, b) {
if (typeof a !== 'object' || typeof b !== 'object' || !a || !b) {
if ((typeof a === "undefined" ? "undefined" : _type_of(a)) !== 'object' || (typeof b === "undefined" ? "undefined" : _type_of(b)) !== 'object' || !a || !b) {
return false;
}
if (Array.isArray(a) || Array.isArray(b)) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
//// [unknownControlFlow.ts]
import "@swc/helpers/_/_type_of";
null.foo, null.foo, null.foo, null.foo;
17 changes: 9 additions & 8 deletions crates/swc/tests/vercel/full/ms/1/output/index.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
export default function(s, c) {
var a, r;
import { _ as e } from "@swc/helpers/_/_type_of";
export default function(c, a) {
var r, n;
try {
if ("string" == typeof s && s.length > 0) return function(e) {
if ("string" == typeof c && c.length > 0) return function(e) {
if ((e = String(e)).length > 100) throw Error("Value exceeds the maximum length of 100 characters.");
var s = /^(-?(?:\d+)?\.?\d+) *(milliseconds?|msecs?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|weeks?|w|years?|yrs?|y)?$/i.exec(e);
if (!s) return NaN;
Expand Down Expand Up @@ -48,13 +49,13 @@ export default function(s, c) {
default:
throw Error("The unit ".concat(a, " was matched, but no matching case exists."));
}
}(s);
if ("number" == typeof s && isFinite(s)) return (null == c ? void 0 : c.long) ? (a = Math.abs(s)) >= 86400000 ? e(s, a, 86400000, "day") : a >= 3600000 ? e(s, a, 3600000, "hour") : a >= 60000 ? e(s, a, 60000, "minute") : a >= 1000 ? e(s, a, 1000, "second") : "".concat(s, " ms") : (r = Math.abs(s)) >= 86400000 ? "".concat(Math.round(s / 86400000), "d") : r >= 3600000 ? "".concat(Math.round(s / 3600000), "h") : r >= 60000 ? "".concat(Math.round(s / 60000), "m") : r >= 1000 ? "".concat(Math.round(s / 1000), "s") : "".concat(s, "ms");
}(c);
if ("number" == typeof c && isFinite(c)) return (null == a ? void 0 : a.long) ? (r = Math.abs(c)) >= 86400000 ? s(c, r, 86400000, "day") : r >= 3600000 ? s(c, r, 3600000, "hour") : r >= 60000 ? s(c, r, 60000, "minute") : r >= 1000 ? s(c, r, 1000, "second") : "".concat(c, " ms") : (n = Math.abs(c)) >= 86400000 ? "".concat(Math.round(c / 86400000), "d") : n >= 3600000 ? "".concat(Math.round(c / 3600000), "h") : n >= 60000 ? "".concat(Math.round(c / 60000), "m") : n >= 1000 ? "".concat(Math.round(c / 1000), "s") : "".concat(c, "ms");
throw Error("Value is not a string or number.");
} catch (e) {
throw Error("object" == typeof e && null !== e && "message" in e ? "".concat(e.message, ". value=").concat(JSON.stringify(s)) : "An unknown error has occurred.");
} catch (s) {
throw Error((void 0 === s ? "undefined" : e(s)) === "object" && null !== s && "message" in s ? "".concat(s.message, ". value=").concat(JSON.stringify(c)) : "An unknown error has occurred.");
}
}
function e(e, s, c, a) {
function s(e, s, c, a) {
return "".concat(Math.round(e / c), " ").concat(a).concat(s >= 1.5 * c ? "s" : "");
}
2 changes: 1 addition & 1 deletion crates/swc_ecma_compat_es2015/src/typeof_symbol.rs
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ fn is_non_symbol_literal(e: &Expr) -> bool {
match e {
Expr::Lit(Lit::Str(Str { value, .. })) => matches!(
&**value,
"undefined" | "object" | "boolean" | "number" | "string" | "function"
"undefined" | "boolean" | "number" | "string" | "function"
),
_ => false,
}
Expand Down

0 comments on commit 51e0639

Please sign in to comment.