From ad960c76c059fbd33de1cdb0525aef509124e205 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Donny/=EA=B0=95=EB=8F=99=EC=9C=A4?= Date: Wed, 12 Oct 2022 08:06:58 +0900 Subject: [PATCH] feat(es/minifier): Detect type of `.length` (#6120) **Description:** This PR updates minifier to detect the type of `xxx.length` if possible. --- .../full-compact/d3-color/1/output/index.js | 2 +- .../vercel/full/d3-color/1/output/index.js | 2 +- crates/swc_ecma_minifier/src/alias/mod.rs | 16 ++---- .../src/compress/optimize/sequences.rs | 9 ++-- .../src/compress/optimize/unused.rs | 7 +-- .../src/compress/pure/misc.rs | 9 ++-- .../src/compress/util/mod.rs | 45 ---------------- crates/swc_ecma_minifier/src/util/mod.rs | 53 ++++++++++++++++++- .../tests/benches-full/d3.js | 20 +++---- .../tests/benches-full/jquery.js | 2 +- .../tests/benches-full/moment.js | 2 +- .../tests/benches-full/victory.js | 14 ++--- .../tests/benches-full/vue.js | 2 +- .../tests/fixture/issues/2257/full/output.js | 2 +- .../tests/fixture/issues/d3-color/1/output.js | 2 +- .../fixture/issues/d3-time-format/3/output.js | 2 +- .../tests/fixture/issues/moment/1/output.js | 2 +- .../d6e1aeb5-38a8d7ae57119c23/output.js | 4 +- .../pages/index-cb36c1bf7f830e3c/output.js | 6 +-- .../pages/_app-72ad41192608e93a/output.js | 2 +- .../fixture/next/react-pdf-renderer/output.js | 18 +++---- .../fixture/next/wrap-contracts/output.js | 8 +-- .../tests/projects/output/jquery-1.9.1.js | 4 +- .../projects/output/jquery.mobile-1.4.2.js | 2 +- .../tests/projects/output/underscore-1.5.2.js | 3 +- crates/swc_ecma_utils/src/lib.rs | 20 ++++++- 26 files changed, 136 insertions(+), 122 deletions(-) diff --git a/crates/swc/tests/vercel/full-compact/d3-color/1/output/index.js b/crates/swc/tests/vercel/full-compact/d3-color/1/output/index.js index 66dea3fd8b0..28540b8c111 100644 --- a/crates/swc/tests/vercel/full-compact/d3-color/1/output/index.js +++ b/crates/swc/tests/vercel/full-compact/d3-color/1/output/index.js @@ -1 +1 @@ -import t from"@swc/helpers/src/_instanceof.mjs";import{Color as i,rgbConvert as e,Rgb as h}from"./color.js";var r=Math.PI/180,n=180/Math.PI,s=-1.78277*.29227-.1347134789;export default function o(i,r,o,a){return 1===arguments.length?function(i){if(t(i,Cubehelix))return new Cubehelix(i.h,i.s,i.l,i.opacity);t(i,h)||(i=e(i));var r=i.r/255,o=i.g/255,a=i.b/255,u=(s*a+-1.7884503806*r-3.5172982438*o)/(s+-1.7884503806-3.5172982438),c=a-u,l=-((1.97294*(o-u)- -.29227*c)/.90649),p=Math.sqrt(l*l+c*c)/(1.97294*u*(1-u)),f=p?Math.atan2(l,c)*n-120:NaN;return new Cubehelix(f<0?f+360:f,p,u,i.opacity)}(i):new Cubehelix(i,r,o,null==a?1:a)}export function Cubehelix(t,i,e,h){this.h=+t,this.s=+i,this.l=+e,this.opacity=+h}!function(t,i,e){t.prototype=i.prototype=e,e.constructor=t}(Cubehelix,o,function(t,i){var e=Object.create(t.prototype);for(var h in i)e[h]=i[h];return e}(i,{brighter:function(t){return t=null==t?1.4285714285714286:Math.pow(1.4285714285714286,t),new Cubehelix(this.h,this.s,this.l*t,this.opacity)},darker:function(t){return t=null==t?.7:Math.pow(.7,t),new Cubehelix(this.h,this.s,this.l*t,this.opacity)},rgb:function(){var t=isNaN(this.h)?0:(this.h+120)*r,i=+this.l,e=isNaN(this.s)?0:this.s*i*(1-i),n=Math.cos(t),s=Math.sin(t);return new h(255*(i+e*(-.14861*n+1.78277*s)),255*(i+e*(-.29227*n+-.90649*s)),255*(i+e*(1.97294*n)),this.opacity)}})); +import t from"@swc/helpers/src/_instanceof.mjs";import{Color as i,rgbConvert as e,Rgb as h}from"./color.js";var r=Math.PI/180,n=180/Math.PI,s=-1.78277*.29227-.1347134789;export default function o(i,r,o,a){return 1==arguments.length?function(i){if(t(i,Cubehelix))return new Cubehelix(i.h,i.s,i.l,i.opacity);t(i,h)||(i=e(i));var r=i.r/255,o=i.g/255,a=i.b/255,u=(s*a+-1.7884503806*r-3.5172982438*o)/(s+-1.7884503806-3.5172982438),c=a-u,l=-((1.97294*(o-u)- -.29227*c)/.90649),p=Math.sqrt(l*l+c*c)/(1.97294*u*(1-u)),f=p?Math.atan2(l,c)*n-120:NaN;return new Cubehelix(f<0?f+360:f,p,u,i.opacity)}(i):new Cubehelix(i,r,o,null==a?1:a)}export function Cubehelix(t,i,e,h){this.h=+t,this.s=+i,this.l=+e,this.opacity=+h}!function(t,i,e){t.prototype=i.prototype=e,e.constructor=t}(Cubehelix,o,function(t,i){var e=Object.create(t.prototype);for(var h in i)e[h]=i[h];return e}(i,{brighter:function(t){return t=null==t?1.4285714285714286:Math.pow(1.4285714285714286,t),new Cubehelix(this.h,this.s,this.l*t,this.opacity)},darker:function(t){return t=null==t?.7:Math.pow(.7,t),new Cubehelix(this.h,this.s,this.l*t,this.opacity)},rgb:function(){var t=isNaN(this.h)?0:(this.h+120)*r,i=+this.l,e=isNaN(this.s)?0:this.s*i*(1-i),n=Math.cos(t),s=Math.sin(t);return new h(255*(i+e*(-.14861*n+1.78277*s)),255*(i+e*(-.29227*n+-.90649*s)),255*(i+e*(1.97294*n)),this.opacity)}})); diff --git a/crates/swc/tests/vercel/full/d3-color/1/output/index.js b/crates/swc/tests/vercel/full/d3-color/1/output/index.js index 86da92cebdc..27e81e22155 100644 --- a/crates/swc/tests/vercel/full/d3-color/1/output/index.js +++ b/crates/swc/tests/vercel/full/d3-color/1/output/index.js @@ -4,7 +4,7 @@ import { Color as e, rgbConvert as s, Rgb as r, darker as n, brighter as o } fro import { deg2rad as a, rad2deg as u } from "./math.js"; var l = -1.78277 * 0.29227 - 0.1347134789; export default function c(i, h, e, n) { - return 1 === arguments.length ? function(i) { + return 1 == arguments.length ? function(i) { if (t(i, Cubehelix)) return new Cubehelix(i.h, i.s, i.l, i.opacity); t(i, r) || (i = s(i)); var h = i.r / 255, e = i.g / 255, n = i.b / 255, o = (l * n + -1.7884503806 * h - 3.5172982438 * e) / (l + -1.7884503806 - 3.5172982438), a = n - o, c = -((1.97294 * (e - o) - -0.29227 * a) / 0.90649), p = Math.sqrt(c * c + a * a) / (1.97294 * o * (1 - o)), f = p ? Math.atan2(c, a) * u - 120 : NaN; diff --git a/crates/swc_ecma_minifier/src/alias/mod.rs b/crates/swc_ecma_minifier/src/alias/mod.rs index 42e92a3e3dd..827ab3e6c6b 100644 --- a/crates/swc_ecma_minifier/src/alias/mod.rs +++ b/crates/swc_ecma_minifier/src/alias/mod.rs @@ -1,14 +1,13 @@ #![allow(clippy::needless_update)] use rustc_hash::FxHashSet; -use swc_atoms::js_word; use swc_common::{collections::AHashSet, SyntaxContext}; use swc_ecma_ast::*; use swc_ecma_utils::{collect_decls, BindingCollector}; use swc_ecma_visit::{noop_visit_type, Visit, VisitWith}; use self::ctx::Ctx; -use crate::marks::Marks; +use crate::{marks::Marks, util::is_global_var_with_pure_property_access}; mod ctx; @@ -109,17 +108,8 @@ impl InfectionCollector<'_> { } if self.unresolved_ctxt == Some(e.1) { - match e.0 { - js_word!("JSON") - | js_word!("Array") - | js_word!("String") - | js_word!("Object") - | js_word!("Number") - | js_word!("BigInt") - | js_word!("Boolean") - | js_word!("Math") - | js_word!("Error") => return, - _ => {} + if is_global_var_with_pure_property_access(&e.0) { + return; } } diff --git a/crates/swc_ecma_minifier/src/compress/optimize/sequences.rs b/crates/swc_ecma_minifier/src/compress/optimize/sequences.rs index 2913eb3a69c..d296a817730 100644 --- a/crates/swc_ecma_minifier/src/compress/optimize/sequences.rs +++ b/crates/swc_ecma_minifier/src/compress/optimize/sequences.rs @@ -20,13 +20,14 @@ use crate::{ alias::{collect_infects_from, AccessKind, AliasConfig}, compress::{ optimize::{unused::PropertyAccessOpts, util::replace_id_with_expr}, - util::{ - is_directive, is_global_var_with_pure_property_access, is_ident_used_by, replace_expr, - }, + util::{is_directive, is_ident_used_by, replace_expr}, }, mode::Mode, option::CompressOptions, - util::{idents_used_by, idents_used_by_ignoring_nested, ExprOptExt, ModuleItemExt}, + util::{ + idents_used_by, idents_used_by_ignoring_nested, is_global_var_with_pure_property_access, + ExprOptExt, ModuleItemExt, + }, }; /// Methods related to the option `sequences`. All methods are noop if diff --git a/crates/swc_ecma_minifier/src/compress/optimize/unused.rs b/crates/swc_ecma_minifier/src/compress/optimize/unused.rs index 5e24c98b5f1..c580eacbec3 100644 --- a/crates/swc_ecma_minifier/src/compress/optimize/unused.rs +++ b/crates/swc_ecma_minifier/src/compress/optimize/unused.rs @@ -7,11 +7,8 @@ use super::Optimizer; #[cfg(feature = "debug")] use crate::debug::dump; use crate::{ - compress::{ - optimize::util::extract_class_side_effect, util::is_global_var_with_pure_property_access, - }, - mode::Mode, - option::PureGetterOption, + compress::optimize::util::extract_class_side_effect, mode::Mode, option::PureGetterOption, + util::is_global_var_with_pure_property_access, }; #[derive(Debug, Default, Clone, Copy)] diff --git a/crates/swc_ecma_minifier/src/compress/pure/misc.rs b/crates/swc_ecma_minifier/src/compress/pure/misc.rs index fb735bf02bf..3539c62830b 100644 --- a/crates/swc_ecma_minifier/src/compress/pure/misc.rs +++ b/crates/swc_ecma_minifier/src/compress/pure/misc.rs @@ -9,9 +9,12 @@ use swc_ecma_utils::{ }; use super::Pure; -use crate::compress::{ - pure::strings::{convert_str_value_to_tpl_cooked, convert_str_value_to_tpl_raw}, - util::{is_global_var_with_pure_property_access, is_pure_undefined}, +use crate::{ + compress::{ + pure::strings::{convert_str_value_to_tpl_cooked, convert_str_value_to_tpl_raw}, + util::is_pure_undefined, + }, + util::is_global_var_with_pure_property_access, }; impl Pure<'_> { diff --git a/crates/swc_ecma_minifier/src/compress/util/mod.rs b/crates/swc_ecma_minifier/src/compress/util/mod.rs index 337171051e7..0cda374caa7 100644 --- a/crates/swc_ecma_minifier/src/compress/util/mod.rs +++ b/crates/swc_ecma_minifier/src/compress/util/mod.rs @@ -735,51 +735,6 @@ impl VisitMut for UnreachableHandler { } } -pub(super) fn is_global_var_with_pure_property_access(s: &str) -> bool { - matches!( - s, - "console" - | "clearInterval" - | "clearTimeout" - | "setInterval" - | "setTimeout" - | "btoa" - | "Boolean" - | "Date" - | "decodeURI" - | "decodeURIComponent" - | "encodeURI" - | "encodeURIComponent" - | "escape" - | "eval" - | "Error" - | "EvalError" - | "Function" - | "isFinite" - | "isNaN" - | "JSON" - | "parseFloat" - | "parseInt" - | "RegExp" - | "RangeError" - | "ReferenceError" - | "SyntaxError" - | "TypeError" - | "unescape" - | "URIError" - | "atob" - | "globalThis" - | "String" - | "Object" - | "Array" - | "Number" - | "NaN" - | "Symbol" - | "Promise" - | "Math" - ) -} - // TODO: remove pub(crate) fn contains_super(body: &N) -> bool where diff --git a/crates/swc_ecma_minifier/src/util/mod.rs b/crates/swc_ecma_minifier/src/util/mod.rs index 982ced64585..a0d2a4b4385 100644 --- a/crates/swc_ecma_minifier/src/util/mod.rs +++ b/crates/swc_ecma_minifier/src/util/mod.rs @@ -1,7 +1,7 @@ use std::time::Instant; use rustc_hash::FxHashSet; -use swc_atoms::js_word; +use swc_atoms::{js_word, JsWord}; use swc_common::{util::take::Take, Mark, Span, Spanned, DUMMY_SP}; use swc_ecma_ast::*; use swc_ecma_utils::{ModuleItemLike, StmtLike, Value}; @@ -12,6 +12,57 @@ pub(crate) mod size; pub(crate) mod sort; pub(crate) mod unit; +pub(crate) fn is_global_var_with_pure_property_access(s: &JsWord) -> bool { + match *s { + js_word!("JSON") + | js_word!("Array") + | js_word!("String") + | js_word!("Object") + | js_word!("Number") + | js_word!("Date") + | js_word!("BigInt") + | js_word!("Boolean") + | js_word!("Math") + | js_word!("Error") => return true, + _ => {} + } + + matches!( + &**s, + "console" + | "clearInterval" + | "clearTimeout" + | "setInterval" + | "setTimeout" + | "btoa" + | "decodeURI" + | "decodeURIComponent" + | "encodeURI" + | "encodeURIComponent" + | "escape" + | "eval" + | "EvalError" + | "Function" + | "isFinite" + | "isNaN" + | "JSON" + | "parseFloat" + | "parseInt" + | "RegExp" + | "RangeError" + | "ReferenceError" + | "SyntaxError" + | "TypeError" + | "unescape" + | "URIError" + | "atob" + | "globalThis" + | "NaN" + | "Symbol" + | "Promise" + ) +} + /// pub(crate) fn make_number(span: Span, value: f64) -> Expr { trace_op!("Creating a numeric literal"); diff --git a/crates/swc_ecma_minifier/tests/benches-full/d3.js b/crates/swc_ecma_minifier/tests/benches-full/d3.js index 67e2e9b8dee..8c4c8057986 100644 --- a/crates/swc_ecma_minifier/tests/benches-full/d3.js +++ b/crates/swc_ecma_minifier/tests/benches-full/d3.js @@ -1323,7 +1323,7 @@ return (o instanceof Color || (o = color(o)), o) ? (o = o.rgb(), new Rgb(o.r, o.g, o.b, o.opacity)) : new Rgb; } function rgb(r, g, b, opacity) { - return 1 === arguments.length ? rgbConvert(r) : new Rgb(r, g, b, null == opacity ? 1 : opacity); + return 1 == arguments.length ? rgbConvert(r) : new Rgb(r, g, b, null == opacity ? 1 : opacity); } function Rgb(r, g, b, opacity) { this.r = +r, this.g = +g, this.b = +b, this.opacity = +opacity; @@ -1349,7 +1349,7 @@ return s ? (h = r === max ? (g - b) / s + (g < b) * 6 : g === max ? (b - r) / s + 2 : (r - g) / s + 4, s /= l < 0.5 ? max + min : 2 - max - min, h *= 60) : s = l > 0 && l < 1 ? 0 : h, new Hsl(h, s, l, o.opacity); } function hsl(h, s, l, opacity) { - return 1 === arguments.length ? hslConvert(h) : new Hsl(h, s, l, null == opacity ? 1 : opacity); + return 1 == arguments.length ? hslConvert(h) : new Hsl(h, s, l, null == opacity ? 1 : opacity); } function Hsl(h, s, l, opacity) { this.h = +h, this.s = +s, this.l = +l, this.opacity = +opacity; @@ -1416,7 +1416,7 @@ return r === g && g === b ? x = z = y : (x = xyz2lab((0.4360747 * r + 0.3850649 * g + 0.1430804 * b) / 0.96422), z = xyz2lab((0.0139322 * r + 0.0971045 * g + 0.7141733 * b) / 0.82521)), new Lab(116 * y - 16, 500 * (x - y), 200 * (y - z), o.opacity); } function lab(l, a, b, opacity) { - return 1 === arguments.length ? labConvert(l) : new Lab(l, a, b, null == opacity ? 1 : opacity); + return 1 == arguments.length ? labConvert(l) : new Lab(l, a, b, null == opacity ? 1 : opacity); } function Lab(l, a, b, opacity) { this.l = +l, this.a = +a, this.b = +b, this.opacity = +opacity; @@ -1440,7 +1440,7 @@ return new Hcl(h < 0 ? h + 360 : h, Math.sqrt(o.a * o.a + o.b * o.b), o.l, o.opacity); } function hcl(h, c, l, opacity) { - return 1 === arguments.length ? hclConvert(h) : new Hcl(h, c, l, null == opacity ? 1 : opacity); + return 1 == arguments.length ? hclConvert(h) : new Hcl(h, c, l, null == opacity ? 1 : opacity); } function Hcl(h, c, l, opacity) { this.h = +h, this.c = +c, this.l = +l, this.opacity = +opacity; @@ -1474,7 +1474,7 @@ })); var BC_DA = -1.78277 * 0.29227 - 0.1347134789; function cubehelix(h, s, l, opacity) { - return 1 === arguments.length ? function(o) { + return 1 == arguments.length ? function(o) { if (o instanceof Cubehelix) return new Cubehelix(o.h, o.s, o.l, o.opacity); o instanceof Rgb || (o = rgbConvert(o)); var r = o.r / 255, g = o.g / 255, b = o.b / 255, l = (BC_DA * b + -1.7884503806 * r - 3.5172982438 * g) / (BC_DA + -1.7884503806 - 3.5172982438), bl = b - l, k = -((1.97294 * (g - l) - -0.29227 * bl) / 0.90649), s = Math.sqrt(k * k + bl * bl) / (1.97294 * l * (1 - l)), h = s ? Math.atan2(k, bl) * degrees - 120 : NaN; @@ -4020,7 +4020,7 @@ } function dsvParse(parse) { return function(input, init, row) { - return 2 === arguments.length && "function" == typeof init && (row = init, init = void 0), text(input, init).then(function(response) { + return 2 == arguments.length && "function" == typeof init && (row = init, init = void 0), text(input, init).then(function(response) { return parse(response, row); }); }; @@ -6394,7 +6394,7 @@ } var defaultSource$1 = Math.random, uniform = function sourceRandomUniform(source) { function randomUniform(min, max) { - return min = null == min ? 0 : +min, max = null == max ? 1 : +max, 1 === arguments.length ? (max = min, min = 0) : max -= min, function() { + return min = null == min ? 0 : +min, max = null == max ? 1 : +max, 1 == arguments.length ? (max = min, min = 0) : max -= min, function() { return source() * max + min; }; } @@ -6873,7 +6873,7 @@ var t0$1 = new Date, t1$1 = new Date; function newInterval(floori, offseti, count, field) { function interval(date) { - return floori(date = 0 === arguments.length ? new Date : new Date(+date)), date; + return floori(date = 0 == arguments.length ? new Date : new Date(+date)), date; } return interval.floor = function(date) { return floori(date = new Date(+date)), date; @@ -9324,7 +9324,7 @@ return arguments.length ? (clickDistance2 = (_ = +_) * _, drag) : Math.sqrt(clickDistance2); }, drag; }, exports1.dragDisable = dragDisable, exports1.dragEnable = yesdrag, exports1.dsv = function(delimiter, input, init, row) { - 3 === arguments.length && "function" == typeof init && (row = init, init = void 0); + 3 == arguments.length && "function" == typeof init && (row = init, init = void 0); var format = dsvFormat(delimiter); return text(input, init).then(function(response) { return format.parse(response, row); @@ -10079,7 +10079,7 @@ }, exports1.isoFormat = formatIso, exports1.isoParse = parseIso, exports1.json = function(input, init) { return fetch(input, init).then(responseJson); }, exports1.lab = lab, exports1.lch = function(l, c, h, opacity) { - return 1 === arguments.length ? hclConvert(l) : new Hcl(h, c, l, null == opacity ? 1 : opacity); + return 1 == arguments.length ? hclConvert(l) : new Hcl(h, c, l, null == opacity ? 1 : opacity); }, exports1.least = function(values, compare = ascending) { let min; let defined = !1; diff --git a/crates/swc_ecma_minifier/tests/benches-full/jquery.js b/crates/swc_ecma_minifier/tests/benches-full/jquery.js index 3985ae470c4..5eaa01b7aa6 100644 --- a/crates/swc_ecma_minifier/tests/benches-full/jquery.js +++ b/crates/swc_ecma_minifier/tests/benches-full/jquery.js @@ -3042,7 +3042,7 @@ return this.on(types, selector, data, fn); }, undelegate: function(selector, types, fn) { - return 1 === arguments.length ? this.off(selector, "**") : this.off(types, selector || "**", fn); + return 1 == arguments.length ? this.off(selector, "**") : this.off(types, selector || "**", fn); }, hover: function(fnOver, fnOut) { return this.mouseenter(fnOver).mouseleave(fnOut || fnOver); diff --git a/crates/swc_ecma_minifier/tests/benches-full/moment.js b/crates/swc_ecma_minifier/tests/benches-full/moment.js index f68c20c0742..9bad187af26 100644 --- a/crates/swc_ecma_minifier/tests/benches-full/moment.js +++ b/crates/swc_ecma_minifier/tests/benches-full/moment.js @@ -1161,7 +1161,7 @@ return string; } proto.add = add, proto.calendar = function(time, formats) { - if (1 === arguments.length) { + if (1 == arguments.length) { if (arguments[0]) { var input, input1, arrayTest, dataTypeTest; if (input = arguments[0], isMoment(input) || isDate(input) || isString(input) || isNumber(input) || (arrayTest = isArray(input1 = input), dataTypeTest = !1, arrayTest && (dataTypeTest = 0 === input1.filter(function(item) { diff --git a/crates/swc_ecma_minifier/tests/benches-full/victory.js b/crates/swc_ecma_minifier/tests/benches-full/victory.js index ed4d28f4c3c..9c5c1964a8c 100644 --- a/crates/swc_ecma_minifier/tests/benches-full/victory.js +++ b/crates/swc_ecma_minifier/tests/benches-full/victory.js @@ -947,7 +947,7 @@ return (o instanceof Color || (o = color(o)), o) ? (o = o.rgb(), new Rgb(o.r, o.g, o.b, o.opacity)) : new Rgb; } function rgb(r, g, b, opacity) { - return 1 === arguments.length ? rgbConvert(r) : new Rgb(r, g, b, null == opacity ? 1 : opacity); + return 1 == arguments.length ? rgbConvert(r) : new Rgb(r, g, b, null == opacity ? 1 : opacity); } function Rgb(r, g, b, opacity) { this.r = +r, this.g = +g, this.b = +b, this.opacity = +opacity; @@ -973,7 +973,7 @@ return s ? (h = r === max ? (g - b) / s + (g < b) * 6 : g === max ? (b - r) / s + 2 : (r - g) / s + 4, s /= l < 0.5 ? max + min : 2 - max - min, h *= 60) : s = l > 0 && l < 1 ? 0 : h, new Hsl(h, s, l, o.opacity); } function hsl(h, s, l, opacity) { - return 1 === arguments.length ? hslConvert(h) : new Hsl(h, s, l, null == opacity ? 1 : opacity); + return 1 == arguments.length ? hslConvert(h) : new Hsl(h, s, l, null == opacity ? 1 : opacity); } function Hsl(h, s, l, opacity) { this.h = +h, this.s = +s, this.l = +l, this.opacity = +opacity; @@ -1041,7 +1041,7 @@ }); var _define_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__("../../../node_modules/d3-color/src/define.js"), _color_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__("../../../node_modules/d3-color/src/color.js"), _math_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__("../../../node_modules/d3-color/src/math.js"), BC_DA = -1.78277 * 0.29227 - 0.1347134789; function cubehelix(h, s, l, opacity) { - return 1 === arguments.length ? function(o) { + return 1 == arguments.length ? function(o) { if (o instanceof Cubehelix) return new Cubehelix(o.h, o.s, o.l, o.opacity); o instanceof _color_js__WEBPACK_IMPORTED_MODULE_1__.Rgb || (o = Object(_color_js__WEBPACK_IMPORTED_MODULE_1__.rgbConvert)(o)); var r = o.r / 255, g = o.g / 255, b = o.b / 255, l = (BC_DA * b + -1.7884503806 * r - 3.5172982438 * g) / (BC_DA + -1.7884503806 - 3.5172982438), bl = b - l, k = -((1.97294 * (g - l) - -0.29227 * bl) / 0.90649), s = Math.sqrt(k * k + bl * bl) / (1.97294 * l * (1 - l)), h = s ? Math.atan2(k, bl) * _math_js__WEBPACK_IMPORTED_MODULE_2__.rad2deg - 120 : NaN; @@ -1130,7 +1130,7 @@ return new Lab(l, 0, 0, null == opacity ? 1 : opacity); } function lab(l, a, b, opacity) { - return 1 === arguments.length ? labConvert(l) : new Lab(l, a, b, null == opacity ? 1 : opacity); + return 1 == arguments.length ? labConvert(l) : new Lab(l, a, b, null == opacity ? 1 : opacity); } function Lab(l, a, b, opacity) { this.l = +l, this.a = +a, this.b = +b, this.opacity = +opacity; @@ -1154,10 +1154,10 @@ return new Hcl(h < 0 ? h + 360 : h, Math.sqrt(o.a * o.a + o.b * o.b), o.l, o.opacity); } function lch(l, c, h, opacity) { - return 1 === arguments.length ? hclConvert(l) : new Hcl(h, c, l, null == opacity ? 1 : opacity); + return 1 == arguments.length ? hclConvert(l) : new Hcl(h, c, l, null == opacity ? 1 : opacity); } function hcl(h, c, l, opacity) { - return 1 === arguments.length ? hclConvert(h) : new Hcl(h, c, l, null == opacity ? 1 : opacity); + return 1 == arguments.length ? hclConvert(h) : new Hcl(h, c, l, null == opacity ? 1 : opacity); } function Hcl(h, c, l, opacity) { this.h = +h, this.c = +c, this.l = +l, this.opacity = +opacity; @@ -5640,7 +5640,7 @@ __webpack_require__.r(__webpack_exports__), __webpack_require__.d(__webpack_exports__, "default", function() { return function newInterval(floori, offseti, count, field) { function interval(date) { - return floori(date = 0 === arguments.length ? new Date : new Date(+date)), date; + return floori(date = 0 == arguments.length ? new Date : new Date(+date)), date; } return interval.floor = function(date) { return floori(date = new Date(+date)), date; diff --git a/crates/swc_ecma_minifier/tests/benches-full/vue.js b/crates/swc_ecma_minifier/tests/benches-full/vue.js index f8457c94e80..f557793b0df 100644 --- a/crates/swc_ecma_minifier/tests/benches-full/vue.js +++ b/crates/swc_ecma_minifier/tests/benches-full/vue.js @@ -341,7 +341,7 @@ var dep = new Dep(), property = Object.getOwnPropertyDescriptor(obj, key); if (!property || !1 !== property.configurable) { var getter = property && property.get, setter = property && property.set; - (!getter || setter) && 2 === arguments.length && (val = obj[key]); + (!getter || setter) && 2 == arguments.length && (val = obj[key]); var childOb = !shallow && observe(val); Object.defineProperty(obj, key, { enumerable: !0, diff --git a/crates/swc_ecma_minifier/tests/fixture/issues/2257/full/output.js b/crates/swc_ecma_minifier/tests/fixture/issues/2257/full/output.js index c1ba8242666..294893f2539 100644 --- a/crates/swc_ecma_minifier/tests/fixture/issues/2257/full/output.js +++ b/crates/swc_ecma_minifier/tests/fixture/issues/2257/full/output.js @@ -3816,7 +3816,7 @@ var global = __webpack_require__(19514); module.exports = function(a, b) { var console1 = global.console; - console1 && console1.error && (1 === arguments.length ? console1.error(a) : console1.error(a, b)); + console1 && console1.error && (1 == arguments.length ? console1.error(a) : console1.error(a, b)); }; }, 40969: function(module, __unused_webpack_exports, __webpack_require__) { diff --git a/crates/swc_ecma_minifier/tests/fixture/issues/d3-color/1/output.js b/crates/swc_ecma_minifier/tests/fixture/issues/d3-color/1/output.js index a4a1219f267..9e07c13a03b 100644 --- a/crates/swc_ecma_minifier/tests/fixture/issues/d3-color/1/output.js +++ b/crates/swc_ecma_minifier/tests/fixture/issues/d3-color/1/output.js @@ -3,7 +3,7 @@ import { Color, rgbConvert, Rgb, darker, brighter } from "./color.js"; import { deg2rad, rad2deg } from "./math.js"; var BC_DA = -1.78277 * 0.29227 - 0.1347134789; export default function cubehelix(h, s, l, opacity) { - return 1 === arguments.length ? function(o) { + return 1 == arguments.length ? function(o) { if (o instanceof Cubehelix) return new Cubehelix(o.h, o.s, o.l, o.opacity); o instanceof Rgb || (o = rgbConvert(o)); var r = o.r / 255, g = o.g / 255, b = o.b / 255, l = (BC_DA * b + -1.7884503806 * r - 3.5172982438 * g) / (BC_DA + -1.7884503806 - 3.5172982438), bl = b - l, k = -((1.97294 * (g - l) - -0.29227 * bl) / 0.90649), s = Math.sqrt(k * k + bl * bl) / (1.97294 * l * (1 - l)), h = s ? Math.atan2(k, bl) * rad2deg - 120 : NaN; diff --git a/crates/swc_ecma_minifier/tests/fixture/issues/d3-time-format/3/output.js b/crates/swc_ecma_minifier/tests/fixture/issues/d3-time-format/3/output.js index 760f5fd1fb3..fd92e13338d 100644 --- a/crates/swc_ecma_minifier/tests/fixture/issues/d3-time-format/3/output.js +++ b/crates/swc_ecma_minifier/tests/fixture/issues/d3-time-format/3/output.js @@ -13,7 +13,7 @@ var locale, bisector = __webpack_require__(24852), src_ticks = __webpack_require__(73002), t0 = new Date(), t1 = new Date(); function newInterval(floori, offseti, count, field) { function interval(date) { - return floori(date = 0 === arguments.length ? new Date() : new Date(+date)), date; + return floori(date = 0 == arguments.length ? new Date() : new Date(+date)), date; } return interval.floor = function(date) { return floori(date = new Date(+date)), date; diff --git a/crates/swc_ecma_minifier/tests/fixture/issues/moment/1/output.js b/crates/swc_ecma_minifier/tests/fixture/issues/moment/1/output.js index 507530ae720..fb2e8c7b1c7 100644 --- a/crates/swc_ecma_minifier/tests/fixture/issues/moment/1/output.js +++ b/crates/swc_ecma_minifier/tests/fixture/issues/moment/1/output.js @@ -1160,7 +1160,7 @@ return string; } proto.add = add, proto.calendar = function(time, formats) { - if (1 === arguments.length) { + if (1 == arguments.length) { if (arguments[0]) { var input, arrayTest, dataTypeTest; (input = arguments[0], isMoment(input) || isDate(input) || isString(input) || isNumber(input) || (arrayTest = isArray(input), dataTypeTest = !1, arrayTest && (dataTypeTest = 0 === input.filter(function(item) { diff --git a/crates/swc_ecma_minifier/tests/fixture/next/33265/static/chunks/d6e1aeb5-38a8d7ae57119c23/output.js b/crates/swc_ecma_minifier/tests/fixture/next/33265/static/chunks/d6e1aeb5-38a8d7ae57119c23/output.js index 29ba4046055..ab58bc46c7e 100644 --- a/crates/swc_ecma_minifier/tests/fixture/next/33265/static/chunks/d6e1aeb5-38a8d7ae57119c23/output.js +++ b/crates/swc_ecma_minifier/tests/fixture/next/33265/static/chunks/d6e1aeb5-38a8d7ae57119c23/output.js @@ -7596,7 +7596,7 @@ }, this.trigger = function(type) { var callbacks, i, length, args; if (callbacks = listeners[type]) { - if (2 === arguments.length) for(i = 0, length = callbacks.length; i < length; ++i)callbacks[i].call(this, arguments[1]); + if (2 == arguments.length) for(i = 0, length = callbacks.length; i < length; ++i)callbacks[i].call(this, arguments[1]); else { for(args = [], i = arguments.length, i = 1; i < arguments.length; ++i)args.push(arguments[i]); for(i = 0, length = callbacks.length; i < length; ++i)callbacks[i].apply(this, args); @@ -13341,7 +13341,7 @@ }, _proto.trigger = function(type) { var callbacks = this.listeners[type]; if (callbacks) { - if (2 === arguments.length) for(var length = callbacks.length, i = 0; i < length; ++i)callbacks[i].call(this, arguments[1]); + if (2 == arguments.length) for(var length = callbacks.length, i = 0; i < length; ++i)callbacks[i].call(this, arguments[1]); else for(var args = Array.prototype.slice.call(arguments, 1), _length = callbacks.length, _i = 0; _i < _length; ++_i)callbacks[_i].apply(this, args); } }, _proto.dispose = function() { diff --git a/crates/swc_ecma_minifier/tests/fixture/next/33265/static/chunks/pages/index-cb36c1bf7f830e3c/output.js b/crates/swc_ecma_minifier/tests/fixture/next/33265/static/chunks/pages/index-cb36c1bf7f830e3c/output.js index bb1780e41aa..e9859a78c35 100644 --- a/crates/swc_ecma_minifier/tests/fixture/next/33265/static/chunks/pages/index-cb36c1bf7f830e3c/output.js +++ b/crates/swc_ecma_minifier/tests/fixture/next/33265/static/chunks/pages/index-cb36c1bf7f830e3c/output.js @@ -2348,7 +2348,7 @@ }, _proto.trigger = function(type) { var callbacks = this.listeners[type]; if (callbacks) { - if (2 === arguments.length) for(var length = callbacks.length, i = 0; i < length; ++i)callbacks[i].call(this, arguments[1]); + if (2 == arguments.length) for(var length = callbacks.length, i = 0; i < length; ++i)callbacks[i].call(this, arguments[1]); else for(var args = Array.prototype.slice.call(arguments, 1), _length = callbacks.length, _i = 0; _i < _length; ++_i)callbacks[_i].apply(this, args); } }, _proto.dispose = function() { @@ -3826,7 +3826,7 @@ var document1 = __webpack_require__(9144), _objCreate = Object.create || function() { function F() {} return function(o) { - if (1 !== arguments.length) throw Error("Object.create shim only accepts one parameter."); + if (1 != arguments.length) throw Error("Object.create shim only accepts one parameter."); return F.prototype = o, new F(); }; }(); @@ -5413,7 +5413,7 @@ return this; }, Buffer.prototype.toString = function() { var length = this.length; - return 0 === length ? "" : 0 === arguments.length ? utf8Slice(this, 0, length) : slowToString.apply(this, arguments); + return 0 === length ? "" : 0 == arguments.length ? utf8Slice(this, 0, length) : slowToString.apply(this, arguments); }, Buffer.prototype.toLocaleString = Buffer.prototype.toString, Buffer.prototype.equals = function(b) { if (!Buffer.isBuffer(b)) throw TypeError("Argument must be a Buffer"); return this === b || 0 === Buffer.compare(this, b); diff --git a/crates/swc_ecma_minifier/tests/fixture/next/feedback-util-promisify/chunks/pages/_app-72ad41192608e93a/output.js b/crates/swc_ecma_minifier/tests/fixture/next/feedback-util-promisify/chunks/pages/_app-72ad41192608e93a/output.js index abaf5f87ce5..fd629d800e4 100644 --- a/crates/swc_ecma_minifier/tests/fixture/next/feedback-util-promisify/chunks/pages/_app-72ad41192608e93a/output.js +++ b/crates/swc_ecma_minifier/tests/fixture/next/feedback-util-promisify/chunks/pages/_app-72ad41192608e93a/output.js @@ -433,7 +433,7 @@ return this; }, Buffer.prototype.toString = function() { var e = this.length; - return 0 === e ? "" : 0 === arguments.length ? utf8Slice(this, 0, e) : slowToString.apply(this, arguments); + return 0 === e ? "" : 0 == arguments.length ? utf8Slice(this, 0, e) : slowToString.apply(this, arguments); }, Buffer.prototype.toLocaleString = Buffer.prototype.toString, Buffer.prototype.equals = function(e) { if (!Buffer.isBuffer(e)) throw TypeError("Argument must be a Buffer"); return this === e || 0 === Buffer.compare(this, e); diff --git a/crates/swc_ecma_minifier/tests/fixture/next/react-pdf-renderer/output.js b/crates/swc_ecma_minifier/tests/fixture/next/react-pdf-renderer/output.js index c83bc18da54..46acbbef002 100644 --- a/crates/swc_ecma_minifier/tests/fixture/next/react-pdf-renderer/output.js +++ b/crates/swc_ecma_minifier/tests/fixture/next/react-pdf-renderer/output.js @@ -15505,7 +15505,7 @@ function k(e, t, r, a) { if ("function" != typeof t) { if (g(t)) return t.test(e); - if (2 === arguments.length) throw new l("expected", [ + if (2 == arguments.length) throw new l("expected", [ "Function", "RegExp" ], t); @@ -15580,7 +15580,7 @@ } function P(e, t, r, i) { if ("string" == typeof r) { - if (4 === arguments.length) throw new l("error", [ + if (4 == arguments.length) throw new l("error", [ "Object", "Error", "Function", @@ -16108,13 +16108,13 @@ }); } function M(e, t, r, o, l, c) { - if (5 === arguments.length) { + if (5 == arguments.length) { c = Object.keys(e); var f = Object.keys(t); if (c.length !== f.length) return !1; } for(var h = 0; h < c.length; h++)if (!d(t, c[h])) return !1; - if (r && 5 === arguments.length) { + if (r && 5 == arguments.length) { var y = s(e); if (0 !== y.length) { var g = 0; @@ -18313,7 +18313,7 @@ }, f.prototype._error = function(e) { this.strm.msg && (e = this.strm.msg), this.onerror(e, this.err), this.write_in_progress = !1, this.pending_close && this.close(); }, f.prototype.init = function(e, r, n, i, a) { - o(4 === arguments.length || 5 === arguments.length, "init(windowBits, level, memLevel, strategy, [dictionary])"), o(e >= 8 && e <= 15, "invalid windowBits"), o(r >= -1 && r <= 9, "invalid compression level"), o(n >= 1 && n <= 9, "invalid memlevel"), o(i === t.Z_FILTERED || i === t.Z_HUFFMAN_ONLY || i === t.Z_RLE || i === t.Z_FIXED || i === t.Z_DEFAULT_STRATEGY, "invalid strategy"), this._init(r, e, n, i, a), this._setDictionary(); + o(4 == arguments.length || 5 == arguments.length, "init(windowBits, level, memLevel, strategy, [dictionary])"), o(e >= 8 && e <= 15, "invalid windowBits"), o(r >= -1 && r <= 9, "invalid compression level"), o(n >= 1 && n <= 9, "invalid memlevel"), o(i === t.Z_FILTERED || i === t.Z_HUFFMAN_ONLY || i === t.Z_RLE || i === t.Z_FIXED || i === t.Z_DEFAULT_STRATEGY, "invalid strategy"), this._init(r, e, n, i, a), this._setDictionary(); }, f.prototype.params = function() { throw Error("deflateParams Not supported"); }, f.prototype.reset = function() { @@ -20227,7 +20227,7 @@ return this; }, u.prototype.toString = function() { var e = this.length; - return 0 === e ? "" : 0 === arguments.length ? b(this, 0, e) : h.apply(this, arguments); + return 0 === e ? "" : 0 == arguments.length ? b(this, 0, e) : h.apply(this, arguments); }, u.prototype.toLocaleString = u.prototype.toString, u.prototype.equals = function(e) { if (!u.isBuffer(e)) throw TypeError("Argument must be a Buffer"); return this === e || 0 === u.compare(this, e); @@ -20596,7 +20596,7 @@ return e; } function c() { - if (!this.fired) return (this.target.removeListener(this.type, this.wrapFn), this.fired = !0, 0 === arguments.length) ? this.listener.call(this.target) : this.listener.apply(this.target, arguments); + if (!this.fired) return (this.target.removeListener(this.type, this.wrapFn), this.fired = !0, 0 == arguments.length) ? this.listener.call(this.target) : this.listener.apply(this.target, arguments); } function f(e, t, r) { var n = { @@ -20699,8 +20699,8 @@ }, o.prototype.off = o.prototype.removeListener, o.prototype.removeAllListeners = function(e) { var t, r, n; if (void 0 === (r = this._events)) return this; - if (void 0 === r.removeListener) return 0 === arguments.length ? (this._events = Object.create(null), this._eventsCount = 0) : void 0 !== r[e] && (0 == --this._eventsCount ? this._events = Object.create(null) : delete r[e]), this; - if (0 === arguments.length) { + if (void 0 === r.removeListener) return 0 == arguments.length ? (this._events = Object.create(null), this._eventsCount = 0) : void 0 !== r[e] && (0 == --this._eventsCount ? this._events = Object.create(null) : delete r[e]), this; + if (0 == arguments.length) { var i, o = Object.keys(r); for(n = 0; n < o.length; ++n)"removeListener" !== (i = o[n]) && this.removeAllListeners(i); return this.removeAllListeners("removeListener"), this._events = Object.create(null), this._eventsCount = 0, this; diff --git a/crates/swc_ecma_minifier/tests/fixture/next/wrap-contracts/output.js b/crates/swc_ecma_minifier/tests/fixture/next/wrap-contracts/output.js index bc78b4ca039..3ef12fb16ee 100644 --- a/crates/swc_ecma_minifier/tests/fixture/next/wrap-contracts/output.js +++ b/crates/swc_ecma_minifier/tests/fixture/next/wrap-contracts/output.js @@ -9096,7 +9096,7 @@ return this; }, Buffer.prototype.toString = function() { const length = this.length; - return 0 === length ? '' : 0 === arguments.length ? utf8Slice(this, 0, length) : slowToString.apply(this, arguments); + return 0 === length ? '' : 0 == arguments.length ? utf8Slice(this, 0, length) : slowToString.apply(this, arguments); }, Buffer.prototype.toLocaleString = Buffer.prototype.toString, Buffer.prototype.equals = function(b) { if (!Buffer.isBuffer(b)) throw TypeError('Argument must be a Buffer'); return this === b || 0 === Buffer.compare(this, b); @@ -11604,7 +11604,7 @@ return target; } function onceWrapper() { - if (!this.fired) return (this.target.removeListener(this.type, this.wrapFn), this.fired = !0, 0 === arguments.length) ? this.listener.call(this.target) : this.listener.apply(this.target, arguments); + if (!this.fired) return (this.target.removeListener(this.type, this.wrapFn), this.fired = !0, 0 == arguments.length) ? this.listener.call(this.target) : this.listener.apply(this.target, arguments); } function _onceWrap(target, type, listener) { var state = { @@ -11727,8 +11727,8 @@ }, EventEmitter.prototype.off = EventEmitter.prototype.removeListener, EventEmitter.prototype.removeAllListeners = function(type) { var listeners, events, i; if (void 0 === (events = this._events)) return this; - if (void 0 === events.removeListener) return 0 === arguments.length ? (this._events = Object.create(null), this._eventsCount = 0) : void 0 !== events[type] && (0 == --this._eventsCount ? this._events = Object.create(null) : delete events[type]), this; - if (0 === arguments.length) { + if (void 0 === events.removeListener) return 0 == arguments.length ? (this._events = Object.create(null), this._eventsCount = 0) : void 0 !== events[type] && (0 == --this._eventsCount ? this._events = Object.create(null) : delete events[type]), this; + if (0 == arguments.length) { var key, keys = Object.keys(events); for(i = 0; i < keys.length; ++i)'removeListener' !== (key = keys[i]) && this.removeAllListeners(key); return this.removeAllListeners('removeListener'), this._events = Object.create(null), this._eventsCount = 0, this; diff --git a/crates/swc_ecma_minifier/tests/projects/output/jquery-1.9.1.js b/crates/swc_ecma_minifier/tests/projects/output/jquery-1.9.1.js index 362ae240a40..e44042a865d 100644 --- a/crates/swc_ecma_minifier/tests/projects/output/jquery-1.9.1.js +++ b/crates/swc_ecma_minifier/tests/projects/output/jquery-1.9.1.js @@ -614,7 +614,7 @@ return this; }, removeClass: function(value) { - var classes, elem, cur, clazz, j, i = 0, len = this.length, proceed = 0 === arguments.length || "string" == typeof value && value; + var classes, elem, cur, clazz, j, i = 0, len = this.length, proceed = 0 == arguments.length || "string" == typeof value && value; if (jQuery.isFunction(value)) return this.each(function(j) { jQuery(this).removeClass(value.call(this, j, this.className)); }); @@ -1099,7 +1099,7 @@ return this.on(types, selector, data, fn); }, undelegate: function(selector, types, fn) { - return 1 === arguments.length ? this.off(selector, "**") : this.off(types, selector || "**", fn); + return 1 == arguments.length ? this.off(selector, "**") : this.off(types, selector || "**", fn); }, trigger: function(type, data) { return this.each(function() { diff --git a/crates/swc_ecma_minifier/tests/projects/output/jquery.mobile-1.4.2.js b/crates/swc_ecma_minifier/tests/projects/output/jquery.mobile-1.4.2.js index abb1d9c7212..8a1c8a07e4c 100644 --- a/crates/swc_ecma_minifier/tests/projects/output/jquery.mobile-1.4.2.js +++ b/crates/swc_ecma_minifier/tests/projects/output/jquery.mobile-1.4.2.js @@ -392,7 +392,7 @@ }, option: function(key, value) { var parts, curOption, i, options = key; - if (0 === arguments.length) return $2.widget.extend({}, this.options); + if (0 == arguments.length) return $2.widget.extend({}, this.options); if ("string" == typeof key) { if (options = {}, key = (parts = key.split(".")).shift(), parts.length) { for(i = 0, curOption = options[key] = $2.widget.extend({}, this.options[key]); i < parts.length - 1; i++)curOption[parts[i]] = curOption[parts[i]] || {}, curOption = curOption[parts[i]]; diff --git a/crates/swc_ecma_minifier/tests/projects/output/underscore-1.5.2.js b/crates/swc_ecma_minifier/tests/projects/output/underscore-1.5.2.js index 65eaba2c0f1..7e3412ab8ae 100644 --- a/crates/swc_ecma_minifier/tests/projects/output/underscore-1.5.2.js +++ b/crates/swc_ecma_minifier/tests/projects/output/underscore-1.5.2.js @@ -506,9 +506,8 @@ "\u2029": "u2029" }, escaper = /\\|'|\r|\n|\t|\u2028|\u2029/g; _.template = function(text, data, settings) { - settings = _.defaults({}, settings, _.templateSettings); var render, matcher = RegExp([ - (settings.escape || noMatch).source, + ((settings = _.defaults({}, settings, _.templateSettings)).escape || noMatch).source, (settings.interpolate || noMatch).source, (settings.evaluate || noMatch).source ].join("|") + "|$", "g"), index = 0, source = "__p+='"; diff --git a/crates/swc_ecma_utils/src/lib.rs b/crates/swc_ecma_utils/src/lib.rs index 562e33f4357..33fba258ab4 100644 --- a/crates/swc_ecma_utils/src/lib.rs +++ b/crates/swc_ecma_utils/src/lib.rs @@ -1067,13 +1067,31 @@ pub trait ExprExt { fn get_type(&self) -> Value { let expr = self.as_expr(); - match *expr { + match expr { Expr::Assign(AssignExpr { ref right, op: op!("="), .. }) => right.get_type(), + Expr::Member(MemberExpr { + obj, + prop: + MemberProp::Ident(Ident { + sym: js_word!("length"), + .. + }), + .. + }) => match &**obj { + Expr::Array(ArrayLit { .. }) + | Expr::Lit(Lit::Str(..)) + | Expr::Ident(Ident { + sym: js_word!("arguments"), + .. + }) => Known(Type::Num), + _ => Unknown, + }, + Expr::Seq(SeqExpr { ref exprs, .. }) => exprs .last() .expect("sequence expression should not be empty")