fix(es/codegen): Fix codegen of a property key in ascii-only mode (#8493)

**Related issue:**

 - Closes #8491
This commit is contained in:
Donny/강동윤 2024-01-14 17:11:08 +09:00 committed by GitHub
parent 0c28f7217a
commit 8d9bf4cfaa
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 78 additions and 10 deletions

View File

@ -21,8 +21,8 @@ var SUPPORTED_LOCALE = {
I: "i\u0307",
J: "j\u0307",
\u012E: "\u012F\u0307",
\u00CC: "i\u0307\u0300",
\u00CD: "i\u0307\u0301",
"\xcc": "i\u0307\u0300",
"\xcd": "i\u0307\u0301",
\u0128: "i\u0307\u0303"
}
}

View File

@ -1,2 +1,2 @@
function p(\u00B5, \u03C3) {}
function p(\xb5, \u03C3) {}
console.log(p);

View File

@ -0,0 +1,21 @@
{
"jsc": {
"parser": {
"syntax": "ecmascript",
"jsx": false
},
"target": "es5",
"loose": false,
"minify": {
"compress": true,
"format": {
"asciiOnly": true
}
}
},
"module": {
"type": "es6"
},
"minify": false,
"isModule": true
}

View File

@ -0,0 +1,3 @@
const a = { aób: 'ó' }
console.log(a)

View File

@ -0,0 +1,3 @@
console.log({
"a\xf3b": "\xf3"
});

View File

@ -1721,7 +1721,33 @@ where
fn emit_prop_name(&mut self, node: &PropName) -> Result {
match node {
PropName::Ident(ident) => {
emit!(ident)
// TODO: Use write_symbol when ident is a symbol.
self.emit_leading_comments_of_span(ident.span, false)?;
// Source map
self.wr.commit_pending_semi()?;
srcmap!(ident, true);
if self.cfg.ascii_only {
if self.wr.can_ignore_invalid_unicodes() {
self.wr.write_symbol(
DUMMY_SP,
&get_ascii_only_ident(&ident.sym, true, self.cfg.target),
)?;
} else {
self.wr.write_symbol(
DUMMY_SP,
&get_ascii_only_ident(
&handle_invalid_unicodes(&ident.sym),
true,
self.cfg.target,
),
)?;
}
} else {
emit!(ident);
}
}
PropName::Str(ref n) => emit!(n),
PropName::Num(ref n) => emit!(n),
@ -2259,12 +2285,18 @@ where
if self.cfg.ascii_only {
if self.wr.can_ignore_invalid_unicodes() {
self.wr
.write_symbol(DUMMY_SP, &get_ascii_only_ident(&ident.sym, self.cfg.target))?;
self.wr.write_symbol(
DUMMY_SP,
&get_ascii_only_ident(&ident.sym, false, self.cfg.target),
)?;
} else {
self.wr.write_symbol(
DUMMY_SP,
&get_ascii_only_ident(&handle_invalid_unicodes(&ident.sym), self.cfg.target),
&get_ascii_only_ident(
&handle_invalid_unicodes(&ident.sym),
false,
self.cfg.target,
),
)?;
}
} else if self.wr.can_ignore_invalid_unicodes() {
@ -3751,7 +3783,7 @@ fn get_template_element_from_raw(s: &str, ascii_only: bool) -> String {
buf
}
fn get_ascii_only_ident(sym: &str, target: EsVersion) -> Cow<str> {
fn get_ascii_only_ident(sym: &str, may_need_quote: bool, target: EsVersion) -> Cow<str> {
if sym.chars().all(|c| c.is_ascii()) {
return Cow::Borrowed(sym);
}
@ -3759,6 +3791,7 @@ fn get_ascii_only_ident(sym: &str, target: EsVersion) -> Cow<str> {
let mut first = true;
let mut buf = String::with_capacity(sym.len() + 8);
let mut iter = sym.chars().peekable();
let mut need_quote = false;
while let Some(c) = iter.next() {
match c {
@ -3859,7 +3892,11 @@ fn get_ascii_only_ident(sym: &str, target: EsVersion) -> Cow<str> {
'\x20'..='\x7e' => {
buf.push(c);
}
'\u{7f}'..='\u{ff}' if !first => {
'\u{7f}'..='\u{ff}' => {
if may_need_quote {
need_quote = true;
}
let _ = write!(buf, "\\x{:x}", c as u8);
}
'\u{2028}' => {
@ -3897,7 +3934,11 @@ fn get_ascii_only_ident(sym: &str, target: EsVersion) -> Cow<str> {
first = false;
}
Cow::Owned(buf)
if need_quote {
Cow::Owned(format!("\"{}\"", buf))
} else {
Cow::Owned(buf)
}
}
fn get_quoted_utf16(v: &str, ascii_only: bool, target: EsVersion) -> String {