Skip to content

Commit

Permalink
fix(es/codegen): Respect ascii_only for identifiers (#7247)
Browse files Browse the repository at this point in the history
**Related issue:**

 - #7240.
  • Loading branch information
kdy1 committed Apr 11, 2023
1 parent 33ff2ba commit e35097f
Show file tree
Hide file tree
Showing 2 changed files with 180 additions and 3 deletions.
162 changes: 159 additions & 3 deletions crates/swc_ecma_codegen/src/lib.rs
Expand Up @@ -2128,8 +2128,17 @@ where

srcmap!(ident, true);
// TODO: span
self.wr
.write_symbol(DUMMY_SP, &handle_invalid_unicodes(&ident.sym))?;

if self.cfg.ascii_only {
self.wr.write_symbol(
DUMMY_SP,
&get_ascii_only_ident(&handle_invalid_unicodes(&ident.sym), self.cfg.target),
)?;
} else {
self.wr
.write_symbol(DUMMY_SP, &handle_invalid_unicodes(&ident.sym))?;
}

if ident.optional {
punct!("?");
}
Expand Down Expand Up @@ -3579,8 +3588,155 @@ fn get_template_element_from_raw(s: &str, ascii_only: bool) -> String {
buf
}

fn get_ascii_only_ident(sym: &str, target: EsVersion) -> Cow<str> {
if sym.chars().all(|c| c.is_ascii()) {
return Cow::Borrowed(sym);
}

let mut buf = String::with_capacity(sym.len() + 8);
let mut iter = sym.chars().peekable();

while let Some(c) = iter.next() {
match c {
'\x00' => {
buf.push_str("\\x00");
}
'\u{0008}' => buf.push_str("\\b"),
'\u{000c}' => buf.push_str("\\f"),
'\n' => buf.push_str("\\n"),
'\r' => buf.push_str("\\r"),
'\u{000b}' => buf.push_str("\\v"),
'\t' => buf.push('\t'),
'\\' => {
let next = iter.peek();

match next {
// TODO fix me - workaround for surrogate pairs
Some('u') => {
let mut inner_iter = iter.clone();

inner_iter.next();

let mut is_curly = false;
let mut next = inner_iter.peek();

if next == Some(&'{') {
is_curly = true;

inner_iter.next();
next = inner_iter.peek();
}

if let Some(c @ 'D' | c @ 'd') = next {
let mut inner_buf = String::new();

inner_buf.push('\\');
inner_buf.push('u');

if is_curly {
inner_buf.push('{');
}

inner_buf.push(*c);

inner_iter.next();

let mut is_valid = true;

for _ in 0..3 {
let c = inner_iter.next();

match c {
Some('0'..='9') | Some('a'..='f') | Some('A'..='F') => {
inner_buf.push(c.unwrap());
}
_ => {
is_valid = false;

break;
}
}
}

if is_curly {
inner_buf.push('}');
}

if is_valid {
buf.push_str(&inner_buf);

let end = if is_curly { 7 } else { 5 };

for _ in 0..end {
iter.next();
}
}
} else {
buf.push_str("\\\\");
}
}
_ => {
buf.push_str("\\\\");
}
}
}
'\'' => {
buf.push('\'');
}
'"' => {
buf.push('"');
}
'\x01'..='\x0f' => {
let _ = write!(buf, "\\x0{:x}", c as u8);
}
'\x10'..='\x1f' => {
let _ = write!(buf, "\\x{:x}", c as u8);
}
'\x20'..='\x7e' => {
buf.push(c);
}
'\u{7f}'..='\u{ff}' => {
let _ = write!(buf, "\\x{:x}", c as u8);
}
'\u{2028}' => {
buf.push_str("\\u2028");
}
'\u{2029}' => {
buf.push_str("\\u2029");
}
'\u{FEFF}' => {
buf.push_str("\\uFEFF");
}
_ => {
if c.is_ascii() {
buf.push(c);
} else if c > '\u{FFFF}' {
// if we've got this far the char isn't reserved and if the callee has specified
// we should output unicode for non-ascii chars then we have
// to make sure we output unicode that is safe for the target
// Es5 does not support code point escapes and so surrograte formula must be
// used
if target <= EsVersion::Es5 {
// https://mathiasbynens.be/notes/javascript-encoding#surrogate-formulae
let h = ((c as u32 - 0x10000) / 0x400) + 0xd800;
let l = (c as u32 - 0x10000) % 0x400 + 0xdc00;

let _ = write!(buf, "\\u{:04X}\\u{:04X}", h, l);
} else {
let _ = write!(buf, "\\u{{{:04X}}}", c as u32);
}
} else {
let _ = write!(buf, "\\u{:04X}", c as u16);
}
}
}
}

Cow::Owned(buf)
}

fn get_quoted_utf16(v: &str, ascii_only: bool, target: EsVersion) -> String {
let mut buf = String::with_capacity(v.len());
let mut buf = String::with_capacity(v.len() + 2);
let mut iter = v.chars().peekable();

let mut single_quote_count = 0;
Expand Down
21 changes: 21 additions & 0 deletions crates/swc_ecma_codegen/src/tests.rs
Expand Up @@ -868,3 +868,24 @@ fn ascii_only_tpl_lit() {
},
);
}

#[test]
fn ascii_only_issue_7240() {
test_all(
r"
export default {
\u3131: '\u11B0',
}
",
r"
export default {
\u3131: '\u11B0'
};
",
r##"export default{\u3131:"\u11B0"}"##,
Config {
ascii_only: true,
..Default::default()
},
);
}

1 comment on commit e35097f

@github-actions
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Benchmark

Benchmark suite Current: e35097f Previous: 559d120 Ratio
es/full/bugs-1 315765 ns/iter (± 16102) 303972 ns/iter (± 2787) 1.04
es/full/minify/libraries/antd 1587314589 ns/iter (± 19895504) 1632955795 ns/iter (± 51258387) 0.97
es/full/minify/libraries/d3 298140636 ns/iter (± 10277053) 304914250 ns/iter (± 12568438) 0.98
es/full/minify/libraries/echarts 1213888651 ns/iter (± 16868572) 1231987932 ns/iter (± 47344545) 0.99
es/full/minify/libraries/jquery 90506682 ns/iter (± 1547090) 88761084 ns/iter (± 1532737) 1.02
es/full/minify/libraries/lodash 106162635 ns/iter (± 1649507) 104541419 ns/iter (± 2085302) 1.02
es/full/minify/libraries/moment 52864156 ns/iter (± 314137) 52889369 ns/iter (± 734479) 1.00
es/full/minify/libraries/react 19436642 ns/iter (± 327834) 19258895 ns/iter (± 287549) 1.01
es/full/minify/libraries/terser 247667293 ns/iter (± 1780584) 244736861 ns/iter (± 5232656) 1.01
es/full/minify/libraries/three 444968535 ns/iter (± 6147193) 450722409 ns/iter (± 10455313) 0.99
es/full/minify/libraries/typescript 2938249500 ns/iter (± 20180615) 3053062376 ns/iter (± 47867101) 0.96
es/full/minify/libraries/victory 675348497 ns/iter (± 8650905) 693572441 ns/iter (± 7285310) 0.97
es/full/minify/libraries/vue 133376074 ns/iter (± 3929929) 131748134 ns/iter (± 1630164) 1.01
es/full/codegen/es3 28949 ns/iter (± 56) 28787 ns/iter (± 277) 1.01
es/full/codegen/es5 29086 ns/iter (± 62) 28993 ns/iter (± 126) 1.00
es/full/codegen/es2015 29080 ns/iter (± 57) 29083 ns/iter (± 459) 1.00
es/full/codegen/es2016 29051 ns/iter (± 48) 29274 ns/iter (± 34) 0.99
es/full/codegen/es2017 29105 ns/iter (± 60) 28993 ns/iter (± 271) 1.00
es/full/codegen/es2018 29111 ns/iter (± 75) 28576 ns/iter (± 433) 1.02
es/full/codegen/es2019 29152 ns/iter (± 62) 28448 ns/iter (± 120) 1.02
es/full/codegen/es2020 29129 ns/iter (± 83) 28901 ns/iter (± 123) 1.01
es/full/all/es3 185362398 ns/iter (± 2452259) 181837823 ns/iter (± 2794068) 1.02
es/full/all/es5 176126921 ns/iter (± 1900434) 173302375 ns/iter (± 1188257) 1.02
es/full/all/es2015 138050433 ns/iter (± 2557908) 134372305 ns/iter (± 1361398) 1.03
es/full/all/es2016 133995062 ns/iter (± 2435533) 131092045 ns/iter (± 2126445) 1.02
es/full/all/es2017 130843956 ns/iter (± 2904641) 128042887 ns/iter (± 2710592) 1.02
es/full/all/es2018 127578322 ns/iter (± 5242779) 124602920 ns/iter (± 1875507) 1.02
es/full/all/es2019 126857185 ns/iter (± 1868445) 124879962 ns/iter (± 1274757) 1.02
es/full/all/es2020 119153484 ns/iter (± 1529293) 118093511 ns/iter (± 1391534) 1.01
es/full/parser 514532 ns/iter (± 8043) 509922 ns/iter (± 4215) 1.01
es/full/base/fixer 22959 ns/iter (± 35) 24093 ns/iter (± 101) 0.95
es/full/base/resolver_and_hygiene 86955 ns/iter (± 137) 82821 ns/iter (± 698) 1.05
serialization of serde 121 ns/iter (± 0) 121 ns/iter (± 1) 1
css/minify/libraries/bootstrap 27315175 ns/iter (± 77955) 27760778 ns/iter (± 223920) 0.98
css/visitor/compare/clone 2128723 ns/iter (± 10897) 2221787 ns/iter (± 129687) 0.96
css/visitor/compare/visit_mut_span 2342959 ns/iter (± 3555) 2651781 ns/iter (± 9357) 0.88
css/visitor/compare/visit_mut_span_panic 2383127 ns/iter (± 3439) 2718716 ns/iter (± 19777) 0.88
css/visitor/compare/fold_span 3095908 ns/iter (± 12829) 3495269 ns/iter (± 27377) 0.89
css/visitor/compare/fold_span_panic 3233969 ns/iter (± 16785) 3656735 ns/iter (± 14529) 0.88
css/lexer/bootstrap_5_1_3 5106207 ns/iter (± 20864) 5031181 ns/iter (± 61702) 1.01
css/lexer/foundation_6_7_4 4341285 ns/iter (± 2778) 4201523 ns/iter (± 22171) 1.03
css/lexer/tailwind_3_1_1 823718 ns/iter (± 305) 815300 ns/iter (± 9040) 1.01
css/parser/bootstrap_5_1_3 21199935 ns/iter (± 180394) 21237712 ns/iter (± 200511) 1.00
css/parser/foundation_6_7_4 16879038 ns/iter (± 102723) 16638610 ns/iter (± 277703) 1.01
css/parser/tailwind_3_1_1 3246933 ns/iter (± 8807) 3246653 ns/iter (± 26017) 1.00
es/codegen/colors 326502 ns/iter (± 185653) 327901 ns/iter (± 188401) 1.00
es/codegen/large 1254649 ns/iter (± 659051) 1294096 ns/iter (± 665545) 0.97
es/codegen/with-parser/colors 47538 ns/iter (± 379) 47178 ns/iter (± 623) 1.01
es/codegen/with-parser/large 509736 ns/iter (± 1045) 501090 ns/iter (± 6495) 1.02
es/minify/libraries/antd 1341652799 ns/iter (± 11979495) 1352989374 ns/iter (± 78541943) 0.99
es/minify/libraries/d3 254833439 ns/iter (± 5060070) 249245662 ns/iter (± 11021965) 1.02
es/minify/libraries/echarts 1035409227 ns/iter (± 16025202) 1094717066 ns/iter (± 28291970) 0.95
es/minify/libraries/jquery 79403099 ns/iter (± 502181) 79181930 ns/iter (± 1411704) 1.00
es/minify/libraries/lodash 95793180 ns/iter (± 1780742) 94689352 ns/iter (± 1831390) 1.01
es/minify/libraries/moment 46085189 ns/iter (± 391089) 45167341 ns/iter (± 700419) 1.02
es/minify/libraries/react 17305582 ns/iter (± 483210) 17059033 ns/iter (± 131940) 1.01
es/minify/libraries/terser 207192230 ns/iter (± 4322670) 206097902 ns/iter (± 3977396) 1.01
es/minify/libraries/three 356461583 ns/iter (± 8604742) 376714766 ns/iter (± 10334038) 0.95
es/minify/libraries/typescript 2495097778 ns/iter (± 17433550) 2663000614 ns/iter (± 67752570) 0.94
es/minify/libraries/victory 543344743 ns/iter (± 11798925) 592189789 ns/iter (± 14598142) 0.92
es/minify/libraries/vue 114630589 ns/iter (± 1046688) 117599643 ns/iter (± 2225245) 0.97
es/visitor/compare/clone 2300601 ns/iter (± 15291) 2553019 ns/iter (± 72849) 0.90
es/visitor/compare/visit_mut_span 2669819 ns/iter (± 4551) 2972212 ns/iter (± 6922) 0.90
es/visitor/compare/visit_mut_span_panic 2736173 ns/iter (± 3926) 2979890 ns/iter (± 29837) 0.92
es/visitor/compare/fold_span 3788995 ns/iter (± 8268) 4099984 ns/iter (± 39460) 0.92
es/visitor/compare/fold_span_panic 3936930 ns/iter (± 4055) 4249287 ns/iter (± 27679) 0.93
es/lexer/colors 13119 ns/iter (± 8) 12857 ns/iter (± 138) 1.02
es/lexer/angular 6347651 ns/iter (± 4325) 6285982 ns/iter (± 46784) 1.01
es/lexer/backbone 784698 ns/iter (± 599) 763971 ns/iter (± 8769) 1.03
es/lexer/jquery 4390041 ns/iter (± 3049) 4278000 ns/iter (± 53747) 1.03
es/lexer/jquery mobile 6861509 ns/iter (± 3825) 6693427 ns/iter (± 57342) 1.03
es/lexer/mootools 3444117 ns/iter (± 7475) 3369881 ns/iter (± 22492) 1.02
es/lexer/underscore 647442 ns/iter (± 349) 643971 ns/iter (± 1711) 1.01
es/lexer/three 20869670 ns/iter (± 15039) 20492090 ns/iter (± 222007) 1.02
es/lexer/yui 3855536 ns/iter (± 1848) 3836361 ns/iter (± 21555) 1.00
es/parser/colors 29031 ns/iter (± 62) 28989 ns/iter (± 307) 1.00
es/parser/angular 15055752 ns/iter (± 256691) 14922404 ns/iter (± 240595) 1.01
es/parser/backbone 2164260 ns/iter (± 11209) 2139135 ns/iter (± 36651) 1.01
es/parser/jquery 11876406 ns/iter (± 114220) 11843667 ns/iter (± 107874) 1.00
es/parser/jquery mobile 18449123 ns/iter (± 395140) 17874106 ns/iter (± 283744) 1.03
es/parser/mootools 8979694 ns/iter (± 21625) 8957854 ns/iter (± 56957) 1.00
es/parser/underscore 1824504 ns/iter (± 9665) 1834347 ns/iter (± 9100) 0.99
es/parser/three 54310520 ns/iter (± 449054) 55733867 ns/iter (± 561884) 0.97
es/parser/yui 9111370 ns/iter (± 28895) 9172182 ns/iter (± 95816) 0.99
es/preset-env/usage/builtin_type 143892 ns/iter (± 33607) 139762 ns/iter (± 30919) 1.03
es/preset-env/usage/property 21278 ns/iter (± 61) 21108 ns/iter (± 135) 1.01
es/resolver/typescript 110315223 ns/iter (± 2852671) 122363347 ns/iter (± 2373076) 0.90
es/fixer/typescript 79881524 ns/iter (± 1958158) 91435732 ns/iter (± 1986008) 0.87
es/hygiene/typescript 167594849 ns/iter (± 1225488) 192286710 ns/iter (± 1945461) 0.87
es/resolver_with_hygiene/typescript 301102017 ns/iter (± 2901350) 321963156 ns/iter (± 3094799) 0.94
es/visitor/base-perf/module_clone 81252 ns/iter (± 584) 80110 ns/iter (± 1030) 1.01
es/visitor/base-perf/fold_empty 90782 ns/iter (± 734) 87714 ns/iter (± 361) 1.03
es/visitor/base-perf/fold_noop_impl_all 90804 ns/iter (± 345) 89405 ns/iter (± 699) 1.02
es/visitor/base-perf/fold_noop_impl_vec 90754 ns/iter (± 320) 90652 ns/iter (± 831) 1.00
es/visitor/base-perf/boxing_boxed_clone 58 ns/iter (± 0) 56 ns/iter (± 0) 1.04
es/visitor/base-perf/boxing_unboxed_clone 41 ns/iter (± 0) 41 ns/iter (± 0) 1
es/visitor/base-perf/boxing_boxed 102 ns/iter (± 0) 101 ns/iter (± 1) 1.01
es/visitor/base-perf/boxing_unboxed 78 ns/iter (± 0) 78 ns/iter (± 0) 1
es/visitor/base-perf/visit_contains_this 3504 ns/iter (± 75) 3437 ns/iter (± 68) 1.02
es/base/parallel/resolver/typescript 6252530668 ns/iter (± 446322032) 6276850805 ns/iter (± 525929933) 1.00
es/base/parallel/hygiene/typescript 2008230070 ns/iter (± 26527131) 2219023652 ns/iter (± 12161507) 0.91
misc/visitors/time-complexity/time 5 99 ns/iter (± 0) 96 ns/iter (± 0) 1.03
misc/visitors/time-complexity/time 10 331 ns/iter (± 0) 328 ns/iter (± 2) 1.01
misc/visitors/time-complexity/time 15 649 ns/iter (± 10) 640 ns/iter (± 11) 1.01
misc/visitors/time-complexity/time 20 1197 ns/iter (± 1) 1175 ns/iter (± 12) 1.02
misc/visitors/time-complexity/time 40 6521 ns/iter (± 41) 6516 ns/iter (± 61) 1.00
misc/visitors/time-complexity/time 60 17054 ns/iter (± 43) 16688 ns/iter (± 217) 1.02
es/full-target/es2016 252839 ns/iter (± 659) 252704 ns/iter (± 1141) 1.00
es/full-target/es2017 246169 ns/iter (± 511) 239357 ns/iter (± 2563) 1.03
es/full-target/es2018 235305 ns/iter (± 301) 229942 ns/iter (± 2709) 1.02
es2020_nullish_coalescing 92660 ns/iter (± 438) 91033 ns/iter (± 1123) 1.02
es2020_optional_chaining 125484 ns/iter (± 242) 124589 ns/iter (± 207) 1.01
es2022_class_properties 148987 ns/iter (± 379) 147028 ns/iter (± 1166) 1.01
es2018_object_rest_spread 95929 ns/iter (± 238) 95131 ns/iter (± 609) 1.01
es2019_optional_catch_binding 85547 ns/iter (± 162) 84658 ns/iter (± 1065) 1.01
es2017_async_to_generator 86072 ns/iter (± 176) 85350 ns/iter (± 461) 1.01
es2016_exponentiation 90480 ns/iter (± 249) 89417 ns/iter (± 1039) 1.01
es2015_arrow 94225 ns/iter (± 185) 93687 ns/iter (± 561) 1.01
es2015_block_scoped_fn 92323 ns/iter (± 143) 91427 ns/iter (± 646) 1.01
es2015_block_scoping 169692 ns/iter (± 300) 169367 ns/iter (± 472) 1.00

This comment was automatically generated by workflow using github-action-benchmark.

Please sign in to comment.