fix(es/minifier): Check variable type while optimizing += (#9575)

**Related issue:**

 - Closes https://github.com/swc-project/swc/issues/9504
This commit is contained in:
Donny/강동윤 2024-09-20 16:43:53 +09:00 committed by GitHub
parent 6d15d9c2eb
commit 04016e9687
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
21 changed files with 97 additions and 32 deletions

View File

@ -3,7 +3,7 @@ export default class Demo {
let ranges = [], range = [], retrString = A.encode(value), bitField = '';
return value.forEach((curValue, i)=>{
bitField += B.encode(curValue), range.push(i), ranges.push(range);
}), retrString += '.' + C.encode(ranges);
}), retrString += '.', retrString += C.encode(ranges);
}
}
console.log(Deno.encode());

View File

@ -1,3 +1,3 @@
//// [compoundAdditionAssignmentLHSCanBeAssigned.ts]
var E, E1;
(E1 = E || (E = {}))[E1.a = 0] = "a", E1[E1.b = 1] = "b";
var E, a, b, x1, x2, x3, x4, x6, E1;
(E1 = E || (E = {}))[E1.a = 0] = "a", E1[E1.b = 1] = "b", x1 += a, x1 += b, x1 += !0, x1 += 0, x1 += '', x1 += 0, x1 += {}, x1 += null, x1 += void 0, x2 += a, x2 += b, x2 += !0, x2 += 0, x2 += '', x2 += 0, x2 += {}, x2 += null, x2 += void 0, x3 += a, x3 += 0, x3 += null, x3 += void 0, x4 += a, x4 += 0, x4 += null, x4 += void 0, x6 += a, x6 += '';

View File

@ -1,3 +1,3 @@
//// [compoundAdditionAssignmentWithInvalidOperands.ts]
var E, E1;
(E1 = E || (E = {}))[E1.a = 0] = "a", E1[E1.b = 1] = "b";
var E, a, x1, x2, x3, x4, x5, E1;
(E1 = E || (E = {}))[E1.a = 0] = "a", E1[E1.b = 1] = "b", x1 += a, x1 += !0, x1 += 0, x1 += {}, x1 += null, x1 += void 0, x2 += a, x2 += !0, x2 += 0, x2 += {}, x2 += null, x2 += void 0, x3 += a, x3 += !0, x3 += 0, x3 += {}, x3 += null, x3 += void 0, x4 += a, x4 += !0, x4 += {}, x5 += a, x5 += !0;

View File

@ -1,3 +1,3 @@
//// [symbolType12.ts]
var s = Symbol.for("assign"), str = "";
s *= 0 * s, s /= s, s /= 0, s %= s, s %= 0, s += s + 0 + "", str += s, s -= s, s -= 0, s <<= s, s <<= 0, s >>= s, s >>= 0, s >>>= s, s >>>= 0, s &= s, s &= 0, s ^= s, s ^= 0, s |= s, s |= 0, str += s || str;
s *= 0 * s, s /= s, s /= 0, s %= s, s %= 0, s += s, s += 0, s += "", str += s, s -= s, s -= 0, s <<= s, s <<= 0, s >>= s, s >>= 0, s >>>= s, s >>>= 0, s &= s, s &= 0, s ^= s, s ^= 0, s |= s, s |= 0, str += s || str;

View File

@ -8,6 +8,7 @@ use swc_ecma_usage_analyzer::{
};
use swc_ecma_utils::{
contains_arguments, contains_this_expr, prepend_stmts, ExprExt, IdentUsageFinder, StmtLike,
Type, Value,
};
use swc_ecma_visit::{noop_visit_type, Visit, VisitWith};
#[cfg(feature = "debug")]
@ -2379,6 +2380,8 @@ impl Optimizer<'_> {
Mergable::Drop => return Ok(false),
};
let a_type = a_right.as_deref().map(|a| a.get_type());
if let Some(a_right) = a_right {
if a_right.is_this() || a_right.is_ident_ref_to("arguments") {
return Ok(false);
@ -2482,8 +2485,13 @@ impl Optimizer<'_> {
_ => None,
};
let Some(a_type) = a_type else {
return Ok(false);
};
let b_type = b.right.get_type();
if let Some(a_op) = a_op {
if can_drop_op_for(a_op, b.op) {
if can_drop_op_for(a_op, b.op, a_type, b_type) {
if b_left.to_id() == left_id.to_id() {
if let Some(bin_op) = b.op.to_update() {
report_change!(
@ -2715,13 +2723,17 @@ pub(crate) fn is_trivial_lit(e: &Expr) -> bool {
}
/// This assumes `a.left.to_id() == b.left.to_id()`
fn can_drop_op_for(a: AssignOp, b: AssignOp) -> bool {
fn can_drop_op_for(a: AssignOp, b: AssignOp, a_type: Value<Type>, b_type: Value<Type>) -> bool {
if a == op!("=") {
return true;
}
if a == b {
return matches!(a, op!("+=") | op!("*="));
if a == op!("+=") && a_type.is_known() && a_type == b_type {
return true;
}
return matches!(a, op!("*="));
}
false

View File

@ -5716,7 +5716,7 @@
var width = data[i++], height = data[i++];
if (x1 = x0 + width, y1 = y0 + height, isStroke) {
if (containStroke(x0, y0, x1, y0, lineWidth, x, y) || containStroke(x1, y0, x1, y1, lineWidth, x, y) || containStroke(x1, y1, x0, y1, lineWidth, x, y) || containStroke(x0, y1, x0, y0, lineWidth, x, y)) return !0;
} else w += windingLine(x1, y0, x1, y1, x, y) + windingLine(x0, y1, x0, y0, x, y);
} else w += windingLine(x1, y0, x1, y1, x, y), w += windingLine(x0, y1, x0, y0, x, y);
break;
case CMD$1.Z:
if (isStroke) {

View File

@ -913,8 +913,9 @@
getParsingFlags(config).invalidFormat = !0, config._d = new Date(NaN);
return;
}
for(i = 0; i < config._f.length; i++)currentScore = 0, validFormatFound = !1, tempConfig = copyConfig({}, config), null != config._useUTC && (tempConfig._useUTC = config._useUTC), tempConfig._f = config._f[i], configFromStringAndFormat(tempConfig), isValid(tempConfig) && (validFormatFound = !0), //or tokens
currentScore += getParsingFlags(tempConfig).charsLeftOver + 10 * getParsingFlags(tempConfig).unusedTokens.length, getParsingFlags(tempConfig).score = currentScore, bestFormatIsValid ? currentScore < scoreToBeat && (scoreToBeat = currentScore, bestMoment = tempConfig) : (null == scoreToBeat || currentScore < scoreToBeat || validFormatFound) && (scoreToBeat = currentScore, bestMoment = tempConfig, validFormatFound && (bestFormatIsValid = !0));
for(i = 0; i < config._f.length; i++)currentScore = 0, validFormatFound = !1, tempConfig = copyConfig({}, config), null != config._useUTC && (tempConfig._useUTC = config._useUTC), tempConfig._f = config._f[i], configFromStringAndFormat(tempConfig), isValid(tempConfig) && (validFormatFound = !0), // if there is any input that was not parsed add a penalty for that format
currentScore += getParsingFlags(tempConfig).charsLeftOver, //or tokens
currentScore += 10 * getParsingFlags(tempConfig).unusedTokens.length, getParsingFlags(tempConfig).score = currentScore, bestFormatIsValid ? currentScore < scoreToBeat && (scoreToBeat = currentScore, bestMoment = tempConfig) : (null == scoreToBeat || currentScore < scoreToBeat || validFormatFound) && (scoreToBeat = currentScore, bestMoment = tempConfig, validFormatFound && (bestFormatIsValid = !0));
extend(config, bestMoment || tempConfig);
}(config) : format ? configFromStringAndFormat(config) : isUndefined(input = config._i) ? config._d = new Date(hooks.now()) : isDate(input) ? config._d = new Date(input.valueOf()) : 'string' == typeof input ? // date from 1) ASP.NET, 2) ISO, 3) RFC 2822 formats, or 4) optional fallback if parsing isn't strict
function(config) {

View File

@ -6,7 +6,7 @@ export default class Demo {
bitField += B.encode(curValue);
range.push(i);
ranges.push(range);
}), retrString += '.' + C.encode(ranges);
}), retrString += '.', retrString += C.encode(ranges);
}
}
console.log(Deno.encode());

View File

@ -0,0 +1,31 @@
export function panUpdate(e) {
if (!moveDirectionExpected) {
panStart = false;
return;
}
caf(rafIndex);
if (panStart) { rafIndex = raf(function () { panUpdate(e); }); }
if (moveDirectionExpected === '?') { moveDirectionExpected = getMoveDirectionExpected(); }
if (moveDirectionExpected) {
if (!preventScroll && isTouchEvent(e)) { preventScroll = true; }
try {
if (e.type) { events.emit(isTouchEvent(e) ? 'touchMove' : 'dragMove', info(e)); }
} catch (err) { }
var x = translateInit,
dist = getDist(lastPosition, initPosition);
if (!horizontal || fixedWidth || autoWidth) {
// Relevant lines below
x += dist;
x += 'px';
} else {
var percentageX = TRANSFORM ? dist * items * 100 / ((viewport + gutter) * slideCountNew) : dist * 100 / (viewport + gutter);
x += percentageX;
x += '%';
}
container.style[transformAttr] = transformPrefix + x + transformPostfix;
}
}

View File

@ -0,0 +1,17 @@
export function panUpdate(e) {
if (!moveDirectionExpected) {
panStart = !1;
return;
}
if (caf(rafIndex), panStart && (rafIndex = raf(function() {
panUpdate(e);
})), '?' === moveDirectionExpected && (moveDirectionExpected = getMoveDirectionExpected()), moveDirectionExpected) {
!preventScroll && isTouchEvent(e) && (preventScroll = !0);
try {
e.type && events.emit(isTouchEvent(e) ? 'touchMove' : 'dragMove', info(e));
} catch (err) {}
var x = translateInit, dist = getDist(lastPosition, initPosition);
!horizontal || fixedWidth || autoWidth ? (// Relevant lines below
x += dist, x += 'px') : (x += TRANSFORM ? dist * items * 100 / ((viewport + gutter) * slideCountNew) : 100 * dist / (viewport + gutter), x += '%'), container.style[transformAttr] = transformPrefix + x + transformPostfix;
}
}

View File

@ -1336,7 +1336,7 @@
d = !0;
}
d || (b1 = "", xa(c, function(c, d) {
b1 += d + ":" + c + "\r\n";
b1 += d, b1 += ":", b1 += c, b1 += "\r\n";
}), c = b1, "string" == typeof a ? null != c && encodeURIComponent(String(c)) : R(a, b, c));
}
function Hd(a, b, c) {

View File

@ -1586,7 +1586,7 @@
function Wt(t) {
if (null === t.A) {
let t1 = t.path.canonicalString();
null !== t.collectionGroup && (t1 += "|cg:" + t.collectionGroup), t1 += "|f:" + t.filters.map((t)=>t.field.canonicalString() + t.op.toString() + xt(t.value)).join(",") + "|ob:" + t.orderBy.map((t)=>t.field.canonicalString() + t.dir).join(","), At(t.limit) || (t1 += "|l:" + t.limit), t.startAt && (t1 += "|lb:" + ce(t.startAt)), t.endAt && (t1 += "|ub:" + ce(t.endAt)), t.A = t1;
null !== t.collectionGroup && (t1 += "|cg:" + t.collectionGroup), t1 += "|f:", t1 += t.filters.map((t)=>t.field.canonicalString() + t.op.toString() + xt(t.value)).join(","), t1 += "|ob:", t1 += t.orderBy.map((t)=>t.field.canonicalString() + t.dir).join(","), At(t.limit) || (t1 += "|l:", t1 += t.limit), t.startAt && (t1 += "|lb:", t1 += ce(t.startAt)), t.endAt && (t1 += "|ub:", t1 += ce(t.endAt)), t.A = t1;
}
return t.A;
}

View File

@ -913,8 +913,9 @@ function(global, factory) {
getParsingFlags(config).invalidFormat = !0, config._d = new Date(NaN);
return;
}
for(i = 0; i < config._f.length; i++)currentScore = 0, validFormatFound = !1, tempConfig = copyConfig({}, config), null != config._useUTC && (tempConfig._useUTC = config._useUTC), tempConfig._f = config._f[i], configFromStringAndFormat(tempConfig), isValid(tempConfig) && (validFormatFound = !0), //or tokens
currentScore += getParsingFlags(tempConfig).charsLeftOver + 10 * getParsingFlags(tempConfig).unusedTokens.length, getParsingFlags(tempConfig).score = currentScore, bestFormatIsValid ? currentScore < scoreToBeat && (scoreToBeat = currentScore, bestMoment = tempConfig) : (null == scoreToBeat || currentScore < scoreToBeat || validFormatFound) && (scoreToBeat = currentScore, bestMoment = tempConfig, validFormatFound && (bestFormatIsValid = !0));
for(i = 0; i < config._f.length; i++)currentScore = 0, validFormatFound = !1, tempConfig = copyConfig({}, config), null != config._useUTC && (tempConfig._useUTC = config._useUTC), tempConfig._f = config._f[i], configFromStringAndFormat(tempConfig), isValid(tempConfig) && (validFormatFound = !0), // if there is any input that was not parsed add a penalty for that format
currentScore += getParsingFlags(tempConfig).charsLeftOver, //or tokens
currentScore += 10 * getParsingFlags(tempConfig).unusedTokens.length, getParsingFlags(tempConfig).score = currentScore, bestFormatIsValid ? currentScore < scoreToBeat && (scoreToBeat = currentScore, bestMoment = tempConfig) : (null == scoreToBeat || currentScore < scoreToBeat || validFormatFound) && (scoreToBeat = currentScore, bestMoment = tempConfig, validFormatFound && (bestFormatIsValid = !0));
extend(config, bestMoment || tempConfig);
}(config) : format ? configFromStringAndFormat(config) : isUndefined(input = config._i) ? config._d = new Date(hooks.now()) : isDate(input) ? config._d = new Date(input.valueOf()) : "string" == typeof input ? // date from 1) ASP.NET, 2) ISO, 3) RFC 2822 formats, or 4) optional fallback if parsing isn't strict
function(config) {

View File

@ -19377,7 +19377,8 @@
dts: buffer[0].dts
}; i < tagSize;)tag.data.set(buffer[0].data.subarray(0, tagSize - i), i), i += buffer[0].data.byteLength, bufferSize -= buffer[0].data.byteLength, buffer.shift();
// find the start of the first frame and the end of the tag
frameStart = 10, 0x40 & tag.data[5] && (frameStart += 4 + parseSyncSafeInteger$1(tag.data.subarray(10, 14)), tagSize -= parseSyncSafeInteger$1(tag.data.subarray(16, 20)));
frameStart = 10, 0x40 & tag.data[5] && (// advance the frame start past the extended header
frameStart += 4, frameStart += parseSyncSafeInteger$1(tag.data.subarray(10, 14)), tagSize -= parseSyncSafeInteger$1(tag.data.subarray(16, 20)));
// http://id3.org/id3v2.3.0#ID3v2_frame_overview
do {
if (// determine the number of bytes in this frame
@ -19395,7 +19396,7 @@
var d = frame.data, size = (0x01 & d[3]) << 30 | d[4] << 22 | d[5] << 14 | d[6] << 6 | d[7] >>> 2;
size *= 4, size += 0x03 & d[7], frame.timeStamp = size, void 0 === tag.pts && void 0 === tag.dts && (tag.pts = frame.timeStamp, tag.dts = frame.timeStamp), this.trigger("timestamp", frame);
}
tag.frames.push(frame), frameStart += 10 + frameSize;
tag.frames.push(frame), frameStart += 10, frameStart += frameSize;
}while (frameStart < tagSize)
this.trigger("data", tag);
} // collect the entire frame so it can be parsed
@ -20125,7 +20126,8 @@
},
parseAacTimestamp: function(packet) {
var frameStart, frameSize, frame; // find the start of the first frame and the end of the tag
frameStart = 10, 0x40 & packet[5] && (frameStart += 4 + parseSyncSafeInteger(packet.subarray(10, 14)));
frameStart = 10, 0x40 & packet[5] && (// advance the frame start past the extended header
frameStart += 4, frameStart += parseSyncSafeInteger(packet.subarray(10, 14)));
// http://id3.org/id3v2.3.0#ID3v2_frame_overview
do {
if (// determine the number of bytes in this frame
@ -20140,7 +20142,7 @@
break;
}
}
frameStart += 10 + frameSize; // advance past the frame body
frameStart += 10, frameStart += frameSize;
}while (frameStart < packet.byteLength)
return null;
}
@ -20567,7 +20569,8 @@
var transmuxer_Transmuxer = _Transmuxer, bin_toUnsigned = function(value) {
return value >>> 0;
}, parseType_1 = function(buffer) {
return "" + (String.fromCharCode(buffer[0]) + String.fromCharCode(buffer[1]) + String.fromCharCode(buffer[2]) + String.fromCharCode(buffer[3]));
var result = "";
return result += String.fromCharCode(buffer[0]), result += String.fromCharCode(buffer[1]), result += String.fromCharCode(buffer[2]), result += String.fromCharCode(buffer[3]);
}, findBox_1 = function findBox(data, path) {
var i, size, type, end, subresults, results = [];
if (!path.length) // short-circuit the search for empty paths

View File

@ -16540,7 +16540,7 @@
i += "".concat(t[0], " and ").concat(t[1], " arguments");
break;
default:
i += t.slice(0, o - 1).join(", ") + ", and ".concat(t[o - 1], " arguments");
i += t.slice(0, o - 1).join(", "), i += ", and ".concat(t[o - 1], " arguments");
}
return "".concat(i, " must be specified");
}, TypeError), e.exports.codes = l;

View File

@ -23267,7 +23267,7 @@
}, Toolbar.prototype.itemWidthCal = function(items) {
var style, _this = this, width = 0;
return [].slice.call((0, ej2_base /* selectAll */ .td)('.' + CLS_ITEM, items)).forEach(function(el) {
(0, ej2_base /* isVisible */ .pn)(el) && (style = window.getComputedStyle(el), width += (_this.isVertical ? el.offsetHeight : el.offsetWidth) + parseFloat(_this.isVertical ? style.marginTop : style.marginRight) + parseFloat(_this.isVertical ? style.marginBottom : style.marginLeft));
(0, ej2_base /* isVisible */ .pn)(el) && (style = window.getComputedStyle(el), width += _this.isVertical ? el.offsetHeight : el.offsetWidth, width += parseFloat(_this.isVertical ? style.marginTop : style.marginRight), width += parseFloat(_this.isVertical ? style.marginBottom : style.marginLeft));
}), width;
}, Toolbar.prototype.getScrollCntEle = function(innerItem) {
var trgClass = this.isVertical ? '.e-vscroll-content' : '.e-hscroll-content';

View File

@ -22544,7 +22544,7 @@
let i = 0;
for(; i < maximumValuesToStringify - 1; i++){
const tmp = stringifyFnReplacer(i, value, stack, replacer, spacer, indentation);
res += (void 0 !== tmp ? tmp : 'null') + join;
res += void 0 !== tmp ? tmp : 'null', res += join;
}
const tmp = stringifyFnReplacer(i, value, stack, replacer, spacer, indentation);
if (res += void 0 !== tmp ? tmp : 'null', value.length - 1 > maximumBreadth) {
@ -22597,7 +22597,7 @@
let i = 0;
for(; i < maximumValuesToStringify - 1; i++){
const tmp = stringifyArrayReplacer(i, value[i], stack, replacer, spacer, indentation);
res += (void 0 !== tmp ? tmp : 'null') + join;
res += void 0 !== tmp ? tmp : 'null', res += join;
}
const tmp = stringifyArrayReplacer(i, value[i], stack, replacer, spacer, indentation);
if (res += void 0 !== tmp ? tmp : 'null', value.length - 1 > maximumBreadth) {
@ -22648,7 +22648,7 @@
let i = 0;
for(; i < maximumValuesToStringify - 1; i++){
const tmp = stringifyIndent(i, value[i], stack, spacer, indentation);
res += (void 0 !== tmp ? tmp : 'null') + join;
res += void 0 !== tmp ? tmp : 'null', res += join;
}
const tmp = stringifyIndent(i, value[i], stack, spacer, indentation);
if (res += void 0 !== tmp ? tmp : 'null', value.length - 1 > maximumBreadth) {
@ -22705,7 +22705,7 @@
let i = 0;
for(; i < maximumValuesToStringify - 1; i++){
const tmp = stringifySimple(i, value[i], stack);
res += (void 0 !== tmp ? tmp : 'null') + ',';
res += void 0 !== tmp ? tmp : 'null', res += ',';
}
const tmp = stringifySimple(i, value[i], stack);
if (res += void 0 !== tmp ? tmp : 'null', value.length - 1 > maximumBreadth) {

File diff suppressed because one or more lines are too long

View File

@ -6,7 +6,7 @@ export default class Demo {
bitField += B.encode(curValue);
range.push(i);
ranges.push(range);
}), retrString += '.' + C.encode(ranges);
}), retrString += '.', retrString += C.encode(ranges);
}
}
console.log(Deno.encode());

View File

@ -8601,7 +8601,7 @@
var styleValue = styles[styleName];
if (null != styleValue) {
var isCustomProperty = 0 === styleName.indexOf("--");
serialized += delimiter + (isCustomProperty ? styleName : styleName.replace(uppercasePattern, "-$1").toLowerCase().replace(msPattern, "-ms-")) + ":" + dangerousStyleValue(styleName, styleValue, isCustomProperty), delimiter = ";";
serialized += delimiter + (isCustomProperty ? styleName : styleName.replace(uppercasePattern, "-$1").toLowerCase().replace(msPattern, "-ms-")) + ":", serialized += dangerousStyleValue(styleName, styleValue, isCustomProperty), delimiter = ";";
}
}
return serialized || null;

View File

@ -1,3 +1,3 @@
var a = 100, b = 10;
(b = a) ? (a++, b += a + a) : b ^= a;
(b = a) ? (a++, b += a, b += a) : b ^= a;
console.log(a, b);