Boshen
927f43ff84
feat(minifier): improve .charCodeAt(arg) when arg is valid ( #8534 )
2025-01-16 06:36:34 +00:00
Boshen
b1d018622b
fix(minifier): do not fold !!void b ( #8533 )
2025-01-16 05:52:03 +00:00
Boshen
53adde5003
fix(minifier): x['-2147483648'] -> x[-2147483648] ( #8528 )
2025-01-16 13:43:23 +08:00
Boshen
405b73d8e7
fix(minifier): do not change delete undefined to delete void 0 ( #8527 )
...
`delete undefined` returns `false`
`delete void 0` returns `true`
2025-01-16 03:08:26 +00:00
Boshen
92e44cba6b
fix(minifier): do not remove undefined in var x = undefined ( #8526 )
2025-01-16 02:57:28 +00:00
Boshen
06f14d526b
feat(minifier): remove empty class static block class Foo { static {} } ( #8525 )
2025-01-16 02:46:25 +00:00
Boshen
1860411656
feat(minifier): remove last redundant return statement ( #8523 )
2025-01-16 02:07:28 +00:00
Boshen
209e313e40
fix(minifier): class C { ['-1']() {} } cannot be minifized ( #8516 )
2025-01-15 16:15:01 +00:00
Boshen
629c41713b
test(minifier): port esbuild minification tests ( #8497 )
2025-01-15 06:29:01 +00:00
Boshen
65854630be
fix(minifier): always keep the last value of sequence expression ( #8490 )
...
Caught in react app:
```
React.useEffect(() => {
isMountRef.current = false;
return () => {
isMountRef.current = true;
};
}, []);
```
->
```
React.useEffect(() => isMountRef.current = !1 , []);
```
Two problems: there were no unit tests guarding this, no good way of knowing when code gets deleted.
2025-01-14 15:35:00 +00:00
oxc-bot
3e05055783
release(crates): v0.46.0 ( #8487 )
...
## [0.46.0] - 2025-01-14
- 7eb6ccd ast: [**BREAKING**] Remove unused and not useful `ContentHash`
(#8483 ) (Boshen)
### Features
- 8accfef minifier: Minify `var x; void x` -> `void 0` (#8466 ) (Boshen)
- 870a583 minifier: Fold `false['toString']` (#8447 ) (Boshen)
- 4ad695d napi/minify: Implement napi (#8478 ) (Boshen)
- 9d550aa span: Add `Atom::r#static` (#8479 ) (_Kerman)
### Bug Fixes
- 4071878 isolated-declarations: Retain `declare` declarations when they
are exported (#8477 ) (Dunqing)
- 7ee7634 isolated-declarations: Import statement disappears when import
binding is referenced in nested `typeof` (#8476 ) (Dunqing)
- 7252cb0 isolated-declarations: Unexpected error when global `Symbol`
as property key (#8475 ) (Dunqing)
- 4c6675c minifier: Do not convert while to fors in DCE (#8484 ) (Boshen)
- 1d6e84d minifier: Fix incorrect `null.toString()` and `1n.toString()`
(#8464 ) (Boshen)
- 25d4bf9 minifier: Remove usage of empty spans (#8462 ) (Boshen)
- dd64340 minifier: Keep `return undefined` in async generator function
(#8439 ) (Boshen)
- c444de8 transformer/arrow-functions: Transform `this` and `super`
incorrectly in async arrow function (#8435 ) (Dunqing)
- 270245f transformer/typescript: Correct the semantic for
TSImportEqualsDeclaration transformation (#8463 ) (Dunqing)
- 2a400d6 transformer/typescript: Retain TSImportEqualsDeclaration when
it is exported (Dunqing)
- ab694b0 transformer/typescript: Retain `TSImportEqualsDeclaration` in
`namespace` when its binding has been referenced or
`onlyRemoveTypeImports` is true (#8458 ) (Dunqing)
### Performance
- 7a8200c mangler: Allocate base54 name without heap allocation (#8472 )
(Boshen)
- 31dac22 mangler: Allocate data in arena (#8471 ) (Boshen)
- 8fc238a minifier: Merge `Normalize` and `RemoveSyntax` pass (#8467 )
(Boshen)
- 372eb09 minifier: Preallocate mangler's semantic data (#8451 ) (Boshen)
### Refactor
- 6e64eef codegen: Remove `match_expression!` (#8450 ) (Boshen)
- de5b288 span: Rename `Atom::new_const` method (#8480 ) (overlookmotel)
- c83ce5c transformer/typescript: Improve transforming namespace (#8459 )
(Dunqing)
Co-authored-by: Boshen <1430279+Boshen@users.noreply.github.com>
2025-01-14 19:40:44 +08:00
Boshen
4c6675c46d
fix(minifier): do not convert while to fors in DCE ( #8484 )
2025-01-14 10:01:35 +00:00
Boshen
4ad695dcfb
feat(napi/minify): implement napi ( #8478 )
2025-01-14 08:55:55 +00:00
Boshen
8fc238ac34
perf(minifier): merge Normalize and RemoveSyntax pass ( #8467 )
2025-01-13 16:08:00 +00:00
Boshen
8accfefa74
feat(minifier): minify var x; void x -> void 0 ( #8466 )
2025-01-13 16:07:59 +00:00
Boshen
1d6e84dd33
fix(minifier): fix incorrect null.toString() and 1n.toString() ( #8464 )
2025-01-13 15:08:49 +00:00
Boshen
25d4bf9aad
fix(minifier): remove usage of empty spans ( #8462 )
2025-01-13 13:53:53 +00:00
Boshen
372eb09569
perf(minifier): preallocate mangler's semantic data ( #8451 )
2025-01-12 16:06:48 +00:00
Boshen
870a583ae5
feat(minifier): fold false['toString'] ( #8447 )
2025-01-12 13:17:59 +00:00
Boshen
dd643407dd
fix(minifier): keep return undefined in async generator function ( #8439 )
...
closes #8403
2025-01-12 02:02:15 +00:00
oxc-bot
01722f34ff
release(crates): v0.45.0 ( #8434 )
...
## [0.45.0] - 2025-01-11
- 7f69561 ast: [**BREAKING**] `oxc_ast` do not export `BigUint` (#8428 )
(overlookmotel)
- d8b27af ast: [**BREAKING**] No unneccesary trailing underscores on
`AstBuilder` method names (#8283 ) (overlookmotel)
- 5106088 ast: [**BREAKING**] Remove `FromIn<Expression> for Statement`
(#8280 ) (overlookmotel)
### Features
- 6c7acac allocator: Implement `IntoIterator` for `&mut Vec` (#8389 )
(overlookmotel)
- 3212bcd ast_tools: Ignore `raw` field of `NumericLiteral` and
`StringLiteral` in `ContentEq` (#8417 ) (Boshen)
- ad146bb codegen: Print real newline when `\n` is inside template
literals (#8178 ) (Boshen)
- 41ddf60 minfier: Add `CompressOptions::target` (#8179 ) (Boshen)
- d56020b minifier: Drop `0` from `new Int8Array(0)` and other
TypedArrays (#8431 ) (sapphi-red)
- f935d94 minifier: Remove `new` from NativeErrors / `AggregateError`
(#8430 ) (sapphi-red)
- dab7a51 minifier: Minimize not `!(x === undefined)` -> `x !==
undefined` (#8429 ) (Boshen)
- 0e7bab8 minifier: Remove `if(false){}` in a single pass (#8421 )
(Boshen)
- 5b5b844 minifier: Fold `ambiguous if else` (#8415 ) (Boshen)
- 438a6e7 minifier: Minimize conditions in boolean context (#8381 )
(Boshen)
- 793cb43 minifier: `a != null ? a : b` -> `a ?? b` (#8352 ) (camc314)
- 814da55 minifier: Compress `x = x || 1` to `x ||= 1` (#8368 )
(sapphi-red)
- a596821 minifier: Compress `a.b = a.b + c` to `a.b += c` (#8367 )
(sapphi-red)
- 579eb60 minifier: Compress `a.b || (a.b = c)` to `a.b ||= c` (#8366 )
(sapphi-red)
- f367a16 minifier: Port esbuild conditional expr minification (#8351 )
(camc314)
- 8d52cd0 minifier: Merge assign expression in conditional expression
(#8345 ) (sapphi-red)
- a69d15f minifier: Compress `new Array(2)` -> `[,,]` (#8344 )
(sapphi-red)
- 819c475 minifier: Compress `new Array(7n)` -> `[7n]` (#8343 )
(sapphi-red)
- e085d66 minifier: Remove empty IIFE (#8340 ) (Boshen)
- 2c2e483 minifier: Fold object spread `({ ...null })` -> `({})` (#8339 )
(Boshen)
- 6220e05 minifier: Remove empty if statment `if (test) {}` -> `test`
(#8336 ) (Boshen)
- a76dfae minifier: Remove label statement with empty body (#8333 )
(Boshen)
- e88a6bd minifier: Minimize `!0 + null !== 1` -> `!0 + null != 1`
(#8332 ) (Boshen)
- ec88c68 minifier: Compress `a || (a = b)` to `a ||= b` (#8315 )
(sapphi-red)
- e6fe84d minifier: Compress `a = a + b` to `a += b` (#8314 )
(sapphi-red)
- 9ea4e31 minifier: Remove `new` from `new Error`/`new Function`/`new
RegExp` (#8313 ) (sapphi-red)
- 051fbb6 minifier: Minimize `x["0"]` -> x[0] (#8316 ) (Boshen)
- a542013 minifier: Minimize `do{}while(true)` -> `do;while(true)`
(#8311 ) (Boshen)
- e3ff81e minifier: Minimize `(x = 1) === 1` -> `(x = 1) == 1` (#8310 )
(Boshen)
- 4b68cc0 minifier: Minimize empty `try` statement (#8309 ) (Boshen)
- 922c514 minifier: Fold `.toString()` (#8308 ) (Boshen)
- 66a2443 minifier: Minify sequence expressions (#8305 ) (camc314)
- af65c36 minifier: Minimize double negated binary expressions (#8304 )
(camc314)
- 76c778b minifier: Remove logical nots when arg is a delete expression
(#8303 ) (camc314)
- 5ed439b minifier: Minify typeof in binary expressions (#8302 )
(camc314)
- 6afc590 minifier: Compress typeof addition string (#8301 ) (camc314)
- ecc789f minifier: Fold `if(x >> y == 0){}` -> `if(!(x >> y)){}`
(#8277 ) (Boshen)
- 0e3b79a minifier: Fold `String()` -> `''`, `Number()` -> `false`
(#8274 ) (Boshen)
- c9cf593 minifier: Compress property key `{[1]: _}` -> {1: _} (#8272 )
(Boshen)
- b92b2ab minifier: Fold `BigInt(1n)` -> `1n` (#8270 ) (Boshen)
- a4df387 minifier: Compress loose equals undefined (#8268 ) (camc314)
- f000596 minifier: Minify call expressionsto `Number` (#8267 ) (camc314)
- 092aeaf minifier: Flatten spread args in call expressions (#8266 )
(camc314)
- 04ec38d minifier: Remove unused arrow function expressions (#8262 )
(camc314)
- e446c15 minifier: Improve minimizing unary not expressions (#8261 )
(camc314)
- 7f19211 minifier: Minimize unary expression statements (#8256 )
(camc314)
- cec63e2 minifier: `{}` evals to `f64::NaN` (Boshen)
- 4d8a08d minifier: Improve constant evaluation (#8252 ) (Boshen)
- e84f267 minifier: Compress more property keys (#8253 ) (Boshen)
- d1224f9 minifier: Improve minimizing conditional expressions (#8251 )
(camc314)
- 65f46f5 minifier: Constant fold `String.fromCharCode` (#8248 ) (Boshen)
- bd8d677 minifier: Minimize `~undefined`, `~null`, `~true`, `~false`
(#8247 ) (Boshen)
- f73dc9e minifier: Constant fold `'x'.toString()` and `true.toString()`
(#8246 ) (Boshen)
- fd5af73 minifier: Minimize `Number` constructor (#8245 ) (Boshen)
- 2f52f33 minifier: Minsize `!!!foo ? bar : baz` -> `foo ? baz : bar`
(#8244 ) (Boshen)
- ccdc039 minifier: Always put literals on the rhs of equal op `1==x` =>
`x==1` (#8240 ) (Boshen)
- 39353b2 minifier: Improve minimizing conditionals (#8238 ) (Cameron)
- c90fc16 minifier: Restore conditional minification and fix edge case
(#8235 ) (camc314)
- 6c8ee9f minifier: Remove last redundant `return` statement (#8234 )
(Boshen)
- 51f4792 minifier: Minimize `foo ? foo : bar` and `foo ? bar : foo`
(#8229 ) (Boshen)
- 6e2ec17 minifier: Statement fusion switch cases; improved minimize
exit poitns (#8228 ) (Boshen)
- 574a242 minifier: Minimize all variants of `typeof x == 'undefined'`
(#8227 ) (Boshen)
- 2041477 minifier: Fold `if(x)return;y` -> `if(!x)y` (#8226 ) (Boshen)
- 9c1afa4 minifier: Optional catch binding when catch param is unused
(#8221 ) (Boshen)
- 4a29845 minifier: Add `ConvertToDottedProperties` (#8212 ) (Boshen)
- 2786dea minifier: Add `RemoveUnusedCode` (#8210 ) (Boshen)
- cd274ee minifier: Minimize logical exprs (#8209 ) (Cameron)
- 4ae15df minifier: Imprve more conditional expr minification with
boolean lit (#8208 ) (camc314)
- 3202b4f minifier: Imprve conditional expr minification with boolean
lit (#8207 ) (camc314)
- 3b45011 minifier: Handle conditional expr with boolean lit (#8206 )
(camc314)
- 4c2059a minifier: Reverse negated conditional exprs (#8205 ) (camc314)
- 4804933 minifier: Add `MinimizeExitPoints` and ExploitAssigns`
boilerplate (#8203 ) (Boshen)
- bf266e1 minifier: Try collapse conditional to logical or expr (#8197 )
(Cameron)
- 06e1780 minifier: Improve `StatementFusion` (#8194 ) (Boshen)
- 42e211a minifier: Only constant fold numbers when result is smaller
(#8092 ) (Boshen)
- d0de560 minifier: Change `NaN` to `f64::NAN` (#8191 ) (Boshen)
- cef8eb8 minifier: Change `foo?.['bar']` to `foo?.bar` (#8176 ) (翠 /
green)
- 8149e34 minifier: Optional catch binding when es target >= es2019
(#8180 ) (Boshen)
- fc43ec5 minifier: Fold `string.length` / `array.length` (#8172 )
(sapphi-red)
- 29dc0dc minifier: Change `foo['bar']` -> foo.bar (#8169 ) (Boshen)
- 3c5718d minifier: Fold `typeof foo == undefined` into `foo ==
undefined` when possible (#8160 ) (翠 / green)
- f3a36e1 minifier: Fold `typeof foo != "undefined"` into `typeof foo <
"u"` (#8159 ) (翠 / green)
- 37c9959 minifier: Normalize `Infinity` into `f64::Infinity` (#8148 )
(Boshen)
- 8fb71f5 minifier: Minify string `PropertyKey` (#8147 ) (Boshen)
- 6615e1e minifier: Constant fold `instanceof` (#8142 ) (翠 / green)
- 2b2a373 minifier: Minimize `a + 'b' + 'c'` -> `a + 'bc'` (#8137 )
(Boshen)
- 213364a minifier: Minimize `if (x) if (y) z` -> `if (x && y) z`
(#8136 ) (Boshen)
- 6b51e6d minifier: Minimize `if(foo) bar else baz` -> `foo ? bar : baz`
(#8133 ) (Boshen)
- f615bfa minifier: Minimize `if (x) return; return 1` -> `return x ?
void 0 : 1` (#8130 ) (Boshen)
- f0b1ee5 minifier: Minimize `if(!x) foo()` -> `x || foo()` (#8122 )
(Boshen)
- f8200a8 minifier: Minimize `if(foo) bar` -> `foo && bar` (#8121 )
(Boshen)
- 72d9967 minifier: Add `Normalize` ast pass (#8120 ) (Boshen)
- fef0b25 minifier: Collapse `var` into for loop initializer (#8119 )
(Boshen)
- 2331ea8 minifier: `typeof foo === 'number'` => `typeof foo ==
'number'` (#8112 ) (Boshen)
- ad9a0a9 mininifier: Minimize variants of `a instanceof b == true`
(#8241 ) (Boshen)
- 2da4365 parser: Missing initializer in destructuring declaration
inside for loop head (#8222 ) (Boshen)
- 55744fd semantic: Allow getting mutable reference to symbols table
(#8189 ) (Max Stoumen)
- 0592a8b transformer/class-properties: Transform private in expression
(#8202 ) (Dunqing)
- ad77ad5 transformer/class-properties: Transform static/instance
accessor methods (#8132 ) (Dunqing)
- e405f79 transformer/class-properties: Transform static private method
invoking (#8117 ) (Dunqing)
- 3303e99 transformer/class-properties: Insert statements after
statement of class expression (#8116 ) (Dunqing)
- 0cc71cf transformer/class-properties: Transform super expressions and
identifiers that refers to class binding in private method (#8106 )
(Dunqing)
- 58ed832 transformer/class-properties: Transform private field
expression which invokes private method (#8102 ) (Dunqing)
- f14567a transformer/class-properties: Transform callee which invokes
private method (#8100 ) (Dunqing)
- 13349ef transformer/class-properties: Transform private methods
(#8099 ) (Dunqing)
### Bug Fixes
- eb25bc0 allocator: Fix lifetimes on `IntoIterator` for `Vec` (#8388 )
(overlookmotel)
- 97a7992 ast: Fix `ContentEq` and `ContentHash` impls for literal types
(#8426 ) (overlookmotel)
- a1752a0 codegen: Fix incorrect minified `return 1n` output (#8374 )
(Boshen)
- 5a648bc codegen: Fix white space issue with do statements (#8348 )
(Boshen)
- b6d16f4 codegen: Print parenthesis on negative bigint lit when
neccessary (#8258 ) (camc314)
- 8ed9766 codegen: Source map builder panicked because it attempted to
subtract with overflow in `search_original_line_and_column` (#8185 )
(Dunqing)
- ad61e70 codegen: Print if else without block with proper indentation
(#8135 ) (Boshen)
- 74572de ecmascript: Incorrect `to_int_32` value for Infinity (#8144 )
(翠 / green)
- e1f8ea4 lexer: `Source` is not `Clone` (#8294 ) (overlookmotel)
- 5c63414 mangler: Keep exported symbols for `top_level: true` (#7927 )
(翠 / green)
- 3c93549 minifier: Dce if statement should keep side effects and vars
(#8433 ) (Boshen)
- 52f88c0 minifier: Rotate associative operators to make it more
idempotent (#8424 ) (camc314)
- a80460c minifier: Correctly set `self.changed` when minimizing if
stmts (#8420 ) (camc314)
- d4ca8d4 minifier: `!!x` is not idempotent in `RemoveDeadCode` (#8419 )
(Boshen)
- 357b61d minifier: Do not minify `Object.defineProperty` in sequence
expressions (#8416 ) (Boshen)
- 0efc845 minifier: `+0n` produces `TypeError` (#8410 ) (Boshen)
- 7ce6a7c minifier: `a in b` has error throwing side effect (#8406 )
(Boshen)
- 2f3a9dc minifier: Cannot transform property key `#constructor` (#8405 )
(Boshen)
- c0a3dda minifier: `instanceof` has error throwing side effect (#8378 )
(Boshen)
- 5516f7f minifier: Do not fold object comparisons (#8375 ) (Boshen)
- cb098c7 minifier: Computed property key `prototype` cannot be changed
(#8373 ) (Boshen)
- 82ee77e minifier: Do not remove shadowned `undefined` in return
statement (#8371 ) (Boshen)
- f87da16 minifier: Do not fold literals in `-0 != +0` (#8278 ) (Boshen)
- 62a2644 minifier: Handle arrow fn expressions correctly in
`is_in_boolean_context` (#8260 ) (camc314)
- d2f8eaa minifier: Fix panic in `peephole_minimize_conditions` (#8242 )
(Boshen)
- a698def minifier: Fix incorrect return value for `(x ? true : y)`
(#8233 ) (Boshen)
- 05be1fc minifier: Remove incorrect fold
`Expression::AssignmentExpression` (#8211 ) (Boshen)
- 56b7f13 minifier: Do not constant fold `0 instanceof F` (#8199 )
(Boshen)
- 75d5f17 minifier: Minify string `PropertyKey` (#8177 ) (sapphi-red)
- f88acb3 parser: Allow line breaks between `const` and `enum` (#8193 )
(branchseer)
- 79a8fc6 semantic: Report error for super property appearing in
function body (#8376 ) (Dunqing)
- 79af100 semantic: Reference flags not correctly resolved when after an
export stmt (#8134 ) (camc314)
- 3eaff2a transformer: Ensure last expression statement in arrow
function expression is wrapped in return (#8192 ) (Dunqing)
- 3feac27 transformer/arrow-functions: Outer `super()` in nested class
(#8382 ) (Dunqing)
- 335065d transformer/arrow-functions: Do not transform super that
inside nested non-async method (#8335 ) (Dunqing)
- e4d66e4 transformer/arrow-functions: Store `super_methods` on a
`Stack` to fix nested async methods (#8331 ) (Dunqing)
- 775a289 transformer/arrow-functions: `_this = this` should be inserted
after super call expression (#8024 ) (Dunqing)
- ac72adb transformer/private-methods: Fix panic if instance private
accessor in class (#8362 ) (overlookmotel)
- f1f129b transformer/private-methods: Create brand binding `var` in
hoist scope (#8361 ) (overlookmotel)
- ab61425 transformer/private-methods: No temp var for class when unused
private methods (#8360 ) (overlookmotel)
- 9a03bd2 transformer/typescript: Remove type-only `import =` when
`only_remove_type_imports` is true (#8275 ) (Dunqing)
- 0df1866 transformer/typescript: Create `Reference` for `require`
(#8355 ) (overlookmotel)
- 78d7c97 transformer/typescript: Create `Reference` for `Infinity`
(#8354 ) (overlookmotel)
- 2e7207f transformer/typescript: Should strip import specifiers type
with `only_remove_type_imports` (#8141 ) (underfin)
### Performance
- 07edf74 transformer/arrow-function: Stop traversal at function as
super() can't appear in a nested function (#8383 ) (Dunqing)
- 62e3f7e transformer/arrow-functions: Reduce size of inlined visitor
(#8322 ) (overlookmotel)
- aebe0ea transformer/arrow-functions: Use `NonEmptyStack` instead of
`Stack` (#8318 ) (overlookmotel)
### Documentation
- c8e4843 ast: Fix doc comment (#8286 ) (overlookmotel)
- e0a09ab data_structures: Improve docs for stack types (#8356 )
(overlookmotel)
- aaa009d minifier: Clarify assumptions for compressor (#8404 ) (翠 /
green)
- 05cba5b transformer/private-methods: Amend comments (#8398 )
(overlookmotel)
### Refactor
- b29655f ast: Rearrange impls for literal types in same order as they
are defined (#8425 ) (overlookmotel)
- 0db2a22 ast: `AstBuilder` enum builder methods use `alloc_*` methods
(#8281 ) (overlookmotel)
- aea9551 ast: Simplify `get_identifier_reference` of `TSType` and
`TSTypeName` (#8273 ) (Dunqing)
- 9c1844a data_structures: Remove `NonNull` shim (#8423 ) (overlookmotel)
- 1835687 ecmascript: Remove unnecessary `use` statement (#8284 )
(overlookmotel)
- 64bfdfe lexer: Tighten safety of lexer by always including lifetime on
`SourcePosition` (#8293 ) (overlookmotel)
- 0344e98 lexer: Make `handle_byte` a method of `Lexer` (#8291 )
(overlookmotel)
- fabf116 lexer: Replace `#[allow]` with `#[expect]` (#8289 )
(overlookmotel)
- 0462edb lexer: Rename function param (#8288 ) (overlookmotel)
- fb2acd8 minifier: Change minimize conditionals into a loop (#8413 )
(Boshen)
- baaec60 minifier: Remove the buggy `??` transform (#8411 ) (Boshen)
- 1c4658d minifier: Change ast passes order, `!in_fixed_loop` happen
last (#8380 ) (Boshen)
- 09f0f48 minifier: Remove the buggy `minimize_exit_points`
implementation (#8349 ) (Boshen)
- 9a5c66a minifier: Clean up (#8346 ) (Boshen)
- 98f2b1c minifier: Clean up `peephole_substitute_alternate_syntax`
(#8327 ) (Boshen)
- fc662b7 minifier: Handle big int values later (#8324 ) (Boshen)
- d16e598 minifier: Clean up `peephole_replace_known_methods` (#8306 )
(Boshen)
- b8d26ea minifier: Move optional catch param to
peephole_substitute_alternate_syntax (#8282 ) (Boshen)
- 0845162 minifier: Clean up `ReplaceKnownMethods` (Boshen)
- 7c7f5d7 minifier: Clean up `peephole_fold_constants` (Boshen)
- bf0fbce minifier: Improve constant fold numbers (#8239 ) (Boshen)
- 62f8fba minifier: Move all conditional minification logic to
minimze_conditions (#8231 ) (camc314)
- cfb51f2 minifier: Fuse ast passes (#8184 ) (Boshen)
- bf9cafe minifier: Clean up `peephole_substitute_alternate_syntax` a
little bit (Boshen)
- 75264ed minifier: Clean up `try_optimize_block` (#8139 ) (Boshen)
- c22062b minifier: Cleanup peephole_minimize_conditions (#8114 )
(Boshen)
- e594c39 minifier: Clean up `peephole_substitute_alternate_syntax.rs`
(#8111 ) (Boshen)
- 0903501 semantic: Check super usage based on scope (#8377 ) (Dunqing)
- 109b8fc transformer: Elide lifetimes where possible (#8285 )
(overlookmotel)
- fb389f7 transformer/arrow-function: Create a new ident instead of
clone (#8338 ) (Dunqing)
- dddbd29 transformer/arrow-functions: Reorder assertions (#8386 )
(overlookmotel)
- ce6c445 transformer/arrow-functions: Add TODO comments (#8328 )
(overlookmotel)
- 73d0025 transformer/arrow-functions: Reduce repeated code (#8323 )
(overlookmotel)
- 3dd08e9 transformer/arrow-functions: Do not inline non-trivial visitor
method (#8321 ) (overlookmotel)
- ea9cefb transformer/arrow-functions: Reorder visitor methods (#8320 )
(overlookmotel)
- 37199a4 transformer/arrow-functions: Rename lifetime (#8319 )
(overlookmotel)
- 57e9dcf transformer/arrow-functions: Shorten `AstBuilder` call (#8317 )
(overlookmotel)
- a5e3528 transformer/async-to-generator: Pass `TraverseCtx` to function
not `AstBuilder` (#8279 ) (overlookmotel)
- e7c89ba transformer/class-properties: TODO comments (#8392 )
(overlookmotel)
- 6790d1d transformer/class-properties: Simplify determining if class is
declaration (#8357 ) (overlookmotel)
- c786a13 transformer/class-properties: Share
`replace_class_name_with_temp_var` in class_properties (#8105 ) (Dunqing)
- f54f48e transformer/class-properties: Remove all `*_if_super` methods
in `static_block_and_prop_init` (#8104 ) (Dunqing)
- d82fb52 transformer/class-properties: Move `supers` to
`super_converter` (#8103 ) (Dunqing)
- 3dad85e transformer/private-methods: Remove unnecessary clone (#8400 )
(overlookmotel)
- aa5e65f transformer/private-methods: Simplify finding parent statement
of class expression (#8364 ) (overlookmotel)
- c786fd1 transformer/private-methods: TODO comments (#8363 )
(overlookmotel)
### Styling
- 4d2888d lexer: Reorder imports (#8290 ) (overlookmotel)
- e81f34f span: Reformat code (#8296 ) (overlookmotel)
- 45e2402 transformer/private-methods: Move comments (#8399 )
(overlookmotel)
- 0a1ffc0 transformer/private-methods: Rename var (#8397 )
(overlookmotel)
### Testing
- 16dcdaf lexer: Assert size of `Token` in 32-bit WASM (#8292 )
(overlookmotel)
- 3149fe0 minifier: Add anonymous function test case for logical
expression to logical assignment compression (#8347 ) (sapphi-red)
- 91b42de minifier: Enable some passing tests (#8250 ) (camc314)
- 1fa5341 minifier: Port tests from ConvertToDottedPropertiesTest
(#8175 ) (sapphi-red)
Co-authored-by: Boshen <1430279+Boshen@users.noreply.github.com>
2025-01-11 22:34:31 +08:00
Boshen
3c9354983d
fix(minifier): dce if statement should keep side effects and vars ( #8433 )
...
closes #7209
Note: Current output is sub-optimal.
2025-01-11 14:02:12 +00:00
sapphi-red
d56020b84c
feat(minifier): drop 0 from new Int8Array(0) and other TypedArrays ( #8431 )
...
Compresses `new Int8Array(0)` into `new Int8Array()`. (then will be compress into `new Int8Array`).
Partial quote from the [spec](https://tc39.es/ecma262/multipage/indexed-collections.html#sec-typedarray ):
> 5. If numberOfArgs = 0, then
> a. Return ? AllocateTypedArray(constructorName, NewTarget, proto, 0).
> 6. Else,
> c. Else,
> ii. Let elementLength be ? ToIndex(firstArgument).
> iii. Return ? AllocateTypedArray(constructorName, NewTarget, proto, elementLength).
2025-01-11 07:45:36 +00:00
sapphi-red
f935d9434f
feat(minifier): remove new from NativeErrors / AggregateError ( #8430 )
...
Remove `new` in the some cases:
- NativeErrors (e.g. `new EvalError(...)` -> `EvalError(...)`): [spec](https://tc39.es/ecma262/multipage/fundamental-objects.html#sec-nativeerror-constructors:~:text=the%20function%20call%20NativeError(%E2%80%A6)%20is%20equivalent%20to%20the%20object%20creation%20expression%20new%20NativeError(%E2%80%A6)%20with%20the%20same%20arguments .), [the list of NativeErrors in spec](https://tc39.es/ecma262/multipage/fundamental-objects.html#sec-native-error-types-used-in-this-standard )
- `new AggregateError(...)` -> `AggregateError(...)`: [spec](https://tc39.es/ecma262/multipage/fundamental-objects.html#sec-aggregate-error-constructor:~:text=the%20function%20call%20AggregateError(%E2%80%A6)%20is%20equivalent%20to%20the%20object%20creation%20expression%20new%20AggregateError(%E2%80%A6)%20with%20the%20same%20arguments .)
2025-01-11 07:23:07 +00:00
Boshen
dab7a51e78
feat(minifier): minimize not !(x === undefined) -> x !== undefined ( #8429 )
2025-01-11 06:30:36 +00:00
camc314
52f88c0e9c
fix(minifier): rotate associative operators to make it more idempotent ( #8424 )
...
another **massive** pain to debug
~~https://github.com/oxc-project/monitor-oxc/actions/runs/12717213600~~
https://github.com/oxc-project/monitor-oxc/actions/runs/12717978983/job/35455601146
2025-01-11 01:12:10 +00:00
camc314
a80460c6fe
fix(minifier): correctly set self.changed when minimizing if stmts ( #8420 )
...
Before:
```
==== Input ====
require('./index.js')(function (e, os) {
if (e) return console.log(e)
return console.log(JSON.stringify(os))
})
==== First Minification
require("./index.js")(function(e, os) {
return console.log(e ? e : JSON.stringify(os));
});
==== Second Minification ====
require("./index.js")(function(e, os) {
return console.log(e || JSON.stringify(os));
});
same = false
```
After:
```
==== Input ====
require('./index.js')(function (e, os) {
if (e) return console.log(e)
return console.log(JSON.stringify(os))
})
==== First Minification ====
require("./index.js")(function(e, os) {
return console.log(e || JSON.stringify(os));
});
==== Second Minification ====
require("./index.js")(function(e, os) {
return console.log(e || JSON.stringify(os));
});
same = true
```
2025-01-11 01:12:09 +00:00
Boshen
0e7bab887f
feat(minifier): remove if(false){} in a single pass ( #8421 )
2025-01-10 16:22:09 +00:00
Boshen
d4ca8d4f5c
fix(minifier): !!x is not idempotent in RemoveDeadCode ( #8419 )
2025-01-10 15:31:11 +00:00
Boshen
0550e81da6
chore(minifier): add oxc_minifier/examples/dce.rs ( #8418 )
2025-01-10 15:05:36 +00:00
Boshen
357b61d179
fix(minifier): do not minify Object.defineProperty in sequence expressions ( #8416 )
2025-01-10 12:04:39 +00:00
Boshen
5b5b8443f4
feat(minifier): fold ambiguous if else ( #8415 )
2025-01-10 19:51:31 +08:00
Boshen
fb2acd87b3
refactor(minifier): change minimize conditionals into a loop ( #8413 )
2025-01-10 09:49:09 +00:00
Boshen
baaec6020c
refactor(minifier): remove the buggy ?? transform ( #8411 )
...
e.g. `(a != null ? a : b);` is not `a ?? b`
There are also no unit tests.
2025-01-10 09:33:09 +00:00
Boshen
0efc845c97
fix(minifier): +0n produces TypeError ( #8410 )
2025-01-10 07:18:06 +00:00
翠 / green
5c63414c23
fix(mangler): keep exported symbols for top_level: true ( #7927 )
...
~~I'm not going to work on a fix for a while so feel free to fix it if
anyone wants to work on it.~~
Exported symbols are now not mangled.
2025-01-10 15:14:30 +08:00
Boshen
d15c856b13
chore(rust): update clippy rules ( #8408 )
2025-01-10 06:41:53 +00:00
Boshen
7ce6a7c741
fix(minifier): a in b has error throwing side effect ( #8406 )
2025-01-10 05:23:07 +00:00
Boshen
2f3a9dc74c
fix(minifier): cannot transform property key #constructor ( #8405 )
2025-01-10 04:04:05 +00:00
Boshen
438a6e7abc
feat(minifier): minimize conditions in boolean context ( #8381 )
2025-01-10 03:47:10 +00:00
翠 / green
aaa009dd4d
docs(minifier): clarify assumptions for compressor ( #8404 )
...
Listed the assumptions that the compressor probably makes.
2025-01-10 11:37:41 +08:00
renovate
772b71c838
chore(deps): update dependency rust to v1.84.0 ( #8391 )
...
This PR contains the following updates:
| Package | Update | Change |
|---|---|---|
| [rust](https://redirect.github.com/rust-lang/rust ) | minor | `1.83.0` -> `1.84.0` |
---
### Release Notes
<details>
<summary>rust-lang/rust (rust)</summary>
### [`v1.84.0`](https://redirect.github.com/rust-lang/rust/blob/HEAD/RELEASES.md#Version-1840-2025-01-09 )
[Compare Source](https://redirect.github.com/rust-lang/rust/compare/1.83.0...1.84.0 )
\==========================
<a id="
Language"></a>
## Language
- [Allow `#[deny]` inside `#[forbid]` as a no-op](https://redirect.github.com/rust-lang/rust/pull/121560/ )
- [Show a warning when `-Ctarget-feature` is used to toggle features that can lead to unsoundness due to ABI mismatches](https://redirect.github.com/rust-lang/rust/pull/129884 )
- [Use the next-generation trait solver in coherence](https://redirect.github.com/rust-lang/rust/pull/130654 )
- [Allow coercions to drop the principal of trait objects](https://redirect.github.com/rust-lang/rust/pull/131857 )
- [Support `/` as the path separator for `include!()` in all cases on Windows](https://redirect.github.com/rust-lang/rust/pull/125205 )
- [Taking a raw ref (`raw (const|mut)`) of a deref of a pointer (`*ptr`) is now safe](https://redirect.github.com/rust-lang/rust/pull/129248 )
- [Stabilize s390x inline assembly](https://redirect.github.com/rust-lang/rust/pull/131258 )
- [Stabilize Arm64EC inline assembly](https://redirect.github.com/rust-lang/rust/pull/131781 )
- [Lint against creating pointers to immediately dropped temporaries](https://redirect.github.com/rust-lang/rust/pull/128985 )
- [Execute drop glue when unwinding in an `extern "C"` function](https://redirect.github.com/rust-lang/rust/pull/129582 )
<a id="1.84.0-Compiler"></a>
## Compiler
- [Add `--print host-tuple` flag to print the host target tuple and affirm the "target tuple" terminology over "target triple"](https://redirect.github.com/rust-lang/rust/pull/125579 )
- [Declaring functions with a calling convention not supported on the current target now triggers a hard error](https://redirect.github.com/rust-lang/rust/pull/129935 )
- [Set up indirect access to external data for `loongarch64-unknown-linux-{musl,ohos}`](https://redirect.github.com/rust-lang/rust/pull/131583 )
- [Enable XRay instrumentation for LoongArch Linux targets](https://redirect.github.com/rust-lang/rust/pull/131818 )
- [Extend the `unexpected_cfgs` lint to also warn in external macros](https://redirect.github.com/rust-lang/rust/pull/132577 )
- [Stabilize WebAssembly `multivalue`, `reference-types`, and `tail-call` target features](https://redirect.github.com/rust-lang/rust/pull/131080 )
- [Added Tier 2 support for the `wasm32v1-none` target](https://redirect.github.com/rust-lang/rust/pull/131487 )
<a id="1.84.0-Libraries"></a>
## Libraries
- [Implement `From<&mut {slice}>` for `Box/Rc/Arc<{slice}>`](https://redirect.github.com/rust-lang/rust/pull/129329 )
- [Move `<float>::copysign`, `<float>::abs`, `<float>::signum` to `core`](https://redirect.github.com/rust-lang/rust/pull/131304 )
- [Add `LowerExp` and `UpperExp` implementations to `NonZero`](https://redirect.github.com/rust-lang/rust/pull/131377 )
- [Implement `FromStr` for `CString` and `TryFrom<CString>` for `String`](https://redirect.github.com/rust-lang/rust/pull/130608 )
- [`std::os::darwin` has been made public](https://redirect.github.com/rust-lang/rust/pull/123723 )
<a id="1.84.0-Stabilized-APIs"></a>
## Stabilized APIs
- [`Ipv6Addr::is_unique_local`](https://doc.rust-lang.org/stable/core/net/struct.Ipv6Addr.html#method.is_unique_local )
- [`Ipv6Addr::is_unicast_link_local`](https://doc.rust-lang.org/stable/core/net/struct.Ipv6Addr.html#method.is_unicast_link_local )
- [`core::ptr::with_exposed_provenance`](https://doc.rust-lang.org/stable/core/ptr/fn.with_exposed_provenance.html )
- [`core::ptr::with_exposed_provenance_mut`](https://doc.rust-lang.org/stable/core/ptr/fn.with_exposed_provenance_mut.html )
- [`<ptr>::addr`](https://doc.rust-lang.org/stable/core/primitive.pointer.html#method.addr )
- [`<ptr>::expose_provenance`](https://doc.rust-lang.org/stable/core/primitive.pointer.html#method.expose_provenance )
- [`<ptr>::with_addr`](https://doc.rust-lang.org/stable/core/primitive.pointer.html#method.with_addr )
- [`<ptr>::map_addr`](https://doc.rust-lang.org/stable/core/primitive.pointer.html#method.map_addr )
- [`<int>::isqrt`](https://doc.rust-lang.org/stable/core/primitive.i32.html#method.isqrt )
- [`<int>::checked_isqrt`](https://doc.rust-lang.org/stable/core/primitive.i32.html#method.checked_isqrt )
- [`<uint>::isqrt`](https://doc.rust-lang.org/stable/core/primitive.u32.html#method.isqrt )
- [`NonZero::isqrt`](https://doc.rust-lang.org/stable/core/num/struct.NonZero.html#impl-NonZero%3Cu128%3E/method.isqrt )
- [`core::ptr::without_provenance`](https://doc.rust-lang.org/stable/core/ptr/fn.without_provenance.html )
- [`core::ptr::without_provenance_mut`](https://doc.rust-lang.org/stable/core/ptr/fn.without_provenance_mut.html )
- [`core::ptr::dangling`](https://doc.rust-lang.org/stable/core/ptr/fn.dangling.html )
- [`core::ptr::dangling_mut`](https://doc.rust-lang.org/stable/core/ptr/fn.dangling_mut.html )
These APIs are now stable in const contexts
- [`AtomicBool::from_ptr`](https://doc.rust-lang.org/stable/core/sync/atomic/struct.AtomicBool.html#method.from_ptr )
- [`AtomicPtr::from_ptr`](https://doc.rust-lang.org/stable/core/sync/atomic/struct.AtomicPtr.html#method.from_ptr )
- [`AtomicU8::from_ptr`](https://doc.rust-lang.org/stable/core/sync/atomic/struct.AtomicU8.html#method.from_ptr )
- [`AtomicU16::from_ptr`](https://doc.rust-lang.org/stable/core/sync/atomic/struct.AtomicU16.html#method.from_ptr )
- [`AtomicU32::from_ptr`](https://doc.rust-lang.org/stable/core/sync/atomic/struct.AtomicU32.html#method.from_ptr )
- [`AtomicU64::from_ptr`](https://doc.rust-lang.org/stable/core/sync/atomic/struct.AtomicU64.html#method.from_ptr )
- [`AtomicUsize::from_ptr`](https://doc.rust-lang.org/stable/core/sync/atomic/struct.AtomicUsize.html#method.from_ptr )
- [`AtomicI8::from_ptr`](https://doc.rust-lang.org/stable/core/sync/atomic/struct.AtomicI8.html#method.from_ptr )
- [`AtomicI16::from_ptr`](https://doc.rust-lang.org/stable/core/sync/atomic/struct.AtomicI16.html#method.from_ptr )
- [`AtomicI32::from_ptr`](https://doc.rust-lang.org/stable/core/sync/atomic/struct.AtomicI32.html#method.from_ptr )
- [`AtomicI64::from_ptr`](https://doc.rust-lang.org/stable/core/sync/atomic/struct.AtomicI64.html#method.from_ptr )
- [`AtomicIsize::from_ptr`](https://doc.rust-lang.org/stable/core/sync/atomic/struct.AtomicIsize.html#method.from_ptr )
- [`<ptr>::is_null`](https://doc.rust-lang.org/stable/core/primitive.pointer.html#method.is_null-1 )
- [`<ptr>::as_ref`](https://doc.rust-lang.org/stable/core/primitive.pointer.html#method.as_ref-1 )
- [`<ptr>::as_mut`](https://doc.rust-lang.org/stable/core/primitive.pointer.html#method.as_mut )
- [`Pin::new`](https://doc.rust-lang.org/stable/core/pin/struct.Pin.html#method.new )
- [`Pin::new_unchecked`](https://doc.rust-lang.org/stable/core/pin/struct.Pin.html#method.new_unchecked )
- [`Pin::get_ref`](https://doc.rust-lang.org/stable/core/pin/struct.Pin.html#method.get_ref )
- [`Pin::into_ref`](https://doc.rust-lang.org/stable/core/pin/struct.Pin.html#method.into_ref )
- [`Pin::get_mut`](https://doc.rust-lang.org/stable/core/pin/struct.Pin.html#method.get_mut )
- [`Pin::get_unchecked_mut`](https://doc.rust-lang.org/stable/core/pin/struct.Pin.html#method.get_unchecked_mut )
- [`Pin::static_ref`](https://doc.rust-lang.org/stable/core/pin/struct.Pin.html#method.static_ref )
- [`Pin::static_mut`](https://doc.rust-lang.org/stable/core/pin/struct.Pin.html#method.static_mut )
<a id="1.84.0-Cargo"></a>
## Cargo
- [Stabilize MSRV-aware resolver config](https://redirect.github.com/rust-lang/cargo/pull/14639/ )
- [Stabilize resolver v3](https://redirect.github.com/rust-lang/cargo/pull/14754/ )
<a id="1.84-Rustdoc"></a>
## Rustdoc
- [rustdoc-search: improve type-driven search](https://redirect.github.com/rust-lang/rust/pull/127589 )
<a id="1.84.0-Compatibility-Notes"></a>
## Compatibility Notes
- [Enable by default the `LSX` target feature for LoongArch Linux targets](https://redirect.github.com/rust-lang/rust/pull/132140 )
- [The unstable `-Zprofile` flag (“gcov-style” coverage instrumentation) has been removed.](https://redirect.github.com/rust-lang/rust/pull/131829 ) This does not affect the stable flags for coverage instrumentation (`-Cinstrument-coverage`) and profile-guided optimization (`-Cprofile-generate`, `-Cprofile-use`), which are unrelated and remain available.
- Support for the target named `wasm32-wasi` has been removed as the target is now named `wasm32-wasip1`. This completes the [transition](https://redirect.github.com/rust-lang/compiler-team/issues/607 ) [plan](https://redirect.github.com/rust-lang/compiler-team/issues/695 ) for this target following [the introduction of `wasm32-wasip1`](https://redirect.github.com/rust-lang/rust/pull/120468 ) in Rust 1.78. Compiler warnings on [use of `wasm32-wasi`](https://redirect.github.com/rust-lang/rust/pull/126662 ) introduced in Rust 1.81 are now gone as well as the target is removed.
- [The syntax `&pin (mut|const) T` is now parsed as a type which in theory could affect macro expansion results in some edge cases](https://redirect.github.com/rust-lang/rust/pull/130635#issuecomment-2375462821 )
- [Legacy syntax for calling `std::arch` functions is no longer permitted to declare items or bodies (such as closures, inline consts, or async blocks).](https://redirect.github.com/rust-lang/rust/pull/130443#issuecomment-2445678945 )
- The `wasm32-unknown-emscripten` target's binary release of the standard library is now [built with the latest emsdk 3.1.68](https://redirect.github.com/rust-lang/rust/pull/131533 ), which fixes an ABI-incompatibility with Emscripten >= 3.1.42. If you are locally using a version of emsdk with an incompatible ABI (e.g. before 3.1.42 or a future one), you should build your code with `-Zbuild-std` to ensure that `std` uses the correct ABI.
- [Declaring functions with a calling convention not supported on the current target now triggers a hard error](https://redirect.github.com/rust-lang/rust/pull/129935 )
- [The next-generation trait solver is now enabled for coherence, fixing multiple soundness issues](https://redirect.github.com/rust-lang/rust/pull/130654 )
</details>
---
### Configuration
📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - "before 11am on monday" in timezone Asia/Shanghai.
🚦 **Automerge**: Enabled.
♻ **Rebasing**: Whenever PR is behind base branch, or you tick the rebase/retry checkbox.
🔕 **Ignore**: Close this PR and you won't be reminded about this update again.
---
- [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box
---
This PR was generated by [Mend Renovate](https://mend.io/renovate/ ). View the [repository job log](https://developer.mend.io/github/oxc-project/oxc ).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzOS45Mi4wIiwidXBkYXRlZEluVmVyIjoiMzkuOTIuMCIsInRhcmdldEJyYW5jaCI6Im1haW4iLCJsYWJlbHMiOltdfQ==-->
2025-01-09 18:11:17 +00:00
overlookmotel
6c7acac72e
feat(allocator): implement IntoIterator for &mut Vec ( #8389 )
...
Implement `IntoIterator` for `&mut Vec` like `std::vec::Vec` does. This allows shorter and more idiomatic syntax.
Before:
```rs
for item in object.collection.iter_mut() {
// ...
}
```
After:
```rs
for item in &mut object.collection {
// ...
}
```
2025-01-09 15:32:16 +00:00
camc314
793cb43138
feat(minifier): a != null ? a : b -> a ?? b ( #8352 )
2025-01-09 10:12:52 +00:00
Boshen
1c4658d617
refactor(minifier): change ast passes order, !in_fixed_loop happen last ( #8380 )
2025-01-09 07:45:20 +00:00
Boshen
c0a3ddac28
fix(minifier): instanceof has error throwing side effect ( #8378 )
2025-01-09 06:49:27 +00:00
Boshen
5516f7fcb9
fix(minifier): do not fold object comparisons ( #8375 )
2025-01-09 05:47:35 +00:00
Boshen
cb098c7d3c
fix(minifier): computed property key prototype cannot be changed ( #8373 )
2025-01-09 04:24:03 +00:00
Boshen
82ee77ef19
fix(minifier): do not remove shadowned undefined in return statement ( #8371 )
...
closes #8370
2025-01-09 04:03:18 +00:00
sapphi-red
814da55f81
feat(minifier): compress x = x || 1 to x ||= 1 ( #8368 )
...
The simplified version of the evaluation of `a = a || b` is:
> AssignmentExpression : LeftHandSideExpression = LogicalORExpression || LogicalANDExpression
> 1. Let lRef be ? Evaluation of LeftHandSideExpression.
> 2. Let llRef be ? Evaluation of LogicalORExpression.
> 3. Let llVal be ? GetValue(llRef).
> 4. If ToBoolean(llVal) is true
> a. Perform ? PutValue(lRef, llVal).
> b. return llVal.
> 5. Let lrRef be ? Evaluation of LogicalANDExpression.
> 6. Let rRef be ? GetValue(lrRef).
> 7. Let rVal be ? GetValue(rRef). [Note GetValue(rRef) returns rRef itself]
> 8. Perform ? PutValue(lRef, rVal).
> 9. Return rVal.
The simplified version of the evaluation of `a ||= b` is:
> AssignmentExpression : LeftHandSideExpression ||= AssignmentExpression
> 1. Let lRef be ? Evaluation of LeftHandSideExpression.
> 2. Let lVal be ? GetValue(lRef).
> 3. If ToBoolean(lVal) is true, return lVal.
> 4. Let rRef be ? Evaluation of AssignmentExpression.
> 5. Let rVal be ? GetValue(rRef).
> 6. Perform ? PutValue(lRef, rVal).
> 7. Return rVal.
The difference of these is that
- the evaluation of `a` is done twice for `a = a || b`, one with `1. Let lRef be ? Evaluation of LeftHandSideExpression` and one with `2. Let llRef be ? Evaluation of LogicalORExpression.`. This is same with #8366 , #8367 .
- `PutValue(lRef, llVal)` is performed when `ToBoolean(lVal)` is `true`.
So `x = x || 1` can be compressed to `x ||= 1` when the conditions written in #8366 are met and `PutValue(lRef, llVal)` does not have a side effect. When `a` is a non-global identifier (and not a reference created by a `with` statement), these conditions are met.
**References**
- [Spec of `||`](https://tc39.es/ecma262/multipage/ecmascript-language-expressions.html#sec-binary-logical-operators-runtime-semantics-evaluation )
- [Spec of `=` / `||=`](https://tc39.es/ecma262/multipage/ecmascript-language-expressions.html#sec-binary-logical-operators-runtime-semantics-evaluation )
2025-01-09 03:47:12 +00:00