mirror of
https://github.com/aphrody-labs/oxc.git
synced 2026-10-14 06:09:20 +00:00
JavaScript strings can contain lone surrogates, which Rust's `str` cannot hold. String literal values and template cooked values stored them in a private U+FFFD escape encoding behind a `lone_surrogates` flag that every consumer had to check. This migrates `StringLiteral::value` and `TemplateElementValue::cooked` to `JSStr`, which keeps the exact UTF-16 value through parsing, AST consumers, codegen and ESTree/raw transfer. Code that needs Rust text calls `JSStr::as_str()`, which returns `None` for a value with a lone surrogate. Surrogate halves written as separate escapes or concatenated from separate parts are joined. Enum members whose name or value contains a lone surrogate keep their string kind, so lowering no longer emits a reverse mapping for a string alias that could overwrite another member. Some lint and declaration checks skip lone-surrogate names until #26677, #27095, #26716 and #26717. ## Breaking changes - `StringLiteral::value` is `JSStr<'a>`, and `TemplateElementValue::cooked` is `Option<JSStr<'a>>`. - Removed: the `lone_surrogates` fields, the `*_with_lone_surrogates` builder methods, `oxc_parser::Token::lone_surrogates`, and `impl Display for StringLiteral`. - `ImportAttributeKey::as_arena_str` is renamed to `as_js_str`. `TSEnumMemberName::static_name`, `TemplateLiteral::single_quasi` and `ModuleRunnerTransform::transform` return `JSStr`. - `oxc_estree::LoneSurrogatesString` wraps an iterator of code points. - `ModuleExportName::name` panics on a string name with a lone surrogate, which only a built AST can contain. Part of #26242. Implemented with AI assistance.