Skip to content

Commit 8d9bf4c

Browse files
authoredJan 14, 2024
fix(es/codegen): Fix codegen of a property key in ascii-only mode (#8493)
**Related issue:** - Closes #8491
1 parent 0c28f72 commit 8d9bf4c

File tree

6 files changed

+78
-10
lines changed

6 files changed

+78
-10
lines changed
 

‎crates/swc/tests/fixture/issues-7xxx/7805/output/1.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,8 @@ var SUPPORTED_LOCALE = {
2121
I: "i\u0307",
2222
J: "j\u0307",
2323
\u012E: "\u012F\u0307",
24-
\u00CC: "i\u0307\u0300",
25-
\u00CD: "i\u0307\u0301",
24+
"\xcc": "i\u0307\u0300",
25+
"\xcd": "i\u0307\u0301",
2626
\u0128: "i\u0307\u0303"
2727
}
2828
}
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
1-
function p(\u00B5, \u03C3) {}
1+
function p(\xb5, \u03C3) {}
22
console.log(p);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
{
2+
"jsc": {
3+
"parser": {
4+
"syntax": "ecmascript",
5+
"jsx": false
6+
},
7+
"target": "es5",
8+
"loose": false,
9+
"minify": {
10+
"compress": true,
11+
"format": {
12+
"asciiOnly": true
13+
}
14+
}
15+
},
16+
"module": {
17+
"type": "es6"
18+
},
19+
"minify": false,
20+
"isModule": true
21+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
const a = { aób: 'ó' }
2+
3+
console.log(a)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
console.log({
2+
"a\xf3b": "\xf3"
3+
});

‎crates/swc_ecma_codegen/src/lib.rs

+48-7
Original file line numberDiff line numberDiff line change
@@ -1721,7 +1721,33 @@ where
17211721
fn emit_prop_name(&mut self, node: &PropName) -> Result {
17221722
match node {
17231723
PropName::Ident(ident) => {
1724-
emit!(ident)
1724+
// TODO: Use write_symbol when ident is a symbol.
1725+
self.emit_leading_comments_of_span(ident.span, false)?;
1726+
1727+
// Source map
1728+
self.wr.commit_pending_semi()?;
1729+
1730+
srcmap!(ident, true);
1731+
1732+
if self.cfg.ascii_only {
1733+
if self.wr.can_ignore_invalid_unicodes() {
1734+
self.wr.write_symbol(
1735+
DUMMY_SP,
1736+
&get_ascii_only_ident(&ident.sym, true, self.cfg.target),
1737+
)?;
1738+
} else {
1739+
self.wr.write_symbol(
1740+
DUMMY_SP,
1741+
&get_ascii_only_ident(
1742+
&handle_invalid_unicodes(&ident.sym),
1743+
true,
1744+
self.cfg.target,
1745+
),
1746+
)?;
1747+
}
1748+
} else {
1749+
emit!(ident);
1750+
}
17251751
}
17261752
PropName::Str(ref n) => emit!(n),
17271753
PropName::Num(ref n) => emit!(n),
@@ -2259,12 +2285,18 @@ where
22592285

22602286
if self.cfg.ascii_only {
22612287
if self.wr.can_ignore_invalid_unicodes() {
2262-
self.wr
2263-
.write_symbol(DUMMY_SP, &get_ascii_only_ident(&ident.sym, self.cfg.target))?;
2288+
self.wr.write_symbol(
2289+
DUMMY_SP,
2290+
&get_ascii_only_ident(&ident.sym, false, self.cfg.target),
2291+
)?;
22642292
} else {
22652293
self.wr.write_symbol(
22662294
DUMMY_SP,
2267-
&get_ascii_only_ident(&handle_invalid_unicodes(&ident.sym), self.cfg.target),
2295+
&get_ascii_only_ident(
2296+
&handle_invalid_unicodes(&ident.sym),
2297+
false,
2298+
self.cfg.target,
2299+
),
22682300
)?;
22692301
}
22702302
} else if self.wr.can_ignore_invalid_unicodes() {
@@ -3751,14 +3783,15 @@ fn get_template_element_from_raw(s: &str, ascii_only: bool) -> String {
37513783
buf
37523784
}
37533785

3754-
fn get_ascii_only_ident(sym: &str, target: EsVersion) -> Cow<str> {
3786+
fn get_ascii_only_ident(sym: &str, may_need_quote: bool, target: EsVersion) -> Cow<str> {
37553787
if sym.chars().all(|c| c.is_ascii()) {
37563788
return Cow::Borrowed(sym);
37573789
}
37583790

37593791
let mut first = true;
37603792
let mut buf = String::with_capacity(sym.len() + 8);
37613793
let mut iter = sym.chars().peekable();
3794+
let mut need_quote = false;
37623795

37633796
while let Some(c) = iter.next() {
37643797
match c {
@@ -3859,7 +3892,11 @@ fn get_ascii_only_ident(sym: &str, target: EsVersion) -> Cow<str> {
38593892
'\x20'..='\x7e' => {
38603893
buf.push(c);
38613894
}
3862-
'\u{7f}'..='\u{ff}' if !first => {
3895+
'\u{7f}'..='\u{ff}' => {
3896+
if may_need_quote {
3897+
need_quote = true;
3898+
}
3899+
38633900
let _ = write!(buf, "\\x{:x}", c as u8);
38643901
}
38653902
'\u{2028}' => {
@@ -3897,7 +3934,11 @@ fn get_ascii_only_ident(sym: &str, target: EsVersion) -> Cow<str> {
38973934
first = false;
38983935
}
38993936

3900-
Cow::Owned(buf)
3937+
if need_quote {
3938+
Cow::Owned(format!("\"{}\"", buf))
3939+
} else {
3940+
Cow::Owned(buf)
3941+
}
39013942
}
39023943

39033944
fn get_quoted_utf16(v: &str, ascii_only: bool, target: EsVersion) -> String {

0 commit comments

Comments
 (0)
Please sign in to comment.