mirror of
https://github.com/oxc-project/oxc.git
synced 2026-11-04 10:29:58 +00:00
String constant evaluation used `Cow<str>`, so folds stopped at any string with a lone surrogate. `ConstantValue::String` now holds a `JSStr`, so these strings fold too, and results are built with `JSStrBuilder`, which joins surrogate halves the way the runtime does.
`indexOf`, `lastIndexOf`, `substring` and `slice` now share one UTF-16 code-unit implementation for every string. This also fixes miscompiles on main: `'éx'.indexOf('x')` folded to 2, `'abc'.indexOf('a', 4294967296)` to 0, `'abab'.lastIndexOf('b', NaN)` to -1, and `'abc'.substring(1, void 0)` to `''`. It includes #27097, which is closed.
String `concat` calls and chains fold into a template only when no argument with side effects follows one that may be an object, so `''.concat(a, (a.push(1), 'x'))` no longer becomes `` `${a}${(a.push(1), 'x')}` ``.
## Breaking changes
- `ConstantValue::String` holds `JSStr<'a>`, and `ConstantValue::into_string`, `evaluate_value_to_string` and `get_side_free_string_value` return `JSStr<'a>`.
- `StringIndexOf` and `StringLastIndexOf` take the search value as `JSStr` and use UTF-16 code unit positions.
- `StringSubstring` is removed.
Closes #15524. Closes #25158. Closes #26053. Based on #27096. Part of #26242. Continues #26759.
Implemented with AI assistance.