oxc/crates/oxc_syntax/src
sapphi-red ec88c68c28
feat(minifier): compress a || (a = b) to a ||= b (#8315)
Compress `a || (a = b)` to `a ||= b` and for other logical operators that are possible to.

I didn't find other minifiers doing this, but this is safe for identifiers. [Quoting MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Logical_OR_assignment#description):

> Logical OR assignment short-circuits, meaning that `x ||= y` is equivalent to `x || (x = y)`, except that the expression x is only evaluated once.

I actually checked the spec and the only difference was that `Let lRef be ? Evaluation of LeftHandSideExpression` was done twice. Evaluating an IdentifierReference is idempotent so it should be safe to do this compression.

References:

- [Spec of `&&=`](https://tc39.es/ecma262/multipage/ecmascript-language-expressions.html#sec-assignment-operators:~:text=Return%20r.-,AssignmentExpression,7.%20Return%20rVal.,-AssignmentExpression)
- [Spec of `=`](https://tc39.es/ecma262/multipage/ecmascript-language-expressions.html#prod-AssignmentExpression:~:text=Runtime%20Semantics%3A%20Evaluation-,AssignmentExpression,6.%20Return%20rVal.,-AssignmentExpression)
- [Spec of `&&`](https://tc39.es/ecma262/multipage/ecmascript-language-expressions.html#sec-binary-logical-operators:~:text=Runtime%20Semantics%3A%20Evaluation-,LogicalANDExpression,5.%20Return%20%3F%C2%A0GetValue(rRef).,-LogicalORExpression)

I think this is safe for `a.b || (a.b = foo)` as well because the number of `GetValue` and `SetValue` does not change, but I didn't include that in this PR.
2025-01-07 23:19:52 +00:00
..
generated perf(syntax): reorder operator enum variants (#7351) 2024-11-19 01:23:28 +00:00
class.rs docs(syntax): enable lint warnings on missing docs, and add a lot of documentation (#6611) 2024-10-15 22:50:45 +00:00
es_target.rs feat(minfier): add CompressOptions::target (#8179) 2024-12-29 12:27:32 +00:00
identifier.rs fix(identifier): add ZWSP to is_irregular_whitespace (#6662) 2024-10-18 22:20:02 +00:00
keyword.rs docs(syntax): enable lint warnings on missing docs, and add a lot of documentation (#6611) 2024-10-15 22:50:45 +00:00
lib.rs feat(minfier): add CompressOptions::target (#8179) 2024-12-29 12:27:32 +00:00
module_record.rs refactor(global): sort imports (#7883) 2024-12-14 15:07:21 +00:00
node.rs feat(parser)!: Build ModuleRecord directly in parser (#7546) 2024-11-29 14:50:42 +00:00
number.rs docs(syntax): enable lint warnings on missing docs, and add a lot of documentation (#6611) 2024-10-15 22:50:45 +00:00
operator.rs feat(minifier): compress a || (a = b) to a ||= b (#8315) 2025-01-07 23:19:52 +00:00
precedence.rs docs(syntax): enable lint warnings on missing docs, and add a lot of documentation (#6611) 2024-10-15 22:50:45 +00:00
reference.rs refactor(semantic): remove serialize (#8015) 2024-12-19 09:51:12 +00:00
scope.rs refactor(semantic)!: remove ScopeFlags::Modifiers (#7935) 2024-12-16 12:15:12 +00:00
symbol.rs feat(syntax): add SymbolId::new method (#8041) 2024-12-21 10:10:56 +00:00
xml_entities.rs docs(syntax): enable lint warnings on missing docs, and add a lot of documentation (#6611) 2024-10-15 22:50:45 +00:00